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/ BasicsYou 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 And then they can be referenced in the system command lines with 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. AdvancedExample 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 VPATHThis is a catch-all variable, a place to stash needed paths for directory search when the file does not live in working directory. includeRead and process other makefiles before continuing with the include <filename> command You can call sub-makes without having to put down a cd command with the -C option: foo : $(MAKE) -C $(FOO_SRC_DIR) defineSend the preprocessor a definition using the -D flag on invoking gcc, e.g. -DLINUX. .PHONYUse 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. Problemsmake: *** ErrorIt sounds like the number given with this error just tells the level of recursion at which the error occurs... 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. SubstituteUse $@ and $< to substitute the names of the target file and the source file in rule The target: | dependency pipe symbolOccasionally 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. DirectivesYou can nest a define inside of an ifeq, but they both start at the same indentation level. OrganizationIf 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? Highlighting ResultsUse 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. |