xref: /kvmtool/config/utilities.mak (revision 93dd1288081497146b3a7ad98e40c5b2635c3148)
1328a03bcSCyrill Gorcunov# This allows us to work with the newline character:
2328a03bcSCyrill Gorcunovdefine newline
3328a03bcSCyrill Gorcunov
4328a03bcSCyrill Gorcunov
5328a03bcSCyrill Gorcunovendef
6328a03bcSCyrill Gorcunovnewline := $(newline)
7328a03bcSCyrill Gorcunov
8328a03bcSCyrill Gorcunov# nl-escape
9328a03bcSCyrill Gorcunov#
10328a03bcSCyrill Gorcunov# Usage: escape = $(call nl-escape[,escape])
11328a03bcSCyrill Gorcunov#
12328a03bcSCyrill Gorcunov# This is used as the common way to specify
13328a03bcSCyrill Gorcunov# what should replace a newline when escaping
14328a03bcSCyrill Gorcunov# newlines; the default is a bizarre string.
15328a03bcSCyrill Gorcunov#
16328a03bcSCyrill Gorcunovnl-escape = $(or $(1),m822df3020w6a44id34bt574ctac44eb9f4n)
17328a03bcSCyrill Gorcunov
18328a03bcSCyrill Gorcunov# escape-nl
19328a03bcSCyrill Gorcunov#
20328a03bcSCyrill Gorcunov# Usage: escaped-text = $(call escape-nl,text[,escape])
21328a03bcSCyrill Gorcunov#
22328a03bcSCyrill Gorcunov# GNU make's $(shell ...) function converts to a
23328a03bcSCyrill Gorcunov# single space each newline character in the output
24328a03bcSCyrill Gorcunov# produced during the expansion; this may not be
25328a03bcSCyrill Gorcunov# desirable.
26328a03bcSCyrill Gorcunov#
27328a03bcSCyrill Gorcunov# The only solution is to change each newline into
28328a03bcSCyrill Gorcunov# something that won't be converted, so that the
29328a03bcSCyrill Gorcunov# information can be recovered later with
30328a03bcSCyrill Gorcunov# $(call unescape-nl...)
31328a03bcSCyrill Gorcunov#
32328a03bcSCyrill Gorcunovescape-nl = $(subst $(newline),$(call nl-escape,$(2)),$(1))
33328a03bcSCyrill Gorcunov
34328a03bcSCyrill Gorcunov# unescape-nl
35328a03bcSCyrill Gorcunov#
36328a03bcSCyrill Gorcunov# Usage: text = $(call unescape-nl,escaped-text[,escape])
37328a03bcSCyrill Gorcunov#
38328a03bcSCyrill Gorcunov# See escape-nl.
39328a03bcSCyrill Gorcunov#
40328a03bcSCyrill Gorcunovunescape-nl = $(subst $(call nl-escape,$(2)),$(newline),$(1))
41328a03bcSCyrill Gorcunov
42328a03bcSCyrill Gorcunov# shell-escape-nl
43328a03bcSCyrill Gorcunov#
44328a03bcSCyrill Gorcunov# Usage: $(shell some-command | $(call shell-escape-nl[,escape]))
45328a03bcSCyrill Gorcunov#
46328a03bcSCyrill Gorcunov# Use this to escape newlines from within a shell call;
47328a03bcSCyrill Gorcunov# the default escape is a bizarre string.
48328a03bcSCyrill Gorcunov#
49328a03bcSCyrill Gorcunov# NOTE: The escape is used directly as a string constant
50328a03bcSCyrill Gorcunov#       in an `awk' program that is delimited by shell
51328a03bcSCyrill Gorcunov#       single-quotes, so be wary of the characters
52328a03bcSCyrill Gorcunov#       that are chosen.
53328a03bcSCyrill Gorcunov#
54328a03bcSCyrill Gorcunovdefine shell-escape-nl
55328a03bcSCyrill Gorcunovawk 'NR==1 {t=$$0} NR>1 {t=t "$(nl-escape)" $$0} END {printf t}'
56328a03bcSCyrill Gorcunovendef
57328a03bcSCyrill Gorcunov
58328a03bcSCyrill Gorcunov# shell-unescape-nl
59328a03bcSCyrill Gorcunov#
60328a03bcSCyrill Gorcunov# Usage: $(shell some-command | $(call shell-unescape-nl[,escape]))
61328a03bcSCyrill Gorcunov#
62328a03bcSCyrill Gorcunov# Use this to unescape newlines from within a shell call;
63328a03bcSCyrill Gorcunov# the default escape is a bizarre string.
64328a03bcSCyrill Gorcunov#
65328a03bcSCyrill Gorcunov# NOTE: The escape is used directly as an extended regular
66328a03bcSCyrill Gorcunov#       expression constant in an `awk' program that is
67328a03bcSCyrill Gorcunov#       delimited by shell single-quotes, so be wary
68328a03bcSCyrill Gorcunov#       of the characters that are chosen.
69328a03bcSCyrill Gorcunov#
70328a03bcSCyrill Gorcunov# (The bash shell has a bug where `{gsub(...),...}' is
71328a03bcSCyrill Gorcunov#  misinterpreted as a brace expansion; this can be
72328a03bcSCyrill Gorcunov#  overcome by putting a space between `{' and `gsub').
73328a03bcSCyrill Gorcunov#
74328a03bcSCyrill Gorcunovdefine shell-unescape-nl
75328a03bcSCyrill Gorcunovawk 'NR==1 {t=$$0} NR>1 {t=t "\n" $$0} END { gsub(/$(nl-escape)/,"\n",t); printf t }'
76328a03bcSCyrill Gorcunovendef
77328a03bcSCyrill Gorcunov
78328a03bcSCyrill Gorcunov# escape-for-shell-sq
79328a03bcSCyrill Gorcunov#
80328a03bcSCyrill Gorcunov# Usage: embeddable-text = $(call escape-for-shell-sq,text)
81328a03bcSCyrill Gorcunov#
82328a03bcSCyrill Gorcunov# This function produces text that is suitable for
83328a03bcSCyrill Gorcunov# embedding in a shell string that is delimited by
84328a03bcSCyrill Gorcunov# single-quotes.
85328a03bcSCyrill Gorcunov#
86328a03bcSCyrill Gorcunovescape-for-shell-sq =  $(subst ','\'',$(1))
87328a03bcSCyrill Gorcunov
88328a03bcSCyrill Gorcunov# shell-sq
89328a03bcSCyrill Gorcunov#
90328a03bcSCyrill Gorcunov# Usage: single-quoted-and-escaped-text = $(call shell-sq,text)
91328a03bcSCyrill Gorcunov#
92328a03bcSCyrill Gorcunovshell-sq = '$(escape-for-shell-sq)'
93328a03bcSCyrill Gorcunov
94328a03bcSCyrill Gorcunov# shell-wordify
95328a03bcSCyrill Gorcunov#
96328a03bcSCyrill Gorcunov# Usage: wordified-text = $(call shell-wordify,text)
97328a03bcSCyrill Gorcunov#
98328a03bcSCyrill Gorcunov# For instance:
99328a03bcSCyrill Gorcunov#
100328a03bcSCyrill Gorcunov#  |define text
101328a03bcSCyrill Gorcunov#  |hello
102328a03bcSCyrill Gorcunov#  |world
103328a03bcSCyrill Gorcunov#  |endef
104328a03bcSCyrill Gorcunov#  |
105328a03bcSCyrill Gorcunov#  |target:
106328a03bcSCyrill Gorcunov#  |	echo $(call shell-wordify,$(text))
107328a03bcSCyrill Gorcunov#
108328a03bcSCyrill Gorcunov# At least GNU make gets confused by expanding a newline
109328a03bcSCyrill Gorcunov# within the context of a command line of a makefile rule
110328a03bcSCyrill Gorcunov# (this is in constrast to a `$(shell ...)' function call,
111328a03bcSCyrill Gorcunov# which can handle it just fine).
112328a03bcSCyrill Gorcunov#
113328a03bcSCyrill Gorcunov# This function avoids the problem by producing a string
114328a03bcSCyrill Gorcunov# that works as a shell word, regardless of whether or
115328a03bcSCyrill Gorcunov# not it contains a newline.
116328a03bcSCyrill Gorcunov#
117328a03bcSCyrill Gorcunov# If the text to be wordified contains a newline, then
118328a03bcSCyrill Gorcunov# an intrictate shell command substitution is constructed
119328a03bcSCyrill Gorcunov# to render the text as a single line; when the shell
120328a03bcSCyrill Gorcunov# processes the resulting escaped text, it transforms
121328a03bcSCyrill Gorcunov# it into the original unescaped text.
122328a03bcSCyrill Gorcunov#
123328a03bcSCyrill Gorcunov# If the text does not contain a newline, then this function
124328a03bcSCyrill Gorcunov# produces the same results as the `$(shell-sq)' function.
125328a03bcSCyrill Gorcunov#
126328a03bcSCyrill Gorcunovshell-wordify = $(if $(findstring $(newline),$(1)),$(_sw-esc-nl),$(shell-sq))
127328a03bcSCyrill Gorcunovdefine _sw-esc-nl
128328a03bcSCyrill Gorcunov"$$(echo $(call escape-nl,$(shell-sq),$(2)) | $(call shell-unescape-nl,$(2)))"
129328a03bcSCyrill Gorcunovendef
130328a03bcSCyrill Gorcunov
131328a03bcSCyrill Gorcunov# is-absolute
132328a03bcSCyrill Gorcunov#
133328a03bcSCyrill Gorcunov# Usage: bool-value = $(call is-absolute,path)
134328a03bcSCyrill Gorcunov#
135328a03bcSCyrill Gorcunovis-absolute = $(shell echo $(shell-sq) | grep ^/ -q && echo y)
136328a03bcSCyrill Gorcunov
137328a03bcSCyrill Gorcunov# lookup
138328a03bcSCyrill Gorcunov#
139328a03bcSCyrill Gorcunov# Usage: absolute-executable-path-or-empty = $(call lookup,path)
140328a03bcSCyrill Gorcunov#
141328a03bcSCyrill Gorcunov# (It's necessary to use `sh -c' because GNU make messes up by
142328a03bcSCyrill Gorcunov#  trying too hard and getting things wrong).
143328a03bcSCyrill Gorcunov#
144328a03bcSCyrill Gorcunovlookup = $(call unescape-nl,$(shell sh -c $(_l-sh)))
145328a03bcSCyrill Gorcunov_l-sh = $(call shell-sq,command -v $(shell-sq) | $(call shell-escape-nl,))
146328a03bcSCyrill Gorcunov
147328a03bcSCyrill Gorcunov# is-executable
148328a03bcSCyrill Gorcunov#
149328a03bcSCyrill Gorcunov# Usage: bool-value = $(call is-executable,path)
150328a03bcSCyrill Gorcunov#
151328a03bcSCyrill Gorcunov# (It's necessary to use `sh -c' because GNU make messes up by
152328a03bcSCyrill Gorcunov#  trying too hard and getting things wrong).
153328a03bcSCyrill Gorcunov#
154328a03bcSCyrill Gorcunovis-executable = $(call _is-executable-helper,$(shell-sq))
155328a03bcSCyrill Gorcunov_is-executable-helper = $(shell sh -c $(_is-executable-sh))
156328a03bcSCyrill Gorcunov_is-executable-sh = $(call shell-sq,test -f $(1) -a -x $(1) && echo y)
157328a03bcSCyrill Gorcunov
158328a03bcSCyrill Gorcunov# get-executable
159328a03bcSCyrill Gorcunov#
160328a03bcSCyrill Gorcunov# Usage: absolute-executable-path-or-empty = $(call get-executable,path)
161328a03bcSCyrill Gorcunov#
162328a03bcSCyrill Gorcunov# The goal is to get an absolute path for an executable;
163328a03bcSCyrill Gorcunov# the `command -v' is defined by POSIX, but it's not
164328a03bcSCyrill Gorcunov# necessarily very portable, so it's only used if
165328a03bcSCyrill Gorcunov# relative path resolution is requested, as determined
166328a03bcSCyrill Gorcunov# by the presence of a leading `/'.
167328a03bcSCyrill Gorcunov#
168328a03bcSCyrill Gorcunovget-executable = $(if $(1),$(if $(is-absolute),$(_ge-abspath),$(lookup)))
169328a03bcSCyrill Gorcunov_ge-abspath = $(if $(is-executable),$(1))
170328a03bcSCyrill Gorcunov
171328a03bcSCyrill Gorcunov# get-supplied-or-default-executable
172328a03bcSCyrill Gorcunov#
173328a03bcSCyrill Gorcunov# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
174328a03bcSCyrill Gorcunov#
175328a03bcSCyrill Gorcunovdefine get-executable-or-default
176328a03bcSCyrill Gorcunov$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
177328a03bcSCyrill Gorcunovendef
178328a03bcSCyrill Gorcunov_ge_attempt = $(or $(get-executable),$(_gea_warn),$(call _gea_err,$(2)))
179328a03bcSCyrill Gorcunov_gea_warn = $(warning The path '$(1)' is not executable.)
180328a03bcSCyrill Gorcunov_gea_err  = $(if $(1),$(error Please set '$(1)' appropriately))
181328a03bcSCyrill Gorcunov
182328a03bcSCyrill Gorcunov# try-cc
183328a03bcSCyrill Gorcunov# Usage: option = $(call try-cc, source-to-build, cc-options)
184328a03bcSCyrill Gorcunovtry-cc = $(shell sh -c						  \
185328a03bcSCyrill Gorcunov	'TMP="$(OUTPUT)$(TMPOUT).$$$$";				  \
186328a03bcSCyrill Gorcunov	 echo "$(1)" |						  \
1877e66b121SAndre Przywara	 $(CC) -x c -c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
188328a03bcSCyrill Gorcunov	 rm -f "$$TMP"')
1892c82d39aSCyrill Gorcunov
1902c82d39aSCyrill Gorcunov# try-build
1912c82d39aSCyrill Gorcunov# Usage: option = $(call try-build, source-to-build, cc-options, link-options)
1922c82d39aSCyrill Gorcunovtry-build = $(shell sh -c							\
1932c82d39aSCyrill Gorcunov	'TMP="$(OUTPUT)$(TMPOUT).$$$$";						\
1942c82d39aSCyrill Gorcunov	echo "$(1)" |								\
1952c82d39aSCyrill Gorcunov	$(CC) -x c - $(2) $(3) -o "$$TMP" > /dev/null 2>&1 && echo y;		\
1962c82d39aSCyrill Gorcunov	rm -f "$$TMP"')
197*93dd1288SMarc Zyngier
198*93dd1288SMarc Zyngier# binary-to-C
199*93dd1288SMarc Zyngier# create a C source file describing the binary input file as an array
200*93dd1288SMarc Zyngier# Usage: $(call binary-to-C,binary-file,C-symbol-name,C-output-file)
201*93dd1288SMarc Zyngierbinary-to-C = stat -c "unsigned long $(2)_size = %s;" $1 > $3;		\
202*93dd1288SMarc Zyngier	echo "unsigned char $(2)[] = {" >> $3;				\
203*93dd1288SMarc Zyngier	od -v -tx1 -An -w12 $1 | sed -e "s/ \(..\)/0x\1, /g" >> $3;	\
204*93dd1288SMarc Zyngier	echo "};" >> $3
205