Besides building programs, Make can be used to manage any project where some files must be updated automatically from others whenever the others change.
The example below shows how to use a Makefile to automatically compile a C source code file "example.c" (only when it has been changed) and then execute the compiled file "./example".
./example.c
Create the source file.
#include
int main()
{
printf ("Hello\n");
return 0;
}
./Makefile
Create the Makefile.
exec: compile
./example
compile: \
example.c
gcc example.c -o example
echo "compiling..."
touch compile
Makefile Notes
Make assumes that Makefile targets are files in the same directory in which the make command is executed.If the target file is already there, and its dependencies didn't change, nothing will be done.
"compile" is a dependency of the exec target. "compile" will be executed prior to executing the exec command "./example"
"example.c" is a dependency of the compile target. (It could be on the same line as "compile", but we used the line continuation character "backslash" to put in on a separate line.)
"compile" will be executed only if "example.c" has been modified.
The touch command creates a "compile" target file (if it does not already exist) and effectively updates its last updated timestamp.
Make compares the timestamp of example.c to compile. If example.c has been modified after compile, it will run the "compile" target.
Preface each line of a target body with a single TAB character. (There is a TAB character in front of "./example" in the "exec" target.)
This is a lot of work for managing one source file, but is a huge time saver when there are many source files in a project. Make will only compile the files that have been changed since the last time the compile target has been executed.
Results
$ ls -lrt
total 16
-rw-r--r-- 1 lex staff 64 Jun 30 12:34 example.c
-rw-r--r-- 1 lex staff 108 Jun 30 12:35 Makefile
There are only two files in our directory now.
Run make command
$ make
gcc example.c -o example
echo "compiling..."
compiling...
touch compile
./example
Hello
Results
$ ls -lrt
total 40
-rw-r--r-- 1 lex staff 64 Jun 30 12:34 example.c
-rw-r--r-- 1 lex staff 108 Jun 30 12:35 Makefile
-rwxr-xr-x 1 lex staff 8496 Jun 30 12:35 example
-rw-r--r-- 1 lex staff 0 Jun 30 12:35 compile
Now, there are 4 files.
Run the newly created executable
$ ./example
Hello
./example.c
Add ", World!" to the output.
#include
int main()
{
printf ("Hello, World!\n");
return 0;
}
$ ls -lrt
total 40
-rw-r--r-- 1 lex staff 108 Jun 30 12:35 Makefile
-rwxr-xr-x 1 lex staff 8496 Jun 30 12:35 example
-rw-r--r-- 1 lex staff 0 Jun 30 12:35 compile
-rw-r--r-- 1 lex staff 72 Jun 30 12:38 example.c
Now, "example.c" has a more recent timestamp than the "compile" file.
$ make
gcc example.c -o example
echo "compiling..."
compiling...
touch compile
./example
Hello, World!
Summary
- Make ran the "compile" target, because it was the first target listed in the Makefile
- Make ran the "compile" target, because it was a dependency of the "exec" target
- Make compared the compare file's timestamp to its dependency "example.c" and ran it because example.c has a more recent timestamp.
More Complicated Scenarios
This has been a very simple, contrived example to show how a Makefile works.In order to handle more source files, make allows you to use macros, wildcard pattern matching and string substitution features to automatically include files without modifying your Makefile.
References
http://en.wikipedia.org/wiki/Make_(software)http://www.gnu.org/software/make/manual/make.html
This work is licensed under the Creative Commons Attribution 3.0 Unported License.