Я только начал использовать make файлы и столкнулся с проблемой. (Проект C++)
Я пытаюсь создать цепочку зависимостей:
main.cpp зависит от класса a. А класс a зависит от класса b.
Основная идея состоит в том, чтобы перекомпилировать класс a, используя allready скомпилированный класс b, тогда как класс a не имеет функции main(). (Когда класс a изменен)
Makefile
all: main.o
main.o: main.cpp classa.o
g++ main.cpp classa.o -o main.o
classa.o: classa.h classa.cpp classb.o
g++ -c classa.cpp classb.o -o classa.o
classb.o: classb.h classb.cpp
g++ -c classb.cpp -o classb.o
main.cpp
#include "classa.h"
int main() {
ClassA a;
return 0;
}
classa.h
#ifndef CLASSA_H
#define CLASSA_H
#include "classb.h"
class ClassA {
private:
ClassB b;
public:
ClassA();
};
#endif // CLASSA_H
classa.cpp
#include "classa.h"
ClassA::ClassA() {
}
classb.h
#ifndef CLASSB_H
#define CLASSB_H
class ClassB {
public:
ClassB();
};
#endif // CLASSB_H
classb.cpp
#include "classb.h"
ClassB::ClassB() {
}
Когда я использую make -f makefile, я получаю следующую ошибку:
g++ -c classb.cpp -o classb.o
g++ -c classa.cpp classb.o -o classa.o
g++: warning: classb.o: linker input file unused because linking not done
g++ main.cpp classa.o -o main.o
classa.o: In function 'ClassA::ClassA()':
classa.cpp:(.text+0x18): undefined reference to 'ClassB::ClassB()'
collect2: error: ld returned 1 exit status
makefile:4: recipe for target 'main.o' failed
make: *** [main.o] Error 1
Я считаю, что он начинается с повторного использования classb.o с параметром -c.
Мне -c является магическое "использование, когда я компилирую код без параметра main()".
Я был бы счастлив, если бы вы могли просветить меня, где я поступил не так, и возможно, что я пытаюсь сделать.
С уважением, шоколад
Ваш make файл должен выглядеть следующим образом:
all: main
main: main.cpp classa.o classb.o
g++ main.cpp classa.o classb.o -o main
classa.o: classa.h classa.cpp
g++ -c classa.cpp -o classa.o
classb.o: classb.h classb.cpp
g++ -c classb.cpp -o classb.o
Вы .o
файлы .o
из файлов .cpp
а затем связываете файлы .o
с окончательным выходом (также созданным из файла .cpp
).
Вам необходимо указать все соответствующие объектные файлы при связывании и не нужно -c
их при компиляции (что происходит, когда вы используете флаг -c
который указывает gcc
пропустить шаг связывания).
Ключ здесь заключается в том, что classa.o
не зависит от classb.o
или classb.cpp
(он, вероятно, зависит от classb.h
хотя в этом случае вы можете добавить это к требованиям). Полностью связанный двоичный файл зависит от обоих из них, и они тогда зависят друг от друга по мере необходимости.
Тем не менее, вы можете значительно упростить вышеупомянутый make файл, не указав свои собственные правила и просто используя встроенные правила. Следующий make файл должен делать то, что вы хотите.
all: main
main: classa.o classb.o
classa.o: classa.h
classb.o: classb.h
Если вам понадобятся пользовательские флаги компилятора/компоновщика, вы можете использовать переменные по умолчанию, чтобы использовать их в соответствующих строках. См. 10.3 Переменные, используемые неявными правилами, и 10.2 Каталог встроенных правил для переменных и какие правила их используют.