Make
Makefile未連結所需的依賴項
首先成功製作了兩個目標執行檔:
$ rm build/* bin/* $ make g++ -Wall -g -c -o build/Person.o src/Person.cpp g++ -Wall -g -c -o build/PersonTests.o test/PersonTests.cpp g++ -Wall -g -o bin/TestPerson build/Person.o build/PersonTests.o g++ -Wall -g -c -o build/State.o src/State.cpp g++ -Wall -g -c -o build/StateTests.o test/StateTests.cpp g++ -Wall -g -o bin/TestState build/State.o build/StateTests.o
但是,當我編輯 PersonTests.cpp(包含 main 函式)時,它無法辨識我嘗試測試的類的成員:
$ touch test/PersonTests.cpp $ make g++ -Wall -g -c -o build/PersonTests.o test/PersonTests.cpp g++ -Wall -g -o bin/TestPerson build/PersonTests.o build/PersonTests.o: In function `main': Bridge/test/PersonTests.cpp:14: undefined reference to `Person::Cross(Person&, Person&)' Bridge/test/PersonTests.cpp:15: undefined reference to `Person::CrossBack(Person&)' Bridge/test/PersonTests.cpp:17: undefined reference to `operator<<(std::ostream&, Person const&)' Bridge/test/PersonTests.cpp:17: undefined reference to `operator<<(std::ostream&, Person const&)' Bridge/test/PersonTests.cpp:17: undefined reference to `operator<<(std::ostream&, Person const&)' Bridge/test/PersonTests.cpp:19: undefined reference to `Person::Cross(Person&, Person&)' Bridge/test/PersonTests.cpp:20: undefined reference to `Person::CrossBack(Person&)' collect2: error: ld returned 1 exit status Makefile:10: recipe for target 'bin/TestPerson' failed make: *** [bin/TestPerson] Error 1
然後再次使用 make 有效嗎?顯示:
$ make g++ -Wall -g -o bin/TestPerson build/Person.o build/PersonTests.o
我是使用 make 的新手,並假設我的問題是由於我的 Makefile:
CXX = g++ CXXFLAGS = -Wall -g #------EXECUTABLES------ all : bin/TestPerson bin/TestState #bin/BridgeSolution bin/BridgeSolution : build/main.o build/Person.o build/State.o $(CXX) $(CXXFLAGS) -o $@ $? bin/TestPerson : build/Person.o build/PersonTests.o $(CXX) $(CXXFLAGS) -o $@ $? bin/TestState : build/State.o build/StateTests.o $(CXX) $(CXXFLAGS) -o $@ $? #----------------------- #-----TEST_OBJECTS------ build/PersonTests.o : test/PersonTests.cpp build/Person.o include/Person.h $(CXX) $(CXXFLAGS) -c -o $@ $< build/StateTests.o : test/StateTests.cpp build/State.o include/State.h $(CXX) $(CXXFLAGS) -c -o $@ $< #----------------------- #--------OBJECTS-------- build/main.o : src/main.cpp include/State.h $(CXX) $(CXXFLAGS) -c -o $@ $< build/Person.o : src/Person.cpp include/Person.h $(CXX) $(CXXFLAGS) -c -o $@ $< build/State.o : src/State.cpp include/State.h include/Person.h $(CXX) $(CXXFLAGS) -c -o $@ $< #-----------------------
我了解問題與輸出行的差異有關:
g++ -Wall -g -o bin/TestPerson build/Person.o build/PersonTests.o
g++ -Wall -g -o bin/TestPerson build/PersonTests.o
但我不知道為什麼會這樣
在 Makefile 的這一部分:
bin/BridgeSolution : build/main.o build/Person.o build/State.o $(CXX) $(CXXFLAGS) -o $@ $? bin/TestPerson : build/Person.o build/PersonTests.o $(CXX) $(CXXFLAGS) -o $@ $? bin/TestState : build/State.o build/StateTests.o $(CXX) $(CXXFLAGS) -o $@ $?
你需要使用
$^
,而不是$?
。$?
表示比目標更新的先決條件子集;因此,當您在建構後進行編輯時,進行重新PersonTests.cpp
建構,這是唯一比 更新的先決條件,因此變為.TestPerson``PersonTests.o``TestPerson``TestPerson``$?``TestPerson.o
如果你寫
$(CXX) $(CXXFLAGS) -o $@ $^
取而代之的是,配方將一直擴展為包括所有先決條件。