2 # Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution.
12 # * Neither the name of the University of California, Berkeley nor the
13 # names of its contributors may be used to endorse or promote products
14 # derived from this software without specific prior written permission.
16 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 space:= $(empty) $(empty)
30 indent:= $(space)$(space)
32 # define a newline char, useful for debugging with $(info)
38 # $(prefix shell commands with $(Q) to silent them, except if V=1
40 ifeq ("$(V)-$(origin V)", "1-command line")
44 # set variable $1 to $2 if the variable has an implicit value or
47 # $2 new variable content
50 $(compare $(origin $(1)),default), \
51 $(compare $(origin $(1)),undefined) \
59 disp_list = $(info $(1)$(newline)\
60 $(addsuffix $(newline),$(addprefix $(space),$(2))))
62 # add a dot in front of the file name
64 # return: full paths with files prefixed by a dot
65 dotfile = $(strip $(foreach f,$(1),\
66 $(join $(dir $f),.$(notdir $f))))
68 # convert source/obj files into dot-dep filename
70 # return: full paths with files prefixed by a dot and suffixed with .d
71 depfile = $(strip $(call dotfile,$(addsuffix .d,$(1))))
73 # convert source/obj files into dot-dep filename
75 # return: full paths with files prefixed by a dot and suffixed with .d.tmp
76 file2tmpdep = $(strip $(call dotfile,$(addsuffix .d.tmp,$(1))))
78 # convert source/obj files into dot-cmd filename
80 # return: full paths with files prefixed by a dot and suffixed with .cmd
81 cmdfile = $(strip $(call dotfile,$(addsuffix .cmd,$(1))))
83 # add a \ before each quote
84 protect_quote = $(subst ','\'',$(1))
85 #'# editor syntax highlight fix
87 # return an non-empty string if $1 is empty, and vice versa
91 # return 1 if parameter is a non-empty string, else 0
92 boolean = $(if $1,1,0)
94 # return an empty string if string are equal
95 compare = $(strip $(subst $(1),,$(2)) $(subst $(2),,$(1)))
97 # return a non-empty string if a file does not exist
99 file_missing = $(call compare,$(wildcard $1),$1)
101 # return a non-empty string if cmdline changed
102 # $1: file to be built
103 # $2: the command to build it
104 cmdline_changed = $(call compare,$(strip $(cmd-$(1))),$(strip $(2)))
106 # return an non-empty string if the .d file does not exist
107 # $1: the dep file (.d)
108 depfile_missing = $(call compare,$(wildcard $(1)),$(1))
110 # return a non-empty string if, according to dep-xyz variable, a file
111 # needed to build $1 does not exist. In this case we need to rebuild
112 # the file and the .d file.
113 # $1: file to be built
114 dep-missing = $(call compare,$(wildcard $(dep-$(1))),$(dep-$(1)))
116 # return an empty string if no prereq is newer than target
117 # $1: list of prerequisites newer than target ($?)
118 dep-newer = $(strip $(filter-out FORCE,$(1)))
120 # display why a file should be re-built
124 # $4: all prerequisites newer than target ($?)
127 echo -n "$1 -> $2 " ; \
128 echo -n "file_missing=$(call boolean,$(call file_missing,$(2))) " ; \
129 echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(2),$(3))) " ; \
130 echo -n "depfile_missing=$(call boolean,$(call depfile_missing,$(call depfile,$(2)))) " ; \
131 echo -n "dep-missing=$(call boolean,$(call dep-missing,$(2))) " ; \
132 echo "dep-newer=$(call boolean,$(call dep-newer,$(4)))"
137 # return an empty string if a file should be rebuilt
140 # $3: all prerequisites newer than target ($?)
142 $(or $(call file_missing,$(1)),\
143 $(call cmdline_changed,$(1),$(2)),\
144 $(call depfile_missing,$(call depfile,$(1))),\
145 $(call dep-missing,$(1)),\
146 $(call dep-newer,$(3)))
148 # create a depfile (.d) with no additional deps
149 # $1: object file (.o)
150 create_empty_depfile = echo "dep-$(1) =" > $(call depfile,$(1))
152 # save a command in a file
153 # $1: command to build the file
154 # $2: name of the file
155 save_cmd = echo "cmd-$(2) = $(call protect_quote,$(1))" > $(call cmdfile,$(2))
157 # remove the FORCE target from the list of all prerequisites $+
158 # no arguments, use $+
159 prereq = $(filter-out FORCE,$(+))