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 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 but then must invoke make with the
make -f filename
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 dependences must follow on separate lines and each rule line must begin with a tab character.
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 $<
$< 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.
Our suffix rule could then be expressed as
.f90.o: <tab> $(F90) -c $<
Variables make it easy to
Make on Rivanna
Users who write their own code and need to generate a Makefile can start with the makemake script. It is local to Rivanna and should automatically be in the path so it is sufficient to type
This will create a skeleton Makefile. The user must at minimum assign a value to the PROG variable
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 Rivanna 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,
make clean removes the executable and all object (.o) files, as well as any .mod files for Fortran.
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.