107cb536e7
Reviewed-by: jwaters, erikj
243 lines
11 KiB
Plaintext
243 lines
11 KiB
Plaintext
#
|
|
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
#
|
|
# This code is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License version 2 only, as
|
|
# published by the Free Software Foundation. Oracle designates this
|
|
# particular file as subject to the "Classpath" exception as provided
|
|
# by Oracle in the LICENSE file that accompanied this code.
|
|
#
|
|
# This code is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
# version 2 for more details (a copy is included in the LICENSE file that
|
|
# accompanied this code).
|
|
#
|
|
# You should have received a copy of the GNU General Public License version
|
|
# 2 along with this work; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
#
|
|
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
# or visit www.oracle.com if you need additional information or have any
|
|
# questions.
|
|
#
|
|
|
|
################################################################################
|
|
# This file contains functionality related to handling paths for source files
|
|
# and object files. This is complicated by the fact that we usually, but not
|
|
# always, use absolute instead of relative paths. It is further complicated
|
|
# by the fact that not all tools allow inputting large lists of files as
|
|
# "@-files", which we normally use to avoid hitting command line length limits.
|
|
# Finally this file contains functionality for locating all source code files
|
|
# that should be included in the compilation.
|
|
|
|
################################################################################
|
|
# When absolute paths are not allowed in the output, and the compiler does not
|
|
# support any options to avoid it, we need to rewrite compile commands to use
|
|
# relative paths. By doing this, the __FILE__ macro will resolve to relative
|
|
# paths. The relevant input paths on the command line are the -I flags and the
|
|
# path to the source file itself.
|
|
#
|
|
# The macro MakeCommandRelative is used to rewrite the command line like this:
|
|
# 'CD $(WORKSPACE_ROOT) && <cmd>'
|
|
# and changes all paths in cmd to be relative to the workspace root. This only
|
|
# works properly if the build dir is inside the workspace root. If it's not,
|
|
# relative paths are still calculated, but depending on the distance between the
|
|
# dirs, paths in the build dir may end up as essentially absolute anyway.
|
|
#
|
|
# The fix-deps-file macro is used to adjust the contents of the generated make
|
|
# dependency files to contain paths compatible with make.
|
|
#
|
|
REWRITE_PATHS_RELATIVE = false
|
|
ifeq ($(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT)-$(FILE_MACRO_CFLAGS), false-)
|
|
REWRITE_PATHS_RELATIVE = true
|
|
endif
|
|
|
|
# CCACHE_BASEDIR needs fix-deps-file as makefiles use absolute filenames for
|
|
# object files while CCACHE_BASEDIR will make ccache relativize all paths for
|
|
# its compiler. The compiler then produces relative dependency files.
|
|
# make does not know a relative and absolute filename is the same so it will
|
|
# ignore such dependencies. This only applies when the OUTPUTDIR is inside
|
|
# the WORKSPACE_ROOT.
|
|
ifneq ($(CCACHE), )
|
|
ifneq ($(filter $(WORKSPACE_ROOT)/%, $(OUTPUTDIR)), )
|
|
REWRITE_PATHS_RELATIVE = true
|
|
endif
|
|
endif
|
|
|
|
ifeq ($(REWRITE_PATHS_RELATIVE), true)
|
|
# Need to handle -I flags as both '-Ifoo' and '-I foo'.
|
|
MakeCommandRelative = \
|
|
$(CD) $(WORKSPACE_ROOT) && \
|
|
$(foreach o, $1, \
|
|
$(if $(filter $(WORKSPACE_ROOT)/% $(OUTPUTDIR)/%, $o), \
|
|
$(call RelativePath, $o, $(WORKSPACE_ROOT)) \
|
|
, \
|
|
$(if $(filter -I$(WORKSPACE_ROOT)/%, $o), \
|
|
-I$(call RelativePath, $(patsubst -I%, %, $o), $(WORKSPACE_ROOT)) \
|
|
, \
|
|
$o \
|
|
) \
|
|
) \
|
|
)
|
|
|
|
# When compiling with relative paths, the deps file may come out with relative
|
|
# paths, and that path may start with './'. First remove any leading ./, then
|
|
# add WORKSPACE_ROOT to any line not starting with /, while allowing for
|
|
# leading spaces. There may also be multiple entries on the same line, so start
|
|
# with splitting such lines.
|
|
# Non GNU sed (BSD on macosx) cannot substitute in literal \n using regex.
|
|
# Instead use a bash escaped literal newline. To avoid having unmatched quotes
|
|
# ruin the ability for an editor to properly syntax highlight this file, define
|
|
# that newline sequence as a separate variable and add the closing quote behind
|
|
# a comment.
|
|
sed_newline := \'$$'\n''#'
|
|
define fix-deps-file
|
|
$(SED) \
|
|
-e 's|\([^ ]\) \{1,\}\([^\\:]\)|\1 \\$(sed_newline) \2|g' \
|
|
$1.tmp \
|
|
| $(SED) \
|
|
-e 's|^\([ ]*\)\./|\1|' \
|
|
-e '/^[ ]*[^/ ]/s|^\([ ]*\)|\1$(WORKSPACE_ROOT)/|' \
|
|
> $1
|
|
endef
|
|
else
|
|
# By default the MakeCommandRelative macro does nothing.
|
|
MakeCommandRelative = $1
|
|
|
|
# No adjustment is needed.
|
|
define fix-deps-file
|
|
$(MV) $1.tmp $1
|
|
endef
|
|
endif
|
|
|
|
################################################################################
|
|
define SetupSourceFiles
|
|
$$(foreach d, $$($1_SRC), $$(if $$(wildcard $$d), , \
|
|
$$(error SRC specified to SetupNativeCompilation $1 contains missing directory $$d)))
|
|
|
|
$1_SRCS_RAW := $$(call FindFiles, $$($1_SRC))
|
|
# Order src files according to the order of the src dirs
|
|
$1_SRCS := $$(foreach d, $$($1_SRC), $$(filter $$d%, $$($1_SRCS_RAW)))
|
|
$1_SRCS := $$(filter $$(NATIVE_SOURCE_EXTENSIONS), $$($1_SRCS))
|
|
# Extract the C/C++ files.
|
|
ifneq ($$($1_EXCLUDE_PATTERNS), )
|
|
# We must not match the exclude pattern against the src root(s).
|
|
$1_SRCS_WITHOUT_ROOTS := $$($1_SRCS)
|
|
$$(foreach i, $$($1_SRC), $$(eval $1_SRCS_WITHOUT_ROOTS := $$(patsubst \
|
|
$$i/%,%, $$($1_SRCS_WITHOUT_ROOTS))))
|
|
$1_ALL_EXCLUDE_FILES := $$(call containing, $$($1_EXCLUDE_PATTERNS), \
|
|
$$($1_SRCS_WITHOUT_ROOTS))
|
|
endif
|
|
ifneq ($$($1_EXCLUDE_FILES), )
|
|
$1_ALL_EXCLUDE_FILES += $$($1_EXCLUDE_FILES)
|
|
endif
|
|
ifneq ($$($1_ALL_EXCLUDE_FILES), )
|
|
$1_EXCLUDE_FILES_PAT := $$($1_ALL_EXCLUDE_FILES) \
|
|
$$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_ALL_EXCLUDE_FILES)))
|
|
$1_EXCLUDE_FILES_PAT := $$(addprefix %, $$($1_EXCLUDE_FILES_PAT))
|
|
$1_SRCS := $$(filter-out $$($1_EXCLUDE_FILES_PAT), $$($1_SRCS))
|
|
endif
|
|
ifneq ($$($1_INCLUDE_FILES), )
|
|
$1_INCLUDE_FILES_PAT := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_INCLUDE_FILES)))
|
|
$1_SRCS := $$(filter $$($1_INCLUDE_FILES_PAT), $$($1_SRCS))
|
|
endif
|
|
# Now we have a list of all c/c++ files to compile: $$($1_SRCS)
|
|
|
|
# Prepend the source/bin path to the filter expressions. Then do the filtering.
|
|
ifneq ($$($1_INCLUDES), )
|
|
$1_SRC_INCLUDES := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_INCLUDES))))
|
|
$1_SRCS := $$(filter $$($1_SRC_INCLUDES), $$($1_SRCS))
|
|
endif
|
|
ifneq ($$($1_EXCLUDES), )
|
|
$1_SRC_EXCLUDES := $$(addsuffix /%, $$($1_EXCLUDES))
|
|
$1_SRC_EXCLUDES += $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_EXCLUDES))))
|
|
$1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES), $$($1_SRCS))
|
|
endif
|
|
|
|
$1_SRCS += $$($1_EXTRA_FILES)
|
|
|
|
ifeq ($$($1_SRCS), )
|
|
$$(error No sources found for $1 when looking inside the dirs $$($1_SRC))
|
|
endif
|
|
|
|
ifeq ($$($1_TYPE), EXECUTABLE)
|
|
ifeq ($(UBSAN_ENABLED), true)
|
|
# We need to set the default options for UBSan. This needs to be included in every executable.
|
|
# Rather than copy and paste code to everything with a main function, we add an additional
|
|
# source file to every executable that exports __ubsan_default_options.
|
|
ifneq ($$(filter %.cpp %.cc, $$($1_SRCS)), )
|
|
$1_SRCS += $(TOPDIR)/make/data/ubsan/ubsan_default_options.cpp
|
|
else
|
|
$1_SRCS += $(TOPDIR)/make/data/ubsan/ubsan_default_options.c
|
|
endif
|
|
endif
|
|
endif
|
|
endef
|
|
|
|
################################################################################
|
|
define SetupOutputFiles
|
|
# Calculate the expected output from compiling the sources
|
|
$1_EXPECTED_OBJS_FILENAMES := $$(call replace_with_obj_extension, $$(notdir $$($1_SRCS)))
|
|
$1_EXPECTED_OBJS := $$(addprefix $$($1_OBJECT_DIR)/, $$($1_EXPECTED_OBJS_FILENAMES))
|
|
# Sort to remove duplicates and provide a reproducible order on the input files to the linker.
|
|
$1_ALL_OBJS := $$(sort $$($1_EXPECTED_OBJS) $$($1_EXTRA_OBJECT_FILES))
|
|
ifeq ($(STATIC_LIBS), true)
|
|
# Exclude the object files that match with $1_STATIC_LIB_EXCLUDE_OBJS.
|
|
ifneq ($$($1_STATIC_LIB_EXCLUDE_OBJS), )
|
|
$1_ALL_OBJS := $$(call not-containing, $$($1_STATIC_LIB_EXCLUDE_OBJS), $$($1_ALL_OBJS))
|
|
endif
|
|
endif
|
|
endef
|
|
|
|
################################################################################
|
|
define RemoveSuperfluousOutputFiles
|
|
# Are there too many object files on disk? Perhaps because some source file was removed?
|
|
$1_BINS := $$(wildcard $$($1_OBJECT_DIR)/*$(OBJ_SUFFIX))
|
|
$1_SUPERFLOUS_OBJS := $$(sort $$(filter-out $$($1_EXPECTED_OBJS), $$($1_BINS)))
|
|
# Clean out the superfluous object files.
|
|
ifneq ($$($1_SUPERFLUOUS_OBJS), )
|
|
$$(shell $(RM) -f $$($1_SUPERFLUOUS_OBJS))
|
|
endif
|
|
endef
|
|
|
|
################################################################################
|
|
define SetupObjectFileList
|
|
$1_LD_OBJ_ARG := $$($1_ALL_OBJS)
|
|
|
|
# If there are many object files, use an @-file...
|
|
ifneq ($$(word 17, $$($1_ALL_OBJS)), )
|
|
$1_OBJ_FILE_LIST := $$($1_OBJECT_DIR)/_$1_objectfilenames.txt
|
|
$1_LD_OBJ_ARG := @$$($1_OBJ_FILE_LIST)
|
|
|
|
# If we are building static library, 'AR' on macosx/aix may not support @-file.
|
|
ifeq ($$($1_TYPE), STATIC_LIBRARY)
|
|
ifeq ($(call isTargetOs, macosx aix), true)
|
|
$1_LD_OBJ_ARG := `cat $$($1_OBJ_FILE_LIST)`
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
# Unfortunately the @-file trick does not work reliably when using clang.
|
|
# Clang does not propagate the @-file parameter to the ld sub process, but
|
|
# instead puts the full content on the command line. At least the llvm ld
|
|
# does not even support an @-file.
|
|
#
|
|
# When linking a large amount of object files, we risk hitting the limit
|
|
# of the command line length even on posix systems if the path length of
|
|
# the output dir is very long due to our use of absolute paths. To
|
|
# mitigate this, use paths relative to the output dir when linking over
|
|
# 500 files with clang and the output dir path is deep.
|
|
ifneq ($$(word 500, $$($1_ALL_OBJS)), )
|
|
ifeq ($$(TOOLCHAIN_TYPE), clang)
|
|
# There is no strlen function in make, but checking path depth is a
|
|
# reasonable approximation.
|
|
ifneq ($$(word 10, $$(subst /, ,$$(OUTPUTDIR))), )
|
|
$1_LINK_OBJS_RELATIVE := true
|
|
$1_ALL_OBJS_RELATIVE := $$(patsubst $$(OUTPUTDIR)/%, %, $$($1_ALL_OBJS))
|
|
endif
|
|
endif
|
|
endif
|
|
endef
|