Make

make is a utility for building applications. This tutorial will teach you how to use this utility with Makefiles. This tutorial is primarily focused on GNU make.

Hand compilation
Before we start talking about "make", let's first describe the build process used long ago: "hand compilation", aka "manual build". That processes isn't too bad if you only have one or two source files. A simple compilation process would be by typing the following code by hand: For beginners, this might take a while to get used to. As an alternative, using make the command would be: Both commands will do the same thing - take the file.cpp source file, compile it and then link it into an executable. But where the problem comes in is where the user has to use more than one source file, or is dependent on libraries. Making an SDL application might consist of something like this: This is getting harder to remember, isn't it? Let's add some optimisation: Do you really want to type that whole command line every time you make the tiniest edit to your source files? This is where make comes in - it will save your time!

Basics
A make file works as a simple dependency tree - it compiles the stuff that is outdated and then links your software together. You will have to specify the compilation options, but they will not be as tough on you anymore. A simple makefile for compiling your application:

Makefile To compile your application, you may do: or: Well, you may now ask, how much of use is this? I can make a shell script for this myself! So lets now work on multiple files and object files - your application is big enough to be linked now: it contains five files.

The Test Case
Globally, there are three functions present: int main; (file1.cpp) void file2function(std::string from); (file2.cpp) void file3function(std::string from); (file3.cpp) File2 and file3 have their header files, so they could be inter-linked. The actual application will look like this:

file1.cpp

file2.h

file2.cpp

file3.h

file3.cpp

So, how would I link this all up? Well, the most basic way is to do it all by hand: However, make would offer a simpler way, Makefile:

Makefile

Pretty different, eh? There's a different approach to do this, which is what makes make so good:

Makefile

How easy is it to expand now? Just add a file to the OBJS list and you're done!

This is a complete makefile that handles the complete process of converting several source files (and creating a bunch of ".o" files as an intermediate step) into the final "file1" executable.

Good programmers put human-readable comments (lines starting with the "#" character) in the makefile to describe why the makefile was written and what make is intended to do with this makefile (which, alas, is not always what actually happens).

Long Lines
Some statements in a makefile can be very long. To make them easier to read, some programmers break up long statements into several shorter, easier-to-read physical lines. Many consoles displayed 80 characters across, which is the threshold some programmers use for breaking up lines and comments.

In short, a programmer may decide it looks nicer to writes several short physical lines that together compose one statement, like this:

Rather than the same statement, crammed into a single physical line:

Make Clean
When you type "make clean" from the command prompt, "make" deletes all the files that you specified were easily replaceable files—i.e., the intermediate and output files generated from your irreplaceable hand-written source files.

To tell "make" that some file is an easily replaceable file, add it to the "rm" line of the "clean" section of your makefile, and that file will be deleted *every* time you type "make clean" at the command prompt. (If you don't already have a "clean" section in your makefile, add a section to the end of your makefile that looks like the following):

In this example, we've told "make" that all intermediate object files ("*.o") and the final executable ("file") are safe-to-delete, easily regenerated files. Typically people (or automake scripts) set up the clean step to delete every target in the makefile.

Typically a programmer periodically runs " ", then archives *every* file in the directory, and then runs "make" to regenerate every file. Then he tests the program executable, confident that the program he is testing can be easily regenerated entirely from the files in the archive.

make check
Many makefiles include a " " target that performs self-tests (if any). (The  target is usually a synonym for  ).

To support test-first programming and regression tests, " " just runs the tests, it doesn't rebuild the program; but often  first re-builds the program and then also runs "make check".

Variables
"make" accepts three ways of setting variables.
 * Recursively expanded variables are defined by using . This means if one variable 'y' contains references to another variable 'x', and 'x' changes after the 'y' being defined, 'y' will include the change made to 'x'.


 * Simply expanded variables are defined by using . This means if one variable 'x' contains references to another variable 'y', the 'y' variable will be scanned for once and for all.


 * If you just want to make sure a variable is set, you can use . If the variable is already set, then the definition will not be run; if not, then 'variable' will be set as 'value'.

File Names With Special Characters
Many programmers recommend not creating files with spaces or dollar signs in them, in order to avoid the 'spaces in file names' error in "make" and many other utilities.

If you must deal with a file that has spaces or dollar signs in the file name (such as the file "my $0.02 program.c"), sometimes you can escape the literal name of the file with double slashes and double dollar signs—in the Makefile, that filename can be represented as "my\\ $$0.02\\ program.c".

Alas, the double-slash escape doesn't work when "make" works with lists of files (which are internally represented as space-separated filenames). One work-around is to refer to that file name using a space-free representation like "my+$$0.02+program.c", then later in the make file use the $(subst) function to convert that space-free representation back to the actual on-disk file name. Alas, this work-around can't handle filenames that include both spaces and plus-signs.

Perhaps it's simplest to avoid filenames with spaces in them as inputs or outputs of "make".

Name of the makefile
When creating a new makefile, give it the literal name " " (8 characters, no extension).

In principle, you could create a makefile with some other name, such as  or  , which (like ) are automatically found by the GNU version of the   utility, or some other name that you pass to the make utility with the  option.

Example makefiles

 * /Examples/

Books and manuals

 * GNU Make documentation
 * FreeBSD make manual page
 * Microsoft NMAKE reference
 * GNU make Standard Library.
 * Managing Projects with GNU make.

Tutorials

 * The GNU C Programming Tutorial - Writing a makefile
 * Makefile Tutorial: How To Write A Makefile
 * OPUS Makefile Tutorial
 * Makefile Tutorial for C, gcc, & gmake
 * Using NMake

Articles

 * "Ask Mr. Make" series of article about GNU Make
 * What is wrong with make?
 * What’s Wrong With GNU make?
 * Peter Miller. "Recursive Make Considered Harmful". (was Recursive Make Considered Harmful)
 * Advanced Auto-Dependency Generation.
 * "Kleknev: a coarse-grained profiler for build systems". Sometimes "make" is used to build extremely large, complicated systems; the Kleknev system helps people figure out what items are eating the most time during that build process.

C/Więcej o kompilowaniu