Danvdb
Danvdb

Reputation: 103

Makefile error : duplicate symbol _main in

I can compile my two files serveur.c and client.c separately but when I try to use a makefile, it shows me an error. What I want is very simple : two compiled files : serveur.o and client.o.

Here is the code when I compile my two files separately :

gcc -lpthread serveur.c -o serveur.o

And

gcc -lpthread client.c -o client.o

Here is my makefile :

chatroom: serveur.o client.o
    gcc serveur.o client.o -o chatroom 

serveur.o: serveur.c
    gcc -lpthread serveur.c -o serveur.o

client.o: client.c
    gcc -lpthread client.c -o client.o

And here is the error when I write : "make -f makefile" in the terminal

gcc serveur.o client.o -o chatroom 
duplicate symbol _main in:
    serveur.o
    client.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [chatroom] Error 1

Thanks for your help ! :)

Upvotes: 0

Views: 3149

Answers (2)

mikyra
mikyra

Reputation: 10367

Maybe there is some missunderstanding in the way compiler, assembler and linker work in creating an executable.

The usual convention is to give the .o extension to object files generated after the assembler stage not to executables!

As gcc will act as compile, assemble and link manager performing all steps in one run without beeing told to stop at an earlier stage, gcc -lpthread serveur.c -o serveur.o and gcc -lpthread client.c -o client.o will both create executables not object files.

To make gcc stop after the assembly stage you have to pass it the -c switch. gcc -c serveur.c and gcc -c client.c. In this case giving -o serverveur.o and -o client.o is not necessary, as gcc will use them by default.

To link the generated object files the last thing to do would be gcc -lpthread serveur.o client.o -o chatroom

A Makefile to accomplish all that could look like that:

chatroom: serveur.o client.o
    gcc -lpthread $^ -o $@

Unfortunately this will still not fix your problem of having two definitions of a main() function, one in serveur.c and one in client.c.

As gcc -lpthread serveur.c -o serveur.o and gcc -lpthread client.c -o client.o would have been rejected by the linker with an unresolved reference to main without, I am quite sure both of your sources contain a definition.

If instead of building one executable all you wanted to do is have make create two executables, serveur and client for you, your Makefile should look something like this.

.PHONY: all

all: serveur client

Upvotes: 1

Dietmar Kühl
Dietmar Kühl

Reputation: 153820

If you successfully managed to build the two separate parts into a program each, it implies that both of the source files contain a main() or main(int, char*[]). However, you can have only one main() function per program (the restriction that you can have each function defined just once actually applies to all functions).

If each of the two files contains a complete program it is unlikely that you can just link them together: aside from the duplicate main() each of the programs will have some set up and some control. That is, simply getting rid of one of the main() functions is unlikely to result in a working program.

If you just added a main() function to one of the sources because otherwise it wouldn't "compile", you'll need to get rid of this main() and make sure that you actually compile the code into object files by passing the -c option. You'd leave the -c option off when linking the code.

Upvotes: 2

Related Questions