(.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. Пожалуйста, исправьте это.