Red Antigua Logo
Yet another piece of web.
Ads by Goooooogle
Search this site (by Google)
Tools    (top)
Your IP
Check a site for broken links
(W3C)

Perl modules    (top)
Tree::Numbered::Tools
(CPAN)
Perl tutorials    (top)
Perl modules
HTML::Template
CGI::Application
Mail::POP3Client
Mail::Send
MIME::Tools
Cookies with CGI::Application
Upload files with CGI::Application
Download files with CGI::Application
Redirect with CGI::Application
CPAN shell
Install DBD::mysql from the CPAN shell
Perl trim function
Validate an IP with Perl
Run suid Perl scripts under Apache
Perl taint mode
Perl date functions with Date::Calc

In Spanish
Curso de Perl

C tutorials    (top)
C - Introduction
C - Absolute beginner's Emacs
C - Examples for beginners
C - Makefile examples
C - Autotools examples
Server configurations    (top)
DNS
Apache
Apache Authentication and Access Control
mod_perl on FreeBSD
MySQL
MySQL add account
phpMyAdmin
Squid
DHCP

UNIX on Windows    (top)
Apache setup on Windows
MySQL setup on Windows
PHP setup on Windows
Perl setup on Windows
Emacs setup on Windows
UnxUtils
PuTTY
WinSCP
GIMP on Windows
MinGW - gcc on Windows
MSYS - UNIX-styled shell on Windows
msysDTK - autotools on Windows
GDB for MinGW on Windows

Misc. FreeBSD/UNIX    (top)
CD and DVD creation on FreeBSD using 'k3b' on FreeBSD
'portupgrade' on FreeBSD
'ipf' on FreeBSD
'pf' on FreeBSD
'su' on FreeBSD
Mount an ISO image under FreeBSD
Load the correct sound driver under FreeBSD without knowing what sound card you are using
Simultaneous sound channels on FreeBSD
FreeBSD network stuff
DOS-to-UNIX file conversion
favicon.ico on UNIX
Emacs tips
Sendmail tips
GKrellm
Command Line Calculator
Save multimedia streams with 'mplayer'
xargs - solution to 'Argument list too long'
Process multiple images from the command line using 'ImageMagick'
Turn the system bell off under X Windows
Process each line in an input file from the command line (or in a shell script)
How to keep a program running in the background using 'nohup'
How to remove symbolic links in the current directory using 'find' and 'rm'
How to remove Emacs backup files in the current directory and all subdirectories using 'find' and 'rm'
How to execute .profile without logging in
Configure X to handle non-English characters
How to move /var to /usr/var

Redirect a web page    (top)
Redirect to another web page
Apache redirect
C redirect
Perl redirect
PHP redirect
HTML redirect
JavaScript redirect

Javascript    (top)
Trim function
Login form
Register form
Popup window

Virus list    (top)
Latest 10 viruses - Sophos

Off topic    (top)
Personal home links

Makefile - targets are files (almost always)
Makefile - targets are files (almost always)
IndexPreviousNext
Makefiles use so-called rules with the following format:
target: prerequisite(s)
        command(s)

A target is normally the file we want to create.
A prerequisite is another target (normally another file) which is required to exist before we can create the file.
The command(s) are the shell commands which create the target (once again, the file we want to create).
The "target-prerequisites" line starts at the beginning of the line, while the "commands" line always has to start with a TAB.
Note: If the target (the file) already exists and is considered up to date (Makefile term explained later), the commands will NOT be executed, but instead the following message will be shown:
make: <target> is up to date.
(More about rules in the next example).

Even if make mainly is a software compilation tool, in this example we will focus on how file depends on each other (targets and their prerequisites) without invoking a compiler.
Let say we want to create 3 files (independently from each other) called hello.txt, doyoulikemake.txt, and bye.txt, and then display their contents.
To do this using a makefile, we should type:
make hello.txt
make doyoulikemake.txt
make bye.txt
In this case, the targets are hello.txt, doyoulikemake.txt, and bye.txt, respectively.
They will be created independently (no other files need to exist to create them), so there are no prerequistes needed for these targets.
Let's start with the following Makefile (create it in an empty directory):
hello.txt:
        @echo "Hello, world!" > hello.txt
        @cat hello.txt

doyoulikemake.txt:
        @echo "Do you like make?" > doyoulikemake.txt
        @cat doyoulikemake.txt

bye.txt:
        @echo "Bye, see you later." > bye.txt
        @cat bye.txt
Type
$ make hello.txt
and you will see
Hello, world!
Type
$ make hello.txt
again (and again) and you will see
make: `hello.txt' is up to date.
Generally speaking, make considers a target up to date if the following two conditions are fulfilled:
    a. the target exists.
    b. the target is newer than its prerequisites.
When a target has no prerequisites, as in the example above, condition b. is always fulfilled.
In such cases, it is sufficient for a target to exist to be considered up to date.
So if we want to see the file contents again (by executing the rule commands), we have to remove hello.txt, or the commands will not be executed.

Let's add a rule with a target called clean for removing the text files:
clean:
        rm -rf hello.txt doyoulikemake.txt bye.txt
The name of the target is clean, but there is no existing file called clean, nor will it be created by the rule command.

Imagine that a file called clean was created by mistake (with touch clean, for example).
That would imply that both the conditions a. and b. always are fulfilled (the target clean exists, so condition a. is fulfilled, and it has no dependencies, so condition b. is always fulfilled), which in turn would imply that the rm command would never be executed. This is not what we wanted.
To avoid this to happen, we will create a so-called phony target.
A phony target forces the command(s) in a rule to always be executed.
This is how the modified phony target clean looks like:
.PHONY: clean
clean:
        rm -rf hello.txt doyoulikemake.txt bye.txt
Now you can type
make clean
to delete all the text files.

There is a problem with the targets hello.txt, doyoulikemake.txt, and bye.txt - when these targets are up to date (when they exist), the file contents isn't displayed.
With our new target clean we could always type
make clean hello.txt
to force the files to be deleted before we create them again, but it is not an elegant solution.
A better solution is to let the command of each rule only create the target, and create a new rule to display the target file contents.
We always want to display the contents, so the commands for the new rule should always be executed.
This means the new rule should be a phony rule.
To display the contents of the target files, they must obviously exist.
This means that the new rule will depend on the target files, they will be prerequisites for the new rule.
Let's call the new rule display:
.PHONY: display
display: hello.txt doyoulikemake.txt bye.txt
        @cat hello.txt doyoulikemake.txt bye.txt
Read the rule above as:
"Always execute this rule (it is phony), but before doing so, create the prerequisites hello.txt, doyoulikemake.txt, and bye.txt if they did not exist already. Then display the contents of the files with cat."

A modified target rule will look like this (the second command is just used to show when the target is created):
hello.txt:
        @echo "Hello, world!" > hello.txt
        @echo Target 'hello.txt' created.

Makefiles are easier to read using variables.
Let's list all our targets in the variable TARGETS:
TARGETS=hello.txt doyoulikemake.txt bye.txt 

Now we can use the variable TARGETS instead of the target list in existing rules:
.PHONY: display
display: $(TARGETS)
        @cat $(TARGETS)
.PHONY: clean
clean:
        rm -rf $(TARGETS)
With the changes of the target rules, our final Makefile will look like this:
TARGETS=hello.txt doyoulikemake.txt bye.txt 

.PHONY: display
display: $(TARGETS)
        @cat $(TARGETS)

hello.txt:
        @echo "Hello, world!" > hello.txt
        @echo Target 'hello.txt' created.

doyoulikemake.txt:
        @echo "Do you like make?" > doyoulikemake.txt
        @echo Target 'doyoulikemake.txt' created.

bye.txt:
        @echo "Bye, see you later." > bye.txt
        @echo Target 'bye.txt' created.

.PHONY: clean
clean:
        rm -rf $(TARGETS)
Now play around with make, make clean, make display, make hello.txt, and make doyoulikemake.txt clean bye.txt display, and be sure you understand how they interact.

Exercise:
  1. If the target name appears in a rule, it can be replaced by the automatic variable $@.
    Replace target names wherever it is possible with $@.
IndexPreviousNext
Last modified: Thu Jan 03 16:26:34 Romance Standard Time 2008