I am working on a simple project that generates 2 executable files, main and Server.
The program in Main.c makes use of code present in user_interface.c through the header file user_interface.h.
The Makefile I have written is as follows,
all: main user_interface.o Server
main: user_interface.o main.c
gcc main.c user_interface.o -o main
user_interface.o: user_interface.c user_interface.h
gcc user_interface.c -o user_interface.o
Server: Server.c
gcc Server.c -o Server
clean:
rm -rf main *.o Server
When I type make on the terminal, I get the following error:
gcc user_interface.c -o user_interface.o
/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:18: user_interface.o] Error 1
How do I navigate past this error?
CodePudding user response:
Your rule for user_interface.o
is wrong. You need to use the -c
option to tell it that it's creating an object file rather than an executable, so it doesn't need a main()
function.
all: main Server
main: user_interface.o main.o
gcc main.o user_interface.o -o main
main.o: main.c
gcc -c main.c
user_interface.o: user_interface.c
gcc -c user_interface.o
Server: Server.c
gcc Server.c -o Server
clean:
rm -rf main *.o Server
make
actually has a built-in rule for compiling .c
to .o
, so you don't actually need those rules.
CodePudding user response:
I think you're not using makefiles properly.
so a section of your makefile might look something like this:
core: WitchCraft NeuralServer AmoebaServer CDS NLPServer HollyServer
test: ENiX4NeuralCLI DataInjector NNTestServer ENiX4AmoebaCLI CLINLPTest
WitchCraft: ENiX_Net.o ENiX_IPC.o ENiX_SHM.o ENiX_Seq.o ENiX_Packet.o WitchCraft.o ENiX_Config.o ENiX_Disk.o ENiX_Binary.o
g -ggdb -O0 ENiX_Net.o ENiX_IPC.o ENiX_SHM.o ENiX_Seq.o ENiX_Packet.o WitchCraft.o ENiX_Config.o ENiX_Disk.o ENiX_Binary.o -o WitchCraft.bin -std=c 11 -lreadline
These things before the colon, are called targets. The can be called with:
make <target>
e.g.
make WitchCraft
So for the first line of your target you've got source files inside there for some reason and it looks like you're trying to compile user_interface.o as a binary, rather than an object, but you're not linking it to main.o.
So I suspect you want something like:
main: main.o user_interface.o
gcc main.o user_interface.o -o main
And what that should do is cause make to look for the source code for main.o (i.e. main.c) likewise for interface.o (i.e. interface.c) and then compile these into object files (i.e. .o files).
Then you'd link these object files into a binary, using gcc with the -o to specify the binary output file in this case, "main".
And you'd need to do something similar with the server.