make/common/Utils.gmk
changeset 53484 8c296eedfb04
parent 52186 0dac3131b0fd
child 53683 48ff68e2fe5c
child 57145 ceaa243112bd
equal deleted inserted replaced
53483:60add902a57a 53484:8c296eedfb04
       
     1 #
       
     2 # Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4 #
       
     5 # This code is free software; you can redistribute it and/or modify it
       
     6 # under the terms of the GNU General Public License version 2 only, as
       
     7 # published by the Free Software Foundation.  Oracle designates this
       
     8 # particular file as subject to the "Classpath" exception as provided
       
     9 # by Oracle in the LICENSE file that accompanied this code.
       
    10 #
       
    11 # This code is distributed in the hope that it will be useful, but WITHOUT
       
    12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14 # version 2 for more details (a copy is included in the LICENSE file that
       
    15 # accompanied this code).
       
    16 #
       
    17 # You should have received a copy of the GNU General Public License version
       
    18 # 2 along with this work; if not, write to the Free Software Foundation,
       
    19 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20 #
       
    21 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22 # or visit www.oracle.com if you need additional information or have any
       
    23 # questions.
       
    24 #
       
    25 
       
    26 ifeq (,$(_MAKEBASE_GMK))
       
    27   $(error You must include MakeBase.gmk prior to including Utils.gmk)
       
    28 endif
       
    29 
       
    30 ################################################################################
       
    31 #
       
    32 # Common utility functions
       
    33 #
       
    34 ################################################################################
       
    35 
       
    36 ### Debug functions
       
    37 
       
    38 # Prints the name and value of a variable
       
    39 PrintVar = \
       
    40     $(info $(strip $1) >$($(strip $1))<)
       
    41 
       
    42 ################################################################################
       
    43 # This macro translates $ into \$ to protect the $ from expansion in the shell.
       
    44 # To make this macro resilient against already escaped strings, first remove
       
    45 # any present escapes before escaping so that no double escapes are added.
       
    46 EscapeDollar = $(subst $$,\$$,$(subst \$$,$$,$(strip $1)))
       
    47 
       
    48 ################################################################################
       
    49 # This macro works just like EscapeDollar above, but for #.
       
    50 EscapeHash = $(subst \#,\\\#,$(subst \\\#,\#,$(strip $1)))
       
    51 
       
    52 ################################################################################
       
    53 # This macro translates $ into $$ to protect the string from make itself.
       
    54 DoubleDollar = $(subst $$,$$$$,$(strip $1))
       
    55 
       
    56 ################################################################################
       
    57 # Creates a sequence of increasing numbers (inclusive).
       
    58 # Param 1 - starting number
       
    59 # Param 2 - ending number
       
    60 sequence = \
       
    61     $(wordlist $1, $2, $(strip \
       
    62         $(eval SEQUENCE_COUNT :=) \
       
    63         $(call _sequence-do,$(strip $2))))
       
    64 
       
    65 _sequence-do = \
       
    66     $(if $(word $1, $(SEQUENCE_COUNT)),, \
       
    67       $(eval SEQUENCE_COUNT += .) \
       
    68       $(words $(SEQUENCE_COUNT)) \
       
    69       $(call _sequence-do,$1))
       
    70 
       
    71 ################################################################################
       
    72 # Replace question marks with space in string. This macro needs to be called on
       
    73 # files from CacheFind in case any of them contains space in their file name,
       
    74 # since CacheFind replaces space with ?.
       
    75 # Param 1 - String to replace in
       
    76 DecodeSpace = \
       
    77     $(subst ?,$(SPACE),$(strip $1))
       
    78 
       
    79 EncodeSpace = \
       
    80     $(subst $(SPACE),?,$(strip $1))
       
    81 
       
    82 ################################################################################
       
    83 # Assign a variable only if it is empty
       
    84 # Param 1 - Variable to assign
       
    85 # Param 2 - Value to assign
       
    86 SetIfEmpty = \
       
    87     $(if $($(strip $1)),,$(eval $(strip $1) := $2))
       
    88 
       
    89 ################################################################################
       
    90 # Take two paths and return the path of the last common directory.
       
    91 # Ex: /foo/bar/baz, /foo/bar/banan -> /foo/bar
       
    92 #     foo/bar/baz, /foo/bar -> <empty>
       
    93 #
       
    94 # The x prefix is used to preserve the presence of the initial slash
       
    95 #
       
    96 # $1 - Path to compare
       
    97 # $2 - Other path to compare
       
    98 FindCommonPathPrefix = \
       
    99     $(patsubst x%,%,$(subst $(SPACE),/,$(strip \
       
   100         $(call FindCommonPathPrefixHelper, \
       
   101             $(subst /,$(SPACE),x$(strip $1)), $(subst /,$(SPACE),x$(strip $2))) \
       
   102     )))
       
   103 
       
   104 FindCommonPathPrefixHelper = \
       
   105     $(if $(call equals, $(firstword $1), $(firstword $2)), \
       
   106       $(firstword $1) \
       
   107       $(call FindCommonPathPrefixHelper, \
       
   108           $(wordlist 2, $(words $1), $1), $(wordlist 2, $(words $2), $2) \
       
   109       ) \
       
   110     )
       
   111 
       
   112 # Convert a partial path into as many directory levels of ../, removing
       
   113 # leading and following /.
       
   114 # Ex: foo/bar/baz/ -> ../../..
       
   115 #     foo/bar -> ../..
       
   116 #     /foo -> ..
       
   117 DirToDotDot = \
       
   118     $(subst $(SPACE),/,$(foreach d, $(subst /,$(SPACE),$1),..))
       
   119 
       
   120 # Computes the relative path from a directory to a file
       
   121 # $1 - File to compute the relative path to
       
   122 # $2 - Directory to compute the relative path from
       
   123 RelativePath = \
       
   124     $(eval $1_prefix := $(call FindCommonPathPrefix, $1, $2)) \
       
   125     $(eval $1_dotdots := $(call DirToDotDot, $(patsubst $($(strip $1)_prefix)/%, %, $2))) \
       
   126     $(eval $1_suffix := $(patsubst $($(strip $1)_prefix)/%, %, $1)) \
       
   127     $($(strip $1)_dotdots)/$($(strip $1)_suffix)
       
   128 
       
   129 ################################################################################
       
   130 # Filter out duplicate sub strings while preserving order. Keeps the first occurance.
       
   131 uniq = \
       
   132     $(strip $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))))
       
   133 
       
   134 # Returns all whitespace-separated words in $2 where at least one of the
       
   135 # whitespace-separated words in $1 is a substring.
       
   136 containing = \
       
   137     $(strip \
       
   138         $(foreach v,$(strip $2),\
       
   139           $(call uniq,$(foreach p,$(strip $1),$(if $(findstring $p,$v),$v)))))
       
   140 
       
   141 # Returns all whitespace-separated words in $2 where none of the
       
   142 # whitespace-separated words in $1 is a substring.
       
   143 not-containing = \
       
   144     $(strip $(filter-out $(call containing,$1,$2),$2))
       
   145 
       
   146 # Return a list of all string elements that are duplicated in $1.
       
   147 dups = \
       
   148     $(strip $(foreach v, $(sort $1), $(if $(filter-out 1, \
       
   149         $(words $(filter $v, $1))), $v)))
       
   150 
       
   151 # String equals
       
   152 equals = \
       
   153     $(if $(strip $1)$(strip $2),$(strip \
       
   154       $(and $(findstring $(strip $1),$(strip $2)),\
       
   155         $(findstring $(strip $2),$(strip $1)))), \
       
   156       true \
       
   157     )
       
   158 
       
   159 # Remove a whole list of prefixes
       
   160 # $1 - List of prefixes
       
   161 # $2 - List of elements to process
       
   162 remove-prefixes = \
       
   163     $(strip $(if $1,$(patsubst $(firstword $1)%,%,\
       
   164       $(call remove-prefixes,$(filter-out $(firstword $1),$1),$2)),$2))
       
   165 
       
   166 # Convert the string given to upper case, without any $(shell)
       
   167 # Inspired by http://lists.gnu.org/archive/html/help-make/2013-09/msg00009.html
       
   168 uppercase_table := a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O \
       
   169     p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
       
   170 
       
   171 uppercase_internal = \
       
   172   $(if $(strip $1), $$(subst $(firstword $1), $(call uppercase_internal, \
       
   173       $(wordlist 2, $(words $1), $1), $2)), $2)
       
   174 
       
   175 # Convert a string to upper case. Works only on a-z.
       
   176 # $1 - The string to convert
       
   177 uppercase = \
       
   178   $(strip \
       
   179     $(eval uppercase_result := $(call uppercase_internal, $(uppercase_table), $1)) \
       
   180     $(uppercase_result) \
       
   181   )
       
   182 
       
   183 ################################################################################
       
   184 # Parse a multiple-keyword variable, like FOO="KEYWORD1=val1;KEYWORD2=val2;..."
       
   185 # These will be converted into a series of variables like FOO_KEYWORD1=val1,
       
   186 # FOO_KEYWORD2=val2, etc. Unknown keywords will cause an error.
       
   187 #
       
   188 # Parameter 1 is the name of the rule, and is also the name of the variable.
       
   189 #
       
   190 # Remaining parameters are named arguments. These include:
       
   191 #   SINGLE_KEYWORDS   A list of valid keywords with single string values
       
   192 #   STRING_KEYWORDS   A list of valid keywords, processed as string. This means
       
   193 #       that '%20' will be replaced by ' ' to allow for multi-word strings.
       
   194 #
       
   195 ParseKeywordVariable = $(NamedParamsMacroTemplate)
       
   196 define ParseKeywordVariableBody
       
   197   ifneq ($$($1), )
       
   198     # To preserve spaces, substitute them with a hopefully unique pattern
       
   199     # before splitting and then re-substitute spaces back.
       
   200     $1_MANGLED := $$(subst $$(SPACE),||||,$$($1))
       
   201     $$(foreach mangled_part, $$(subst ;, , $$($1_MANGLED)), \
       
   202       $$(eval mangled_part_eval := $$(call DoubleDollar, $$(mangled_part))) \
       
   203       $$(eval part := $$$$(subst ||||,$$$$(SPACE),$$$$(mangled_part_eval))) \
       
   204       $$(eval $1_NO_MATCH := true) \
       
   205       $$(foreach keyword, $$($1_SINGLE_KEYWORDS), \
       
   206         $$(eval keyword_eval := $$(call DoubleDollar, $$(keyword))) \
       
   207         $$(if $$(filter $$(keyword)=%, $$(part)), \
       
   208           $$(eval $(strip $1)_$$$$(keyword_eval) := $$$$(strip $$$$(patsubst $$$$(keyword_eval)=%, %, $$$$(part)))) \
       
   209           $$(eval $1_NO_MATCH := ) \
       
   210         ) \
       
   211       ) \
       
   212       $$(foreach keyword, $$($1_STRING_KEYWORDS), \
       
   213         $$(eval keyword_eval := $$(call DoubleDollar, $$(keyword))) \
       
   214         $$(if $$(filter $$(keyword)=%, $$(part)), \
       
   215           $$(eval $(strip $1)_$$$$(keyword_eval) := $$$$(strip $$$$(subst %20, , $$$$(patsubst $$$$(keyword_eval)=%, %, $$$$(part))))) \
       
   216           $$(eval $1_NO_MATCH := ) \
       
   217         ) \
       
   218       ) \
       
   219       $$(if $$($1_NO_MATCH), \
       
   220         $$(if $$(filter $$(part), $$($1_SINGLE_KEYWORDS) $$($1_STRING_KEYWORDS)), \
       
   221           $$(info Keyword $$(part) for $1 needs to be assigned a value.) \
       
   222         , \
       
   223           $$(info $$(part) is not a valid keyword for $1.) \
       
   224           $$(info Valid keywords: $$($1_SINGLE_KEYWORDS) $$($1_STRING_KEYWORDS).) \
       
   225         ) \
       
   226         $$(error Cannot continue) \
       
   227       ) \
       
   228     )
       
   229   endif
       
   230 endef
       
   231 
       
   232 ################################################################################
       
   233 # ShellQuote
       
   234 #
       
   235 # Quotes a string with single quotes and replaces single quotes with '\'' so
       
   236 # that the contents survives being given to the shell.
       
   237 ShellQuote = \
       
   238     $(SQUOTE)$(subst $(SQUOTE),$(SQUOTE)\$(SQUOTE)$(SQUOTE),$(strip $1))$(SQUOTE)
       
   239 
       
   240 ################################################################################
       
   241 # Find lib dir for module
       
   242 # Param 1 - module name
       
   243 FindLibDirForModule = \
       
   244     $(SUPPORT_OUTPUTDIR)/modules_libs/$(strip $1)
       
   245 
       
   246 ################################################################################
       
   247 # Find executable dir for module
       
   248 # Param 1 - module name
       
   249 FindExecutableDirForModule = \
       
   250     $(SUPPORT_OUTPUTDIR)/modules_cmds/$(strip $1)
       
   251 
       
   252 ################################################################################
       
   253 # Return a string suitable for use after a -classpath or --module-path option. It
       
   254 # will be correct and safe to use on all platforms. Arguments are given as space
       
   255 # separate classpath entries. Safe for multiple nested calls.
       
   256 # param 1 : A space separated list of classpath entries
       
   257 # The surrounding strip is needed to keep additional whitespace out
       
   258 PathList = \
       
   259   "$(subst $(SPACE),$(PATH_SEP),$(strip $(subst $(DQUOTE),,$1)))"
       
   260 
       
   261 ################################################################################
       
   262 # Check if a specified hotspot variant is being built, or at least one of a
       
   263 # list of variants. Will return 'true' or 'false'.
       
   264 # $1 - the variant to test for
       
   265 check-jvm-variant = \
       
   266   $(strip \
       
   267     $(if $(filter-out $(VALID_JVM_VARIANTS), $1), \
       
   268       $(error Internal error: Invalid variant tested: $1)) \
       
   269     $(if $(filter $1, $(JVM_VARIANTS)), true, false))
       
   270 
       
   271 ################################################################################
       
   272 # Converts a space separated list to a comma separated list.
       
   273 #
       
   274 # Replacing double-comma with a single comma is to workaround the issue with
       
   275 # some version of make on windows that doesn't substitute spaces with one comma
       
   276 # properly.
       
   277 CommaList = \
       
   278   $(strip \
       
   279       $(subst $(COMMA)$(COMMA),$(COMMA),$(subst $(SPACE),$(COMMA),$(strip $1))) \
       
   280   )
       
   281 
       
   282 ################################################################################
       
   283 # Converts a space separated list to a colon separated list.
       
   284 #
       
   285 # Replacing double-colon with a single colon is to workaround the issue with
       
   286 # some version of make on windows that doesn't substitute spaces with one colon
       
   287 # properly.
       
   288 ColonList = \
       
   289   $(strip \
       
   290       $(subst ::,:,$(subst $(SPACE),:,$(strip $1))) \
       
   291   )
       
   292 
       
   293 ################################################################################
       
   294 # Given a list of files, filters out locale specific files for translations
       
   295 # that should be excluded from this build.
       
   296 # $1 - The list of files to filter
       
   297 # $2 - The suffix of the files that should be considered (.java or .properties)
       
   298 FilterExcludedTranslations = \
       
   299   $(strip $(if $(EXCLUDE_TRANSLATIONS), \
       
   300     $(filter-out \
       
   301         $(foreach suffix, $2, \
       
   302           $(addprefix %_, $(addsuffix $(suffix), $(EXCLUDE_TRANSLATIONS))) \
       
   303         ), \
       
   304         $1 \
       
   305     ), \
       
   306     $1 \
       
   307   ))