I am having issue getting my makefile to work without errors. The first issue i have is with an undefined reference to main. I have main in my producer.c file as a function. The second issue is an undefined reference to SearchCustomer().
error:
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
When we compile these files separately, the first file gives “undefined reference” for the print function, while the second file gives “undefined reference” for the main function. The way to resolve this error is to compile both the files simultaneously (For example, by using g++).
Used the GCC compiler to compile the exp. c file. The error: undefined reference to function show() has appeared on the terminal shell as predicted. To solve this error, simply open the file and make the name of a function the same in its function definition and function call.
Undefined reference to main() means that your program lacks a main() function, which is mandatory for all C++ programs.
This rule
main: producer.o consumer.o AddRemove.o $(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o
is wrong. It says to create a file named producer.o (with -o producer.o
), but you want to create a file named main
. Please excuse the shouting, but ALWAYS USE $@ TO REFERENCE THE TARGET:
main: producer.o consumer.o AddRemove.o $(COMPILER) -pthread $(CCFLAGS) -o $@ producer.o consumer.o AddRemove.o
As Shahbaz rightly points out, the gmake professionals would also use $^
which expands to all the prerequisites in the rule. In general, if you find yourself repeating a string or name, you're doing it wrong and should use a variable, whether one of the built-ins or one you create.
main: producer.o consumer.o AddRemove.o $(COMPILER) -pthread $(CCFLAGS) -o $@ $^
This error means that, while linking, compiler is not able to find the definition of main()
function anywhere.
In your makefile, the main
rule will expand to something like this.
main: producer.o consumer.o AddRemove.o gcc -pthread -Wall -o producer.o consumer.o AddRemove.o
As per the gcc
manual page, the use of -o
switch is as below
-o file Place output in file file. This applies regardless to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code. If
-o
is not specified, the default is to put an executable file ina.out
.
It means, gcc will put the output in the filename provided immediate next to -o
switch. So, here instead of linking all the .o
files together and creating the binary [main
, in your case], its creating the binary as producer.o
, linking the other .o
files. Please correct that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With