Make basics

From wikinotes

A makefile is just several blocks of instructions (targets), that can require other blocks of instructions to run.

Overview

Makefiles are primarily used to build C, C++, or other compiled projects.
In these projects, the makefile is generally responsible for:

  • configuring compiler to use, and compiler-flags
  • defining program to compile, and all the object-files it is dependent on
  • defining each object-file, it's cpp/header files, and all other dependent header files

Targets

A Target is a unit of work in a makefile.
It's instructions are expressed in shellscript, indented with a TAB character.

install:              # <-- a target
	cp -Ra build/* /  # <-- indented w/ tab

Dependencies

Targets can have dependencies on other targets.
In the example below, install requires build

install: build
	cp -Ra build/* /

build:
	mkdir -p build/bin
	echo "echo 'hello'" > bin/hello
	chmod 755 bin/hello

Targets can have multiple dependencies, and dependencies can have their own dependencies.

cook: chop_veggies add_water salt_to_taste
	cat build/veggies.txt build/water.txt build/salt.txt > build/recipe.txt

chop_veggies:
	echo "chopped carrots\nchopped broccoli" > build/veggies.txt

add_water:
	echo "1 cup of water" > build/water.txt

salt_to_taste:
	echo "salt salt salt" > build/salt.txt

Often, a build target will be created for each intermediate file,
which saves you from rebuilding it if it is already present.

libfoo.o:
	g++ -Wall -c libfoo.cpp

libbar.o:
	g++ -Wall -c libbar.cpp

Helper Functions

Make ships with several useful helper functions that you can use to keep your file short.
Here are a few examples

# replace text
$(subst from,to,text)

# replace path prefixes
# ('%' is a wildcard match, it'ss value is preserved in replacement)
$(patsubst %.c,%.o,file1.c file2.c file3.c)

# single variable pattern-replacement
$(var:pattern=replacement)

See documentation for more: https://www.gnu.org/software/make/manual/html_node/Text-Functions.html .