## Notes for Makefile.am writers ## (Oct 2001 Christian Cornelssen) ## vim: set comments=n\:# tw=78: ## Introduction ## ## Using Automake-generated Makefile[.in]s is quite comfortable, ## and the coresponding Makefile.am-s are easy to write and maintain. ## On the other hand, experienced Makefile writers will suffer pains ## from being forced to adapt to Automake's concepts which are not as ## flexible as they may desire. Additionally, using Automake's rules ## also inherits their shortcomings, deficiencies, and bugs. In the ## following, I present some how-to and don't-do rules that I had to ## learn by experience. To be fair, I have to admit that some problems ## were caused by me trying to be smarter than Automake expected. ## However, Automake's documentation did not warn me about doing so. ## What you should know about `*-local' targets ## ## Two things should be noted about `*-local' targets: First, their rules ## take effect when Automake's subdirectory recursion reaches the current ## directory, that is, after all its $(SUBDIRS), unless you include a `.' at ## some other position in that variable. Second, `*-local' targets are ## subject to subtle internal dependencies. For example, an `all-local' ## target will also be made when doing an `install' or `check'. Now consider: ## You have a SUBDIRS list shorter than $(DIST_SUBDIRS), but you want "make ## clean" to clean all of them. Do not use `clean-local' for that purpose: it ## will also be used when making `distclean', but that applies to all ## $(DIST_SUBDIRS) already, thereby deleting all their Makefiles, so every ## additional subdir-make must fail. If you just want to extend the operation ## of a certain target like `clean', without effecting any other, add a custom ## target to the dependencies of that target directly. Don't use a `*-local' ## target for that purpose. ## Usage of AM_MAKEFLAGS ## ## When writing commands in rules, if you invoke $(MAKE), always add ## $(AM_MAKEFLAGS), as Automake does in its rules. If you pass a variable ## definition in a $(MAKE) argument, also add the definition to the ## environment variable AM_MAKEFLAGS for the call: ## ## target: ## for i in $(SOME_WORDS); do \ ## AM_MAKEFLAGS="$$AM_MAKEFLAGS var='$$i'" \ ## $(MAKE) $(AM_MAKEFLAGS) var="$$i" || exit $$?; \ ## done ## ## (Note that the assignment to AM_MAKEFLAGS and the $(MAKE) call are parts ## of the same command, which limits the scope of the assignment.) ## This ensures that variable settings are passed on to nested sub-makes. ## GNU Make would do that by itself, but we try to be portable. ## ## Here is how it works: Automake does not provide a definition for ## AM_MAKEFLAGS in the generated Makefile[.in], therefore Make uses the ## value of the corresponding environment variable. Then a command "$(MAKE) ## $(AM_MAKEFLAGS) ..." will use the contents of that environment variable to ## tune the sub-make. Note that $(AM_MAKEFLAGS) reflects the value of the ## environment variable imported by the current Make process, regardless of ## what you do to AM_MAKEFLAGS within shell commands. Note also that Make ## recursively expands all `$' stuff when substituting $(AM_MAKEFLAGS), and ## that the result is then subject to the usual shell expansions. Therefore, ## learn to distinguish between $$AM_MAKEFLAGS and $(AM_MAKEFLAGS), and quote ## carefully. The scheme will work as long as you stick to the following ## rules: ## ## (1) Supplement every $(MAKE) call with $(AM_MAKEFLAGS). ## ## (2) Always use the environment for passing this variable to sub-Makes. ## In particular: ## ## (2a) Do not define AM_MAKEFLAGS as a Make variable in a Makefile.am. ## ## (2b) Within a command, do not set AM_MAKEFLAGS in a $(MAKE) argument, ## i.e. don't do "$(MAKE) ... AM_MAKEFLAGS=..." ## ## (3) When changing AM_MAKEFLAGS in a command, append to its (unknown) ## contents instead of overwriting them. ## $(distdir) and $(top_distdir) ## ## As of Automake 1.5, `top_distdir' is not passed correctly to subdir-makes, ## which matters only if you use it in your own rules (Automake doesn't). ## Use something like $(distdir)/../.. instead. ## ## Also note that the variable `distdir' is not set correctly in subdir ## Makefiles (it should include the subdir), but that does not really matter ## because the commands issued by "make dist*" always pass the correct setting ## on the $(MAKE) command line. Future versions of Automake may produce ## cleaner code. ## $(srcdir), $(top_srcdir), and where not to use them ## ## Automake 1.5's dist* rules work correctly only for relative filenames that ## do not explicitly refer to $(srcdir) or $(top_srcdir), so avoid these ## prefixes in Automake variables like *_SOURCES, *_HEADERS, dist_* or ## EXTRA_DIST. Essentially, $(top_srcdir) and $(srcdir) are meant to be used ## in commands, but not in target/dependency specifications. For the latter, ## replace $(top_srcdir) by $(top_builddir) and rely on Automake's VPATH ## setting to find the files when building elsewhere. That is, you have to ## specify your source files in a simple-minded fashion, as if $(srcdir) could ## be assumed to be the current directory. This simplifies the specifications ## and also allows you to experiment with modified copies of source files in ## the build tree, without touching the original files. ## Patterns and VPATH ## ## You may be tempted to use filename patterns in order to shorten long lists. ## But do not use filename patterns where VPATH searches may be needed. ## Furthermore, using patterns in directory components of filenames produces ## very strange results with the dist* targets, so don't do that. ## Typically, filename patterns make sense only for stuff that is to be found ## in the build tree anyway, e.g. configure-generated files and links, object ## files etc., that is, non-distributed stuff. Hence, everything that is to be ## distributed should be listed file by file. ## Directories in EXTRA_DIST ## ## Having read this, you would not think of specifying directory names in an ## EXTRA_DIST variable, would you? Not only might this include lots of stuff ## (CVS dirs, backup files, etc.) that you would have to filter out in a ## dist-hook, but the current (Automake 1.5) support for distributing entire ## directory trees is buggy anyway: they are always looked up in $(srcdir) ## only, any modification located in the build tree is ignored instead of ## added. Currently, "some/path/dir" is distributed as "dir" (whereas regular ## files are handled correctly), so you cannot use nested or external subdirs. ## Again, make filename lists as literal as possible.