2
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
3
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
26
ifeq (,$(_MAKEBASE_GMK))
27
$(error You must include MakeBase.gmk prior to including FileUtils.gmk)
30
################################################################################
32
# Common file utility functions
34
################################################################################
36
################################################################################
37
# Replace question marks with space in string. This macro needs to be called on
38
# files from FindFiles in case any of them contains space in their file name,
39
# since FindFiles replaces space with ?.
40
# Param 1 - String to replace in
42
$(subst ?,$(SPACE),$(strip $1))
45
$(subst $(SPACE),?,$(strip $1))
47
################################################################################
48
# Take two paths and return the path of the last common directory.
49
# Ex: /foo/bar/baz, /foo/bar/banan -> /foo/bar
50
# foo/bar/baz, /foo/bar -> <empty>
52
# The x prefix is used to preserve the presence of the initial slash
53
# On Windows paths are treated as case-insensitive
56
# $2 - Other path to compare
57
FindCommonPathPrefix = \
58
$(call DecodeSpace,$(patsubst x%,%,$(subst $(SPACE),/,$(strip \
59
$(call FindCommonPathPrefixHelper1, \
60
$(subst /,$(SPACE),x$(call EncodeSpace,$(strip $1))), \
61
$(subst /,$(SPACE),x$(call EncodeSpace,$(strip $2)))) \
64
FindCommonPathPrefixHelper1 = \
65
$(if $(filter $(OPENJDK_TARGET_OS), windows), \
66
$(call FindCommonPathPrefixHelper2,$(call uppercase,$1),$(call uppercase,$2),$1), \
67
$(call FindCommonPathPrefixHelper2,$1,$2,$1))
69
FindCommonPathPrefixHelper2 = \
70
$(if $(call equals, $(firstword $1), $(firstword $2)), \
71
$(if $(call equals, $(firstword $1),),, \
73
$(call FindCommonPathPrefixHelper2, \
74
$(wordlist 2, $(words $1), $1), \
75
$(wordlist 2, $(words $2), $2), \
76
$(wordlist 2, $(words $3), $3) \
81
# Computes the relative path from a directory to a file
82
# $1 - File to compute the relative path to
83
# $2 - Directory to compute the relative path from
85
$(call DecodeSpace,$(strip $(call RelativePathHelper,$(call EncodeSpace \
86
,$(strip $1)),$(call EncodeSpace \
87
,$(strip $2)),$(call EncodeSpace \
88
,$(call FindCommonPathPrefix,$1,$2)))))
91
$(eval $3_prefix_length := $(words $(subst /,$(SPACE),$3))) \
92
$(eval $1_words := $(subst /,$(SPACE),$1)) \
93
$(eval $2_words := $(subst /,$(SPACE),$2)) \
94
$(if $(call equals,$($3_prefix_length),0),, \
95
$(eval $1_words := $(wordlist 2,$(words $($1_words)),$(wordlist \
96
$($3_prefix_length),$(words $($1_words)),$($1_words)))) \
97
$(eval $2_words := $(wordlist 2,$(words $($2_words)),$(wordlist \
98
$($3_prefix_length),$(words $($2_words)),$($2_words)))) \
100
$(eval $1_suffix := $(subst $(SPACE),/,$($1_words))) \
101
$(eval $2_dotdots := $(subst $(SPACE),/,$(foreach d,$($2_words),..))) \
103
$(if $($2_dotdots), $($2_dotdots)/$($1_suffix), $($1_suffix)), \
104
$(if $($2_dotdots), $($2_dotdots), .))
106
# Make directory for target file. Should handle spaces in filenames. Just
107
# calling $(call MakeDir $(@D)) will not work if the directory contains a space
108
# and the target file already exists. In that case, the target file will have
109
# its wildcard ? resolved and the $(@D) will evaluate each space separated dir
112
$(call MakeDir, $(dir $(call EncodeSpace, $@)))
114
################################################################################
115
# All install-file and related macros automatically call DecodeSpace when needed.
117
ifeq ($(call isTargetOs, macosx), true)
118
# On mac, extended attributes sometimes creep into the source files, which may later
119
# cause the creation of ._* files which confuses testing. Clear these with xattr if
120
# set. Some files get their write permissions removed after being copied to the
121
# output dir. When these are copied again to images, xattr would fail. By only clearing
122
# attributes when they are present, failing on this is avoided.
124
# If copying a soft link to a directory, need to delete the target first to avoid
127
$(call MakeTargetDir)
128
$(RM) '$(call DecodeSpace, $@)'
129
# Work around a weirdness with cp on Macosx. When copying a symlink, if
130
# the target of the link is write protected (e.g. 444), cp will add
131
# write permission for the user on the target file (644). Avoid this by
132
# using ln to create a new link instead.
133
if [ -h '$(call DecodeSpace, $<)' ]; then \
134
$(LN) -s "`$(READLINK) '$(call DecodeSpace, $<)'`" '$(call DecodeSpace, $@)'; \
136
$(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \
138
if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then \
139
$(XATTR) -cs '$(call DecodeSpace, $@)'; \
144
$(call MakeTargetDir)
145
$(CP) -fP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
149
# Variant of install file that does not preserve symlinks
150
define install-file-nolink
151
$(call MakeTargetDir)
152
$(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
155
################################################################################
156
# link-file-* works similarly to install-file but creates a symlink instead.
157
# There are two versions, either creating a relative or an absolute link. Be
158
# careful when using this on Windows since the symlink created is only valid in
159
# the unix emulation environment.
160
# In msys2 we use mklink /J because its ln would perform a deep copy of the target.
161
# This inhibits performance and can lead to issues with long paths. With mklink /J
162
# relative linking does not work, so we handle the link as absolute path.
163
ifeq ($(OPENJDK_BUILD_OS_ENV), windows.msys2)
164
define link-file-relative
165
$(call MakeTargetDir)
166
$(RM) '$(call DecodeSpace, $@)'
167
cmd //c "mklink /J $(call FixPath, $(call DecodeSpace, $@)) $(call FixPath, $(call DecodeSpace, $<))"
170
define link-file-relative
171
$(call MakeTargetDir)
172
$(RM) '$(call DecodeSpace, $@)'
173
$(LN) -s '$(call DecodeSpace, $(call RelativePath, $<, $(@D)))' '$(call DecodeSpace, $@)'
177
ifeq ($(OPENJDK_BUILD_OS_ENV), windows.msys2)
178
define link-file-absolute
179
$(call MakeTargetDir)
180
$(RM) '$(call DecodeSpace, $@)'
181
cmd //c "mklink /J $(call FixPath, $(call DecodeSpace, $@)) $(call FixPath, $(call DecodeSpace, $<))"
184
define link-file-absolute
185
$(call MakeTargetDir)
186
$(RM) '$(call DecodeSpace, $@)'
187
$(LN) -s '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
191
################################################################################
193
# Recursive wildcard function. Walks down directories recursively and matches
194
# files with the search patterns. Patterns use standard file wildcards (* and
197
# $1 - Directories to start search in
198
# $2 - Search patterns
202
$(patsubst %/,%,$(sort $(dir $(wildcard $(addsuffix /*/*, $(strip $1)))))), \
203
$(call rwildcard,$d,$2) \
205
$(call DoubleDollar, $(wildcard $(foreach p, $2, $(addsuffix /$(strip $p), $(strip $1))))) \
208
# Find non directories using recursive wildcard function. This function may
209
# be used directly when a small amount of directories is expected to be
210
# searched and caching is not expected to be of use.
212
# $1 - Directory to start search in
213
# $2 - Optional search patterns, defaults to '*'.
216
$(eval WildcardFindFiles_result := $(call rwildcard,$(patsubst %/,%,$1),$(if $(strip $2),$2,*))) \
217
$(filter-out $(patsubst %/,%,$(sort $(dir $(WildcardFindFiles_result)))), \
218
$(WildcardFindFiles_result) \
222
# Find non directories using the find utility in the shell. Safe to call for
223
# non existing directories, or directories containing wildcards.
225
# Files containing space will get spaces replaced with ? because GNU Make
226
# cannot handle lists of files with space in them. By using ?, make will match
227
# the wildcard to space in many situations so we don't need to replace back
228
# to space on every use. While not a complete solution it does allow some uses
229
# of FindFiles to function with spaces in file names, including for
230
# SetupCopyFiles. Unfortunately this does not work for WildcardFindFiles so
231
# if files with spaces are anticipated, use ShellFindFiles directly.
233
# $1 - Directories to start search in.
234
# $2 - Optional search patterns, empty means find everything. Patterns use
235
# standard file wildcards (* and ?) and should not be quoted.
236
# $3 - Optional options to find.
238
$(if $(wildcard $1), \
240
$(shell $(FIND) $3 $(patsubst %/,%,$(wildcard $1)) \( -type f -o -type l \) \
241
$(if $(strip $2), -a \( -name "$(firstword $2)" \
242
$(foreach p, $(filter-out $(firstword $2), $2), -o -name "$(p)") \)) \
248
# Find non directories using the method most likely to work best for the
251
# $1 - Directory to start search in
252
# $2 - Optional search patterns, defaults to '*'.
253
ifeq ($(OPENJDK_BUILD_OS)-$(RWILDCARD_WORKS), windows-true)
254
DirectFindFiles = $(WildcardFindFiles)
256
DirectFindFiles = $(ShellFindFiles)
259
# Finds files using a cache that is populated by FillFindCache below. If any of
260
# the directories given have not been cached, DirectFindFiles is used for
261
# everything. Caching is especially useful in Cygwin, where file finds are very
264
# $1 - Directories to start search in.
265
# $2 - Optional search patterns. If used, no caching is done.
266
CacheFindFiles_CACHED_DIRS :=
267
CacheFindFiles_CACHED_FILES :=
270
$(call DirectFindFiles, $1, $2) \
272
$(if $(filter-out $(addsuffix /%, $(CacheFindFiles_CACHED_DIRS)) \
273
$(CacheFindFiles_CACHED_DIRS), $1), \
274
$(call DirectFindFiles, $1) \
276
$(filter $(addsuffix /%,$(patsubst %/,%,$1)) $1,$(CacheFindFiles_CACHED_FILES)) \
280
# Explicitly adds files to the find cache used by CacheFindFiles.
282
# $1 - Directories to start search in
284
$(eval CacheFindFiles_NEW_DIRS := $$(filter-out $$(addsuffix /%,\
285
$$(CacheFindFiles_CACHED_DIRS)) $$(CacheFindFiles_CACHED_DIRS), $1)) \
286
$(if $(CacheFindFiles_NEW_DIRS), \
287
$(eval CacheFindFiles_CACHED_DIRS += $$(patsubst %/,%,$$(CacheFindFiles_NEW_DIRS))) \
288
$(eval CacheFindFiles_CACHED_FILES := $$(sort $$(CacheFindFiles_CACHED_FILES) \
289
$$(call DirectFindFiles, $$(CacheFindFiles_NEW_DIRS)))) \
292
# Findfiles is the default macro that should be used to find files in the file
293
# system. This function does not always support files with spaces in the names.
294
# If files with spaces are anticipated, use ShellFindFiles directly.
296
# $1 - Directories to start search in.
297
# $2 - Optional search patterns, empty means find everything. Patterns use
298
# standard file wildcards (* and ?) and should not be quoted.
299
ifeq ($(DISABLE_CACHE_FIND), true)
300
FindFiles = $(DirectFindFiles)
302
FindFiles = $(CacheFindFiles)