Makefile To Compile Multiple Files - c

I am trying to compile my TCP client server program through Make but I can not get everything linked together.
My current files I am using:
client.c
connectioninfo.c
connectioninfo.h
server.c
splinter.c
splinter.h
All .c files use the two .h files in their code.
Here is what my makefile looks like:
splinter : server.o client.o splint.o connectioninfo.o
server.o: server.c splinter.h connectioninfo.h
gcc -o server server.c
client.o: client.c splinter.h connectioninfo.h
gcc -o client client.c
splint.o: splinter.c splinter.h connectioninfo.h
gcc -o splint splinter.c
connectioninfo.o: connectioninfo.c splinter.h connectioninfo.h
gcc -o connectioninfo connectioninfo.c
I get the errors :
gcc -o server server.c
/tmp/ccAu7sDE.o: In function `main':
server.c:(.text+0x6e): undefined reference to `alloc_serverinfo'
server.c:(.text+0x87): undefined reference to `getconnectioninfo'
server.c:(.text+0xcd): undefined reference to `port'
server.c:(.text+0xdc): undefined reference to `host'
server.c:(.text+0xe7): undefined reference to `s_bind'
server.c:(.text+0x1a5): undefined reference to `s_accept'
collect2: error: ld returned 1 exit status
Makefile:4: recipe for target 'server.o' failed
make: *** [server.o] Error 1
Any idea on how i can get everything to compile? Thanks

You are currently calling gcc to build applications, not object files, for each source file. Please use the option -c and give the appropriate file name for the output, for example
gcc -c -o server.o server.c
Now change the rule for the application so that it is linked:
splinter : server.o client.o splint.o connectioninfo.o
gcc -o splinter server.o client.o splint.o connectioninfo.o
To debug your Makefile and see what commands will be generated without executing them you can use
make -n
You can call commands explicitly like i.e. gcc -c -o server.o server.c in your shell to check each step.
Oh, and you can name the object file splinter.o which is compiled from the source file splinter.c. There will be no problem with the resulting executable splinter.
Now you could also simplify your Makefile to use automatic variables; please see the documentation for make.
All put together, you could use:
splinter : server.o client.o splinter.o connectioninfo.o
gcc -o $# $^
server.o: server.c splinter.h connectioninfo.h
client.o: client.c splinter.h connectioninfo.h
splinter.o: splinter.c splinter.h connectioninfo.h
connectioninfo.o: connectioninfo.c splinter.h connectioninfo.h
%.o: %.c
gcc -o $# $<

For compiling multiple files you will need to do it in two steps:
Compile each source file into an object file (note the use of -c to compile only) as the busybee suggested:
somefile1.o : somefile1.c
gcc -c somefile1.c -o somefile1.o
somefile2.o : somefile2.c
gcc -c somefile2.c -o somefile2.o
Link your object files - create myapp executable
myapp : somefile1.o somefile2.o
gcc somefile1.o somefile2.o -o myapp

Related

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?
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.
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.

"curses.h: No such file or directory" even after installing into Cygwin

I'm working on a C clone of the 2048 game, using curses.h for the UI. When trying to compile it with Cygwin using the make commanad, I get following message:
PS D:\C\ps3> make all
gcc -std=c11 -Wall -Werror -g -c main.c -lm -lcurses -o main.o
main.c:4:20: fatal error: curses.h: No such file or directory
#include <curses.h>
^
compilation terminated.
make: *** [Makefile:13: main.o] Error 1
So I ran the setup again, looking for any package that has "curses" in it's name and installed it, added my /bin folder to the PATH variable but it didn't help.
I'm working on a 64-bit Win10 and trying to compile the program with Cygwin's terminal, using a Makefile. file. I've tried reinstalling the packages with curses in their name multiple times with no help.
Part of my Makefile:
CC=gcc
CFLAGS=-std=c11 -Wall -Werror -g
LDLIBS=-lm -lcurses
OUTPUT=game
# targets
all: $(OUTPUT)
$(OUTPUT): k.o hof.o main.o
$(CC) $(CFLAGS) k.o hof.o main.o $(LDLIBS) -o $(OUTPUT)
main.o: main.c
$(CC) $(CFLAGS) -c main.c $(LDLIBS) -o main.o
The line in main.c the error is pointing to:
#include "hof.h"
#include "k.h"
#include "ui.h"
#include <curses.h>
The header file would be in libncurses-devel (perhaps overlooked). Here's a screenshot showing the "curses" packages which I have in my local repository:

Linking header files with makefile: undefined reference error

I have a project with the following files, all in the same folder
client.c
server.c
reliable_udp.h
reliable_udp.c
conf.h
Among the other libraries, client.c includes also reliable_udp.h ( #include "reliable_udp.h") in order to use the functions packet_send and print_conf (that are implemented in reliable_udp.c).
I'm new to Makefiles, and I'm trying to write one:
CC = gcc
CFLAGS = -Wall -Wextra -Wpedantic -O3
SRC = client.c server.c
OBJ = $(SRC:.c=.o)
all: $(OBJ)
${CC} ${CLFAGS} client.o -o client
${CC} ${CLFAGS} server.o -o server
client.o: reliable_udp.h
clean:
rm -f *.o core
cleanall:
rm -f *.o core client server
If I try to run make, I get the following output:
gcc -Wall -Wextra -Wpedantic -O3 -c -o client.o client.c
gcc client.o -o client
client.o: In function `main':
client.c:(.text.startup+0x84): undefined reference to `packet_send'
client.c:(.text.startup+0x8b): undefined reference to `print_conf'
collect2: error: ld returned 1 exit status
Makefile:7: recipe for target 'all' failed
make: *** [all] Error 1
Obviously I'm failing writing correctly the Makefile. How should I fix it? Why am I getting this error?
Why am I getting this error?
Because the link recipes do not include the 'reliable_udp.0' object and because nothing in the makefile will compile 'reliable_udp.c into 'reliable_udp.o`
the posted makefile contains several problems, as expressed in the comments to the question.
The following is a proposed, simple makefile that should perform the desired functionality.
Note: replace <tab> with a tab character
Note: in the following makefile, the invocation command can be:
make -- to generate both 'client' and 'server'
as it will use the first target, which is 'all'
make all -- to generate both 'client' and 'server'
make client -- to only generate the 'client' executable
make server -- to only generate the 'server' executable
make clean -- to delete the object files
make cleanall -- to delete the object files and the executables
and now the proposed makefile
#use ':=' rather than '=' so macros only evaluated once
#assure the desired utilities are used
CC := /usr/bin/gcc
RM := /usr/bin/rm -f
CFLAGS := -Wall -Wextra -Wpedantic -std=GNU11 -O3
#generate a list of all the source files
SRC := client.c server.c reliable_udp.c
#generate a list of all the object file names
OBJ := $(SRC:.c=.o)
#let make know that the target 'all' will not produce a file of the same name
#notice the 'all' target dependencies are the final executables
.PHONY: all
all: client server
#this will perform all the compiles
#while expecting the user supplied header files to be in the local directory
%.o:%.c
<tab>$(CC) -c $(CFLAGS) $^ -o $# -I.
#link the 'client' executable
client: client.o reliable_udp.o
<tab>${CC} $^ -o $#
#link the 'server' executable
server: server.o reliable_udp.o
<tab>${CC} $^ -o $#
#let make know that this target will not produce a file of the same name
.PHONY: clean
clean:
<tab>$(RM) $(OBJ) core
#let make know that this target will not produce a file of the same name
.PHONY: cleanall
cleanall:
<tab>$(RM) $(OBJ) core client server
A quick fix would be to modify the Makefile as follows:
all: $(OBJ)
${CC} ${CLFAGS} reliable_udp.o client.o -o client
${CC} ${CLFAGS} reliable_udp.o server.o -o server
It's not pretty though, in "real world" a better option might be to make a shared library for "reliable_udp", or at least refactor Makefile a little bit.
The reason of the error is that "reliable_udp" is not compiled in to the final binaries, since it's not explicitly specified anywhere in the makefile.

Makefile error in C with same function

I want use "Makefile" in my project which im working on socket programming. I have two simple .c files but they have their own main function. And makefile returns an error because of these two main functions.
I have one main function in server.c file and one main function in client.c
ERROR
gcc server.o client.o -o output -lpthread client.o: In function
main': client.c:(.text+0x0):main' için birden fazla tanım
server.o:server.c:(.text+0x78): ilk burada tanımlanmış collect2:
error: ld returned 1 exit status Makefile:4: recipe for target
'output' failed make: *** [output] Error 1
MAKEFILE
all: output
output: server.o client.o
gcc server.o client.o -o output -lpthread
server.o: server.c
gcc -c server.c
client.o: client.c
gcc -c client.c
clean:
rm *.o
Thanks :)
It won't work like that. You'll need two outputs, ala
all: server client
server: server.o
gcc server.o -o server -lpthread
client: client.o
gcc client.o -o client -lpthread
This is because your program can only have one main. What are you trying to do that you want to compile both .c files into one executable?

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 ! :)
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.
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

Resources