(.text + 0x20): undefined ссылка на "main" и undefined ссылку на функцию
У меня возникает вопрос, как заставить makefile работать без ошибок. Первый вопрос, который у меня есть, - с ссылкой undefined на главную. У меня есть основной файл my.pro.exe как функция. Вторая проблема - ссылка undefined на SearchCustomer().
Ошибка:
bash-4.1$ make
gcc -Wall -c producer.c shared.h
gcc -Wall -c consumer.c shared.h
gcc -Wall -c AddRemove.c shared.h
gcc -pthread -Wall -o producer.o consumer.o AddRemove.o
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
AddRemove.o: In function `AddRemove':
AddRemove.c:(.text+0xb1): undefined reference to `SearchCustomer'
AddRemove.c:(.text+0x1e9): undefined reference to `SearchCustomer'
AddRemove.c:(.text+0x351): undefined reference to `SearchCustomer'
collect2: ld returned 1 exit status
make: *** [producer] Error 1
Makefile:
COMPILER = gcc
CCFLAGS = -Wall
all: main
debug:
make DEBUG=TRUE
main: producer.o consumer.o AddRemove.o
$(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o
producer.o: producer.c shared.h
$(COMPILER) $(CCFLAGS) -c producer.c shared.h
consumer.o: consumer.c shared.h
$(COMPILER) $(CCFLAGS) -c consumer.c shared.h
AddRemove.o: AddRemove.c shared.h
$(COMPILER) $(CCFLAGS) -c AddRemove.c shared.h
ifeq ($(DEBUG), TRUE)
CCFLAGS += -g
endif
clean:
rm -f *.o
Ответы
Ответ 1
Это правило
main: producer.o consumer.o AddRemove.o
$(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o
не так. В нем говорится, чтобы создать файл с именем Manufacturer.o (с -o producer.o
), но вы хотите создать файл с именем main
. Прошу прощения за крик, но ВСЕГДА ИСПОЛЬЗУЙТЕ $ @ДЛЯ НАЗНАЧЕНИЯ ЗАДАЧИ:
main: producer.o consumer.o AddRemove.o
$(COMPILER) -pthread $(CCFLAGS) -o [email protected] producer.o consumer.o AddRemove.o
Как справедливо отмечает Шабаз, специалисты по gmake также будут использовать $^
, который распространяется на все предпосылки правила. Как правило, если вы повторяете строку или имя, вы делаете это неправильно и должны использовать переменную, будь то встроенная или созданная вами.
main: producer.o consumer.o AddRemove.o
$(COMPILER) -pthread $(CCFLAGS) -o [email protected] $^
Ответ 2
Эта ошибка означает, что при компоновке компилятор нигде не может найти определение функции main()
.
В вашем make файле правило main
расширится до чего-то подобного.
main: producer.o consumer.o AddRemove.o
gcc -pthread -Wall -o producer.o consumer.o AddRemove.o
Согласно странице руководства gcc
manual page, использование переключателя -o
описано ниже
Файл -o Поместить вывод в файл file. Это применимо независимо от того, какой вывод выводится, будь то исполняемый файл файл, объектный файл, файл ассемблера или предварительно обработанный C-код. Если -o
не указано, по умолчанию исполняемый файл помещается в a.out
.
Это означает, что gcc поместит вывод в имя файла, указанное непосредственно рядом с переключателем -o
. Итак, здесь вместо того, чтобы связать все файлы .o
вместе и создать двоичный файл [main
, в вашем случае], он создает двоичный файл как producer.o
, связывая другие файлы .o
. Пожалуйста, исправьте это.