Home | History | Annotate | Download | only in config
      1 # This allows us to work with the newline character:
      2 define newline
      3 
      4 
      5 endef
      6 newline := $(newline)
      7 
      8 # nl-escape
      9 #
     10 # Usage: escape = $(call nl-escape[,escape])
     11 #
     12 # This is used as the common way to specify
     13 # what should replace a newline when escaping
     14 # newlines; the default is a bizarre string.
     15 #
     16 nl-escape = $(or $(1),m822df3020w6a44id34bt574ctac44eb9f4n)
     17 
     18 # escape-nl
     19 #
     20 # Usage: escaped-text = $(call escape-nl,text[,escape])
     21 #
     22 # GNU make's $(shell ...) function converts to a
     23 # single space each newline character in the output
     24 # produced during the expansion; this may not be
     25 # desirable.
     26 #
     27 # The only solution is to change each newline into
     28 # something that won't be converted, so that the
     29 # information can be recovered later with
     30 # $(call unescape-nl...)
     31 #
     32 escape-nl = $(subst $(newline),$(call nl-escape,$(2)),$(1))
     33 
     34 # unescape-nl
     35 #
     36 # Usage: text = $(call unescape-nl,escaped-text[,escape])
     37 #
     38 # See escape-nl.
     39 #
     40 unescape-nl = $(subst $(call nl-escape,$(2)),$(newline),$(1))
     41 
     42 # shell-escape-nl
     43 #
     44 # Usage: $(shell some-command | $(call shell-escape-nl[,escape]))
     45 #
     46 # Use this to escape newlines from within a shell call;
     47 # the default escape is a bizarre string.
     48 #
     49 # NOTE: The escape is used directly as a string constant
     50 #       in an `awk' program that is delimited by shell
     51 #       single-quotes, so be wary of the characters
     52 #       that are chosen.
     53 #
     54 define shell-escape-nl
     55 awk 'NR==1 {t=$$0} NR>1 {t=t "$(nl-escape)" $$0} END {printf t}'
     56 endef
     57 
     58 # shell-unescape-nl
     59 #
     60 # Usage: $(shell some-command | $(call shell-unescape-nl[,escape]))
     61 #
     62 # Use this to unescape newlines from within a shell call;
     63 # the default escape is a bizarre string.
     64 #
     65 # NOTE: The escape is used directly as an extended regular
     66 #       expression constant in an `awk' program that is
     67 #       delimited by shell single-quotes, so be wary
     68 #       of the characters that are chosen.
     69 #
     70 # (The bash shell has a bug where `{gsub(...),...}' is
     71 #  misinterpreted as a brace expansion; this can be
     72 #  overcome by putting a space between `{' and `gsub').
     73 #
     74 define shell-unescape-nl
     75 awk 'NR==1 {t=$$0} NR>1 {t=t "\n" $$0} END { gsub(/$(nl-escape)/,"\n",t); printf t }'
     76 endef
     77 
     78 # escape-for-shell-sq
     79 #
     80 # Usage: embeddable-text = $(call escape-for-shell-sq,text)
     81 #
     82 # This function produces text that is suitable for
     83 # embedding in a shell string that is delimited by
     84 # single-quotes.
     85 #
     86 escape-for-shell-sq =  $(subst ','\'',$(1))
     87 
     88 # shell-sq
     89 #
     90 # Usage: single-quoted-and-escaped-text = $(call shell-sq,text)
     91 #
     92 shell-sq = '$(escape-for-shell-sq)'
     93 
     94 # shell-wordify
     95 #
     96 # Usage: wordified-text = $(call shell-wordify,text)
     97 #
     98 # For instance:
     99 #
    100 #  |define text
    101 #  |hello
    102 #  |world
    103 #  |endef
    104 #  |
    105 #  |target:
    106 #  |	echo $(call shell-wordify,$(text))
    107 #
    108 # At least GNU make gets confused by expanding a newline
    109 # within the context of a command line of a makefile rule
    110 # (this is in constrast to a `$(shell ...)' function call,
    111 # which can handle it just fine).
    112 #
    113 # This function avoids the problem by producing a string
    114 # that works as a shell word, regardless of whether or
    115 # not it contains a newline.
    116 #
    117 # If the text to be wordified contains a newline, then
    118 # an intrictate shell command substitution is constructed
    119 # to render the text as a single line; when the shell
    120 # processes the resulting escaped text, it transforms
    121 # it into the original unescaped text.
    122 #
    123 # If the text does not contain a newline, then this function
    124 # produces the same results as the `$(shell-sq)' function.
    125 #
    126 shell-wordify = $(if $(findstring $(newline),$(1)),$(_sw-esc-nl),$(shell-sq))
    127 define _sw-esc-nl
    128 "$$(echo $(call escape-nl,$(shell-sq),$(2)) | $(call shell-unescape-nl,$(2)))"
    129 endef
    130 
    131 # is-absolute
    132 #
    133 # Usage: bool-value = $(call is-absolute,path)
    134 #
    135 is-absolute = $(shell echo $(shell-sq) | grep ^/ -q && echo y)
    136 
    137 # lookup
    138 #
    139 # Usage: absolute-executable-path-or-empty = $(call lookup,path)
    140 #
    141 # (It's necessary to use `sh -c' because GNU make messes up by
    142 #  trying too hard and getting things wrong).
    143 #
    144 lookup = $(call unescape-nl,$(shell sh -c $(_l-sh)))
    145 _l-sh = $(call shell-sq,command -v $(shell-sq) | $(call shell-escape-nl,))
    146 
    147 # is-executable
    148 #
    149 # Usage: bool-value = $(call is-executable,path)
    150 #
    151 # (It's necessary to use `sh -c' because GNU make messes up by
    152 #  trying too hard and getting things wrong).
    153 #
    154 is-executable = $(call _is-executable-helper,$(shell-sq))
    155 _is-executable-helper = $(shell sh -c $(_is-executable-sh))
    156 _is-executable-sh = $(call shell-sq,test -f $(1) -a -x $(1) && echo y)
    157 
    158 # get-executable
    159 #
    160 # Usage: absolute-executable-path-or-empty = $(call get-executable,path)
    161 #
    162 # The goal is to get an absolute path for an executable;
    163 # the `command -v' is defined by POSIX, but it's not
    164 # necessarily very portable, so it's only used if
    165 # relative path resolution is requested, as determined
    166 # by the presence of a leading `/'.
    167 #
    168 get-executable = $(if $(1),$(if $(is-absolute),$(_ge-abspath),$(lookup)))
    169 _ge-abspath = $(if $(is-executable),$(1))
    170 
    171 # get-supplied-or-default-executable
    172 #
    173 # Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
    174 #
    175 define get-executable-or-default
    176 $(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
    177 endef
    178 _ge_attempt = $(or $(get-executable),$(_gea_warn),$(call _gea_err,$(2)))
    179 _gea_warn = $(warning The path '$(1)' is not executable.)
    180 _gea_err  = $(if $(1),$(error Please set '$(1)' appropriately))
    181 
    182 # try-cc
    183 # Usage: option = $(call try-cc, source-to-build, cc-options)
    184 try-cc = $(shell sh -c						  \
    185 	'TMP="$(OUTPUT)$(TMPOUT).$$$$";				  \
    186 	 echo "$(1)" |						  \
    187 	 $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
    188 	 rm -f "$$TMP"')
    189