xref: /rk3399_ARM-atf/make_helpers/utilities.mk (revision 3dc69bcb88b69f516eb42cea5d6e8acf5b1c6084)
1#
2# Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6
7space :=
8space := $(space) $(space)
9comma := ,
10
11null := �
12rparen := )
13
14compat-path = $(subst $(space),$(null),$(1))
15decompat-path = $(subst $(null), ,$(1))
16
17absolute-path = $(call decompat-path,$(abspath $(call compat-path,$(1))))
18real-path = $(call decompat-path,$(realpath $(call compat-path,$(1))))
19
20file-name = $(call decompat-path,$(notdir $(call compat-path,$(1))))
21directory-name = $(call decompat-path,$(dir $(call compat-path,$(1))))
22
23escape-shell = '$(subst ','\'',$(1))'
24
25#
26# The grouped-target symbol. Grouped targets are not supported on versions of
27# GNU Make <= 4.2, which was most recently packaged with Ubuntu 20.04.
28#
29
30& := $(if $(filter grouped-target,$(.FEATURES)),&)
31
32#
33# Upper-case a string value.
34#
35# Parameters:
36#
37#   - $(1): The string to upper-case.
38#
39# Example usage:
40#
41#     $(call uppercase,HeLlO wOrLd) # "HELLO WORLD"
42#
43
44uppercase = $(shell echo $(call escape-shell,$(1)) | tr '[:lower:]' '[:upper:]')
45
46#
47# Lower-case a string value.
48#
49# Parameters:
50#
51#   - $(1): The string to lower-case.
52#
53# Example usage:
54#
55#     $(call lowercase,HeLlO wOrLd) # "hello world"
56#
57
58lowercase = $(shell echo $(call escape-shell,$(1)) | tr '[:upper:]' '[:lower:]')
59
60#
61# Determine the "truthiness" of a value.
62#
63# Parameters:
64#
65#   - $(1): The value to determine the truthiness of.
66#
67# A value is considered to be falsy if it is:
68#
69#   - empty, or
70#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
71#
72# If the value is truthy then the value is returned as-is, otherwise no value
73# is returned.
74#
75# Example usage:
76#
77#     truthy := y
78#     truthy-bool := $(call bool,$(truthy)) # "y"
79#
80#     falsy := n
81#     falsy-bool := $(call bool,$(falsy)) # <empty>
82#
83
84bool = $(filter-out 0 n no f false,$(call lowercase,$(1)))
85
86#
87# Determine the "truthiness" of a value, returning 0 or 1.
88#
89# Parameters:
90#
91#   - $(1): The value to determine the truthiness of.
92#
93# A value is considered to be falsy if it is:
94#
95#   - empty, or
96#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
97#
98# If the value is truthy then the value is returned as-is, otherwise no value
99# is returned.
100#
101# Example usage:
102#
103#     truthy := y
104#     truthy-bool := $(call bool,$(truthy)) # "1"
105#
106#     falsy := n
107#     falsy-bool := $(call bool,$(falsy)) # "0"
108#
109
110bool-01 = $(if $(call bool,$(1)),1,0)
111
112#
113# Determine whether a variable is defined or not.
114#
115# Parameters:
116#
117#   - $(1): The variable to check.
118#
119# Example usage:
120#
121#     xyz-defined := $(call defined,xyz) # <empty>
122#
123#     xyz :=
124#     xyz-defined := $(call defined,xyz) # <non-empty>
125#
126#     xyz := hello
127#     xyz-defined := $(call defined,xyz) # <non-empty>
128#
129
130defined = $(call bool,$(filter-out undefined,$(origin $(1))))
131
132#
133# Extract include directories from compiler flags and convert them to absolute
134# paths.
135#
136# Parameters:
137#
138#   - $(1): A list of C compiler flags.
139#
140# Example:
141#
142#     includes := $(call include-dirs, -nostdlib -Iinclude-dir) # /absolute/path/to/include-dir
143#
144
145include-dirs-pattern := $(call escape-shell,-I\s*("[^"]*"|'[^']*'|\S+))
146include-dirs = $(shell \
147	printf '%s' $(call escape-shell,$1) | \
148	perl -nle 'print $$1 while /'$(include-dirs-pattern)'/g' | \
149	xargs realpath \
150)
151
152#
153# Determine the path to a program.
154#
155# Parameters:
156#
157#   - $(1): The program to search for.
158#
159# Example usage:
160#
161#     path-to-gcc := $(call which,gcc) # "/usr/bin/gcc"
162#
163
164which = $(shell command -v $(call escape-shell,$(1)) 2>/dev/null)
165
166#
167# Temporarily bind variables while expanding text (scoped "with").
168#
169# Creates temporary variable bindings, expands a body of text with those
170# bindings in effect, then restores all affected variables to their previous
171# values and flavors (or undefines them if they did not exist). This provides a
172# "let"-style scope for variable assignments during text expansion.
173#
174# This function is modelled on the `let` function introduced in GNU Make 4.4:
175#
176#   https://www.gnu.org/software/make/manual/html_node/Let-Function.html
177#
178# Binding specifiers (space-separated in `$(1)`):
179#
180#   - l:name  Bind from the word list in `$(2)`. Bindings are applied
181#             left-to-right; the last `l` binding receives all remaining words
182#             (which may be empty). If there are more `l` names than words, the
183#             excess names are bound to empty values.
184#
185#   - p:name  Bind from subsequent call arguments (`$(2)`, `$(3)`, `$(4)`, ...),
186#             in left-to-right order. If `l` bindings are present, these
187#             arguments instead start from `$(3)`, following the word list.
188#
189#   -   name  Treated as `l:name`.
190#
191# Parameters:
192#
193#   - $(1): Space-separated binding specifiers.
194#   - $(2): The list value used by `l` bindings, if present.
195#   - $(2|3..N-1): Values for `p` bindings, in order (optional).
196#   - $(N): The text to expand with the temporary bindings active.
197#
198# Evaluation and restoration:
199#
200#   - All function arguments in Make are expanded at the call site. The text
201#     must therefore be escaped (write `$$` to produce a literal `$`), or
202#     supplied via `$(value ...)` to avoid premature expansion.
203#
204#   - Whitespace in `l`-style bindings is processed in terms of Make words; if
205#     you need to preserve whitespace then prefer `p` bindings.
206#
207#   - Variables are assigned as simple (`:=`) during the text expansion. After
208#     the text is expanded, each variable is restored to its previous state with
209#     its original flavor (simple or recursive), or undefined if it did not
210#     exist. Origins (e.g., command line, environment) are not preserved.
211#
212# Examples:
213#
214#   # Basic list destructuring (two names from a list):
215#   $(call with,foo bar,10 20,$$(foo) $$(bar)) # "10 20"
216#
217#   # Last list binding receives the remainder:
218#   $(call with,head tail,1 2 3 4,[$$(head)] [$$(tail)]) # "[1] [2 3 4]"
219#
220#   # Extra list names bind to empty values:
221#   $(call with,x y,9,x=<$$(x)> y=<$$(y)>) # "x=<9> y=<>"
222#
223#   # Parameter-only bindings start in `$(2)`:
224#   $(call with,p:x p:y,foo,bar,$$(x)-$$(y)) # "foo-bar"
225#
226#   # Parameter bindings start in `$(3)` when list bindings are specified:
227#   $(call with,l:lhs p:op l:rhs,10 20,+,$$(lhs) $$(op) $$(rhs)) # "10 + 20"
228#
229#   # Variables are restored after expansion, with flavor preserved:
230#
231#   x := outer-x
232#   y  = outer-y
233#
234#   $(info $(call with,x y,inner-x inner-y,$$(x) $$(y))) # "inner-x inner-y"
235#
236#   $(info $(x) ($(flavor x))) # "outer-x (simple)"
237#   $(info $(y) ($(flavor y))) # "outer-y (recursive)"
238#
239#   # Passing the text via `$(value ...)` to avoid `$$` escaping:
240#
241#   text = [$(head)] [$(tail)]
242#   $(call with,head tail,1 2 3 4,$(value text)) # "[1] [2 3 4]"
243#
244#   # Nested usage:
245#
246#   $(call with,a b,foo bar, \
247#       $$(call with,c d,baz qux,$$$$(a) $$$$(b) $$$$(c) $$$$(d)))
248#   # "foo bar baz qux"
249#
250
251with = $(with.ns.push)$(eval $(value with.core))$(with.ns.pop)
252
253with.ns = with.ns.$(with.ns.stack.head)
254
255with.ns.stack :=
256with.ns.stack.head = $(words $(with.ns.stack))
257
258with.ns.push = $(eval with.ns.stack += $(with.ns.stack.head))
259with.ns.pop = $($(with.ns).result)$(eval $(value with.ns.pop.1))
260
261define with.ns.pop.1 =
262        $(foreach variable,$(filter $(with.ns).%,$(.VARIABLES)),$\
263                $(eval undefine $(variable)))
264
265        with.ns.stack := $(wordlist 2,$(with.ns.stack.head),$(with.ns.stack))
266endef
267
268with.bind.norm = $\
269        $(if $(findstring :,$(1)),$\
270                $(or $(filter l: p:,$(firstword $(subst :,: ,$(1)))),$\
271                        $(error invalid binding specifier: $(1)))$\
272                $(or $(filter-out %:,$(word 2,$(subst :,: ,$(1)))),$\
273                        $(error invalid binding specifier: $(1))),$\
274                l:$(1))
275
276with.bind.kind = $(word 1,$(subst :, ,$(call with.bind.norm,$(1))))
277with.bind.name = $(word 2,$(subst :, ,$(call with.bind.norm,$(1))))
278
279define with.core =
280        # Parse and record binding list/kinds/names from `$(1)`
281        $(with.ns).bind.list := $(foreach b,$(1),$(call with.bind.norm,$(b)))
282        $(with.ns).bind.names := $(foreach b,$(1),$(call with.bind.name,$(b)))
283        $(with.ns).bind.kinds := $(foreach b,$(1),$(call with.bind.kind,$(b)))
284
285        # Create a 1..=(N_bindings) list of binding indices
286        $(with.ns).bind.idx :=
287        $(with.ns).bind.next = $(words 0 $($(with.ns).bind.idx))
288
289        $(foreach bind,$($(with.ns).bind.list),$\
290                $(eval $(with.ns).bind.idx += $($(with.ns).bind.next)))
291
292        # Create a 2..=(N_arguments) list pointing to the text argument
293        $(with.ns).text.idx :=
294        $(with.ns).text.next = $(words 1 2 $($(with.ns).text.idx))
295        $(with.ns).text = $($($(with.ns).text.next))
296
297        # Snapshot original flavors/values of all variables to be overwritten
298        $(foreach bind.name,$($(with.ns).bind.names),$\
299        $(foreach bind.name.ns,$(with.ns).bind.names[$(bind.name)],$\
300                $(eval $(bind.name.ns).flavor := $(flavor $(bind.name))$\
301                $(eval $(bind.name.ns).value = $(value $(bind.name))))))
302
303        # Initialize per-kind buckets (e.g., `l`, `p`)
304        $(foreach bind.kind,$(sort $($(with.ns).bind.kinds)),$\
305                $(eval $(with.ns).bind.kind[$(bind.kind)] := ))
306
307        # Distribute binding indices into kind buckets
308        $(foreach bind.i,$($(with.ns).bind.idx),$\
309        $(foreach bind.kind,$(word $(bind.i),$($(with.ns).bind.kinds)),$\
310                $(eval $(with.ns).bind.kind[$(bind.kind)] += $(bind.i))))
311
312        # Per-kind setup (e.g., to set up index vectors before binding)
313        $(foreach bind.kind,$(sort $($(with.ns).bind.kinds)),$\
314        $(foreach bind.kind.ns,$(with.ns).bind.kind[$(bind.kind)],$\
315                $(eval $(value with.core.$(bind.kind)))))
316
317        # Perform binding from left to right
318        $(foreach bind.i,$($(with.ns).bind.idx),$\
319        $(foreach bind.name,$(word $(bind.i),$($(with.ns).bind.names)),$\
320        $(foreach bind.kind,$(word $(bind.i),$($(with.ns).bind.kinds)),$\
321        $(foreach bind.kind.ns,$(with.ns).bind.kind[$(bind.kind)],$\
322                $(eval $(value with.core.$(bind.kind).bind))))))
323
324        # Capture the expansion result from the current text pointer
325        $(eval $(with.ns).result := $($(with.ns).text))
326
327        # Restore originals (flavor/value) or undefine if previously absent
328        $(foreach bind.name,$($(with.ns).bind.names),$\
329        $(foreach bind.name.ns,$(with.ns).bind.names[$(bind.name)],$\
330                $(eval $(value with.core.restore))))
331endef
332
333define with.core.l =
334        # Create a 1..=(N_largs) list capturing the unbound `l` words
335        $(bind.kind.ns).words.idx :=
336        $(bind.kind.ns).words.next = $(words 1 $($(bind.kind.ns).words.idx))
337        $(bind.kind.ns).words = $\
338                $(wordlist $($(bind.kind.ns).words.next),$(words $(2)),$(2))
339
340        # Increment the text pointer
341        $(with.ns).text.idx += $($(with.ns).text.next)
342endef
343
344define with.core.l.bind =
345        # Bind this name to the next unbound word
346        $(bind.name) := $(firstword $($(bind.kind.ns).words))
347
348        # If this is the last `l` binding, absorb the remaining words
349        ifeq ($($(bind.kind.ns).words.next),$(words $($(bind.kind.ns))))
350                $(bind.name) := $($(bind.kind.ns).words)
351        endif
352
353        # Nudge the word pointer forward
354        $(bind.kind.ns).words.idx += $($(bind.kind.ns).words.next)
355endef
356
357define with.core.p =
358        # Compute the parameter index that `p` bindings start at
359        $(bind.kind.ns).param.offset := 1 2
360
361        # When `l` bindings are present, `p` values shift right
362        ifneq ($(filter l,$($(with.ns).bind.kinds)),)
363                $(bind.kind.ns).param.offset += 3
364        endif
365
366        # Create an N_poff..=N_pargs list capturing the unbound `p` arguments
367        $(bind.kind.ns).param.idx :=
368        $(bind.kind.ns).param.next = $\
369                $(words $($(bind.kind.ns).param.offset) $\
370                        $($(bind.kind.ns).param.idx))
371        $(bind.kind.ns).param = $($(lastword $($(bind.kind.ns).param.idx)))
372endef
373
374define with.core.p.bind =
375        # Mark the next parameter as bound
376        $(bind.kind.ns).param.idx += $($(bind.kind.ns).param.next)
377
378        # Bind this name to the next unbound argument
379        $(bind.name) := $($(bind.kind.ns).param)
380
381        # Increment the text pointer
382        $(with.ns).text.idx += $($(with.ns).text.next)
383endef
384
385define with.core.restore =
386        ifeq ($($(bind.name.ns).flavor),simple)
387                $(eval $(bind.name) := $(value $(bind.name.ns).value))
388        else ifeq ($($(bind.name.ns).flavor),recursive)
389                $(eval $(bind.name) = $(value $(bind.name.ns).value))
390        else ifeq ($($(bind.name.ns).flavor),undefined)
391                undefine $(bind.name)
392        endif
393endef
394
395#
396# Quote a string for safe use as a shell word.
397#
398# Takes the input string `$(1)` and escapes any single quotes it contains so
399# that the result can be safely used as a literal shell argument. The output is
400# wrapped in single quotes to ensure that whitespace and special characters are
401# preserved exactly when passed to the shell.
402#
403# This function is useful when constructing shell commands dynamically, since it
404# guarantees that arbitrary values are quoted correctly and will not be
405# misinterpreted by the shell.
406#
407# Parameters:
408#
409#   - $(1): The string to quote for safe shell usage.
410#
411# Examples:
412#
413#   $(call shell-quote,foo) # "'foo'"
414#   $(call shell-quote,bar baz) # "'bar baz'"
415#   $(call shell-quote,foo 'bar baz' qux) # "'foo '\''bar baz'\'' qux'"
416#
417
418shell-quote = '$(subst ','\'',$(1))'
419
420#
421# Parse a shell fragment and extract the N-th word.
422#
423# Parses the shell fragment given by `$(2)` using the shell's word-splitting and
424# quoting rules, then prints the `$(1)`-th shell word in the result. If the
425# index is out of range then this function evaluates to an empty string.
426#
427# This function is useful when working with lists that may contain whitespace or
428# quoted values, since it relies on the shell to do the parsing rather than
429# Make's own word functions. Whitespace is preserved in the return value.
430#
431# Parameters:
432#
433#   - $(1): The 1-based index of the word to extract.
434#   - $(2): The shell fragment to parse.
435#
436# Example usage:
437#
438#       $(call shell-word,1,foo 'bar baz' qux) # "foo"
439#       $(call shell-word,2,foo 'bar baz' qux) # "bar baz"
440#       $(call shell-word,3,foo 'bar baz' qux) # "qux"
441#       $(call shell-word,4,foo 'bar baz' qux) # <empty>
442#
443
444shell-word = $(shell $(shell-word.sh))
445
446define shell-word.sh =
447        set -Cefu -- '' $(2);
448
449        n=$(call shell-quote,$(1));
450
451        shift "$${n}";
452        printf '%s' "$${1:-}";
453endef
454
455#
456# Parse a shell fragment and count the number of shell words.
457#
458# Parses the shell fragment given by `$(1)` using the shell's word-splitting and
459# quoting rules, then prints the total number of words in the result.
460#
461# This function is useful when working with lists that may contain whitespace or
462# quoted values, since it relies on the shell to do the parsing rather than
463# Make's own word functions.
464#
465# Parameters:
466#
467#   - $(1): The shell fragment to parse.
468#
469# Example usage:
470#
471#       $(call shell-words,) # "0"
472#       $(call shell-words,foo) # "1"
473#       $(call shell-words,foo bar baz) # "3"
474#       $(call shell-words,foo 'bar baz' qux) # "3"
475#
476
477shell-words = $(shell $(shell-words.sh))
478shell-words.sh = set -Cefu -- $(1); printf '%s' "$$\#";
479
480#
481# Parse a shell fragment and extract a sequence of shell words.
482#
483# Parses the shell fragment given by `$(1)` using the shell's word-splitting and
484# quoting rules, then extracts the words from index `$(2)` up to but not
485# including index `$(3)`. Each extracted shell word is returned sanitized for
486# safe use in the shell.
487#
488# If `$(3)` is omitted, it defaults to one past the total number of words in the
489# string, allowing you to express "all words starting from `$(2)`".
490#
491# This function is useful for safely selecting and passing subsequences of
492# shell-parsed arguments into other shell commands, ensuring correct handling
493# of whitespace and special characters.
494#
495# Parameters:
496#
497#   - $(1): The shell fragment to parse.
498#   - $(2): The 1-based start index of the slice (default: 1).
499#   - $(3): The 1-based end index of the slice (exclusive, optional).
500#
501# Example usage:
502#
503#       $(call shell-slice,foo 'bar baz' qux)     # "'foo' 'bar baz' 'qux'"
504#       $(call shell-slice,foo 'bar baz' qux,1,3) # "'foo' 'bar baz'"
505#       $(call shell-slice,foo 'bar baz' qux,2)   # "'bar baz' 'qux'"
506#       $(call shell-slice,foo 'bar baz' qux,2,4) # "'bar baz' 'qux'"
507#       $(call shell-slice,foo 'bar baz' qux,2,5) # "'bar baz' 'qux'"
508#
509
510shell-slice = $(shell $(shell-slice.sh))
511
512define shell-slice.sh =
513        set -Cefu -- $(1);
514
515        n=$(if $(2),$(call shell-quote,$(2)),1);
516        m=$(if $(3),$(call shell-quote,$(3)),$$(($$# + 1)));
517
518        printf '%s\n' "$$@" $\
519                | sed -n "$${n},$${m}{ $${m}!p }; $${m}q" $\
520                | sed "s/'/'\\\\''/g; s/^/'/; s/\$$/'/";
521endef
522
523#
524# Join shell words with a custom delimiter.
525#
526# Parses the shell fragment given by `$(1)` using the shell's word-splitting and
527# quoting rules, then joins the resulting words together with the delimiter
528# specified by `$(2)`. If no delimiter is provided, no delimiter is used.
529#
530# This function is useful for safely rejoining a sequence of shell-parsed
531# arguments into a single string with controlled separators, ensuring that
532# whitespace and quoting are preserved correctly.
533#
534# Parameters:
535#
536#   - $(1): The shell fragment to parse and join.
537#   - $(2): The delimiter to insert between words (optional).
538#
539# Example usage:
540#
541#       $(call shell-join,foo 'bar baz' qux) # "foobar bazqux"
542#       $(call shell-join,foo 'bar baz' qux,:) # "foo:bar baz:qux"
543#       $(call shell-join,foo 'bar baz' qux,;) # "foo;bar baz;qux"
544#
545
546shell-join = $(shell $(shell-join.sh))
547
548define shell-join.sh =
549        set -Cefu -- $(1);
550
551        delimiter=$(call shell-quote,$(2));
552
553        printf '%s' "$${1:-}";
554        shift 1;
555
556        while [ "$$#" -gt 0 ]; do
557                printf '%s%s' "$${delimiter}" "$${1}";
558                shift 1;
559        done
560endef
561
562#
563# Apply a function to each shell word in a fragment.
564#
565# Parses the shell fragment given by `$(2)` into words using the shell's
566# word-splitting and quoting rules. For each word, the function `$(1)` is
567# invoked with the word as its first argument and the 1-based index of the word
568# as its second argument. The results are concatenated and returned, separated
569# by whitespace.
570#
571# This function is useful when you want to process each shell word from a
572# fragment through another function, while preserving correct handling of
573# whitespace and quoting.
574#
575# Parameters:
576#
577#   - $(1): The function to apply to each word.
578#   - $(2): The shell fragment to parse into words.
579#
580# Example usage:
581#
582#       $(call shell-map,words,foo 'bar baz' qux) # "1 2 1"
583#       $(call shell-map,uppercase,foo 'bar baz' qux) # "FOO BAR BAZ QUX"
584#
585#       shout = $(1)!
586#       $(call shell-map,shout,foo 'bar baz' qux) # "foo! bar baz! qux!"
587#
588#       make-binary = /bin/$(1)
589#       $(call shell-map,make-binary,cp "ls" 'sh') # "/bin/cp /bin/ls /bin/sh"
590#
591#       index-label = $(1):$(2)
592#       $(call shell-map,index-label,foo 'bar baz') # "foo:1 bar baz:2"
593#
594
595shell-map = $(call with,,$(shell $(shell-map.sh)))
596
597define shell-map.sh =
598        set -Cefu -- $(2);
599
600        function=$(call shell-quote,$(1));
601        index=1;
602
603        for argument in "$$@"; do
604                sanitized=$$(printf '%s' "$${argument}" $\
605                        | sed -e 's/[$$]/$$/g' -e 's/)/$$(rparen)/g' $\
606                                -e 's/,/$$(comma)/g');
607
608                printf '$$(call %s,%s,%s)\n' $\
609                        "$${function}" "$${sanitized}" "$${index}";
610
611                index=$$((index + 1));
612        done
613endef
614
615#
616# Resolve a program name or shell fragment to a safely quoted shell command.
617#
618# Attempts to locate the program given by `$(1)` on the system `PATH`. If the
619# program is found, its name is returned wrapped in single quotes so it can be
620# used safely in a shell command. If the program cannot be found, then the
621# argument is instead parsed as a shell fragment and returned as a sanitized
622# sequence of words, ensuring whitespace and quoting are preserved correctly.
623#
624# This function is useful when dynamically constructing shell command lines
625# that may include either well-known executables or arbitrary user-supplied
626# fragments. It guarantees that the result is safe to embed in shell commands,
627# regardless of whether it resolves to a `PATH` entry or a literal fragment.
628#
629# Parameters:
630#
631#   - $(1): The program name or shell fragment to resolve.
632#
633# Example usage:
634#
635#       $(call shell-program,sh)    # "'sh'"
636#       $(call shell-program,sh -c) # "'sh' '-c'"
637#
638#       # If the program exists and is executable:
639#
640#       $(call shell-program,/foo bar/sh)      # "'/foo bar/sh'"
641#       $(call shell-program,"/foo bar/sh" -c) # "'/foo bar/sh' '-c'"
642#
643#       # If the program does not exist or is not executable:
644#
645#       $(call shell-program,/foo bar/sh)    # "'/foo' 'bar/sh'"
646#       $(call shell-program,/foo bar/sh -c) # "'/foo' 'bar/sh' '-c'"
647#
648
649shell-program = $\
650        $(if $(call which,$(1)),$\
651                $(call shell-quote,$(1)),$\
652                $(call shell-slice,$(1)))
653