| ################################################################################ |
| # |
| # This file contains various utility macros and variables used about |
| # everywhere in make constructs. |
| # |
| ################################################################################ |
| |
| # Strip quotes and then whitespaces |
| qstrip = $(strip $(subst ",,$(1))) |
| #")) |
| |
| # Variables for use in Make constructs |
| comma := , |
| empty := |
| space := $(empty) $(empty) |
| |
| # make 4.3: |
| # https://lwn.net/Articles/810071/ |
| # Number signs (#) appearing inside a macro reference or function invocation |
| # no longer introduce comments and should not be escaped with backslashes: |
| # thus a call such as: |
| # foo := $(shell echo '#') |
| # is legal. Previously the number sign needed to be escaped, for example: |
| # foo := $(shell echo '\#') |
| # Now this latter will resolve to "\#". If you want to write makefiles |
| # portable to both versions, assign the number sign to a variable: |
| # H := \# |
| # foo := $(shell echo '$H') |
| SHARP_SIGN := \# |
| |
| # Case conversion macros. This is inspired by the 'up' macro from gmsl |
| # (http://gmsl.sf.net). It is optimised very heavily because these macros |
| # are used a lot. It is about 5 times faster than forking a shell and tr. |
| # |
| # The caseconvert-helper creates a definition of the case conversion macro. |
| # After expansion by the outer $(eval ), the UPPERCASE macro is defined as: |
| # $(strip $(eval __tmp := $(1)) $(eval __tmp := $(subst a,A,$(__tmp))) ... ) |
| # In other words, every letter is substituted one by one. |
| # |
| # The caseconvert-helper allows us to create this definition out of the |
| # [FROM] and [TO] lists, so we don't need to write down every substition |
| # manually. The uses of $ and $$ quoting are chosen in order to do as |
| # much expansion as possible up-front. |
| # |
| # Note that it would be possible to conceive a slightly more optimal |
| # implementation that avoids the use of __tmp, but that would be even |
| # more unreadable and is not worth the effort. |
| |
| [FROM] := a b c d e f g h i j k l m n o p q r s t u v w x y z - . |
| [TO] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ _ |
| |
| define caseconvert-helper |
| $(1) = $$(strip \ |
| $$(eval __tmp := $$(1))\ |
| $(foreach c, $(2),\ |
| $$(eval __tmp := $$(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)),$$(__tmp))))\ |
| $$(__tmp)) |
| endef |
| |
| $(eval $(call caseconvert-helper,UPPERCASE,$(join $(addsuffix :,$([FROM])),$([TO])))) |
| $(eval $(call caseconvert-helper,LOWERCASE,$(join $(addsuffix :,$([TO])),$([FROM])))) |
| |
| # Reverse the orders of words in a list. Again, inspired by the gmsl |
| # 'reverse' macro. |
| reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1))) $(firstword $(1))) |
| |
| # Sanitize macro cleans up generic strings so it can be used as a filename |
| # and in rules. Particularly useful for VCS version strings, that can contain |
| # slashes, colons (OK in filenames but not in rules), and spaces. |
| sanitize = $(subst $(space),_,$(subst :,_,$(subst /,_,$(strip $(1))))) |
| |
| # MESSAGE Macro -- display a message in bold type |
| MESSAGE = echo "$(TERM_BOLD)>>> $($(PKG)_NAME) $($(PKG)_VERSION) $(call qstrip,$(1))$(TERM_RESET)" |
| TERM_BOLD := $(shell tput smso 2>/dev/null) |
| TERM_RESET := $(shell tput rmso 2>/dev/null) |
| |
| # Utility functions for 'find' |
| # findfileclauses(filelist) => -name 'X' -o -name 'Y' |
| findfileclauses = $(call notfirstword,$(patsubst %,-o -name '%',$(1))) |
| # finddirclauses(base, dirlist) => -path 'base/dirX' -o -path 'base/dirY' |
| finddirclauses = $(call notfirstword,$(patsubst %,-o -path '$(1)/%',$(2))) |
| |
| # Miscellaneous utility functions |
| # notfirstword(wordlist): returns all but the first word in wordlist |
| notfirstword = $(wordlist 2,$(words $(1)),$(1)) |
| |
| # build a comma-separated list of quoted items, from a space-separated |
| # list of unquoted items: a b c d --> "a", "b", "c", "d" |
| make-comma-list = $(subst $(space),$(comma)$(space),$(patsubst %,"%",$(strip $(1)))) |
| |
| # build a comma-separated list of single quoted items, from a space-separated |
| # list of unquoted items: a b c d --> 'a', 'b', 'c', 'd' |
| make-sq-comma-list = $(subst $(space),$(comma)$(space),$(patsubst %,'%',$(strip $(1)))) |
| |
| # Needed for the foreach loops to loop over the list of hooks, so that |
| # each hook call is properly separated by a newline. |
| define sep |
| |
| |
| endef |
| |
| PERCENT = % |
| QUOTE = ' |
| # ' # Meh... syntax-highlighting |
| |
| # This macro properly escapes a command string, then prints it with printf: |
| # |
| # - first, backslash '\' are self-escaped, so that they do not escape |
| # the following char and so that printf properly outputs a backslash; |
| # |
| # - next, single quotes are escaped by closing an existing one, adding |
| # an escaped one, and re-openning a new one (see below for the reason); |
| # |
| # - then '%' signs are self-escaped so that the printf does not interpret |
| # them as a format specifier, in case the variable contains an actual |
| # printf with a format; |
| # |
| # - finally, $(sep) is replaced with the literal '\n' so that make does |
| # not break on the so-expanded variable, but so that the printf does |
| # correctly output an LF. |
| # |
| # Note: this must be escaped in this order to avoid over-escaping the |
| # previously escaped elements. |
| # |
| # Once everything has been escaped, it is passed between single quotes |
| # (that's why the single-quotes are escaped they way they are, above, |
| # and why the dollar sign is not escaped) to printf(1). A trailing |
| # newline is apended, too. |
| # |
| # Note: leading or trailing spaces are *not* stripped. |
| # |
| define PRINTF |
| printf '$(subst $(sep),\n,\ |
| $(subst $(PERCENT),$(PERCENT)$(PERCENT),\ |
| $(subst $(QUOTE),$(QUOTE)\$(QUOTE)$(QUOTE),\ |
| $(subst \,\\,$(1)))))\n' |
| endef |