github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/makelib/misc.mk (about)

     1  # check if we have undefine feature (only in make >=3.82)
     2  ifneq ($(filter undefine,$(.FEATURES)),)
     3  
     4  # we have undefine
     5  define undef
     6  $(eval undefine $1)
     7  endef
     8  
     9  else
    10  
    11  # no undefine available, simply set the variable to empty value
    12  define undef
    13  $(eval $1 :=)
    14  endef
    15  
    16  endif
    17  
    18  # 1 - a list of variables to undefine
    19  #
    20  # Simply uses undefine directive on all passed variables.
    21  #
    22  # It does not check if variables are in any way special (like being
    23  # special make variables or else).
    24  #
    25  # Example: $(call undefine-variables-unchecked,VAR1 VAR2 VAR3)
    26  define undefine-variables-unchecked
    27  $(strip \
    28  	$(foreach v,$1, \
    29  		$(call undef,$v)))
    30  endef
    31  
    32  # 1 - a list of variable namespaces
    33  # 2 - a list of excluded variables
    34  #
    35  # Undefines all variables in all given namespaces (which basically
    36  # means variables with names prefixed with <namespace>_) except for
    37  # ones listed in a given exclusions list.
    38  #
    39  # It does not check if variables are in any way special (like being
    40  # special make variables or else).
    41  #
    42  # It is a bit of make-golf to avoid using variables. See
    43  # undefine-namespaces below, which has clearer code, is doing exactly
    44  # the same, but calls undefine-variables instead (which changes its
    45  # behaviour wrt. the origin of the variables).
    46  #
    47  # Example: $(call undefine-namespaces-unchecked,NS1 NS2 NS3,N1_KEEP_THIS N3_THIS_TOO)
    48  define undefine-namespaces-unchecked
    49  $(strip \
    50  	$(foreach ,x x, \
    51  		$(call undefine-variables-unchecked, \
    52  			$(filter-out $2, \
    53  				$(filter $(foreach n,$1,$n_%),$(.VARIABLES))))))
    54  endef
    55  
    56  # 1 - a list of variables to undefine
    57  #
    58  # Undefines those variables from a given list, which have origin
    59  # "file". If the origin of a variable is different, it is left
    60  # untouched.
    61  #
    62  # This function will bail out if any of the variables starts with a
    63  # dot or MAKE.
    64  #
    65  # Example: $(call undefine-variables,VAR1 VAR2 VAR3)
    66  define undefine-variables
    67  $(strip \
    68  	$(foreach p,.% MAKE%, \
    69  		$(eval _MISC_UV_FORBIDDEN_ := $(strip $(filter $p,$1))) \
    70  		$(if $(_MISC_UV_FORBIDDEN_), \
    71  			$(eval _MISC_UV_ERROR_ += Trying to undefine $(_MISC_UV_FORBIDDEN_) variables which match the forbidden pattern $p.))) \
    72  	$(if $(_MISC_UV_ERROR_), \
    73  		$(error $(_MISC_UV_ERROR_))) \
    74  	$(foreach v,$1, \
    75  		$(if $(filter-out file,$(origin $v)), \
    76  			$(eval _MISC_UV_EXCLUDES_ += $v))) \
    77  	$(eval _MISC_UV_VARS_ := $(filter-out $(_MISC_UV_EXCLUDES_), $1)) \
    78  	$(call undefine-variables-unchecked,$(_MISC_UV_VARS_)) \
    79  	$(call undefine-namespaces-unchecked,_MISC_UV))
    80  endef
    81  
    82  # 1 - a list of variable namespaces
    83  # 2 - a list of excluded variables
    84  #
    85  # Undefines those variables in all given namespaces (which basically
    86  # means variables with names prefixed with <namespace>_), which have
    87  # origin "file". If the origin of the variable is different or the
    88  # variable is a part of exclusions list, it is left untouched.
    89  #
    90  # This function will bail out if any of the variables starts with a
    91  # dot or MAKE.
    92  #
    93  # The function performs the action twice - sometimes defined variables
    94  # are not listed in .VARIABLES list initially, but they do show up
    95  # there after first iteration, so we can remove them then. It is
    96  # likely a make bug.
    97  #
    98  # Example: $(call undefine-namespaces,NS1 NS2 NS3,N1_KEEP_THIS N3_THIS_TOO)
    99  define undefine-namespaces
   100  $(strip \
   101  	$(foreach ,x x, \
   102  		$(eval _MISC_UN_VARS_ := $(filter $(foreach n,$1,$n_%),$(.VARIABLES))) \
   103  		$(eval _MISC_UN_VARS_ := $(filter-out $2,$(_MISC_UN_VARS_))) \
   104  		$(call undefine-variables,$(_MISC_UN_VARS_)) \
   105  		$(call undefine-namespaces-unchecked,_MISC_UN)))
   106  endef
   107  
   108  define multi-subst
   109  $(strip \
   110  	$(eval _MISC_MS_TMP_ := $(strip $3)) \
   111  	$(eval $(foreach s,$1, \
   112  		$(eval _MISC_MS_TMP_ := $(subst $s,$2,$(_MISC_MS_TMP_))))) \
   113  	$(_MISC_MS_TMP_) \
   114  	$(call undefine-namespaces,_MISC_MS))
   115  endef
   116  
   117  # When updating replaced chars here, remember to update them in
   118  # libdepsgen.pm in escape_path sub.
   119  define escape-for-file
   120  $(call multi-subst,- / . : +,_,$1)
   121  endef
   122  
   123  define path-to-file-with-suffix
   124  $(call escape-for-file,$1).$2
   125  endef
   126  
   127  define stamp-file
   128  $(STAMPSDIR)/$(call path-to-file-with-suffix,$1,stamp)
   129  endef
   130  
   131  # Generates a stamp filename and assigns it to passed variable
   132  # name. Generates a stamp's dependency on stamps directory. Adds stamp
   133  # to CLEAN_FILES. Optional second parameter is for adding a suffix to
   134  # stamp.
   135  # Example: $(call setup-custom-stamp-file,FOO_STAMP,/some_suffix)
   136  define setup-custom-stamp-file
   137  $(strip \
   138  	$(eval $1 := $(call stamp-file,$2)) \
   139  	$(eval $($1): | $$(call to-dir,$($1))) \
   140  	$(eval CLEAN_FILES += $($1)))
   141  endef
   142  
   143  # Generates a stamp filename and assigns it to passed variable
   144  # name. Generates a stamp's dependency on stamps directory. Adds stamp
   145  # to CLEAN_FILES. Optional second parameter is for adding a suffix to
   146  # stamp.
   147  # Example: $(call setup-stamp-file,FOO_STAMP,/some_suffix)
   148  define setup-stamp-file
   149  $(eval $(call setup-custom-stamp-file,$1,$(MK_PATH)$2))
   150  endef
   151  
   152  define dep-file
   153  $(DEPSDIR)/$(call path-to-file-with-suffix,$1,dep.mk)
   154  endef
   155  
   156  define setup-custom-dep-file
   157  $(strip \
   158  	$(eval $1 := $(call dep-file,$2)) \
   159  	$(eval $($1): | $$(call to-dir,$($1))) \
   160  	$(eval CLEAN_FILES += $($1)))
   161  endef
   162  
   163  define setup-dep-file
   164  $(eval $(call setup-custom-dep-file,$1,$(MK_PATH)$2))
   165  endef
   166  
   167  # Returns all not-excluded directories inside $REPO_PATH that have
   168  # nonzero files matching given "go list -f {{.ITEM1}} {{.ITEM2}}...".
   169  # 1 - where to look for files (./... to look for all files inside the project)
   170  # 2 - a list of "go list -f {{.ITEM}}" items (GoFiles, TestGoFiles, etc)
   171  # 3 - space-separated list of excluded directories
   172  # Example: $(call go-find-directories,./...,TestGoFiles XTestGoFiles,tests)
   173  define go-find-directories
   174  $(strip \
   175  	$(eval _MISC_GFD_ESCAPED_SRCDIR := $(shell cd $(MK_TOPLEVEL_SRCDIR) && pwd)) \
   176  	$(eval _MISC_GFD_ESCAPED_SRCDIR := $(subst .,\.,$(_MISC_GFD_ESCAPED_SRCDIR))) \
   177  	$(eval _MISC_GFD_ESCAPED_SRCDIR := $(subst /,\/,$(_MISC_GFD_ESCAPED_SRCDIR))) \
   178  	$(eval _MISC_GFD_SPACE_ :=) \
   179  	$(eval _MISC_GFD_SPACE_ +=) \
   180  	$(eval _MISC_GFD_GO_LIST_ITEMS_ := $(foreach i,$2,{{.$i}})) \
   181  	$(eval _MISC_GFD_FILES_ := $(shell $(GO_ENV) "$(GO)" list -f '{{.ImportPath}} $(_MISC_GFD_GO_LIST_ITEMS_)' $1 | \
   182  		grep '\[[^]]' | \
   183  		grep -v '/vendor' | \
   184  		sed -e 's/.*$(_MISC_GFD_ESCAPED_SRCDIR)\///' -e 's/[[:space:]]*\[.*\]$$//' \
   185  		$(if $3,| grep --invert-match '^\($(subst $(_MISC_GFD_SPACE_),\|,$3)\)'))) \
   186  	$(_MISC_GFD_FILES_) \
   187  	$(call undefine-namespaces,_MISC_GFD))
   188  endef
   189  
   190  # Escapes all single quotes in $1 (by replacing all ' with '"'"')
   191  define sq_escape
   192  $(subst ','"'"',$1)
   193  endef
   194  #'
   195  
   196  # Returns 1 if both parameters are equal, otherwise returns empty
   197  # string.
   198  # Example: is_a_equal_to_b := $(if $(call equal,a,b),yes,no)
   199  define equal
   200  $(strip \
   201          $(eval _MISC_EQ_OP1_ := $(call sq_escape,$1)) \
   202          $(eval _MISC_EQ_OP2_ := $(call sq_escape,$2)) \
   203          $(eval _MISC_EQ_TMP_ := $(shell expr '$(_MISC_EQ_OP1_)' = '$(_MISC_EQ_OP2_)')) \
   204          $(filter $(_MISC_EQ_TMP_),1) \
   205          $(call undefine-namespaces,_MISC_EQ))
   206  endef
   207  
   208  # Returns a string with all backslashes and double quotes escaped and
   209  # wrapped in another double quotes. Useful for passing a string as a
   210  # single parameter. In general the following should print the same:
   211  # str := "aaa"
   212  # $(info $(str))
   213  # $(shell echo $(call escape-and-wrap,$(str)))
   214  define escape-and-wrap
   215  "$(subst ",\",$(subst \,\\,$1))"
   216  endef
   217  # "
   218  # the double quotes in comment above remove highlighting confusion
   219  
   220  # Forwards given variables to a given rule.
   221  # 1 - a rule target
   222  # 2 - a list of variables to forward
   223  #
   224  # Example: $(call forward-vars,$(MY_TARGET),VAR1 VAR2 VAR3)
   225  #
   226  # The effect is basically:
   227  # $(MY_TARGET): VAR1 := $(VAR1)
   228  # $(MY_TARGET): VAR2 := $(VAR2)
   229  # $(MY_TARGET): VAR3 := $(VAR3)
   230  define forward-vars
   231  $(strip \
   232  	$(foreach v,$2, \
   233  		$(eval $1: $v := $($v))))
   234  endef
   235  
   236  # Returns a colon (:) if passed value is empty. Useful for avoiding
   237  # shell errors about an empty body.
   238  # 1 - bash code
   239  define colon-if-empty
   240  $(if $(strip $1),$1,:)
   241  endef
   242  
   243  # Used by generate-simple-rule, see its docs.
   244  define simple-rule-template
   245  $1: $2 $(if $(strip $3),| $3)
   246  	$(call colon-if-empty,$4)
   247  endef
   248  
   249  # Generates a simple rule - without variable forwarding and with only
   250  # a single-command recipe.
   251  # 1 - targets
   252  # 2 - reqs
   253  # 3 - order-only reqs
   254  # 4 - recipe
   255  define generate-simple-rule
   256  $(eval $(call simple-rule-template,$1,$2,$3,$4))
   257  endef
   258  
   259  # Generates a rule with a "set -e".
   260  # 1 - target (stamp file)
   261  # 2 - reqs
   262  # 3 - order-only reqs
   263  # 4 - recipe placed after 'set -e'
   264  define generate-strict-rule
   265  $(call generate-simple-rule,$1,$2,$3,$(VQ)set -e; $(call colon-if-empty,$4))
   266  endef
   267  
   268  # Generates a rule for creating a stamp with additional actions to be
   269  # performed before the actual stamp creation.
   270  # 1 - target (stamp file)
   271  # 2 - reqs
   272  # 3 - order-only reqs
   273  # 4 - recipe placed between 'set -e' and 'touch "$@"'
   274  define generate-stamp-rule
   275  $(call generate-strict-rule,$1,$2,$3,$(call colon-if-empty,$4); $$(call vb,v2,STAMP,$$(call vsp,$$@))touch "$$@")
   276  endef
   277  
   278  # 1 - from
   279  # 2 - to
   280  define bash-cond-rename
   281  if cmp --silent "$1" "$2"; then rm -f "$1"; else mv "$1" "$2"; fi
   282  endef
   283  
   284  # Generates a rule for generating a depmk for a given go binary from a
   285  # given package. It also tries to include the depmk.
   286  #
   287  # This function (and the other generate-*-deps) are stamp-based. It
   288  # generates no rule for actual depmk. Instead it generates a rule for
   289  # creating a stamp, which will also generate the depmk. This is to
   290  # avoid generating depmk at make startup, when it parses the
   291  # Makefile. At startup, make tries to rebuild all the files it tries
   292  # to include if there is a rule for the file. We do not want that -
   293  # that would override a depmk with a fresh one, so no file
   294  # additions/deletions made before running make would be detected.
   295  #
   296  # 1 - a stamp file
   297  # 2 - a binary name
   298  # 3 - depmk name
   299  # 4 - a package name
   300  define generate-go-deps
   301  $(strip \
   302  	$(if $(call equal,$2,$(DEPSGENTOOL)), \
   303  		$(eval _MISC_GGD_DEP_ := $(DEPSGENTOOL)), \
   304  		$(eval _MISC_GGD_DEP_ := $(DEPSGENTOOL_STAMP))) \
   305  	$(eval -include $3) \
   306  	$(eval $(call generate-stamp-rule,$1,$(_MISC_GGD_DEP_),$(DEPSDIR),$(call vb,v2,DEPS GO,$(call vsg,$(REPO_PATH)/$4) => $(call vsp,$3))$(GO_ENV) "$(DEPSGENTOOL)" go --repo "$(REPO_PATH)" --module "$4" --target '$2 $1' >"$3.tmp"; $(call bash-cond-rename,$3.tmp,$3))) \
   307  	$(call undefine-namespaces,_MISC_GGD))
   308  endef
   309  
   310  # Generates a rule for generating a key-value depmk for a given target
   311  # with given variable names to store. It also tries to include the
   312  # depmk.
   313  # 1 - a stamp file
   314  # 2 - a target
   315  # 3 - depmk name
   316  # 4 - a list of variable names to store
   317  define generate-kv-deps
   318  $(strip \
   319  	$(if $(call equal,$2,$(DEPSGENTOOL)), \
   320  		$(eval _MISC_GKD_DEP_ := $(DEPSGENTOOL)), \
   321  		$(eval _MISC_GKD_DEP_ := $(DEPSGENTOOL_STAMP))) \
   322  	$(foreach v,$4, \
   323  		$(eval _MISC_GKD_KV_ += $v $(call escape-and-wrap,$($v)))) \
   324  	$(eval -include $3) \
   325  	$(eval $(call generate-stamp-rule,$1,$(_MISC_GKD_DEP_),$(DEPSDIR),$(call vb,v2,DEPS KV,$4 => $(call vsp,$3))"$(DEPSGENTOOL)" kv --target '$2 $1' $(_MISC_GKD_KV_) >"$3.tmp"; $(call bash-cond-rename,$3.tmp,$3))) \
   326  	$(call undefine-namespaces,_MISC_GKD))
   327  endef
   328  
   329  define filelist-file
   330  $(FILELISTDIR)/$(call path-to-file-with-suffix,$1,filelist)
   331  endef
   332  
   333  define setup-custom-filelist-file
   334  $(eval $1 := $(call filelist-file,$2)) \
   335  $(eval $($1): | $$(call to-dir,$($1))) \
   336  $(eval CLEAN_FILES += $($1))
   337  endef
   338  
   339  define setup-filelist-file
   340  $(eval $(call setup-custom-filelist-file,$1,$(MK_PATH)$2))
   341  endef
   342  
   343  # 1 - filelist
   344  define generate-empty-filelist
   345  $(eval $(call generate-strict-rule,$1,$(FILELISTGENTOOL_STAMP),$(FILELISTDIR),$(call vb,v2,FILELIST,<nothing> => $(call vsp,$1))"$(FILELISTGENTOOL)" --empty >"$1.tmp"; $(call bash-cond-rename,$1.tmp,$1)))
   346  endef
   347  
   348  # 1 - filelist
   349  # 2 - directory
   350  define generate-deep-filelist
   351  $(eval $(call generate-strict-rule,$1,$(FILELISTGENTOOL_STAMP),$(FILELISTDIR),$(call vb,v2,FILELIST,$(call vsp,$2) => $(call vsp,$1))"$(FILELISTGENTOOL)" --directory="$2" >"$1.tmp"; $(call bash-cond-rename,$1.tmp,$1)))
   352  endef
   353  
   354  # 1 - filelist
   355  # 2 - a directory
   356  # 3 - a suffix
   357  define generate-shallow-filelist
   358  $(eval $(call generate-strict-rule,$1,$(FILELISTGENTOOL_STAMP),$(FILELISTDIR),$(call vb,v2,FILELIST,$(call vsp,$2/*$3) => $(call vsp,$1))"$(FILELISTGENTOOL)" --directory="$2" --suffix="$3" >"$1.tmp"; $(call bash-cond-rename,$1.tmp,$1)))
   359  endef
   360  
   361  # This is used for the truncated output - it takes a list of
   362  # directories, shortens them and puts them in a comma-separated list
   363  # between parens: (dir1,dir2,...,dirN)
   364  define nice-dirs-output
   365  $(strip \
   366  	$(eval _MISC_NDO_COMMA_ := ,) \
   367  	$(eval _MISC_NDO_SPACE_ := ) \
   368  	$(eval _MISC_NDO_SPACE_ += ) \
   369  	$(eval _MISC_NDO_DIRS_ := ($(subst $(_MISC_NDO_SPACE_),$(_MISC_NDO_COMMA_),$(call vsp,$1)))) \
   370  	$(_MISC_NDO_DIRS_) \
   371  	$(call undefine-namespaces,_MISC_NDO))
   372  endef
   373  
   374  # Generates a rule for generating a glob depmk for a given target
   375  # based on a given filelist. This is up to you to ensure that every
   376  # file in a filelist ends with a given suffix.
   377  # 1 - a stamp file
   378  # 2 - a target
   379  # 3 - depmk name
   380  # 4 - a suffix
   381  # 5 - a filelist
   382  # 6 - a list of directories to map the files from filelist to
   383  # 7 - glob mode, can be all, dot-files, normal (empty means all)
   384  define generate-glob-deps
   385  $(strip \
   386  	$(if $(call equal,$2,$(DEPSGENTOOL)), \
   387  		$(eval _MISC_GLDF_DEP_ := $(DEPSGENTOOL)), \
   388  		$(eval _MISC_GLDF_DEP_ := $(DEPSGENTOOL_STAMP))) \
   389  	$(if $(strip $7), \
   390  		$(eval _MISC_GLDF_GLOB_ := --glob-mode="$(strip $7)")) \
   391  	$(eval -include $3) \
   392  	$(eval _MISC_GLDF_DIRS_ := $(call nice-dirs-output,$6)) \
   393  	$(eval $(call generate-stamp-rule,$1,$(_MISC_GLDF_DEP_) $5,$(DEPSDIR),$(call vb,v2,DEPS GLOB,$(_MISC_GLDF_DIRS_) $(call vsp,$5) => $(call vsp,$3))"$(DEPSGENTOOL)" glob --target "$2 $1" --suffix="$4" --filelist="$5" $(foreach m,$6,--map-to="$m") $(_MISC_GLDF_GLOB_)>"$3.tmp"; $(call bash-cond-rename,$3.tmp,$3))) \
   394  	$(call undefine-namespaces,_MISC_GLDF))
   395  endef
   396  
   397  # Returns a list of directories starting from a subdirectory of given
   398  # base up to the full path made of the given base and a rest. So, if
   399  # base is "base" and rest is "r/e/s/t" then the returned list is
   400  # "base/r base/r/e base/r/e/s base/r/e/s/t".
   401  #
   402  # Useful for getting a list of directories to be removed.
   403  # 1 - a base
   404  # 2 - a dir (or dirs) in base
   405  #
   406  # Example: CREATE_DIRS += $(call dir-chain,$(BASE),src/foo/bar/baz)
   407  define dir-chain
   408  $(strip \
   409  	$(eval _MISC_DC_DIRS_ := $(subst /, ,$2)) \
   410  	$(eval _MISC_DC_PATHS_ :=) \
   411  	$(eval _MISC_DC_LIST_ :=) \
   412  	$(eval $(foreach d,$(_MISC_DC_DIRS_), \
   413  		$(eval _MISC_DC_LAST_ := $(lastword $(_MISC_DC_PATHS_))) \
   414  		$(eval $(if $(_MISC_DC_LAST_), \
   415  			$(eval _MISC_DC_PATHS_ += $(_MISC_DC_LAST_)/$d), \
   416  			$(eval _MISC_DC_PATHS_ := $d))))) \
   417  	$(eval $(foreach d,$(_MISC_DC_PATHS_), \
   418  		$(eval _MISC_DC_LIST_ += $1/$d))) \
   419  	$(_MISC_DC_LIST_) \
   420  	$(call undefine-namespaces,_MISC_DC))
   421  endef
   422  
   423  # 1 - variable for dirname
   424  define setup-tmp-dir
   425  $(strip \
   426  	$(eval _MISC_TMP_DIR_ := $(MAINTEMPDIR)/$(subst .mk,,$(MK_FILENAME)))
   427  	$(eval CREATE_DIRS += $(_MISC_TMP_DIR_)) \
   428  	$(eval $1 := $(_MISC_TMP_DIR_)) \
   429  	$(call undefine-namespaces,_MISC_TMP))
   430  endef
   431  
   432  define clean-file
   433  $(CLEANDIR)/$(call path-to-file-with-suffix,$1,clean.mk)
   434  endef
   435  
   436  define setup-custom-clean-file
   437  $(eval $1 := $(call clean-file,$2)) \
   438  $(eval $($1): | $$(call to-dir,$($1))) \
   439  $(eval CLEAN_FILES += $($1))
   440  endef
   441  
   442  define setup-clean-file
   443  $(eval $(call setup-custom-clean-file,$1,$(MK_PATH)$2))
   444  endef
   445  
   446  # 1 - stamp file
   447  # 2 - cleanmk file
   448  # 3 - filelist name
   449  # 4 - a list of directory mappings
   450  define generate-clean-mk
   451  $(strip \
   452  	$(eval -include $2) \
   453  	$(eval _MISC_GCM_DIRS_ := $(call nice-dirs-output,$4)) \
   454  	$(eval $(call generate-stamp-rule,$1,$(CLEANGENTOOL_STAMP) $3,$(CLEANDIR),$(call vb,v2,CLEANFILE,$(_MISC_GCM_DIRS_) $(call vsp,$3) => $(call vsp,$2))"$(CLEANGENTOOL)" --filelist="$3" $(foreach m,$4,--map-to="$m") >"$2.tmp"; $(call bash-cond-rename,$2.tmp,$2))) \
   455  	$(call undefine-namespaces,_MISC_GCM))
   456  endef
   457  
   458  define sed-replacement-escape
   459  $(strip $(shell echo $1 | sed -e 's/[\/&]/\\&/g'))
   460  endef
   461  
   462  define add-dependency-template
   463  $1: $2
   464  endef
   465  
   466  # 1 - a target
   467  # 2 - a dependency (or a prerequisite in makese)
   468  define add-dependency
   469  $(eval $(call add-dependency-template,$1,$2))
   470  endef
   471  
   472  # 1 - stamp file, which will depend on the generated clean stamp
   473  # 2 - file list
   474  # 3 - a list of directory mappings
   475  # 4 - descriptor
   476  define generate-clean-mk-from-filelist
   477  $(strip \
   478  	$(eval _MISC_GCMFF_MAIN_STAMP_ := $(strip $1)) \
   479  	$(eval _MISC_GCMFF_FILELIST_ := $(strip $2)) \
   480  	$(eval _MISC_GCMFF_DIR_MAPS_ := $(strip $3)) \
   481  	$(eval _MISC_GCMFF_DESCRIPTOR_ := $(strip $4)) \
   482  	\
   483  	$(call setup-stamp-file,_MISC_GCMFF_CLEAN_STAMP_,$(_MISC_GCMFF_DESCRIPTOR_)-gcmff-generated-clean-stamp) \
   484  	$(call setup-clean-file,_MISC_GCMFF_CLEANMK_,$(_MISC_GCMFF_DESCRIPTOR_)-gcmff-generated-cleanmk) \
   485  	\
   486  	$(call add-dependency,$(_MISC_GCMFF_MAIN_STAMP_),$(_MISC_GCMFF_CLEAN_STAMP_)) \
   487  	$(call generate-clean-mk,$(_MISC_GCMFF_CLEAN_STAMP_),$(_MISC_GCMFF_CLEANMK_),$(_MISC_GCMFF_FILELIST_),$(_MISC_GCMFF_DIR_MAPS_)) \
   488  	\
   489  	$(call undefine-namespaces,_MISC_GCMFF))
   490  endef
   491  
   492  # 1 - stamp file, which will depend on the generated clean stamp
   493  # 2 - source directory
   494  # 3 - a list of directory mappings
   495  # 4 - filelist deps
   496  # 5 - descriptor
   497  define generate-clean-mk-simple
   498  $(strip \
   499  	$(eval _MISC_GCMS_MAIN_STAMP_ := $(strip $1)) \
   500  	$(eval _MISC_GCMS_SRCDIR_ := $(strip $2)) \
   501  	$(eval _MISC_GCMS_DIR_MAPS_ := $(strip $3)) \
   502  	$(eval _MISC_GCMS_DEPS_ := $(strip $4)) \
   503  	$(eval _MISC_GCMS_DESCRIPTOR_ := $(strip $5)) \
   504  	\
   505  	$(call setup-filelist-file,_MISC_GCMS_FILELIST_,$(_MISC_GCMS_DESCRIPTOR_)-gcms-generated-filelist) \
   506  	$(call add-dependency,$(_MISC_GCMS_FILELIST_),$(_MISC_GCMS_DEPS_)) \
   507  	$(call generate-deep-filelist,$(_MISC_GCMS_FILELIST_),$(_MISC_GCMS_SRCDIR_)) \
   508  	\
   509  	$(call generate-clean-mk-from-filelist, \
   510  		$(_MISC_GCMS_MAIN_STAMP_), \
   511  		$(_MISC_GCMS_FILELIST_), \
   512  		$(_MISC_GCMS_DIR_MAPS_), \
   513  		$(_MISC_GCMS_DESCRIPTOR_)) \
   514  	\
   515  	$(call undefine-namespaces,_MISC_GCMS))
   516  endef
   517  
   518  # Formats given lists of source and destination files for the
   519  # INSTALL_FILES variable.
   520  #
   521  # 1 - list of src files
   522  # 2 - list of target files
   523  # 3 - mode
   524  define install-file-triplets
   525  $(strip $(join $(addsuffix :,$1),$(addsuffix :$3,$2)))
   526  endef
   527  
   528  define commas-to-spaces
   529  $(strip \
   530  	$(eval _MISC_CTS_COMMA_ := ,) \
   531  	$(eval _MISC_CTS_SPACE_ := ) \
   532  	$(eval _MISC_CTS_SPACE_ += ) \
   533  	$(subst $(_MISC_CTS_COMMA_),$(_MISC_CTS_SPACE_),$1) \
   534  	$(call undefine-namespaces,_MISC_CTS))
   535  endef
   536  
   537  # Generates a rule for given stamp which removes given directory and
   538  # adds a dependency to the directory on a given stamp. That way, the
   539  # directory will be removed before it is created if the stamp does not
   540  # exist or is invalidated. Additional dependencies for the stamp can
   541  # be specified by using usual make syntax ($(stamp): $(dep)).
   542  #
   543  # 1 - stamp
   544  # 2 - directory to remove
   545  define generate-rm-dir-rule
   546  $(strip \
   547  	$(call add-dependency,$2,$1) \
   548  	$(call generate-stamp-rule,$1,,, \
   549  		$(call vb,v2,RM RF,$(call vsp,$2))rm -rf $2))
   550  endef
   551  
   552  define go-pkg-from-dir
   553  $(subst $(MK_TOPLEVEL_SRCDIR)/,,$(MK_SRCDIR))
   554  endef
   555  
   556  # Generate a filelist for patches. Usually, when generating filelists,
   557  # we require the directory to exist. In this case, the patches
   558  # directory may not exist and it is fine. We generate an empty
   559  # filelist.
   560  #
   561  # 1 - patches filelist
   562  # 2 - patches dir
   563  define generate-patches-filelist
   564  $(strip \
   565  	$(eval _MISC_GPF_FILELIST := $(strip $1)) \
   566  	$(eval _MISC_GPF_DIR := $(strip $2)) \
   567  	$(eval $(if $(shell test -d "$(_MISC_GPF_DIR)" && echo yes), \
   568  		$(call generate-shallow-filelist,$(_MISC_GPF_FILELIST),$(_MISC_GPF_DIR),.patch), \
   569  		$(call generate-empty-filelist,$(_MISC_GPF_FILELIST)))) \
   570  	$(call undefine-namespaces,_MISC_GPF))
   571  endef
   572  
   573  # Generate an ACI manifest from a source template.  Fills in
   574  # machine specific values.
   575  #
   576  # 1 - input: manifest source template file
   577  # 2 - output: generated manifest file
   578  define generate-manifest-file
   579  	sed \
   580  		-e "s/@ACI_OS@/linux/" \
   581  		-e "s/@ACI_ARCH@/${RKT_ACI_ARCH}/" \
   582  		-e "s/@GOOS@/linux/" \
   583  		-e "s/@GOARCH@/${RKT_ACI_ARCH}/" \
   584  		$(1) >$(2);
   585  endef
   586  
   587  # Recursive wildcard - recursively generate a list of files
   588  #
   589  # 1 - root directory
   590  # 2 - filter pattern
   591  define rwildcard
   592  $(foreach d, $(wildcard $1/*), \
   593  	$(filter $(subst *, %, $2), $d) $(call rwildcard, $d, $2))
   594  endef
   595  
   596  # Recursively list all files in a given path
   597  # This just shells out to `find`.
   598  #
   599  # 1 - the path (file or directory)
   600  define rlist-files
   601  $(strip \
   602  	$(eval _MISC_RLIST_OP1_ := $(call sq_escape,$1)) \
   603  	$(eval _MISC_RLIST_FILES_ := $(shell find $(_MISC_RLIST_OP1_) -type f)) \
   604  	$(_MISC_RLIST_FILES_))
   605  endef