首先成功制作了两个目标可执行文件:
$ 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
但我不知道为什么会发生这种情况
答案1
在 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
,Make会重建,并且这是比 更新PersonTests.o
的唯一先决条件,因此变为。TestPerson
TestPerson
$?
TestPerson.o
如果你写
$(CXX) $(CXXFLAGS) -o $@ $^
相反,配方将被扩展以始终包含所有先决条件。