#c #linux #makefile #g
Вопрос:
Я пытаюсь скомпилировать несколько файлов .cpp, используя файл Makefile с помощью make. У меня есть файл .cpp, содержащий основную функцию, в другом файле .cpp-базовый класс (при любых сомнениях я помещу здесь весь код, который я использую). Пример имен, используемых для его компиляции или для того, чтобы он не компилировался:
-это работает, если их назвать «prova.cpp»(содержит основную функцию) и «pa.cpp»(содержит класс) (ниже команд, выполняемых файлом Makefile)
gioele@GioPC-U:~/Dev/Cpp/Exercises/666prova$ make
g -g -Wall -c src/prova.cpp -o obj/prova.o
g -g -Wall -c src/pa.cpp -o obj/pa.o
g -g -Wall obj/prova.o -o bin/provaBin
-это не работает, если их называть «ciao.cpp»(содержит основную функцию) и «pa.cpp»(содержит класс)
gioele@GioPC-U:~/Dev/Cpp/Exercises/666prova$ make
g -g -Wall -c src/pa.cpp -o obj/pa.o
g -g -Wall -c src/ciao.cpp -o obj/ciao.o
g -g -Wall obj/pa.o -o bin/provaBin
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text 0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [Makefile:15: bin/provaBin] Errore 1
Я думаю, что проблема в порядке расположения файлов внутри файла Makefile. Когда это не работает, потому что пытается получить двоичный файл из .o без основной функции. Понятия не имею, как это решить.
Файл с основным методом:
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
Файл класса:
class Class {
public:
int x;
int y;
};
Файл Makefile (все еще учусь работать с файлами Makefile, вероятно, проблема здесь, приветствуются любые советы по улучшению файла Makefile такого рода, или если я использую что-то неправильно):
CC=g CFLAGS=-g -Wall OBJ=obj SRC=src BINDIR=bin BIN=$(BINDIR)/provaBin SRCS=$(wildcard $(SRC)/*.cpp) OBJS=$(patsubst $(SRC)/%.cpp, $(OBJ)/%.o, $(SRCS)) all: $(BIN) $(BIN): $(OBJS) $(CC) $(CFLAGS)
lt; -o $@
$(OBJ)/%.o: $(SRC)/%.cpp
$(CC) $(CFLAGS) -clt; -o $@
clean:
$(RM) $(BINDIR)/* $(OBJ)/*
Заранее спасибо.
Комментарии:
1. вы не ссылаетесь
ciao.o
на свой исполняемый файл?
Ответ №1:
Вы можете исправить это, изменив одного персонажа.
В этом правиле:
$(BIN): $(OBJS) $(CC) $(CFLAGS)
lt; -o $@
список обязательных$(OBJS)
условий расширяется до списка объектных файлов, таких какprova.o pa.o
илиpa.o ciao.o
. Вы хотите, чтобы Make включил этот список в команду связывания, например:g -g -Wall prova.o pa.o -o bin/provaBin
Но автоматическая переменная
$<
расширяется только до первого элемента в списке необходимых компонентов. Если первый элемент представляет собой объектный файл, который не содержитmain()
функции, напримерpa.o
, компоновщик будет жаловатьсяmain()
на ее отсутствие. (Если это объектный файл , содержащийmain()
, например,prova.o
, то вы не получите эту ошибку, но у вас все еще могут возникнуть проблемы.)Решение состоит в использовании автоматической переменной
$^
, которая расширяется до полного списка предварительных условий:$(BIN): $(OBJS) $(CC) $(CFLAGS) $^ -o $@