Overview
Make is a program used primarily on Unix systems to manage compiling and linking (building) programs written in C, C++, Fortran, or other compiled languages. Make operates on targets using rules to create those targets. It has a set of built-in rules but users may write their own or override the default rules. Make scans the dependencies of each target looking for files newer than the target. If it finds them, it recreates the target. Targets may and usually do depend on other targets; make will work its way through the chain to rebuild the final target, which is typically an executable.
To utilize the program, the user types
make
Make looks first for a file called makefile
. If it does not find that it will look for Makefile
. If neither is present, it will attempt to use its default rules, which is seldom successful. Users can name their file other than makefile
or Makefile
but then must invoke make with the -f
option
make -f filename
The name Makefile
(capital M) is most frequently used on Unix because it will stand out in a directory where other files are entirely or mostly lower case.
Make is often used in conjunction with autoconf
. Autoconf uses a script called configure
to generate a Makefile. In most cases, the configure script will be provided by the developer of a particular program. The configure script usually takes several optional arguments, including an option --prefix=/path/to/installation
which will allow users to install to a location other than the default, which is usually /usr/bin
and is not writeable by ordinary users.
Another popular build system is cmake. Cmake is more similar to autoconf than to make, since on Unix it creates a Makefile which must then be executed.
Basics of Make
The Makefile must follow a rigid format. The target must start in the first column of a line and must be terminated with a colon (:). Any dependencies, i.e. files required to create this target, must follow the colon as a space-separated list on a single line. The rules required to create the target from the dependencies must follow on separate lines and each rule line must begin with a tab character.
Example:
myexec: file1.o file2.o
<tab>g++ file1.o file2.o
file1.o: file1.cxx
<tab> g++ -c file1.cxx
file2.o: file2.cxx
<tab> g++ -c file2.cxx
Because some patterns occur repeatedly, make supports suffix rules, which describe how to create targets from certain files. For example, a suffix rule to compile any Fortran file ending in .f90 would be written
.SUFFIXES .f90:
.f90.o:
<tab>gfortran -c $<
The $<
special variable stands for the current target.
Make supports variables. Normally collected at the top of the Makefile, these are conventionally written in all capitals.
F90=gfortran
Our suffix rule could then be expressed as
.f90.o:
<tab> $(F90) -c $<
Variables make it easy to
Make on the HPC system
Users who write their own code and need to generate a Makefile can start with the makemake script. It is local to the HPC system and should automatically be in the path so it is sufficient to type
makemake
This will create a skeleton Makefile. The user must at minimum assign a value to the PROG variable
PROG=myexec
Usually it will also be necessary to change the compiler names to that actually used, especially for Fortran programs.
The version of makemake installed on the HPC system attempts to create a Makefile valid for C, C++, and Fortran programs. Any lines in the Makefile not pertinent to the user’s application (such as C++ for a Fortran program or vice versa) may be deleted.
It is important to note that makemake is not intelligent. It simply collects all files it finds in a directory that end in the suffices .f, .f90, .c, .cxx, and a few others. Any of those files that are not compilable, for example because they are included into another source file, must be removed from the SRCS and OBJS lists.
The makemake script also creates a special target, called a dummy, clean
. Typing make clean
removes the executable and all object (.o) files, as well as any .mod files for Fortran.
Users should make clean
every time compiler options are changed.
Special note for Fortran Programs
Modern Fortran programs typically use modules. Make is not very good at determining correct dependency chains with modules and may not rebuild when modules are changed. If this happens it will be necessary to make clean
when module files are altered.