Reputation: 803
I am trying to create a simple makefile. I have one headerfile: "guiBuilder.h
". I have another file that will be using it: "client.c
". The makefile that I am using is:
HEADERS = guiBuilder.h
default: program
program.o: client.c $(HEADERS)
gcc -c client.c -o client.o
program: client.o
gcc client.o -o Client
I found the code for the makefile here:
I now get this error when i run it:
(.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status Makefile:9: recipe for target 'program' failed make: *** [program] Error 1
Upvotes: 1
Views: 3402
Reputation: 86651
Rules in a make file are of the form:
target: dependency1 dependency2 etc
command to build target
target
is the name of the file you want to build. So the line
program: client.o
gcc client.o -o Client
Is trying to build a file called program
. However, the command does not create a file called program
, it creates a file called Client
. This is less of a problem than you might think, it just means that the rule is always executed whether Client
is up to date or not. However, you should change it so the target is the file you are building.
Client: client.o
gcc client.o -o Client
By the way, in most *nixes, file names are case sensitive Client
and client
are different files on Linux, for example.
That rule has a single dependency: client.o
. Unfortunately, your make file does not know how to build client.o
- there is no target called client.o
.
I am speculating the cause of your error is that you have an old client.o
hanging about that doesn't have a main()
function in it. This is why the link (the gcc
command in the program
target) is failing.
The target program.o
has the same problem as the target program
. You are not building program.o
, you are building client.o
. This target needs to be changed to
client.o: client.c $(HEADERS)
gcc -c client.c -o client.o
which is happily the dependency for your Client
target.
Note The indentation for the command part of a make
rule has to be done with a tab. If copy-pasting my answer or any of the other answers, or the answers in the linked question, please make sure your indents are tabs, not spaces.
Update (the issue with test()
being an undefined reference)
If you have a function in guiBuilder.c
that has a prototype in guiBuilder.h
you'll need to compile guiBuilder.c
and add it to the link phase.
Your rule for guiBuilder.o
will look very similar to the rule for client.o
guiBuilder.o: guiBuilder.c $(HEADERS)
gcc -c guiBuilder.c -o guiBuilder.o
Then you need to add guiBuilder.o
as a dependency of Client
Client: client.o guiBuilder.o
gcc client.o guiBuilder.o -o Client
You may have noticed that you now have two rules for creating .o
files that are identical other than the names of the source and object files. The accepted answer to the question that you linked shows how you modify the make file so you only need to define the rule once.
Upvotes: 4
Reputation: 1143
I will suggest you to read the GNU Make manual to get a better understanding of how make
command and makefile
works.
To answer your question, in short, Makefile consists of several things out of which the basic things are target
, dependency
and recipe
. In the following manner
target: dependency
recipe
When you run make
command, it searches for a file with name Makefile
or makefile
and it starts parsing target and dependency and executes the recipe for that target.
In your makefile you want to create final binary with name program
but you don't have program.c
so your makefile should go something like below:
HEADERS = guiBuilder.h
all: program
client.o: client.c $(HEADERS)
gcc -c client.c
program: client.o
gcc client.o -o program
Upvotes: 0