make Make was originally a Unix tool from 1976, but it has been re-implemented several times, notably as GNU Make. Make accepts a Makefile, which is a strictly formatted file detailing a series of desired outputs, their dependencies, and how these should be composed together to yield the requested output. Makefiles contain five kinds of things: explicit rules, implicit rules, variable definitions, directives, and comments. An explicit rule says when and how to remake one or more files, called the rule's targets. It lists the other files that the targets depend on, called the prerequisites of the target, and may also give a recipe to use to create or update the targets. An implicit rule says when and how to remake a class of files based on their names. It describes how a target may depend on a file with a name similar to the target and gives a recipe to create or update such a target. A variable definition is a line that specifies a text string value for a variable that can be substituted into the text later. A directive is an instruction for make to do something special while reading the makefile such as reading another makefile. # in a line of a makefile starts a comment. It and the rest of the line are ignored. compatibility with bash/sh/etc. note that variable defns have spaces around equals, for instance variables: CC,FC, CFLAGS,CXX, etc. The Makefile rules for building and installation can also use compilers and related programs, but should do so via make variables so that the user can substitute alternatives. Here are some of the programs we mean: ar bison cc flex install ld ldconfig lex make makeinfo ranlib texi2dvi yacc Use the following make variables to run those programs: $(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX) $(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC) Also: $(FC) $(CXX) An example Makefile: SHELL = /bin/sh OBJS = hello_world_openmp.o # On a Mac, g++ is an alias for clang which doesn't have great OpenMP support. ARCH := $(firstword $(shell uname -s)) ifeq ($(ARCH),Darwin) CC = gcc-4.8 else CC = gcc endif.suffixes:.suffixes:.c.o
DEBUG = -g CFLAGS = -Wall -c $(DEBUG) -fopenmp -std=c99 LFLAGS = -Wall -lm $(DEBUG) -fopenmp hello_world_openmp : $(OBJS) $(CC) $(LFLAGS) $(OBJS) -o hello_world_openmp hello_world_openmp.o : hello_world_openmp.c $(CC) $(CFLAGS) hello_world_openmp.c clean: rm *.o hello_world_openmp tar: tar cfv hello_world_openmp.tar hello_world_openmp.c test: echo "Executing with 1 thread:" OMP_NUM_THREADS=1 echo "Executing with 2 threads:" OMP_NUM_THREADS=2 echo "Executing with 4 threads:" OMP_NUM_THREADS=4 echo "Executing with 8 threads:" OMP_NUM_THREADS=8 requires file: #include <stdio.h> #include <omp.h> int main(int argc, char *argv[]) { int rank_id; double start_time, wall_time; printf("c OpenMP minimal working example\n"); int num_ranks = omp_get_num_procs(); printf("number of available processors = %d.\n", num_ranks); int num_threads = omp_get_max_threads(); printf("number of available threads = %d.\n", num_threads); start_time = omp_get_wtime(); #pragma omp parallel private (rank_id) {
} rank_id = omp_get_thread_num(); printf("\tprocess number %d branching off.\n", rank_id); wall_time = omp_get_wtime() - start_time; } printf("elapsed wallclock time = %8.6fs.\n", wall_time); return 0; There are magic variables that are important to know about. A file could be written as: CC = gcc Warnings = -Wall test: test.o anothertest.o $(CC) $(Warnings) $^ -o $@ test.o: test.c $(CC) -c $(Warnings) $< anothertest.o: anothertest.c $(CC) -c $(Warning) $< clean: rm -rf *.o test Here $@ becomes the target, $< is the first prerequesite, and $^ is all the prerequisites. This has made the file less readable, but doesn t offer any benefit in this simiple example. And naturally, make install may be a bit more complicated than you might have thought. It can range from a simple attempt to copy things over to /usr/bin (see man install ) to a sophisticated system-independent wrapper: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am./configure Why Autoconf? [Make's] lack of support for automatic dependency tracking, recursive builds in subdirectories, reliable timestamps (e.g., for network file systems)
The configuration scripts that Autoconf produces are by convention called configure. When run, configure creates several files, replacing configuration parameters in them with appropriate values. The files that configure creates are: one or more Makefile files, usually one in each subdirectory of the package (see Makefile Substitutions); optionally, a C header file, the name of which is configurable, containing #define` directives (see Configuration Headers); a shell script called config.status that, when run, recreates the files listed above (see config.status Invocation); an optional shell script normally called config.cache (created when using configure --config-cache ) that saves the results of running many of the tests (see Cache Files); a file called config.log containing any messages produced by compilers, to help debugging if configure makes a mistake. The Autoconf approach to portability is to test for features, not for versions. A Full Example $ ls src/ $ ls src/ hello_world_openmp.c $ autoscan $ mv configure.scan configure.ac AC_INIT([hello_world_opemp], [1.0], [davis68@illinois.edu]) AC_CONFIG_SRCDIR([src/hello_world_openmp.c]) #AC_CONFIG_HEADERS([config.h]) $ vi Makefile.am AUTOMAKE_OPTIONS = foreign SUBDIRS = src $ vi src/makefile.am AM_CFLAGS = -Wall -fopenmp -std=c99 bin_programs=hello_world_openmp hello_world_openmp_sources=hello_world_openmp.c AC_INIT([hello_world_opemp], [1.0], [davis68@illinois.edu]) AC_CONFIG_SRCDIR([hello_world_openmp.c]) #AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE(hello_world_openmp, 1.0.0) $ aclocal $ AC_CONFIG_FILES([ Makefile src/makefile ])
AC_OUTPUT --add-missing $./configure $ make http://aireadfun.com/blog/2012/12/03/study-automake/ https://ftp.gnu.org/old-gnu/manuals/automake- 1.6.1/htmlchapter/automake3.html http://pages.cs.wisc.edu/~beechung/ref/gcc-intro.html https://www.gnu.org/software/automake/manual/html_node/requirements.html Others CMake SCons wmake