# Makefile [TOC] # Introduction ## What is Makefile The “Make” tool needs to get its knowledge of how to build a program from a file called the “makefile”. This makefile lists each of the non-source files and how to compute it from other files. When you write a program, you should write a makefile for it, so that it is possible to use “Make” to build and install the program. ## How to Install ### Ubuntu ```bash apt-get install build-essential #Will install gcc, g++, make ``` ### MacOS ```bash xcode-select --install ``` ### Windows MinGW: https://sourceforge.net/projects/mingw/files/latest/download?source=files ## Simple Makefile ```cmake= objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o ``` # Rules ## Simple Rules ```cmake= target … : prerequisites … recipe … … #or like this: targets : prerequisites ; recipe recipe … ``` - Target - The targets are file names, separated by spaces. - Wildcard characters may be used \(*, ?, \[...\], \~\) - A name of the form a(m) represents member m in archive file a. - Usually there is only one target per rule, but occasionally there is a reason to have more. - Recipe - The recipe lines start with a tab character (or the first character in the value of the .RECIPEPREFIX variable). - Because dollar signs are used to start _make_ variable references, if you really want a dollar sign in a target or prerequisite you must write two of them, ‘\$\$’. - If you have enabled *secondary expansion* and you want a literal dollar sign in the prerequisites list, you must actually write four dollar signs '\$\$\$\$'. Examples : ```cmake= foo.o : foo.c defs.h cc -c -g foo.c ``` This rule says two things: - How to decide whether foo.o is out of date: it is out of date if it does not exist, or if either foo.c or defs.h is more recent than it. - How to update the file foo.o: by running cc as stated. The recipe does not explicitly mention defs.h, but we presume that foo.c includes it, and that is why defs.h was added to the prerequisites. ```cmake= .SECONDEXPANSION: ONEVAR = onefile TWOVAR = twofile myfile: $(ONEVAR) $$(TWOVAR) ``` The final result is that there are two prerequisites, `onefile` and `twofile`. ## Variables Assgin ```cmake= immediate = deferred immediate ?= deferred immediate := immediate immediate ::= immediate immediate += deferred or immediate immediate != immediate define immediate deferred endef define immediate = deferred endef define immediate ?= deferred endef define immediate := immediate endef define immediate ::= immediate endef define immediate += deferred or immediate endef define immediate != immediate endef ``` Comparison examples : ```cmake= x = foo y = $(x) bar x = xyz # the final value of y is xyz bar ``` ```cmake= x := foo y := $(x) bar x := xyz # the final value of y is foo bar ``` ## Wildcard ```cmake= $(wildcard pattern…) $(patsubst pattern, replacement, text) $(patsubst %.c, %.o, x.c.c bar.c) #equals: x.c.o bar.o ``` ## Automatic Variable - `$@` : The file name of the target of the rule. - `$<` : The name of the first prerequisite. - `$^` : The names of all the prerequisites, with spaces between them. - `$*` : The stem with which an implicit rule matches. ## Newline ### newline with whitespace command: \<space\>\\ ```cmake= #object will be assign: abcdef<space>ghijkl<space>mnopqr object = abcdef \ ghijkl \ mnopqr ``` ### new line without whitespace command: \$\\\<newline\> ```cmake= #object will be assign: abcdefghijklmnopqr object = abcdef$\ ghijkl$\ mnopqr$\ ``` ## include others Makefile ```cmake= include filenames… #include others Makefile -include filenames… #exclude others Makefile # # examples # include another_Makefile_name include foo *.mk $(bar) ``` ## Common Variables Name ```cmake= CC = gcc -o # CC usually equals c compiler command CFLAGS = -Wall # CFLAGS is c compiler arguments OBJS = $(SRCS_C:.c=.o) $(SRCS_Y:.y=.o) #Need to be compile .o ``` ## Common Phony Name ```cmake= .PHONY: install .PHONY: clean ``` * Two reasons of using `.PHONY` : * To avoid a conflict with a file of the same name. * To improve performance. # Examples # Reference GNU make: https://www.gnu.org/software/make/manual/make.html