{"id":476,"date":"2012-09-29T13:35:47","date_gmt":"2012-09-29T13:35:47","guid":{"rendered":"http:\/\/blog.bachi.net\/?p=476"},"modified":"2017-02-02T15:58:45","modified_gmt":"2017-02-02T15:58:45","slug":"makefile-rules","status":"publish","type":"post","link":"https:\/\/blog.bachi.net\/?p=476","title":{"rendered":"Makefile rules"},"content":{"rendered":"<p><a href=\"http:\/\/www.conifersystems.com\/whitepapers\/gnu-make\/\">What\u2019s Wrong With GNU make?<\/a><br \/>\n<a href=\"http:\/\/blog.melski.net\/2015\/01\/07\/howto-intro-to-gnu-make-variables\/\">HOWTO: Intro to GNU make variables<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ntarget: normal-prerequisites | order-only-prerequisites\r\n    recipe\r\n<\/pre>\n<h3>Debugging<\/h3>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ make -d\r\n==&gt; print out the parser results\r\n\r\n$ make -p\r\n==&gt; execute make but prints the database\r\n(buildins + Makefile) at the end\r\n<\/pre>\n<h3>.SUFFIXES<\/h3>\n<pre class=\"brush: plain; title: make -d; notranslate\" title=\"make -d\">\r\n      Considering target file 'obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o'.\r\n       File 'obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o' does not exist.\r\n        Considering target file 'src\/ntpd\/ntp_parser.c'.\r\n         Looking for an implicit rule for 'src\/ntpd\/ntp_parser.c'.\r\n         Trying pattern rule with stem 'ntp_parser'.\r\n\r\n         Trying implicit prerequisite 'src\/ntpd\/ntp_parser.y'.\r\n         Found an implicit rule for 'src\/ntpd\/ntp_parser.c'.\r\n          Considering target file 'src\/ntpd\/ntp_parser.y'.\r\n\r\n           Looking for an implicit rule for 'src\/ntpd\/ntp_parser.y'.\r\n           Trying pattern rule with stem 'ntp_parser.y'.\r\n           Found an implicit rule for 'src\/ntpd\/ntp_parser.y'.\r\n           Finished prerequisites of target file 'src\/ntpd\/ntp_parser.y'.\r\n          No need to remake target 'src\/ntpd\/ntp_parser.y'.\r\n         Finished prerequisites of target file 'src\/ntpd\/ntp_parser.c'.\r\n         Prerequisite 'src\/ntpd\/ntp_parser.y' is newer than target 'src\/ntpd\/ntp_parser.c'.\r\n        Must remake target 'src\/ntpd\/ntp_parser.c'.\r\nyacc  src\/ntpd\/ntp_parser.y \r\nPutting child 0xe159d0 (src\/ntpd\/ntp_parser.c) PID 5528 on the chain.\r\nLive child 0xe159d0 (src\/ntpd\/ntp_parser.c) PID 5528 \r\nmake: yacc: Command not found\r\nReaping losing child 0xe159d0 PID 5528 \r\n&lt;builtin&gt;: recipe for target 'src\/ntpd\/ntp_parser.c' failed\r\nmake: *** &#x5B;src\/ntpd\/ntp_parser.c] Error 127\r\nRemoving child 0xe159d0 PID 5528 from chain.\r\n<\/pre>\n<pre class=\"brush: plain; title: make -p; notranslate\" title=\"make -p\">\r\n# default\r\nSUFFIXES := .out .a .ln .o .c .cc .C .cpp .p .f .F .m .r .y .l .ym .yl .s .S .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo .w .ch .web .sh .elc .el\r\n\r\n&#x5B;...]\r\n\r\n%.c: %.y\r\n#  recipe to execute (built-in):\r\n\t$(YACC.y) $&lt; \r\n\t mv -f y.tab.c $@\r\n<\/pre>\n<pre class=\"brush: plain; title: add line to Makefile; notranslate\" title=\"add line to Makefile\">\r\n.SUFFIXES:\r\n<\/pre>\n<pre class=\"brush: plain; title: result; notranslate\" title=\"result\">\r\n      Considering target file 'obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o'.\r\n       File 'obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o' does not exist.\r\n        Considering target file 'src\/ntpd\/ntp_parser.c'.\r\n         Looking for an implicit rule for 'src\/ntpd\/ntp_parser.c'.\r\n         Trying pattern rule with stem 'ntp_parser'.\r\n         Trying implicit prerequisite 'src\/ntpd\/ntp_parser.w'.\r\n         Trying pattern rule with stem 'ntp_parser.c'.\r\n         Found an implicit rule for 'src\/ntpd\/ntp_parser.c'.\r\n         Finished prerequisites of target file 'src\/ntpd\/ntp_parser.c'.\r\n        No need to remake target 'src\/ntpd\/ntp_parser.c'.\r\n       Finished prerequisites of target file 'obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o'.\r\n      Must remake target 'obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o'.\r\nPutting child 0x1dcaaa0 (obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o) PID 5755 on the chain.\r\nLive child 0x1dcaaa0 (obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o) PID 5755 \r\n&#x5B;CC] src\/ntpd\/ntp_parser.c\r\n<\/pre>\n<h3>Tagged Commands \/ Command Prefix<\/h3>\n<p><a href=\"http:\/\/stackoverflow.com\/questions\/3477292\/what-do-and-do-as-prefixes-to-recipe-lines-in-make\">What do @, &#8211; and + do as prefixes to recipe lines in Make?<\/a><\/p>\n<p>Command lines can have one or more of the following three prefixes:<\/p>\n<ul>\n<li>a hyphen-minus (-), specifying that errors are ignored<\/li>\n<li>an at sign (@), specifying that the command is not printed to standard output before it is executed<\/li>\n<li>a plus sign (+), the command is executed even if Make is invoked in a &#8220;do not execute&#8221; mode<\/li>\n<\/ul>\n<ul>\n<li>@ suppresses the normal &#8216;echo&#8217; of the command that is executed.<\/li>\n<li>&#8211; means ignore the exit status of the command that is executed (normally, a non-zero exit status would stop that part of the build).<\/li>\n<li>+ means &#8216;execute this command under make -n&#8217; (when commands are not normally executed).<\/li>\n<\/ul>\n<h3>Substitution<\/h3>\n<p><a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/make.html#Substitution-Refs\">Substitution References<\/a> <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nSOURCE = main.c test.c bla.cpp blu.cpp bli.c\r\nOBJECT = $(SOURCES:%.c=%.o)\r\n\r\nResult:\r\nmain.o test.o bla.cpp blu.cpp bli.o\r\n<\/pre>\n<h3>Functions<\/h3>\n<p><a href=\"https:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Text-Functions.html\">Functions for String Substitution and Analysis<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nSOURCE     = main.c test.c bla.cpp blu.cpp bli.c\r\nC_OBJECT   = $(filter %.c,$(SOURCE): %.c=%.o)\r\nCXX_OBJECT = $(filter %.cpp,$(SOURCE): %.cpp=%.o)\r\n\r\nResult:\r\nmain.o test.o bla.cpp blu.cpp bli.o\r\n<\/pre>\n<h3>Setting Variables = := ?= !=<\/h3>\n<p><a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Setting.html#Setting\">Setting Variables<\/a><br \/>\n<a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Flavors.html#Flavors\">The Two Flavors of Variables<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/1435861\/computing-makefile-variable-on-assignment\">Computing Makefile variable on assignment<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n = Recursively expanded variable\r\n:= Simply expanded variables\r\n?= Only set variable if it\u2019s not already set\r\n!= execute program and set variable to its output\r\n<\/pre>\n<pre class=\"brush: plain; title: ?=; notranslate\" title=\"?=\">\r\nFOO ?= bar\r\n\r\nequal to\r\n\r\nifeq ($(origin FOO), undefined)\r\nFOO = bar\r\nendif\r\n<\/pre>\n<pre class=\"brush: plain; title: !=; notranslate\" title=\"!=\">\r\nhash != printf '&#92;&#48;43'\r\nfile_list != find . -name '*.c'\r\n\r\nequal to\r\n\r\nhash := $(shell printf '&#92;&#48;43')\r\nvar := $(shell find . -name &quot;*.c&quot;)\r\n<\/pre>\n<h3>Double-Colon Rules<\/h3>\n<p><a href=\"https:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Double_002dColon.html\">Double-Colon Rules<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/7891097\/what-are-double-colon-rules-in-a-makefile-for\">What are double-colon rules in a Makefile for?<\/a><br \/>\n<a href=\"http:\/\/owen.sj.ca.us\/~rk\/howto\/slides\/make\/slides\/makecolon.html\">Makefiles &#8211; Make and the Double colon<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nibxxx.a : sub1.o sub2.o\r\n    ar rv libxxx.a sub1.o\r\n    ar rv libxxx.a sub2.o\r\n\r\n====\r\n\r\nlibxxx.a :: sub1.o\r\n    ar rv libxxx.a sub1.o\r\n\r\nlibxxx.a :: sub2.o\r\n    ar rv libxxx.a sub2.o\r\n<\/pre>\n<h3>Empty Recipes (Semicolon)<\/h3>\n<p><a href=\"https:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Empty-Recipes.html#Empty-Recipes\">Using Empty Recipes<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/11533209\/what-does-it-mean-when-a-semicolon-occurs-in-a-makefile-targets-prerequisites\">What does it mean when a semicolon occurs in a makefile target&#8217;s prerequisites?<\/a><\/p>\n<p><a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Match_002dAnything-Rules.html#Match_002dAnything-Rules\">Match-Anything Pattern Rules<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ntarget: ;\r\n\r\n% :: ;\r\n<\/pre>\n<h3>Order-Only-Prerequisites<\/h3>\n<p><a href=\"https:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Prerequisite-Types.html\">Types of Prerequisites<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/12299369\/what-does-and-the-pipe-symbol-in-makefile-stand-for\">What does $$@ and the pipe symbol in Makefile stand for?<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/9007039\/makefile-execute-phonytargets-of-a-file-only-if-file-does-not-exists\">Makefile execute phonytargets of a file only if file does not exists<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ntargets: normal-prerequisites | order-only-prerequisites\r\n    recipe\r\n<\/pre>\n<h3>Pattern Rules<\/h3>\n<blockquote><p>You define an implicit rule by writing a pattern rule. A pattern rule looks like an ordinary rule, except that its target contains the character \u2018%\u2019 (exactly one of them). The target is considered a pattern for matching file names; the \u2018%\u2019 can match any nonempty substring, while other characters match only themselves. The prerequisites likewise use \u2018%\u2019 to show how their names relate to the target name. <\/p><\/blockquote>\n<p><a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Pattern-Rules.html#Pattern-Rules\">Defining and Redefining Pattern Rules<\/a><br \/>\n<a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Pattern-Examples.html#Pattern-Examples\">Pattern Rule Examples<\/a><\/p>\n<pre class=\"brush: plain; title: predefined in make; notranslate\" title=\"predefined in make\">\r\n%.o : %.c\r\n    $(CC) -c $(CFLAGS) $(CPPFLAGS) $&lt; -o $@\r\n<\/pre>\n<h3>Automatic Variables<\/h3>\n<p><a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Automatic-Variables.html#Automatic-Variables\">Automatic Variables<\/a><\/p>\n<table>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$@<\/pre>\n<\/td>\n<td>The file name of the target of the rule.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$%<\/pre>\n<\/td>\n<td>The target member name, when the target is an archive member.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$<<\/pre>\n<\/td>\n<td>The name of the first prerequisite.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$?<\/pre>\n<\/td>\n<td>The names of all the prerequisites that are newer than the target, with spaces between them.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$^<\/pre>\n<\/td>\n<td>The names of all the prerequisites, with spaces between them.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$+<\/pre>\n<\/td>\n<td>This is like \u2018$^\u2019, but prerequisites listed more than once are duplicated in the order they were listed in the makefile.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$|<\/pre>\n<\/td>\n<td>The names of all the order-only prerequisites, with spaces between them.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">$*<\/pre>\n<\/td>\n<td>The stem with which an implicit rule matches.<\/td>\n<\/tr>\n<\/table>\n<h3>Built-in Target Names<\/h3>\n<p><a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Special-Targets.html#Special-Targets\">Special Built-in Target Names<\/a><\/p>\n<table>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.PHONY<\/pre>\n<\/td>\n<td>The prerequisites of the special target .PHONY are considered to be phony targets. When it is time to consider such a target, make will run its recipe unconditionally, regardless of whether a file with that name exists or what its last-modification time is.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.SUFFIXES<\/pre>\n<\/td>\n<td>The prerequisites of the special target .SUFFIXES are the list of suffixes to be used in checking for suffix rules.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.DEFAULT<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.PRECIOUS<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.INTERMEDIATE<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.SECONDARY<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.SECONDEXPANSION<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.DELETE_ON_ERROR<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.IGNORE<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.LOW_RESOLUTION_TIME<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.SILENT<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.EXPORT_ALL_VARIABLES<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.NOTPARALLEL<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.ONESHELL<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<tr>\n<td>\n<pre style=\"margin: 0px; padding: 2px\">.POSIX<\/pre>\n<\/td>\n<td>.<\/td>\n<\/tr>\n<\/table>\n<h3>Canned Recipes \/ Functions\/ Templates<\/h3>\n<p><a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Canned-Recipes.html#Canned-Recipes\">Defining Canned Recipes<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/21254862\/makefiles-can-canned-recipes-have-parameters\">Makefiles: can 'canned recipes' have parameters?<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndefine run-yacc =\r\nyacc $(firstword $^)\r\nmv y.tab.c $@\r\nendef\r\n\r\ndefine DIRECTORY_template\r\n$(1):\r\n\t@echo &quot;&#x5B;MKDIR] $$@&quot;\r\n\t@mkdir -p $(1)\r\n\r\nendef\r\n\r\n$(eval $(call DIRECTORY_template,testdir))\r\n\r\nfoo.c : foo.y testdir\r\n    $(run-yacc)\r\n\r\n<\/pre>\n<h3>Makefile as a functional language program<\/h3>\n<p>The following article describes a real practical application: avoiding the explosion of makefile rules in a project that executes many test cases on many platforms. Each test target is built from its own set of source code files. Each (Scheme) platform has its own particular way of assembling source code files into a project; some source code files might need be omitted from the build for a particular platform. Because GNU make turns out to be a functional programming system, we can reduce the number of rules from <number-of-targets> * <number-of-platforms> to just <number-of-targets>+ <number-of-platforms>.<\/p>\n<p>The language of GNU make is indeed functional, complete with combinators (map and filter), applications and anonymous abstractions. GNU make does support lambda-abstractions. The following is one example from the Makefile in question: it is a rule to build a test target for the SCM Scheme system. The list of source code files and the name of the target\/root-test-file are passed as two arguments of the rule:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n make-scmi= scm -b -l $(LIBDIR)\/myenv-scm.scm \\\r\n            $(foreach file,$(1),-l $(LIBDIR)\/$(file)) \\\r\n            -l $(2).scm\r\n<\/pre>\n<p>The rule returns an OS command to interpret or compile the target. The rule can be invoked as <\/p>\n<pre style=\"margin: 0px; padding: 2px; display: inline\">$(call make-scmi,util.scm catch-error.scm,vmyenv)<\/pre>\n<p>. As in TeX, the arguments of a function are numbered (it is possible to assign them meaningful symbolic names, too). Makefile's foreach corresponds to Scheme's map. The comparison with the corresponding Scheme code is striking:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n (define make-scmi\r\n    (lambda (arg1 arg2)\r\n         `(scm -b -l ,(mks LIBDIR '\/ 'myenv-scm.scm)\r\n            ,@(map (lambda (file) `(-l ,(mks LIBDIR '\/ file))) arg1)\r\n           -l ,(mks arg2 '.scm))))\r\n<\/pre>\n<h3>Timestamp on files and directories<\/h3>\n<p>Makefile re-generates some object-files, but I didn't know why:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ cat Makefile\r\n&#x5B;...]\r\nobj\/pi\/main.o: obj\/pi src\/main.f90\r\n\t@echo &quot;&#x5B;FC] src\/main.f90&quot;\r\n\t@gfortran -o $@ -c src\/main.f90\r\n\r\nobj\/pi\/pi.o: obj\/pi src\/pi.f90\r\n\t@echo &quot;&#x5B;FC] src\/pi.f90&quot;\r\n\t@gfortran -o $@ -c src\/pi.f90 \r\n&#x5B;...]\r\n\r\n$ make clean &amp;&amp; make\r\n$ make -d\r\n&#x5B;...]\r\n     Prerequisite 'obj\/pi' is newer than target 'obj\/pi\/main.o'.\r\n     Prerequisite 'src\/main.f90' is older than target 'obj\/pi\/main.o'.\r\n    Must remake target 'obj\/pi\/main.o'.\r\n&#x5B;...]\r\n<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ntarget: dependencies\/prerequisites\r\n&lt;Tab&gt; system command(s)\/recipe\r\n<\/pre>\n<blockquote><p>It imposes a dependency relationship: if any prerequisite is newer than the target, then the target is considered out-of-date and must be rebuilt.<\/p><\/blockquote>\n<p>The directory timestamp is updated, when a file in this directory is updated!!<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ stat obj\/pi --printf '%n\\nmtime: %y\\nctime: %z\\natime: %x\\ncrtime:%w\\n'\r\nobj\/pi\r\nmtime: 2016-01-08 18:48:17.841692523 +0100\r\nctime: 2016-01-08 18:48:17.841692523 +0100\r\natime: 2016-01-08 18:49:34.724417557 +0100\r\n\r\n$ touch obj\/pi\/test\r\n\r\n$ stat obj\/pi --printf '%n\\nmtime: %y\\nctime: %z\\natime: %x\\ncrtime:%w\\n'\r\nobj\/pi\r\nmtime: 2016-01-08 18:49:46.300225133 +0100\r\nctime: 2016-01-08 18:49:46.300225133 +0100\r\natime: 2016-01-08 18:49:34.724417557 +0100\r\n\r\n$ stat obj\/pi\/test --printf '%n\\nmtime: %y\\nctime: %z\\natime: %x\\ncrtime:%w\\n'\r\nobj\/pi\/test\r\nmtime: 2016-01-08 18:49:46.300225133 +0100\r\nctime: 2016-01-08 18:49:46.300225133 +0100\r\natime: 2016-01-08 18:49:46.300225133 +0100\r\n<\/pre>\n<p>I changed the directory creation on target 'all' so that the object files doesn't directly depend on the directories anymore:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndefine DIRECTORY_template\r\n\r\nDIRECTORIES += obj\/$(1)\r\n\r\nobj\/$(1):\r\n\t@echo &quot;&#x5B;MKDIR] $$@&quot;\r\n\t@mkdir -p obj\/$(1)\r\n\r\nendef\r\n\r\n&#x5B;...]\r\n\r\nDIRECTORIES =\r\n\r\nall: mkdirs $(PROGRAMS)\r\n\r\n$(foreach prog,$(PROGRAMS),$(eval $(call VARIABLE_template,$(prog))))\r\n$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))\r\n\r\nmkdirs: $(DIRECTORIES) \r\n<\/pre>\n<h3>Difference between Build Tools<\/h3>\n<p><a href=\"http:\/\/hyperpolyglot.org\/build\">Build Tools: Make, Rake, Ant, MSBuild<\/a><br \/>\n<a href=\"http:\/\/rake.rubyforge.org\/\">RAKE \u2013 Ruby Make<\/a><\/p>\n<h3>Multi-Architecture Builds<\/h3>\n<p><a href=\"http:\/\/make.mad-scientist.net\/papers\/multi-architecture-builds\/\">Multi-Architecture Builds<\/a><br \/>\n<a href=\"http:\/\/make.mad-scientist.net\/papers\/how-not-to-use-vpath\/\">How Not to Use VPATH<\/a><br \/>\n<a href=\"http:\/\/make.mad-scientist.net\/papers\/rules-of-makefiles\/\">Rules of Makefiles<\/a><\/p>\n<h3>BSD make<\/h3>\n<p><a href=\"http:\/\/www.netbsd.org\/docs\/pkgsrc\/makefile.html\">Programming in Makefiles for NetBSD<\/a><\/p>\n<h3>GNU make<\/h3>\n<h3>GNU make with Java<\/h3>\n<p><a href=\"http:\/\/jwrr.com\/content\/Gnu-Makefile-Examples\/\">Java: Gnu Make Makefile Examples<\/a><\/p>\n<h3>make++<\/h3>\n<p><a href=\"http:\/\/makepp.sourceforge.net\/\">Makepp<\/a><br \/>\n<a href=\"http:\/\/makepp.sourceforge.net\/2.0\/makepp_rules.html#foreach_rules\">Makepp Rules<\/a><\/p>\n<p>Kleines Beispiel<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nSOURCES = main.c \\\r\n          draw.c \\\r\n          camera.c \\\r\n          utils.c \\\r\n          createTexture.c \\\r\n          text.c\r\n\r\nCFLAGS = `sdl-config --cflags` -D_REENTRANT -Wall\r\nLDFLAGS = `sdl-config --libs` -lopengl32 -lglu32 -lSDL_ttf\r\n\r\nOBJECTS = $(SOURCES:%.c=%.o)\r\n\r\n.PHONY: all clean\r\n\r\nall : Aufgabe4\r\n\r\nAufgabe4 : $(OBJECTS)\r\ng++ -o $@ $(OBJECTS) $(LDFLAGS)\r\n\r\n%.o : %.c\r\ng++ $(CFLAGS) -c $&lt;\r\n\r\nclean :\r\nrm *.o\r\n\r\nbuild : clean all\r\n\r\nPHONY: \r\n<\/pre>\n<p>Links dazu:<br \/>\n<a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/make.html#Automatic-Variables\">Automatic Variables<\/a> f\u00fcr $< oder $@\n<a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/make.html#Pattern-Match\">How Patterns Match<\/a> f\u00fcr %.o oder %.c<br \/>\n<a href=\"http:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Phony-Targets.html\">Phony Targets<\/a> f\u00fcr .PHONY: clean<br \/>\n<a href=\"http:\/\/skramm.blogspot.ch\/2012\/04\/gnu-make-and-foreach-function.html\">GNU Make and the foreach() function<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/19412960\/display-the-results-of-foreach-eval-call-expansion\">Display the results of foreach \/ eval \/ call expansion<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/9691508\/how-can-i-use-macros-to-generate-multiple-makefile-targets-rules-inside-foreach\">How can I use macros to generate multiple Makefile targets\/rules inside foreach?<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/664601\/in-gnu-make-how-do-i-convert-a-variable-to-lower-case\">In GNU Make, how do I convert a variable to lower case?<\/a><br \/>\n<a href=\"https:\/\/www.gnu.org\/software\/make\/manual\/html_node\/Conditional-Functions.html\">8.4 Functions for Conditionals<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/9008649\/gnu-make-conditional-function-if-inside-a-user-defined-function-always-ev\">GNU make conditional function $(if \u2026) inside a user-defined function always evaluates to true<\/a><br \/>\n<a href=\"https:\/\/lists.gnu.org\/archive\/html\/bug-make\/2003-09\/msg00029.html\">GNU make: Please give an example for the 'if' function<\/a><\/p>\n<pre class=\"brush: plain; title: Debugging Makefiles; notranslate\" title=\"Debugging Makefiles\">\r\nstatt:\r\n$(foreach prog, $(PROGRAMS), $(eval $(call VARIABLE_template,$(prog))))\r\n\r\nnun:\r\n$(foreach prog, $(PROGRAMS), $(info $(call VARIABLE_template,$(prog))))\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>What\u2019s Wrong With GNU make? HOWTO: Intro to GNU make variables target: normal-prerequisites | order-only-prerequisites recipe Debugging $ make -d ==&gt; print out the parser results $ make -p ==&gt; execute make but prints the database (buildins + Makefile) at the end .SUFFIXES Considering target file &#8216;obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o&#8217;. File &#8216;obj\/osa541x_sim\/advaNtpd\/ntpd\/ntp_parser.o&#8217; does not exist. Considering target file [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[],"class_list":["post-476","post","type-post","status-publish","format-standard","hentry","category-programming-languages"],"_links":{"self":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=476"}],"version-history":[{"count":43,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/476\/revisions"}],"predecessor-version":[{"id":5727,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/476\/revisions\/5727"}],"wp:attachment":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}