Ссылка C++ undefined в Makefile
Я создал свой Makefile для простой программы, но он постоянно возвращает неопределенную ссылку для функций класса:
g++ -c src/main.cpp -o lib/main.o
g++ -c src/functions.cpp -o lib/functions.o
g++ -c src/Circular.cpp -o lib/Circular.o
g++ lib/main.o -o bin/app.exe
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: lib/main.o:main.cpp:(.text+0x20): undefined reference to `Circular::Circular()'
collect2.exe: error: ld returned 1 exit status
make.exe: *** [app.exe] Error 1
Вот мой Makefile:
app.exe: lib/main.o lib/Circular.o lib/functions.o
g++ lib/main.o -o bin/app.exe
lib/functions.o: src/functions.cpp
g++ -c src/functions.cpp -o lib/functions.o
lib/Circular.o: src/Circular.cpp
g++ -c src/Circular.cpp -o lib/Circular.o
lib/main.o: src/main.cpp
g++ -c src/main.cpp -o lib/main.o
Вот небольшой фрагмент main.cpp:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include "../include/Circular.h"
#include "../include/functions.h"
using namespace std;
int main(int argc, const char * argv[]) {
Circular item;
return 0;
}
Circular.h:
#include "node.h"
class Circular
{
public:
Circular();
node *start;
node *last;
int counter;
}
Circular.cpp:
#include "../include/Circular.h"
#include <iostream>
using namespace std;
Circular::Circular()
{
start = NULL;
last = NULL;
}
и node.h:
struct node
{
int data;
struct node *next;
struct node *prev;
};
Я знаю, что проблема связана с компоновщиком и Makefile, но, хотя я пробовал разные возможные решения, почему-то это не работает. Поэтому, может быть, кто-то увидит мою ошибку. Спасибо!
2 ответа
Мне удалось создать Makefile из этого источника.
Makefile выглядит так:
CXX = g++
CXXFLAGS = -std=c++17 -Wall
LXXFLAGS = -std=c++17
OBJECTS = main.o Circular.o functions.o
TARGET = main
$(TARGET): $(OBJECTS)
$(CXX) $(LXXFLAG) $(OBJECTS) -o $(TARGET)
main.o: main.cpp Circular.cpp Circular.h functions.cpp functions.h
$(CXX) $(CXXFLAGS) -c main.cpp
Circular.o: Circular.cpp
$(CXX) $(CXXFLAGS) -c Circular.cpp
functions.o: functions.cpp
$(CXX) $(CXXFLAGS) -c functions.cpp
clean:
rm -f $(TARGET) $(OBJECTS)
А также добавил cout
вам Круговой конструктор, чтобы проверить выполнение, как показано ниже:
#include "Circular.h"
#include <iostream>
using namespace std;
Circular::Circular()
{
start = NULL;
last = NULL;
cout << "Yes!" << endl;
}
Вот результат:
Выходные данные
Не забудьте поставить точку с запятой для вашего класса Circular в вашемCircular.h
.
ПРИМЕЧАНИЕ. Если вы не можете использовать make в cmd, используйтеchoco install make
.
В Makefile
должен быть структурирован для построения зависимостей, а затем окончательная сборка в .exe
. Каждый путь должен быть указан именно так, а не приблизительно:
app.exe: lib/main.o lib/Circular.o lib/functions.o
g++ lib/main.o lib/Circular.o lib/functions.o -o app.exe
lib/main.o: src/main.cpp
g++ -c src/main.cpp -o lib/main.o
lib/functions.o: src/functions.cpp
g++ -c src/functions.cpp -o lib/functions.o
lib/Circular.o: src/Circular.cpp
g++ -c src/Circular.cpp -o lib/Circular.o
Ключ здесь - быть последовательным, и это включает такие вещи, как порядок вещей, указанный в этом файле. Какой бы заказ вы ни выбрали, придерживайтесь его. Это значительно упрощает отслеживание проблем.
Если этот проект становится более сложным, вы, вероятно, захотите перейти к использованию отслеживания зависимостей.Makefile
шаблон вместо этого доморощенного. Обратите внимание, что в них вам не нужно указывать правило для каждого файла, а вместо этого правило для каждого типа файла, как в.cpp
-> .o
, а остальное происходит автоматически.