Makefile이 필수 종속성을 연결하지 않습니다.

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를 편집하면 테스트하려는 클래스의 멤버가 인식되지 않습니다.

$ 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.cppTestPersonPersonTests.oTestPersonTestPerson$?TestPerson.o

당신이 쓴다면

        $(CXX) $(CXXFLAGS) -o $@ $^

대신, 레시피는 항상 모든 필수 구성 요소를 포함하도록 확장됩니다.

관련 정보