Deekshith Patil
Deekshith Patil

Reputation: 101

makefile: undefined reference to main

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?

Upvotes: 0

Views: 752

Answers (2)

Owl
Owl

Reputation: 1562

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.

Upvotes: 1

Barmar
Barmar

Reputation: 782436

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.

Upvotes: 1

Related Questions