Simple Introduction to Makefiles

Programming HOW TOs and in-depth guides for programmers of all levels. Programming is an essential skill for hackers, so start learning today!
Post Reply
User avatar
foldingstock
htd0rg lieutenant
Posts: 300
Joined: Sat Aug 16, 2008 10:38 pm

Simple Introduction to Makefiles

Post by foldingstock » Wed Oct 21, 2009 5:17 am

When coding in C/C++, large projects can very quickly become to cumbersome to keep in a single file. It is a good practice to split up source code into smaller, more manageable parts.

To understand this, lets look at a simple "Hello World" program. To begin with, we will use a single source file, "main.c":

Code: Select all

/* File: main.c */
#include <stdio.h>

int main(){
	printf("Hello World! \n");
	return 0;
}
Compiled, this will look output "Hello World!." To take this one step further, we could modify the code and use a function for the actual printing:

Code: Select all

/* File: main.c */
#include <stdio.h>

void hello(){
	printf("Hello World! \n");
}
int main(){
	hello();
	return 0;
}
This code does the exact same thing as our first, but instead of running everything within main() we use a function for the actual printing, hello(), and call that function from main().

Both of the above files can be compiled by simply issuing: "gcc -c main.c"

What if this program consisted of several very large functions? That is where multiple files come in handy. We could split up the above code across three files, a header and two source code files, like this:

Code: Select all

/* File: hellow.h */

//This is a header file used to declare a function. Any source that 
//wants to use the hello() function needs to include this header file. 

void hello();

Code: Select all

/* File: hellow.c */

void hello(){
        printf("Hello world! \n");

}

Code: Select all

/* File: main.c */
#include <stdio.h>

int main(){
        hello();
        return 0;
}
We now have three files: hellow.h, hellow.c, and main.c. "hellow.h" is a header file, used to define the function for the compiler. "hellow.c" is the actual program code for the "hello()" function, and "main.c" is the main code that calls the function.

To compile this project, we can use: "gcc -o hello hellow.c main.c"

This will create the executable file, hello, from hellow.c and main.c.

To make compiling this project simpler and more flexible, a Makefile could be used. A Makefile is an easy way to organize and compile the source code of a program. The Makefile is used as configuration parameters for the *nix command "make," which tell make how to build your program.

The syntax of a Makefile is:

Code: Select all

target: prerequisites
command
A sample Makefile for our hello world project might look like this:

Code: Select all

# File: Makefile

all:    hello

hello: hellow.c main.c
        gcc -o hello hellow.c main.c

To understand this, lets take it step by step.

Code: Select all

all: hello
This first line tells make that the file "hello" is going to be required. Since "hello" does not exist, it will be created. If "hello" already exists, make will exit.

Code: Select all

hello: hellow.c main.c
        gcc -o hello hellow.c main.c
In order to build the "hello" file, "hellow.c" and "main.c" are required. If they exist, the gcc command "gcc -o hello hellow.c main.c" will be issued. As we saw earlier, this will build an executable file, "hello," from the source files "hellow.c" and "main.c."

Once we have this Makefile in place, we call it like this:

Code: Select all

$ ls
Makefile hellow.c hellow.h main.c
$ make
gcc -o hello hellow.c main.c
$ ls
Makefile hello    hellow.c hellow.h main.c
$ ./hello
Hello world!
$
Now we could extend out Makefile and add a new option:

Code: Select all

# File: Makefile

all:    hello

hello: hellow.c main.c
        gcc -o hello hellow.c main.c
clean:
	rm hello
This does not change the way the program is built, but it gives us the option to cleanup the workspace. Lets look at an example:

Code: Select all

$ ls
Makefile hellow.c hellow.h main.c
$ make
gcc -o hello hellow.c main.c
$ ls
Makefile hello    hellow.c hellow.h main.c
$ ./hello
Hello world!
$ make clean
rm hello
$ ls
Makefile hellow.c hellow.h main.c
$
As you can see, calling make with the "clean" option we added will remove the compiled executable file, "hello."

You could go a step further with this and add an "install" option that copied/moved "hello" to /usr/bin, which would "install" hello by invoking "make install."

This is a very simplistic use of Makefiles. I will probably be making a more complex guide soon, if time permits.

User avatar
Cool_Fire
Not a sandwich
Posts: 1881
Joined: Fri May 09, 2003 1:20 pm
Location: 41 6d 73 74 65 72 64 61 6d
Contact:

Re: Simple Introduction to Makefiles

Post by Cool_Fire » Wed Oct 21, 2009 6:07 am

Nice, I've been too lazy to look into makefiles really. Though I could have used them on a couple of occasions.

Post Reply