简体   繁体   中英

Creating a makefile - (C)

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:

How do I make a simple makefile for gcc on Linux?

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM