C/C++

 

 

 

 

makefile

 

As you know, in order to execute the program written in C, we need to do compilation and link to convert the c source code to an executable binary file. This compilation and link process would not be a big issue if you are handling a small number of c files and h files, but the process would go more and more complicated as the number of those files increases and you need to use more complicated compilation / link options. Repeating those compilation and link process over and over can be an annoying process. makefile is a kind of batch file (similar to shell program) that execute the predefined compilation/link procedure.

If you have tried to use any large scale programs (like those open source programs you can get from internet or github), you would noticed that most of the program source codes are provided with its own makefile and understanding the contents of the makefiles are not an easy task.

This note is intended to help you with understanding the contents of makefile provided with those programs and help you with creating makefiles for your own program.

 

 

 

Compile without makefile

 

hello.c

hello.h

#include "hello.h"

 

int main(void)

{

    print_hello();

    return 1;

}

#include <stdio.h>

 

void print_hello(void)

{

     printf("Hello World \n");

}

 

 

# gcc hello.c  -o hello.o

 

 

 

 

 

Simplest makefile

 

hello.c

hello.h

#include "hello.h"

 

int main(void)

{

    print_hello();

    return 1;

}

#include <stdio.h>

 

void print_hello(void)

{

     printf("Hello World \n");

}

 

Example 01 >

makefile

hello:

        gcc  hello.c -o hello

 

Example 02 >

makefile

hello:

        gcc  -o hello hello.c

 

Example 03 >

makefile

hello: hello.c

        gcc  -o hello hello.c

 

Example 04 >

makefile

hello: hello.c hello.h

        gcc  -o hello hello.c

 

All the example shown above gives the same result as shown below except the printout of 'make' command

 

 

 

Simplest makefile with Macro

 

hello.c

hello.h

#include "hello.h"

 

int main(void)

{

    print_hello();

    return 1;

}

#include <stdio.h>

 

void print_hello(void)

{

     printf("Hello World \n");

}

 

 

Example 01 >

makefile

CC=gcc

 

hello:

        $(CC)  hello.c -o hello

 

Example 02 >

makefile

CC=gcc

 

hello:

        $(CC)  hello.c -o $@   #  $@ represents 'target' ('hello' in this case)

 

Example 04 >

makefile

CC=gcc

 

hello: hello.c hello.h

        $(CC)  $< -o $@      #  $< represents the first items of the rule  ('hello.c' in this case)

 

Example 05 >

makefile

CC=gcc

 

hello: hello.c hello.h

        $(CC)  $^ -o $@    #  $^ represents the all items of the rule  ('hello.c hello.h' in this case)

 

Example 06 >

makefile

CC=gcc

 

hello: hello.c hello.h

        $(CC)  -o $@ $^

 

All the example shown above gives the same result as shown below except the printout of 'make' command

 

 

 

Special Symbols

 

Symbol

Description

$@

file name indicating target

$%

The target member name, when the target is an archive member

$<

The filename of the first prerequisite.

$?

The names of all the prerequisites that are newer than the target, with spaces between them

$^

The names of all the prerequisites, with spaces between them

$+

This is like ‘$^’, but prerequisites listed more than once are duplicated in the order they were listed in the makefile. This is primarily useful for use in linking commands where it is meaningful to repeat library file names in a particular order

$*

The stem with which an implicit rule matches (see How Patterns Match). If the target is dir/a.foo.b and the target pattern is a.%.b then the stem is dir/foo. The stem is useful for constructing names of related files.

 

Example 01 >

makefile

hello.o: hello.c hello.h       # hello.o is target, [hello.c hello.h] is prerequisite

         gcc -c $< -o $@     # $@ indicates the target (hello.o in this case)

                                     # $< indicates the first elements of the prerequisites (hello.c in this case)

 

 

 

 

 

Reference :