node_any: check attribute presence
[protos/libecoli.git] / mk / ecoli-tools.mk
1 # SPDX-License-Identifier: BSD-3-Clause
2 # Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
3
4 empty:=
5 space:= $(empty) $(empty)
6 indent:= $(space)$(space)
7
8 # define a newline char, useful for debugging with $(info)
9 define newline
10
11
12 endef
13
14 # $(prefix shell commands with $(Q) to silent them, except if V=1
15 Q=@
16 ifeq ("$(V)-$(origin V)", "1-command line")
17 Q=
18 endif
19
20 # set variable $1 to $2 if the variable has an implicit value or
21 # is not defined
22 #  $1 variable name
23 #  $2 new variable content
24 set_default = $(if \
25         $(call not,$(or \
26                 $(compare $(origin $(1)),default), \
27                 $(compare $(origin $(1)),undefined) \
28         )),\
29         $(eval $(1) = $(2)) \
30 )
31
32 # display a list
33 #  $1 title
34 #  $2 list
35 disp_list = $(info $(1)$(newline)\
36         $(addsuffix $(newline),$(addprefix $(space),$(2))))
37
38 # add a dot in front of the file name
39 #  $1 list of paths
40 #  return: full paths with files prefixed by a dot
41 dotfile = $(strip $(foreach f,$(1),\
42         $(join $(dir $f),.$(notdir $f))))
43
44 # convert source/obj files into dot-dep filename
45 #  $1 list of paths
46 #  return: full paths with files prefixed by a dot and suffixed with .d
47 depfile = $(strip $(call dotfile,$(addsuffix .d,$(1))))
48
49 # convert source/obj files into dot-dep filename
50 #  $1 list of paths
51 #  return: full paths with files prefixed by a dot and suffixed with .d.tmp
52 file2tmpdep = $(strip $(call dotfile,$(addsuffix .d.tmp,$(1))))
53
54 # convert source/obj files into dot-cmd filename
55 #  $1 list of paths
56 #  return: full paths with files prefixed by a dot and suffixed with .cmd
57 cmdfile = $(strip $(call dotfile,$(addsuffix .cmd,$(1))))
58
59 # add a \ before each quote
60 protect_quote = $(subst ','\'',$(1))
61 #'# editor syntax highlight fix
62
63 # return an non-empty string if $1 is empty, and vice versa
64 #  $1 a string
65 not = $(if $1,,true)
66
67 # return 1 if parameter is a non-empty string, else 0
68 boolean = $(if $1,1,0)
69
70 # return an empty string if string are equal
71 compare = $(strip $(subst $(1),,$(2)) $(subst $(2),,$(1)))
72
73 # return a non-empty string if a file does not exist
74 #  $1: file
75 file_missing = $(call compare,$(wildcard $1),$1)
76
77 # return a non-empty string if cmdline changed
78 #  $1: file to be built
79 #  $2: the command to build it
80 cmdline_changed = $(call compare,$(strip $(cmd-$(1))),$(strip $(2)))
81
82 # return an non-empty string if the .d file does not exist
83 #  $1: the dep file (.d)
84 depfile_missing = $(call compare,$(wildcard $(1)),$(1))
85
86 # return a non-empty string if, according to dep-xyz variable, a file
87 # needed to build $1 does not exist. In this case we need to rebuild
88 # the file and the .d file.
89 #  $1: file to be built
90 dep-missing = $(call compare,$(wildcard $(dep-$(1))),$(dep-$(1)))
91
92 # return an empty string if no prereq is newer than target
93 #  $1: list of prerequisites newer than target ($?)
94 dep-newer = $(strip $(filter-out FORCE,$(1)))
95
96 # display why a file should be re-built
97 #  $1: source files
98 #  $2: dst file
99 #  $3: build command
100 #  $4: all prerequisites newer than target ($?)
101 ifeq ($(D),1)
102 display_deps = \
103         echo -n "$1 -> $2 " ; \
104         echo -n "file_missing=$(call boolean,$(call file_missing,$(2))) " ; \
105         echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(2),$(3))) " ; \
106         echo -n "depfile_missing=$(call boolean,$(call depfile_missing,$(call depfile,$(2)))) " ; \
107         echo -n "dep-missing=$(call boolean,$(call dep-missing,$(2))) " ; \
108         echo "dep-newer=$(call boolean,$(call dep-newer,$(4)))"
109 else
110 display_deps=
111 endif
112
113 # return an empty string if a file should be rebuilt
114 #  $1: dst file
115 #  $2: build command
116 #  $3: all prerequisites newer than target ($?)
117 check_deps = \
118         $(or $(call file_missing,$(1)),\
119         $(call cmdline_changed,$(1),$(2)),\
120         $(call depfile_missing,$(call depfile,$(1))),\
121         $(call dep-missing,$(1)),\
122         $(call dep-newer,$(3)))
123
124 # create a depfile (.d) with no additional deps
125 #  $1: object file (.o)
126 create_empty_depfile = echo "dep-$(1) =" > $(call depfile,$(1))
127
128 # save a command in a file
129 #  $1: command to build the file
130 #  $2: name of the file
131 save_cmd = echo "cmd-$(2) = $(call protect_quote,$(1))" > $(call cmdfile,$(2))
132
133 # remove the FORCE target from the list of all prerequisites $+
134 #  no arguments, use $+
135 prereq = $(filter-out FORCE,$(+))