utilities.mak 5.2 KB

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