Home > Net >  makefile: undefined reference to main
makefile: undefined reference to main

Time:04-15

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.

  • Related