Search:

PmWiki

pmwiki.org

edit SideBar

Main / Make

'gmake' refers specifically to GNU make. 'make' refers to the system's default make implementation; on most Linux distros this is GNU make, but on other unixes, it could refer to some other implementation of make, such as BSD make, or the make implementations of various commercial unixes. The language accepted by GNU make is a superset of the one supported by the traditional make utility. By using 'gmake' specifically you can use GNU make extensions without worrying about them being misinterpreted by some other make implementation.

Only decent make tutorials I've come across: http://makefiletutorial.com/ and http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

Basics

You can use any file as a makefile by calling make -f <filename>. If using this method instead of the standard Makefile, you can pass specific targets as an extra argument, e.g. make -f <filename> clean

There's a make preview, it prints out all the commands without execution = make -n

Makefile is composed of target constructs. The tab here indicates that this line is a recipe.
target(s): dependency(ies)
    system command

You may split a long line by inserting a backslash followed by a newline, but this is not required, as make places no limit on the length of a line in a makefile.

Declaring variables is easy
VAR=-char

And then they can be referenced in the system command lines with
$(VAR)

You can call on other targets within the Makefile from a target by name:

all : clean

clean : ...

The typical standard is make clean will remove all intermediate files, and make distclean makes the tree just the way it was when it was un-tarred (or something pretty close) including removing any configure script output. This is the way the Linux kernel works for instance.

To make a target that will build all the files of a certain extension

%.o: %.cpp
	$(PLAT_CP) -o $@ $< $(COMPILERFLAGS)

Note that when you compile, make and gcc by default won't go look into the subfolders of include locations.

Advanced

Example of using conditionals and making definitions. In this case a Buildroot package make, and the BR2_PACKAGE_ variables are set in the _defconfig file.

ifeq ($(BR2_PACKAGE_ROOTFS_S99),y)
define ROOTFS_EXTRACT_CMDS
	$(TAR) -C $(@D) $(TAR_OPTIONS) $(DL_DIR)/$(ROOTFS_SOURCE)
	mkdir -p $(@D)/rootfs
endef
else
# this is for the S55 and S77, non-UBI
define ROOTFS_EXTRACT_CMDS
	$(TAR) -C $(@D) $(TAR_OPTIONS) $(DL_DIR)/$(ROOTFS_SOURCE)
	mkdir -p $(@D)/rootfs
	cd $(@D)/rootfs && \
		tail -c +65 $(@D)/initramfs.bin.SD | gunzip | cpio -idm
endef	  
endif

Is there a way to check multiple conditionals in one ifeq statement? Yes. This test Makefile can be run to illustrate. The answer is "yes" if exactly one of the three VARs is y.

#VARA = y
#VARB = y
VARC = y

foo:
ifeq (y,$(VARA)$(VARB)$(VARC))
	echo "yes"
else
	echo "no"
endif

# ($(VARA)$(VARB)$(VARC),y) also works

VPATH

This is a catch-all variable, a place to stash needed paths for directory search when the file does not live in working directory.

include

Read and process other makefiles before continuing with the include <filename> command
http://www.gnu.org/software/make/manual/make.html#Makefile-Contents

You can call sub-makes without having to put down a cd command with the -C option:

foo :
	$(MAKE) -C $(FOO_SRC_DIR)

define

Send the preprocessor a definition using the -D flag on invoking gcc, e.g. -DLINUX.

.PHONY

Use this to designate a target that is not an actual filename. For example, ‘make clean’ will run the recipe regardless of whether there is a file named clean in this example.
.PHONY : clean

Problems

make: *** Error

It sounds like the number given with this error just tells the level of recursion at which the error occurs...
http://www.gnu.org/software/make/manual/html_node/Error-Messages.html

Running make with -d will make it tell you what the heck it's doing. (Also --debug=verbose to some extent, and VERBOSE=1)

make: Nothing to be done for `all'.

Inside a Makefile, the TAB character is critical. The dependency lines must have a tab before the "make".

make[1]: *** No rule to make target 'XXXXXXXX', needed by 'XXXXXXXX'. Stop.

This will happen if make is given a target it doesn't understand. Apparently, it will also do this if a specified source file is missing.

Makefile keywords and options

$(shell command)

It seems you can run commands during the make process by housing them inside a $(shell <cmd>) construct in your makefiles.

&(call command)

This runs a Make 'function' defined by 'function_name = command' located in the master config.mk file.

Substitute

Use $@ and $< to substitute the names of the target file and the source file in rule
$(@D) gives the directory path of the target filename, without the file. Here is a link for other so-called automatic variables: https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html

The target: | dependency pipe symbol

Occasionally you have a situation where you want to impose a specific ordering on the rules to be invoked without forcing the target to be updated if one of those rules is executed. In that case, you want to define order-only prerequisites. Order-only prerequisites can be specified by placing a pipe symbol (|) in the prerequisites list: any prerequisites to the left of the pipe symbol are normal; any prerequisites to the right are order-only:

targets : normal-prerequisites | order-only-prerequisites

example:
$(OBJS): | $(OBJDIR)

$(OBJDIR):
  mkdir $(OBJDIR)

The normal prerequisites section may of course be empty. This means that you want the rules to run, but not to cause the target to be updated if the command is executed. It's like "X has to happen first, but if it's already done don't re-create Y".

Comments

‘#’ in a line of a makefile starts a comment. It and the rest of the line are ignored, except that a trailing backslash not escaped by another backslash will continue the comment across multiple lines. Pay attention to this for SOURCES lists.

Directives

You can nest a define inside of an ifeq, but they both start at the same indentation level.

Organization

If you are wondering where your command options and definitions are, look for a folder called mk with files like flags.mk.

What is a .o.cmd file?
In essence, the command used to compile each file in the kernel is saved in a .cmd file. When a subsequent build is executed, make reads the .cmd files and compares the current compile command with the last command. If they are different, the .cmd dependency file is regenerated causing the object file to be rebuilt. The .cmd file usually contains two items: the dependencies that represent actual files for the target file and a single variable recording the command-line options.

Highlighting Results

Use a log colorizer like ccze (sudo apt-get install ccze) and run make | ccze -A to color the output text for easy-find warnings and errors.


Page last modified on September 10, 2020, at 10:48 AM