initial revision
[ucgine.git] / mk / ucgine-tools.mk
1 #
2 # Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
6 #
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.
15 #
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.
26 #
27
28 empty:=
29 space:= $(empty) $(empty)
30 indent:= $(space)$(space)
31
32 # define a newline char, useful for debugging with $(info)
33 define newline
34
35
36 endef
37
38 # $(prefix shell commands with $(Q) to silent them, except if V=1
39 Q=@
40 ifeq ("$(V)-$(origin V)", "1-command line")
41 Q=
42 endif
43
44 # set variable $1 to $2 if the variable has an implicit value or
45 # is not defined
46 #  $1 variable name
47 #  $2 new variable content
48 set_default = $(if \
49         $(call not,$(or \
50                 $(compare $(origin $(1)),default), \
51                 $(compare $(origin $(1)),undefined) \
52         )),\
53         $(eval $(1) = $(2)) \
54 )
55
56 # display a list
57 #  $1 title
58 #  $2 list
59 disp_list = $(info $(1)$(newline)\
60         $(addsuffix $(newline),$(addprefix $(space),$(2))))
61
62 # add a dot in front of the file name
63 #  $1 list of paths
64 #  return: full paths with files prefixed by a dot
65 dotfile = $(strip $(foreach f,$(1),\
66         $(join $(dir $f),.$(notdir $f))))
67
68 # convert source/obj files into dot-dep filename
69 #  $1 list of paths
70 #  return: full paths with files prefixed by a dot and suffixed with .d
71 depfile = $(strip $(call dotfile,$(addsuffix .d,$(1))))
72
73 # convert source/obj files into dot-dep filename
74 #  $1 list of paths
75 #  return: full paths with files prefixed by a dot and suffixed with .d.tmp
76 file2tmpdep = $(strip $(call dotfile,$(addsuffix .d.tmp,$(1))))
77
78 # convert source/obj files into dot-cmd filename
79 #  $1 list of paths
80 #  return: full paths with files prefixed by a dot and suffixed with .cmd
81 cmdfile = $(strip $(call dotfile,$(addsuffix .cmd,$(1))))
82
83 # add a \ before each quote
84 protect_quote = $(subst ','\'',$(1))
85 #'# editor syntax highlight fix
86
87 # return an non-empty string if $1 is empty, and vice versa
88 #  $1 a string
89 not = $(if $1,,true)
90
91 # return 1 if parameter is a non-empty string, else 0
92 boolean = $(if $1,1,0)
93
94 # return an empty string if string are equal
95 compare = $(strip $(subst $(1),,$(2)) $(subst $(2),,$(1)))
96
97 # return a non-empty string if a file does not exist
98 #  $1: file
99 file_missing = $(call compare,$(wildcard $1),$1)
100
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)))
105
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))
109
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)))
115
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)))
119
120 # display why a file should be re-built
121 #  $1: source files
122 #  $2: dst file
123 #  $3: build command
124 #  $4: all prerequisites newer than target ($?)
125 ifeq ($(D),1)
126 display_deps = \
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)))"
133 else
134 display_deps=
135 endif
136
137 # return an empty string if a file should be rebuilt
138 #  $1: dst file
139 #  $2: build command
140 #  $3: all prerequisites newer than target ($?)
141 check_deps = \
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)))
147
148 # create a depfile (.d) with no additional deps
149 #  $1: object file (.o)
150 create_empty_depfile = echo "dep-$(1) =" > $(call depfile,$(1))
151
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))
156
157 # remove the FORCE target from the list of all prerequisites $+
158 #  no arguments, use $+
159 prereq = $(filter-out FORCE,$(+))