Skip to main content

Make file and make utility

Compiling the source code files can be tiring, especially when you have to include several source files and type the compiling command every time you need to compile. Makefiles are the solution to simplify this task.

Makefiles are special format files that help build and manage the projects automatically.
A Simple Example
Let's start off with the following three files, hellomake.c, hellofunc.c, and hellomake.h, which would represent a typical main program, some functional code in a separate file, and an include file, respectively. hellomake.c
include
int main()
{ // call a function in another file
myPrintHelloMake();
return(0);
}

hellofunc.c

#include  
#include  
void myPrintHelloMake(void)
{ printf("Hello makefiles!\n");
 return;
 }
hellomake.h
/* example include file */
void myPrintHelloMake(void);
Normally, you would compile this collection of code by executing the following command:

gcc -o hellomake hellomake.c hellofunc.c -I.

This command generates hellomake binary. In this example we have only two files and we know the sequence of the function calls. Hence, it is feasible to type the above command and prepare a final binary.
However, for a large project where we have thousands of source code files, it becomes difficult to maintain the binary builds.
The make command allows you to manage large programs or groups of programs. As you begin to write large programs, you notice that re-compiling large programs takes longer time than re-compiling short programs. Moreover, you notice that you usually only work on a small section of the program ( such as a single function ), and much of the remaining program is unchanged.

The simplest makefile you could create would look something like:

Makefile

hellomake: hellomake.c hellofunc.c 
    gcc -o hellomake hellomake.c hellofunc.c -I.

If you put this rule into a file called Makefile or makefile and then type make on the command line, it will execute the compile command as you have written it in the makefile. Note that make with no arguments executes the first rule in the file. Furthermore, by putting the list of files on which the command depends on the first line after the :, make knows that the rule hello needs to be executed if any of those files change. 
One very important thing to note is that there is a tab before the gcc command in the makefile. There must be a tab at the beginning of any command, and make will not be happy if it's not there.
In order to be a bit more efficient, let's try the following:

CC=gcc
CFLAGS=-I. 
hellomake: hellomake.o hellofunc.o 
$(CC) -o hellomake hellomake.o hellofunc.o 
 
So now we've defined some constants CC and CFLAGS. It turns out these are special constants that communicate to make how we want to compile the files hellomake.c and hellofunc.c. In particular, the macro CC is the C compiler to use, and CFLAGS is the list of flags to pass to the compilation command. By putting the object files--hellomake.o and hellofunc.o--in the dependency list and in the rule, make knows it must first compile the .c versions individually, and then build the executable hellomake.
Using this form of makefile is sufficient for most small scale projects. However, there is one thing missing: dependency on the include files. If you were to make a change to hellomake.h, for example, make would not recompile the .c files, even though they needed to be. In order to fix this, we need to tell make that all .c files depend on certain .h files. We can do this by writing a simple rule and adding it
to the makefile.

CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
%.o: %.c $(DEPS)
     $(CC) -c -o $@ $< $(CFLAGS)
hellomake: hellomake.o hellofunc.o
     $(CC) -o hellomake hellomake.o hellofunc.o
This addition first creates the macro DEPS, which is the set of .h files on which the .c files depend. Then we define a rule that applies to all files ending in the .o suffix. The rule says that the .o file depends upon the .c version of the file and the .h files included in the DEPS macro. The rule then says that to generate the .o file, make needs to compile the .c file using the compiler defined in the CC macro. The -c flag says to generate the object file, the -o $@ says to put the output of the compilation in the file named on the left side of the :, the $< is the first item in the dependencies list, and the CFLAGS macro is defined as above.
As a final simplification, let's use the special macros $@ and $^, which are the left and right sides of the :, respectively, to make the overall compilation rule more general. In the example below, all of the include files should be listed as part of the macro DEPS, and all of the object files should be listed as part of the macro OBJ.
CC=gcc 
CFLAGS=-I. 
DEPS = hellomake.h 
OBJ = hellomake.o hellofunc.o
 %.o: %.c $(DEPS) 
       $(CC) -c -o $@ $< $(CFLAGS) 
 hellomake: $(OBJ)
       $(CC) -o $@ $^ $(CFLAGS)

Comments

Popular posts from this blog

Writing a Bash Shell Script

Bash shell scripts in Linux are text files that contain a series of commands that can be executed by the Bash shell. Bash (Bourne Again Shell) is a popular shell in Linux and UNIX systems, and shell scripts are used to automate tasks, configure systems, or perform a sequence of operations. How to Write a Bash Shell Script Create a New File: You can create a new script using any text editor like nano , vim , or gedit . gedit myscript.sh Write the Script: A basic shell script begins with a "shebang" ( #!/bin/bash ) to specify the interpreter that will be used to execute the script. The rest of the file contains the commands to be run. Example of a simple script: #!/bin/bash # This is a comment echo "Hello, World!" # Print "Hello, World!" #!/bin/bash : Specifies that the script will be executed using the Bash shell. echo "Hello, World!" : A command that prints the string "Hello, World!" to the terminal. Comments: Any line starting ...

Basic Linux Commands For Beginner's

Basic Linux Commands for Beginners Linux is an Operating System’s Kernel. You might have heard of UNIX. Well, Linux is a UNIX clone. But it was actually created by Linus Torvalds from Scratch. Linux is free and open-source, that means that you can simply change anything in Linux and redistribute it in your own name! There are several Linux Distributions, commonly called “distros”. A few of them are: Mint Ubuntu Linux Red Hat Enterprise Linux Debian Fedora Kali Linux is Mainly used in Servers. About 90% of the Internet is powered by Linux Servers. This is because Linux is fast, secure, and free! The main problem of using Windows Servers are their cost. This is solved by using Linux Servers. Forgot to mention, the OS that runs in about 80% of the Smartphones in the World, Android, is also made from the Linux Kernel. Yes, Linux is amazing! A simple example of its security is that most of the viruses in the world run on Windows, but not on Linux...

Linux History and GNU

Linus Torvalds ,a student at the University of Helsinki started developing Linux to create a system similar to MINIX, a UNIX operating system. In 1991 he released version 0.02; Version 1.0 of the Linux kernel, the core of the operating system, was released in 1994. About the same time, American software developer Richard Stallman and the FSF made efforts to create an open-source UNIX-like operating system called GNU. In contrast to Torvalds, Stallman and the FSF started by creating utilities for the operating system first. These utilities were then added to the Linux kernel to create a complete system called GNU/Linux, or, less precisely, just Linux. Linus Torvalds Richard Stallman Linux grew throughout the 1990s because of the efforts of hobbyist developers. Although Linux is not as user-friendly as the popular Microsoft Windows and Mac OS operating systems, it is an efficient and reliable system that rarely crashes. Combined with Apache, an open-source Web server, Linux accounts fo...