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
################################################################################
27
# This file contains functionality related to handling paths for source files
28
# and object files. This is complicated by the fact that we usually, but not
29
# always, use absolute instead of relative paths. It is further complicated
30
# by the fact that not all tools allow inputting large lists of files as
31
# "@-files", which we normally use to avoid hitting command line length limits.
32
# Finally this file contains functionality for locating all source code files
33
# that should be included in the compilation.
35
################################################################################
36
# When absolute paths are not allowed in the output, and the compiler does not
37
# support any options to avoid it, we need to rewrite compile commands to use
38
# relative paths. By doing this, the __FILE__ macro will resolve to relative
39
# paths. The relevant input paths on the command line are the -I flags and the
40
# path to the source file itself.
42
# The macro MakeCommandRelative is used to rewrite the command line like this:
43
# 'CD $(WORKSPACE_ROOT) && <cmd>'
44
# and changes all paths in cmd to be relative to the workspace root. This only
45
# works properly if the build dir is inside the workspace root. If it's not,
46
# relative paths are still calculated, but depending on the distance between the
47
# dirs, paths in the build dir may end up as essentially absolute anyway.
49
# The fix-deps-file macro is used to adjust the contents of the generated make
50
# dependency files to contain paths compatible with make.
52
REWRITE_PATHS_RELATIVE = false
53
ifeq ($(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT)-$(FILE_MACRO_CFLAGS), false-)
54
REWRITE_PATHS_RELATIVE = true
57
# CCACHE_BASEDIR needs fix-deps-file as makefiles use absolute filenames for
58
# object files while CCACHE_BASEDIR will make ccache relativize all paths for
59
# its compiler. The compiler then produces relative dependency files.
60
# make does not know a relative and absolute filename is the same so it will
61
# ignore such dependencies. This only applies when the OUTPUTDIR is inside
64
ifneq ($(filter $(WORKSPACE_ROOT)/%, $(OUTPUTDIR)), )
65
REWRITE_PATHS_RELATIVE = true
69
ifeq ($(REWRITE_PATHS_RELATIVE), true)
70
# Need to handle -I flags as both '-Ifoo' and '-I foo'.
71
MakeCommandRelative = \
72
$(CD) $(WORKSPACE_ROOT) && \
74
$(if $(filter $(WORKSPACE_ROOT)/% $(OUTPUTDIR)/%, $o), \
75
$(call RelativePath, $o, $(WORKSPACE_ROOT)) \
77
$(if $(filter -I$(WORKSPACE_ROOT)/%, $o), \
78
-I$(call RelativePath, $(patsubst -I%, %, $o), $(WORKSPACE_ROOT)) \
85
# When compiling with relative paths, the deps file may come out with relative
86
# paths, and that path may start with './'. First remove any leading ./, then
87
# add WORKSPACE_ROOT to any line not starting with /, while allowing for
88
# leading spaces. There may also be multiple entries on the same line, so start
89
# with splitting such lines.
90
# Non GNU sed (BSD on macosx) cannot substitute in literal \n using regex.
91
# Instead use a bash escaped literal newline. To avoid having unmatched quotes
92
# ruin the ability for an editor to properly syntax highlight this file, define
93
# that newline sequence as a separate variable and add the closing quote behind
95
sed_newline := \'$$'\n''#'
98
-e 's|\([^ ]\) \{1,\}\([^\\:]\)|\1 \\$(sed_newline) \2|g' \
101
-e 's|^\([ ]*\)\./|\1|' \
102
-e '/^[ ]*[^/ ]/s|^\([ ]*\)|\1$(WORKSPACE_ROOT)/|' \
106
# By default the MakeCommandRelative macro does nothing.
107
MakeCommandRelative = $1
109
# No adjustment is needed.
115
################################################################################
116
define SetupSourceFiles
117
$$(foreach d, $$($1_SRC), $$(if $$(wildcard $$d), , \
118
$$(error SRC specified to SetupNativeCompilation $1 contains missing directory $$d)))
120
$1_SRCS_RAW := $$(call FindFiles, $$($1_SRC))
121
# Order src files according to the order of the src dirs
122
$1_SRCS := $$(foreach d, $$($1_SRC), $$(filter $$d%, $$($1_SRCS_RAW)))
123
$1_SRCS := $$(filter $$(NATIVE_SOURCE_EXTENSIONS), $$($1_SRCS))
124
# Extract the C/C++ files.
125
ifneq ($$($1_EXCLUDE_PATTERNS), )
126
# We must not match the exclude pattern against the src root(s).
127
$1_SRCS_WITHOUT_ROOTS := $$($1_SRCS)
128
$$(foreach i, $$($1_SRC), $$(eval $1_SRCS_WITHOUT_ROOTS := $$(patsubst \
129
$$i/%,%, $$($1_SRCS_WITHOUT_ROOTS))))
130
$1_ALL_EXCLUDE_FILES := $$(call containing, $$($1_EXCLUDE_PATTERNS), \
131
$$($1_SRCS_WITHOUT_ROOTS))
133
ifneq ($$($1_EXCLUDE_FILES), )
134
$1_ALL_EXCLUDE_FILES += $$($1_EXCLUDE_FILES)
136
ifneq ($$($1_ALL_EXCLUDE_FILES), )
137
$1_EXCLUDE_FILES_PAT := $$($1_ALL_EXCLUDE_FILES) \
138
$$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_ALL_EXCLUDE_FILES)))
139
$1_EXCLUDE_FILES_PAT := $$(addprefix %, $$($1_EXCLUDE_FILES_PAT))
140
$1_SRCS := $$(filter-out $$($1_EXCLUDE_FILES_PAT), $$($1_SRCS))
142
ifneq ($$($1_INCLUDE_FILES), )
143
$1_INCLUDE_FILES_PAT := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_INCLUDE_FILES)))
144
$1_SRCS := $$(filter $$($1_INCLUDE_FILES_PAT), $$($1_SRCS))
146
# Now we have a list of all c/c++ files to compile: $$($1_SRCS)
148
# Prepend the source/bin path to the filter expressions. Then do the filtering.
149
ifneq ($$($1_INCLUDES), )
150
$1_SRC_INCLUDES := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_INCLUDES))))
151
$1_SRCS := $$(filter $$($1_SRC_INCLUDES), $$($1_SRCS))
153
ifneq ($$($1_EXCLUDES), )
154
$1_SRC_EXCLUDES := $$(addsuffix /%, $$($1_EXCLUDES))
155
$1_SRC_EXCLUDES += $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_EXCLUDES))))
156
$1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES), $$($1_SRCS))
159
$1_SRCS += $$($1_EXTRA_FILES)
162
$$(error No sources found for $1 when looking inside the dirs $$($1_SRC))
165
ifeq ($$($1_TYPE), EXECUTABLE)
166
ifeq ($(UBSAN_ENABLED), true)
167
# We need to set the default options for UBSan. This needs to be included in every executable.
168
# Rather than copy and paste code to everything with a main function, we add an additional
169
# source file to every executable that exports __ubsan_default_options.
170
ifneq ($$(filter %.cpp %.cc, $$($1_SRCS)), )
171
$1_SRCS += $(TOPDIR)/make/data/ubsan/ubsan_default_options.cpp
173
$1_SRCS += $(TOPDIR)/make/data/ubsan/ubsan_default_options.c
179
################################################################################
180
define SetupOutputFiles
181
# Calculate the expected output from compiling the sources
182
$1_EXPECTED_OBJS_FILENAMES := $$(call replace_with_obj_extension, $$(notdir $$($1_SRCS)))
183
$1_EXPECTED_OBJS := $$(addprefix $$($1_OBJECT_DIR)/, $$($1_EXPECTED_OBJS_FILENAMES))
184
# Sort to remove duplicates and provide a reproducible order on the input files to the linker.
185
$1_ALL_OBJS := $$(sort $$($1_EXPECTED_OBJS) $$($1_EXTRA_OBJECT_FILES))
186
ifeq ($(STATIC_LIBS), true)
187
# Exclude the object files that match with $1_STATIC_LIB_EXCLUDE_OBJS.
188
ifneq ($$($1_STATIC_LIB_EXCLUDE_OBJS), )
189
$1_ALL_OBJS := $$(call not-containing, $$($1_STATIC_LIB_EXCLUDE_OBJS), $$($1_ALL_OBJS))
194
################################################################################
195
define RemoveSuperfluousOutputFiles
196
# Are there too many object files on disk? Perhaps because some source file was removed?
197
$1_BINS := $$(wildcard $$($1_OBJECT_DIR)/*$(OBJ_SUFFIX))
198
$1_SUPERFLOUS_OBJS := $$(sort $$(filter-out $$($1_EXPECTED_OBJS), $$($1_BINS)))
199
# Clean out the superfluous object files.
200
ifneq ($$($1_SUPERFLUOUS_OBJS), )
201
$$(shell $(RM) -f $$($1_SUPERFLUOUS_OBJS))
205
################################################################################
206
define SetupObjectFileList
207
$1_LD_OBJ_ARG := $$($1_ALL_OBJS)
209
# If there are many object files, use an @-file...
210
ifneq ($$(word 17, $$($1_ALL_OBJS)), )
211
$1_OBJ_FILE_LIST := $$($1_OBJECT_DIR)/_$1_objectfilenames.txt
212
$1_LD_OBJ_ARG := @$$($1_OBJ_FILE_LIST)
214
# If we are building static library, 'AR' on macosx/aix may not support @-file.
215
ifeq ($$($1_TYPE), STATIC_LIBRARY)
216
ifeq ($(call isTargetOs, macosx aix), true)
217
$1_LD_OBJ_ARG := `cat $$($1_OBJ_FILE_LIST)`
222
# Unfortunately the @-file trick does not work reliably when using clang.
223
# Clang does not propagate the @-file parameter to the ld sub process, but
224
# instead puts the full content on the command line. At least the llvm ld
225
# does not even support an @-file.
227
# When linking a large amount of object files, we risk hitting the limit
228
# of the command line length even on posix systems if the path length of
229
# the output dir is very long due to our use of absolute paths. To
230
# mitigate this, use paths relative to the output dir when linking over
231
# 500 files with clang and the output dir path is deep.
232
ifneq ($$(word 500, $$($1_ALL_OBJS)), )
233
ifeq ($$(TOOLCHAIN_TYPE), clang)
234
# There is no strlen function in make, but checking path depth is a
235
# reasonable approximation.
236
ifneq ($$(word 10, $$(subst /, ,$$(OUTPUTDIR))), )
237
$1_LINK_OBJS_RELATIVE := true
238
$1_ALL_OBJS_RELATIVE := $$(patsubst $$(OUTPUTDIR)/%, %, $$($1_ALL_OBJS))