user3030653
user3030653

Reputation: 39

Creating a Makefile in Raspbian

I'm trying to create a Makefile for my C program in Raspbian (Raspberry Pi). My program consists of a bunch of .c and .h Files. I've looked at countless Makefiles, but I just don't unterstand how it works with multiple files. There are always .o files in the Makefile but as I understand object files are the result of compiling, so I dont have any o. Files as I am trying to compile my .c Files.

Please explain to me how this works.

Edit:

Thank you. So I tried this and it starts compiling but there are errors 'multiple definition'. Example:

These are my Files:

main.c main.h
calibration.c calibration.h
file.c file.h
frame.c frame.h
gamepad.c gamepad.h
gpio.c gpio.h
uart.c uart.h
types.h

this is my makefile:

all: main

main: main.o calibration.o file.o frame.o gamepad.o gpio.o uart.o

%.o: %.c
    gcc -c -std=c99 -Wall $< -o $@ -lncurses

Where can i put 'types.h'? With every file I get errors 'multiple definitions'

Upvotes: 0

Views: 10155

Answers (2)

bzeaman
bzeaman

Reputation: 1128

The basic syntax of a make rule is:

target … : prerequisites …
    recipe
    …
    …

On the left of the semicolon are the targets. The targets are your object files(.o). On the right of the semicolon are the files that you will need to create this file. Those files are the source files(.c).

Lets give a basic example of what such a rule could look like.

%.o: %.c
    gcc -c $< -o $@

The % sign is a wildcard. %.o means everything that ends with .o. So, if you want to make an object file, you can say make file.o, and make will try to find a rule with which it can make this target. This happens to be the rule I just showed as an example, because file.o matches %.o.

Then the recipe. This is what will be executed. Usually it's about invoking the compiler(gcc), and feeding it the source file to generate the object file. That's what we do with gcc -c $< -o $@. The $< and $@ mean target and prerequisites respectively.

So, what happens when you 'just' want to build your program? You usually will type make, and it will build. The default rule that's used when you type make, is all. So, if you make a rule about all, then you can specify what files you want to create to build your program. Example of such a rule:

all: main

Then, when make is invoked, it will find that rule and finds out it needs main. To create main you need another rule:

main: file.o

This rule says that to build main, you need file.o. So, when you put all of the example rules together you get this:

all: main

main: file.o

%.o: %.c
    gcc -c $< -o $@

Note that you can specify more than one file, so instead of file.o, you can say file.o main.o other_file.o etc. Every prerequisite that you specify will be made, if they can find a rule to make it.

Upvotes: 2

Some programmer dude
Some programmer dude

Reputation: 409166

A very simple but typical makefile could look like this

SOURCES = source1.c source2.c source3.c
OBJECTS = $(SOURCES:%.c=%.o)

TARGET = myExecutable

$(TARGET): $(OBJECTS)
    gcc $^ -o $@

%.o: %.c
    gcc -c $< -o $@

The complicated parts:

  • SOURCES = source1.c source2.c source3.c This is a variable definition, it assigns the string "source1.c source2.c source3.c to the variable SOURCES.

  • $(SOURCES:%.c=%.o) This is a shorthand for the patsubst text function. It takes all text from the $(SOUCES) variable, and replaces the pattern %.c with %.o, i.e. it takes e.g. the string source1.c and replace it with source1.o.

  • $(TARGET): $(OBJECTS) This makes myExecutable depend on all object files, meaning if one object file is modified then the command in the rule will be executed.

  • gcc $^ -o $@ This calls the gcc command, passing all dependencies ($^) as arguments (that is, all object files), and tells gcc to output a file with the name of the target ($@).

  • %.o: %.c This is the rule that makes object files depend in their source file. So if you have source1.c then source1.o will depend on that source file.

  • gcc -c $< -o $@ This is the command that compiles the source file (the first dependency, $<) to an object file (with the -c option) and name it as the target of the rule ($@).

Also note that if you invoke make without a specific target, then the first rule will be selected. In the case of the above makefile, it will be the $(TARGET): $(OBJECTS) rule which will make sure that all object files are build from the source files, and then link the object files into the resulting executable.

Upvotes: 2

Related Questions