8325963: Clean up NativeCompilation.gmk and its newly created parts
Reviewed-by: jwaters, erikj
This commit is contained in:
parent
4d50ee63d6
commit
1bd91cdebe
@ -25,8 +25,8 @@
|
||||
|
||||
################################################################################
|
||||
# This is the top-level entry point for our native compilation and linking.
|
||||
# It contains the SetupNativeCompilation function, but is supported by helper
|
||||
# functions in the make/common/native directory.
|
||||
# It contains the SetupNativeCompilation macro, but is supported by helper
|
||||
# macros in the make/common/native directory.
|
||||
################################################################################
|
||||
|
||||
ifndef _NATIVE_COMPILATION_GMK
|
||||
@ -129,23 +129,25 @@ include native/ToolchainDefinitions.gmk
|
||||
#
|
||||
SetupNativeCompilation = $(NamedParamsMacroTemplate)
|
||||
define SetupNativeCompilationBody
|
||||
# Setup variables for the rest of the function to work with
|
||||
$$(eval $$(call SetupBasicVariables1,$1))
|
||||
$$(eval $$(call SetupDebugSymbols,$1))
|
||||
$$(eval $$(call SetupBasicVariables2,$1))
|
||||
$$(eval $$(call VerifyArguments,$1))
|
||||
$$(eval $$(call SetupBasicVariables3,$1))
|
||||
# When reading this code, note that macros named Setup<Foo> are just setting
|
||||
# variables, and macros called Create<Foo> are setting up rules to create
|
||||
# files. Macros starting with any other verb are more complicated, and can do
|
||||
# all of the above, and also call directly to the shell.
|
||||
|
||||
# Need to make sure TARGET is first on list
|
||||
$1 := $$($1_TARGET)
|
||||
###
|
||||
### Prepare for compilation and linking
|
||||
###
|
||||
|
||||
$$(eval $$(call VerifyArguments,$1))
|
||||
|
||||
# Setup variables for the rest of this macro to work with
|
||||
$$(eval $$(call SetupBasicVariables,$1))
|
||||
|
||||
# Setup the toolchain to be used
|
||||
$$(eval $$(call SetupToolchain,$1))
|
||||
|
||||
# Figure out all source files to compile
|
||||
$$(eval $$(call LocateSourceFiles,$1))
|
||||
|
||||
# ... and what the output object files will be
|
||||
# Find all source files to compile and determine the output object file names
|
||||
$$(eval $$(call SetupSourceFiles,$1))
|
||||
$$(eval $$(call SetupOutputFiles,$1))
|
||||
|
||||
# Setup CFLAGS/CXXFLAGS based on warnings, optimizations, extra flags etc.
|
||||
@ -154,20 +156,29 @@ define SetupNativeCompilationBody
|
||||
# Machinery needed for the build to function properly
|
||||
$$(eval $$(call SetupBuildSystemSupport,$1))
|
||||
|
||||
$$(eval $$(call RemoveSuperfluousOutputFiles,$1))
|
||||
|
||||
# Need to make sure TARGET is first on list before starting to create files
|
||||
$1 := $$($1_TARGET)
|
||||
|
||||
# Have make print information about the library when we start compiling
|
||||
$$(eval $$(call PrintStartInfo,$1))
|
||||
|
||||
###
|
||||
### Compile all native source code files
|
||||
###
|
||||
|
||||
# Create a PCH, if requested
|
||||
$$(eval $$(call CreatePrecompiledHeader,$1))
|
||||
|
||||
# Now call SetupCompileNativeFile for each source file we are going to compile.
|
||||
# Now call CreateCompiledNativeFile for each source file we are going to compile.
|
||||
$$(foreach file, $$($1_SRCS), \
|
||||
$$(eval $$(call SetupCompileNativeFile,$1_$$(notdir $$(file)),\
|
||||
$$(eval $$(call CreateCompiledNativeFile,$1_$$(notdir $$(file)),\
|
||||
FILE := $$(file), \
|
||||
BASE := $1, \
|
||||
)) \
|
||||
)
|
||||
|
||||
# Have make print information about the library when we start compiling
|
||||
$$(eval $$(call PrintInfo,$1))
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
# On windows we need to create a resource file
|
||||
$$(eval $$(call CreateWindowsResourceFile,$1))
|
||||
@ -178,15 +189,16 @@ define SetupNativeCompilationBody
|
||||
$$(eval $$(call CreateDependencyFile,$1))
|
||||
$$(eval $$(call ImportDependencyFile,$1))
|
||||
|
||||
# Prepare for linking
|
||||
$$(eval $$(call SetupLinkerFlags,$1))
|
||||
|
||||
$$(eval $$(call SetupMapfile,$1))
|
||||
###
|
||||
### Link the object files into a native output library/executable
|
||||
###
|
||||
|
||||
# Handle native debug symbols
|
||||
$$(eval $$(call CreateDebugSymbols,$1))
|
||||
|
||||
$$(eval $$(call SetupStrip,$1))
|
||||
# Prepare for linking
|
||||
$$(eval $$(call SetupLinkerFlags,$1))
|
||||
$$(eval $$(call SetupLinking,$1))
|
||||
|
||||
$$(eval $$(call SetupObjectFileList,$1))
|
||||
|
||||
@ -200,8 +212,30 @@ define SetupNativeCompilationBody
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
# Setup basic variables, part 1
|
||||
define SetupBasicVariables1
|
||||
# Verify that user passed arguments are valid
|
||||
define VerifyArguments
|
||||
ifneq ($$($1_NAME), $(basename $$($1_NAME)))
|
||||
$$(error NAME must not contain any directory path in $1)
|
||||
endif
|
||||
ifneq ($(findstring $$($1_SUFFIX), $$($1_NAME)), )
|
||||
$$(error NAME should be specified without suffix: $$($1_SUFFIX) in $1)
|
||||
endif
|
||||
ifneq ($(findstring $$($1_PREFIX), $$($1_NAME)), )
|
||||
$$(error NAME should be specified without prefix: $$($1_PREFIX) in $1)
|
||||
endif
|
||||
ifeq ($$($1_OUTPUT_DIR), )
|
||||
$$(error OUTPUT_DIR is missing in $1)
|
||||
endif
|
||||
ifneq ($$($1_MANIFEST), )
|
||||
ifeq ($$($1_MANIFEST_VERSION), )
|
||||
$$(error If MANIFEST is provided, then MANIFEST_VERSION is required in $1)
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
# Setup basic variables
|
||||
define SetupBasicVariables
|
||||
# If type is unspecified, default to LIBRARY
|
||||
ifeq ($$($1_TYPE), )
|
||||
$1_TYPE := LIBRARY
|
||||
@ -214,11 +248,7 @@ define SetupBasicVariables1
|
||||
$1_TYPE := STATIC_LIBRARY
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
# Setup basic variables, part 2
|
||||
define SetupBasicVariables2
|
||||
# STATIC_LIBS is set from Main.gmk when building static versions of certain
|
||||
# native libraries.
|
||||
ifeq ($(STATIC_LIBS), true)
|
||||
@ -247,33 +277,7 @@ define SetupBasicVariables2
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
# Verify that user passed arguments are valid
|
||||
define VerifyArguments
|
||||
ifneq ($$($1_NAME), $(basename $$($1_NAME)))
|
||||
$$(error NAME must not contain any directory path in $1)
|
||||
endif
|
||||
ifneq ($(findstring $$($1_SUFFIX), $$($1_NAME)), )
|
||||
$$(error NAME should be specified without suffix: $$($1_SUFFIX) in $1)
|
||||
endif
|
||||
ifneq ($(findstring $$($1_PREFIX), $$($1_NAME)), )
|
||||
$$(error NAME should be specified without prefix: $$($1_PREFIX) in $1)
|
||||
endif
|
||||
ifeq ($$($1_OUTPUT_DIR), )
|
||||
$$(error OUTPUT_DIR is missing in $1)
|
||||
endif
|
||||
ifneq ($$($1_MANIFEST), )
|
||||
ifeq ($$($1_MANIFEST_VERSION), )
|
||||
$$(error If MANIFEST is provided, then MANIFEST_VERSION is required in $1)
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
# Setup basic variables, part 3
|
||||
define SetupBasicVariables3
|
||||
$1_BASENAME := $$($1_PREFIX)$$($1_NAME)$$($1_SUFFIX)
|
||||
$1_TARGET := $$($1_OUTPUT_DIR)/$$($1_BASENAME)
|
||||
$1_NOSUFFIX := $$($1_PREFIX)$$($1_NAME)
|
||||
@ -283,8 +287,6 @@ endef
|
||||
################################################################################
|
||||
# Setup machinery needed by the build system
|
||||
define SetupBuildSystemSupport
|
||||
$1_BUILD_INFO := $$($1_OBJECT_DIR)/_build-info.marker
|
||||
|
||||
# Track variable changes for all variables that affect the compilation command
|
||||
# lines for all object files in this setup. This includes at least all the
|
||||
# variables used in the call to add_native_source below.
|
||||
@ -297,13 +299,15 @@ endef
|
||||
|
||||
################################################################################
|
||||
# Have make print information about the library when we start compiling
|
||||
define PrintInfo
|
||||
define PrintStartInfo
|
||||
# Setup rule for printing progress info when compiling source files.
|
||||
# This is a rough heuristic and may not always print accurate information.
|
||||
# The $1_BUILD_INFO and $1_BUILD_INFO_DEPS variables are used in
|
||||
# TestFilesCompilation.gmk.
|
||||
$$(call SetIfEmpty, $1_BUILD_INFO_LOG_MACRO, LogWarn)
|
||||
$1_BUILD_INFO_DEPS := $$($1_SRCS) $$($1_COMPILE_VARDEPS_FILE)
|
||||
$1_BUILD_INFO := $$($1_OBJECT_DIR)/_build-info.marker
|
||||
|
||||
$$($1_BUILD_INFO): $$($1_BUILD_INFO_DEPS)
|
||||
ifeq ($$(wildcard $$($1_TARGET)), )
|
||||
$$(call $$($1_BUILD_INFO_LOG_MACRO), \
|
||||
|
@ -100,8 +100,8 @@ DEPENDENCY_TARGET_SED_PATTERN := \
|
||||
# FILE - The full path of the source file to compiler
|
||||
# BASE - The name of the rule for the entire binary to build ($1)
|
||||
#
|
||||
SetupCompileNativeFile = $(NamedParamsMacroTemplate)
|
||||
define SetupCompileNativeFileBody
|
||||
CreateCompiledNativeFile = $(NamedParamsMacroTemplate)
|
||||
define CreateCompiledNativeFileBody
|
||||
$1_FILENAME := $$(notdir $$($1_FILE))
|
||||
|
||||
# The target file to be generated.
|
||||
@ -120,7 +120,7 @@ define SetupCompileNativeFileBody
|
||||
# This is the definite source file to use for $1_FILENAME.
|
||||
$1_SRC_FILE := $$($1_FILE)
|
||||
|
||||
$$(eval $$(call SetupCompileFileFlags,$1))
|
||||
$$(eval $$(call SetupCompileFileFlags,$1,$$($1_BASE)))
|
||||
|
||||
ifneq ($$(filter %.c, $$($1_FILENAME)), )
|
||||
# Compile as a C file
|
||||
@ -250,7 +250,7 @@ define CreatePrecompiledHeader
|
||||
$1_GENERATED_PCH_SRC := $$($1_OBJECT_DIR)/$1_pch.cpp
|
||||
$1_GENERATED_PCH_OBJ := $$($1_OBJECT_DIR)/$1_pch$(OBJ_SUFFIX)
|
||||
|
||||
$$(eval $$(call SetupCompileNativeFile, $1_$$(notdir $$($1_GENERATED_PCH_SRC)), \
|
||||
$$(eval $$(call CreateCompiledNativeFile, $1_$$(notdir $$($1_GENERATED_PCH_SRC)), \
|
||||
FILE := $$($1_GENERATED_PCH_SRC), \
|
||||
BASE := $1, \
|
||||
EXTRA_CXXFLAGS := -Fp$$($1_PCH_FILE) -Yc$$(notdir $$($1_PRECOMPILED_HEADER)), \
|
||||
|
@ -26,23 +26,6 @@
|
||||
################################################################################
|
||||
# This file contains functionality related to native debug symbol handling.
|
||||
|
||||
################################################################################
|
||||
define SetupDebugSymbols
|
||||
$$(call SetIfEmpty, $1_COMPILE_WITH_DEBUG_SYMBOLS, $$(COMPILE_WITH_DEBUG_SYMBOLS))
|
||||
|
||||
ifeq ($(STATIC_LIBS), true)
|
||||
# For release builds where debug symbols are configured to be moved to
|
||||
# separate debuginfo files, disable debug symbols for static libs instead.
|
||||
# We don't currently support this configuration and we don't want symbol
|
||||
# information in release builds unless explicitly asked to provide it.
|
||||
ifeq ($(DEBUG_LEVEL), release)
|
||||
ifeq ($(COPY_DEBUG_SYMBOLS), true)
|
||||
$1_COMPILE_WITH_DEBUG_SYMBOLS := false
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
define CreateDebugSymbols
|
||||
ifneq ($$($1_COPY_DEBUG_SYMBOLS), false)
|
||||
|
@ -29,10 +29,12 @@
|
||||
# like optimization level.
|
||||
|
||||
################################################################################
|
||||
# $1 is the prefix of the file to be compiled
|
||||
# $2 is the prefix of the library, i.e. $$($1_BASE)
|
||||
define SetupCompileFileFlags
|
||||
ifeq ($$($1_OPTIMIZATION), )
|
||||
$1_OPT_CFLAGS := $$($$($1_BASE)_OPT_CFLAGS)
|
||||
$1_OPT_CXXFLAGS := $$($$($1_BASE)_OPT_CXXFLAGS)
|
||||
$1_OPT_CFLAGS := $$($2_OPT_CFLAGS)
|
||||
$1_OPT_CXXFLAGS := $$($2_OPT_CXXFLAGS)
|
||||
else
|
||||
ifeq ($$($1_OPTIMIZATION), NONE)
|
||||
$1_OPT_CFLAGS := $(C_O_FLAG_NONE)
|
||||
@ -57,23 +59,23 @@ define SetupCompileFileFlags
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($$($$($1_BASE)_PRECOMPILED_HEADER), )
|
||||
ifeq ($$(filter $$($1_FILENAME), $$($$($1_BASE)_PRECOMPILED_HEADER_EXCLUDE)), )
|
||||
$1_USE_PCH_FLAGS := $$($$($1_BASE)_USE_PCH_FLAGS)
|
||||
ifneq ($$($2_PRECOMPILED_HEADER), )
|
||||
ifeq ($$(filter $$($1_FILENAME), $$($2_PRECOMPILED_HEADER_EXCLUDE)), )
|
||||
$1_USE_PCH_FLAGS := $$($2_USE_PCH_FLAGS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(DISABLE_WARNING_PREFIX), )
|
||||
$1_WARNINGS_FLAGS := $$(addprefix $(DISABLE_WARNING_PREFIX), \
|
||||
$$($$($1_BASE)_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)_$$($1_FILENAME)) \
|
||||
$$($$($1_BASE)_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)_$(OPENJDK_TARGET_OS)_$$($1_FILENAME)))
|
||||
$$($2_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)_$$($1_FILENAME)) \
|
||||
$$($2_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)_$(OPENJDK_TARGET_OS)_$$($1_FILENAME)))
|
||||
endif
|
||||
|
||||
$1_BASE_CFLAGS := $$($$($1_BASE)_CFLAGS) $$($$($1_BASE)_EXTRA_CFLAGS) \
|
||||
$$($$($1_BASE)_SYSROOT_CFLAGS)
|
||||
$1_BASE_CXXFLAGS := $$($$($1_BASE)_CXXFLAGS) $$($$($1_BASE)_EXTRA_CXXFLAGS) \
|
||||
$$($$($1_BASE)_SYSROOT_CFLAGS) $$($1_EXTRA_CXXFLAGS)
|
||||
$1_BASE_ASFLAGS := $$($$($1_BASE)_ASFLAGS) $$($$($1_BASE)_EXTRA_ASFLAGS)
|
||||
$1_BASE_CFLAGS := $$($2_CFLAGS) $$($2_EXTRA_CFLAGS) \
|
||||
$$($2_SYSROOT_CFLAGS)
|
||||
$1_BASE_CXXFLAGS := $$($2_CXXFLAGS) $$($2_EXTRA_CXXFLAGS) \
|
||||
$$($2_SYSROOT_CFLAGS) $$($1_EXTRA_CXXFLAGS)
|
||||
$1_BASE_ASFLAGS := $$($2_ASFLAGS) $$($2_EXTRA_ASFLAGS)
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
@ -129,6 +131,20 @@ define SetupCompilerFlags
|
||||
$1_EXTRA_CXXFLAGS := $$($1_EXTRA_CFLAGS)
|
||||
endif
|
||||
|
||||
$$(call SetIfEmpty, $1_COMPILE_WITH_DEBUG_SYMBOLS, $$(COMPILE_WITH_DEBUG_SYMBOLS))
|
||||
|
||||
ifeq ($(STATIC_LIBS), true)
|
||||
# For release builds where debug symbols are configured to be moved to
|
||||
# separate debuginfo files, disable debug symbols for static libs instead.
|
||||
# We don't currently support this configuration and we don't want symbol
|
||||
# information in release builds unless explicitly asked to provide it.
|
||||
ifeq ($(DEBUG_LEVEL), release)
|
||||
ifeq ($(COPY_DEBUG_SYMBOLS), true)
|
||||
$1_COMPILE_WITH_DEBUG_SYMBOLS := false
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($$($1_COMPILE_WITH_DEBUG_SYMBOLS), true)
|
||||
$1_EXTRA_CFLAGS += $$(CFLAGS_DEBUG_SYMBOLS)
|
||||
$1_EXTRA_CXXFLAGS += $$(CFLAGS_DEBUG_SYMBOLS)
|
||||
|
@ -27,51 +27,19 @@
|
||||
# This file contains functionality related to linking a native binary;
|
||||
# creating either a dynamic library, a static library or an executable.
|
||||
|
||||
################################################################################
|
||||
# Create exported symbols file for static libraries
|
||||
################################################################################
|
||||
|
||||
# get the exported symbols from mapfiles and if there
|
||||
# is no mapfile, get them from the archive
|
||||
define GetSymbols
|
||||
$(RM) $$(@D)/$$(basename $$(@F)).symbols; \
|
||||
if [ ! -z $$($1_MAPFILE) -a -e $$($1_MAPFILE) ]; then \
|
||||
$(ECHO) "Getting symbols from mapfile $$($1_MAPFILE)"; \
|
||||
$(AWK) '/global:/','/local:/' $$($1_MAPFILE) | \
|
||||
$(SED) -e 's/#.*//;s/global://;s/local://;s/\;//;s/^[ ]*/_/;/^_$$$$/d' | \
|
||||
$(EGREP) -v "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" > \
|
||||
$$(@D)/$$(basename $$(@F)).symbols || true; \
|
||||
$(NM) $(NMFLAGS) $$($1_TARGET) | $(GREP) " T " | \
|
||||
$(EGREP) "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" | \
|
||||
$(CUT) -d ' ' -f 3 >> $$(@D)/$$(basename $$(@F)).symbols || true;\
|
||||
else \
|
||||
$(ECHO) "Getting symbols from nm"; \
|
||||
$(NM) $(NMFLAGS) -m $$($1_TARGET) | $(GREP) "__TEXT" | \
|
||||
$(EGREP) -v "non-external|private extern|__TEXT,__eh_frame" | \
|
||||
$(SED) -e 's/.* //' > $$(@D)/$$(basename $$(@F)).symbols; \
|
||||
fi
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
# GetEntitlementsFile
|
||||
# Find entitlements file for executable when signing on macosx. If no
|
||||
# specialized file is found, returns the default file.
|
||||
# $1 Executable to find entitlements file for.
|
||||
ENTITLEMENTS_DIR := $(TOPDIR)/make/data/macosxsigning
|
||||
ifeq ($(MACOSX_CODESIGN_MODE), debug)
|
||||
CODESIGN_PLIST_SUFFIX := -debug
|
||||
else
|
||||
CODESIGN_PLIST_SUFFIX :=
|
||||
endif
|
||||
DEFAULT_ENTITLEMENTS_FILE := $(ENTITLEMENTS_DIR)/default$(CODESIGN_PLIST_SUFFIX).plist
|
||||
|
||||
GetEntitlementsFile = \
|
||||
$(foreach f, $(ENTITLEMENTS_DIR)/$(strip $(notdir $1))$(CODESIGN_PLIST_SUFFIX).plist, \
|
||||
$(if $(wildcard $f), $f, $(DEFAULT_ENTITLEMENTS_FILE)) \
|
||||
)
|
||||
|
||||
################################################################################
|
||||
define SetupMapfile
|
||||
define SetupLinking
|
||||
ifneq ($(DISABLE_MAPFILES), true)
|
||||
$1_REAL_MAPFILE := $$($1_MAPFILE)
|
||||
endif
|
||||
@ -79,10 +47,7 @@ define SetupMapfile
|
||||
ifneq ($$($1_REAL_MAPFILE), )
|
||||
$1_EXTRA_LDFLAGS += $(call SET_SHARED_LIBRARY_MAPFILE,$$($1_REAL_MAPFILE))
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
define SetupStrip
|
||||
# Unless specifically set, stripping should only happen if symbols are also
|
||||
# being copied.
|
||||
$$(call SetIfEmpty, $1_STRIP_SYMBOLS, $$($1_COPY_DEBUG_SYMBOLS))
|
||||
@ -94,44 +59,60 @@ define SetupStrip
|
||||
$1_STRIP_CMD := $$($1_STRIP) $$($1_STRIPFLAGS) $$($1_TARGET)
|
||||
endif
|
||||
endif
|
||||
|
||||
ENTITLEMENTS_DIR := $(TOPDIR)/make/data/macosxsigning
|
||||
ifeq ($(MACOSX_CODESIGN_MODE), debug)
|
||||
CODESIGN_PLIST_SUFFIX := -debug
|
||||
else
|
||||
CODESIGN_PLIST_SUFFIX :=
|
||||
endif
|
||||
DEFAULT_ENTITLEMENTS_FILE := $$(ENTITLEMENTS_DIR)/default$$(CODESIGN_PLIST_SUFFIX).plist
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
define CreateLinkedResult
|
||||
ifeq ($$($1_TYPE), STATIC_LIBRARY)
|
||||
# Include partial linking when building the static library with clang on linux.
|
||||
ifeq ($(call isTargetOs, linux), true)
|
||||
ifneq ($(findstring $(TOOLCHAIN_TYPE), clang), )
|
||||
$1_ENABLE_PARTIAL_LINKING := true
|
||||
endif
|
||||
$$(eval $$(call CreateStaticLibrary,$1))
|
||||
else
|
||||
$$(eval $$(call CreateDynamicLibraryOrExecutable,$1))
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
define CreateStaticLibrary
|
||||
# Include partial linking when building the static library with clang on linux.
|
||||
ifeq ($(call isTargetOs, linux), true)
|
||||
ifneq ($(findstring $(TOOLCHAIN_TYPE), clang), )
|
||||
$1_ENABLE_PARTIAL_LINKING := true
|
||||
endif
|
||||
endif
|
||||
|
||||
$1_VARDEPS := $$($1_AR) $$(ARFLAGS) $$($1_ARFLAGS) $$($1_LIBS) \
|
||||
$$($1_EXTRA_LIBS)
|
||||
ifeq ($$($1_ENABLE_PARTIAL_LINKING), true)
|
||||
$1_VARDEPS += $$($1_LD) $$($1_SYSROOT_LDFLAGS)
|
||||
$1_VARDEPS := $$($1_AR) $$(ARFLAGS) $$($1_ARFLAGS) $$($1_LIBS) \
|
||||
$$($1_EXTRA_LIBS)
|
||||
ifeq ($$($1_ENABLE_PARTIAL_LINKING), true)
|
||||
$1_VARDEPS += $$($1_LD) $$($1_SYSROOT_LDFLAGS)
|
||||
endif
|
||||
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
|
||||
$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).vardeps)
|
||||
|
||||
# Generating a static library, ie object file archive.
|
||||
ifeq ($(STATIC_BUILD), true)
|
||||
ifeq ($$($1_USE_MAPFILE_FOR_SYMBOLS), true)
|
||||
STATIC_MAPFILE_DEP := $$($1_MAPFILE)
|
||||
endif
|
||||
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
|
||||
$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).vardeps)
|
||||
endif
|
||||
|
||||
# Generating a static library, ie object file archive.
|
||||
ifeq ($(STATIC_BUILD), true)
|
||||
ifeq ($$($1_USE_MAPFILE_FOR_SYMBOLS), true)
|
||||
STATIC_MAPFILE_DEP := $$($1_MAPFILE)
|
||||
endif
|
||||
endif
|
||||
$1_TARGET_DEPS := $$($1_ALL_OBJS) $$($1_RES) $$($1_VARDEPS_FILE) $$(STATIC_MAPFILE_DEP)
|
||||
|
||||
$1_TARGET_DEPS := $$($1_ALL_OBJS) $$($1_RES) $$($1_VARDEPS_FILE) $$(STATIC_MAPFILE_DEP)
|
||||
$1_AR_OBJ_ARG := $$($1_LD_OBJ_ARG)
|
||||
# With clang on linux, partial linking is enabled and 'AR' takes the output
|
||||
# object from the partial linking step.
|
||||
ifeq ($$($1_ENABLE_PARTIAL_LINKING), true)
|
||||
$1_TARGET_RELOCATABLE := $$($1_OBJECT_DIR)/$$($1_PREFIX)$$($1_NAME)_relocatable$(OBJ_SUFFIX)
|
||||
$1_AR_OBJ_ARG := $$($1_TARGET_RELOCATABLE)
|
||||
endif
|
||||
|
||||
$1_AR_OBJ_ARG := $$($1_LD_OBJ_ARG)
|
||||
# With clang on linux, partial linking is enabled and 'AR' takes the output
|
||||
# object from the partial linking step.
|
||||
ifeq ($$($1_ENABLE_PARTIAL_LINKING), true)
|
||||
$1_TARGET_RELOCATABLE := $$($1_OBJECT_DIR)/$$($1_PREFIX)$$($1_NAME)_relocatable$(OBJ_SUFFIX)
|
||||
$1_AR_OBJ_ARG := $$($1_TARGET_RELOCATABLE)
|
||||
endif
|
||||
|
||||
$$($1_TARGET): $$($1_TARGET_DEPS)
|
||||
$$($1_TARGET): $$($1_TARGET_DEPS)
|
||||
ifneq ($$($1_OBJ_FILE_LIST), )
|
||||
ifeq ($$($1_LINK_OBJS_RELATIVE), true)
|
||||
$$(eval $$(call ListPathsSafely, $1_ALL_OBJS_RELATIVE, $$($1_OBJ_FILE_LIST)))
|
||||
@ -147,7 +128,7 @@ define CreateLinkedResult
|
||||
$(if $$($1_LINK_OBJS_RELATIVE), $$(CD) $$(OUTPUTDIR) ; ) \
|
||||
$$($1_LD) $(LDFLAGS_CXX_PARTIAL_LINKING) $$($1_SYSROOT_LDFLAGS) \
|
||||
$(LD_OUT_OPTION)$$($1_TARGET_RELOCATABLE) \
|
||||
$$($1_LD_OBJ_ARG))
|
||||
$$($1_LD_OBJ_ARG))
|
||||
endif
|
||||
$$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
|
||||
$(if $$($1_LINK_OBJS_RELATIVE), $$(CD) $$(OUTPUTDIR) ; ) \
|
||||
@ -157,106 +138,124 @@ define CreateLinkedResult
|
||||
ifeq ($$($1_USE_MAPFILE_FOR_SYMBOLS), true)
|
||||
$(CP) $$($1_MAPFILE) $$(@D)/$$(basename $$(@F)).symbols
|
||||
else
|
||||
$(GetSymbols)
|
||||
# get the exported symbols from mapfiles and if there
|
||||
# is no mapfile, get them from the archive
|
||||
$(RM) $$(@D)/$$(basename $$(@F)).symbols; \
|
||||
if [ ! -z $$($1_MAPFILE) -a -e $$($1_MAPFILE) ]; then \
|
||||
$(ECHO) "Getting symbols from mapfile $$($1_MAPFILE)"; \
|
||||
$(AWK) '/global:/','/local:/' $$($1_MAPFILE) | \
|
||||
$(SED) -e 's/#.*//;s/global://;s/local://;s/\;//;s/^[ ]*/_/;/^_$$$$/d' | \
|
||||
$(EGREP) -v "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" > \
|
||||
$$(@D)/$$(basename $$(@F)).symbols || true; \
|
||||
$(NM) $(NMFLAGS) $$($1_TARGET) | $(GREP) " T " | \
|
||||
$(EGREP) "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" | \
|
||||
$(CUT) -d ' ' -f 3 >> $$(@D)/$$(basename $$(@F)).symbols || true;\
|
||||
else \
|
||||
$(ECHO) "Getting symbols from nm"; \
|
||||
$(NM) $(NMFLAGS) -m $$($1_TARGET) | $(GREP) "__TEXT" | \
|
||||
$(EGREP) -v "non-external|private extern|__TEXT,__eh_frame" | \
|
||||
$(SED) -e 's/.* //' > $$(@D)/$$(basename $$(@F)).symbols; \
|
||||
fi
|
||||
endif
|
||||
endif
|
||||
else
|
||||
# A shared dynamic library or an executable binary has been specified
|
||||
ifeq ($$($1_TYPE), LIBRARY)
|
||||
# Generating a dynamic library.
|
||||
$1_EXTRA_LDFLAGS += $$(call SET_SHARED_LIBRARY_NAME,$$($1_BASENAME))
|
||||
|
||||
# Create loadmap on AIX. Helps in diagnosing some problems.
|
||||
ifneq ($(COMPILER_BINDCMD_FILE_FLAG), )
|
||||
$1_EXTRA_LDFLAGS += $(COMPILER_BINDCMD_FILE_FLAG)$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).loadmap
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
ifeq ($$($1_EMBED_MANIFEST), true)
|
||||
$1_EXTRA_LDFLAGS += -manifest:embed
|
||||
endif
|
||||
|
||||
$1_IMPORT_LIBRARY := $$($1_OBJECT_DIR)/$$($1_NAME).lib
|
||||
$1_EXTRA_LDFLAGS += "-implib:$$($1_IMPORT_LIBRARY)"
|
||||
ifeq ($$($1_TYPE), LIBRARY)
|
||||
# To properly trigger downstream dependants of the import library, just as
|
||||
# for debug files, we must have a recipe in the rule. To avoid rerunning
|
||||
# the recipe every time have it touch the target. If an import library
|
||||
# file is deleted by something external, explicitly delete the target to
|
||||
# trigger a rebuild of both.
|
||||
ifneq ($$(wildcard $$($1_IMPORT_LIBRARY)), $$($1_IMPORT_LIBRARY))
|
||||
$$(call LogDebug, Deleting $$($1_BASENAME) because import library is missing)
|
||||
$$(shell $(RM) $$($1_TARGET))
|
||||
endif
|
||||
$$($1_IMPORT_LIBRARY): $$($1_TARGET)
|
||||
$(TOUCH) $$@
|
||||
|
||||
$1 += $$($1_IMPORT_LIBRARY)
|
||||
endif
|
||||
endif
|
||||
|
||||
$1_VARDEPS := $$($1_LD) $$($1_SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) \
|
||||
$$($1_LIBS) $$($1_EXTRA_LIBS) $$($1_MT) \
|
||||
$$($1_CREATE_DEBUGINFO_CMDS) $$($1_MANIFEST_VERSION) \
|
||||
$$($1_STRIP_CMD) $$($1_CREATE_DEBUGLINK_CMDS)
|
||||
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
|
||||
$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).vardeps)
|
||||
|
||||
$1_TARGET_DEPS := $$($1_ALL_OBJS) $$($1_RES) $$($1_MANIFEST) \
|
||||
$$($1_REAL_MAPFILE) $$($1_VARDEPS_FILE)
|
||||
|
||||
$$($1_TARGET): $$($1_TARGET_DEPS)
|
||||
ifneq ($$($1_OBJ_FILE_LIST), )
|
||||
ifeq ($$($1_LINK_OBJS_RELATIVE), true)
|
||||
$$(eval $$(call ListPathsSafely, $1_ALL_OBJS_RELATIVE, $$($1_OBJ_FILE_LIST)))
|
||||
else
|
||||
$$(eval $$(call ListPathsSafely, $1_ALL_OBJS, $$($1_OBJ_FILE_LIST)))
|
||||
endif
|
||||
endif
|
||||
# Keep as much as possible on one execution line for best performance
|
||||
# on Windows
|
||||
$$(call LogInfo, Linking $$($1_BASENAME))
|
||||
$$(call MakeDir, $$($1_OUTPUT_DIR) $$($1_SYMBOLS_DIR))
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
|
||||
$$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
|
||||
$$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
|
||||
$(LD_OUT_OPTION)$$($1_TARGET) $$($1_LD_OBJ_ARG) $$($1_RES) \
|
||||
$$($1_LIBS) $$($1_EXTRA_LIBS)) \
|
||||
| $(GREP) -v "^ Creating library .*\.lib and object .*\.exp" || \
|
||||
test "$$$$?" = "1" ; \
|
||||
$$($1_CREATE_DEBUGINFO_CMDS)
|
||||
$$($1_STRIP_CMD)
|
||||
$$($1_CREATE_DEBUGLINK_CMDS)
|
||||
ifeq ($(call isBuildOsEnv, windows.wsl2), true)
|
||||
$$(CHMOD) +x $$($1_TARGET)
|
||||
endif
|
||||
else
|
||||
$$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
|
||||
$$(if $$($1_LINK_OBJS_RELATIVE), $$(CD) $$(OUTPUTDIR) ; ) \
|
||||
$$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
|
||||
$(LD_OUT_OPTION)$$($1_TARGET) $$($1_LD_OBJ_ARG) $$($1_RES) \
|
||||
$$($1_LIBS) $$($1_EXTRA_LIBS)) ; \
|
||||
$$($1_CREATE_DEBUGINFO_CMDS)
|
||||
$$($1_STRIP_CMD)
|
||||
$$($1_CREATE_DEBUGLINK_CMDS)
|
||||
endif
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
ifneq ($$($1_MANIFEST), )
|
||||
$$($1_MT) -nologo -manifest $$($1_MANIFEST) -identity:"$$($1_NAME).exe, version=$$($1_MANIFEST_VERSION)" -outputresource:$$@;#1
|
||||
endif
|
||||
endif
|
||||
# On macosx, optionally run codesign on every binary.
|
||||
# Remove signature explicitly first to avoid warnings if the linker
|
||||
# added a default adhoc signature.
|
||||
ifeq ($(MACOSX_CODESIGN_MODE), hardened)
|
||||
$(CODESIGN) --remove-signature $$@
|
||||
$(CODESIGN) -f -s "$(MACOSX_CODESIGN_IDENTITY)" --timestamp --options runtime \
|
||||
--entitlements $$(call GetEntitlementsFile, $$@) $$@
|
||||
else ifeq ($(MACOSX_CODESIGN_MODE), debug)
|
||||
$(CODESIGN) --remove-signature $$@
|
||||
$(CODESIGN) -f -s - --entitlements $$(call GetEntitlementsFile, $$@) $$@
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
################################################################################
|
||||
define CreateDynamicLibraryOrExecutable
|
||||
# A shared dynamic library or an executable binary has been specified
|
||||
ifeq ($$($1_TYPE), LIBRARY)
|
||||
# Generating a dynamic library.
|
||||
$1_EXTRA_LDFLAGS += $$(call SET_SHARED_LIBRARY_NAME,$$($1_BASENAME))
|
||||
|
||||
# Create loadmap on AIX. Helps in diagnosing some problems.
|
||||
ifneq ($(COMPILER_BINDCMD_FILE_FLAG), )
|
||||
$1_EXTRA_LDFLAGS += $(COMPILER_BINDCMD_FILE_FLAG)$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).loadmap
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
ifeq ($$($1_EMBED_MANIFEST), true)
|
||||
$1_EXTRA_LDFLAGS += -manifest:embed
|
||||
endif
|
||||
|
||||
$1_IMPORT_LIBRARY := $$($1_OBJECT_DIR)/$$($1_NAME).lib
|
||||
$1_EXTRA_LDFLAGS += "-implib:$$($1_IMPORT_LIBRARY)"
|
||||
ifeq ($$($1_TYPE), LIBRARY)
|
||||
# To properly trigger downstream dependants of the import library, just as
|
||||
# for debug files, we must have a recipe in the rule. To avoid rerunning
|
||||
# the recipe every time have it touch the target. If an import library
|
||||
# file is deleted by something external, explicitly delete the target to
|
||||
# trigger a rebuild of both.
|
||||
ifneq ($$(wildcard $$($1_IMPORT_LIBRARY)), $$($1_IMPORT_LIBRARY))
|
||||
$$(call LogDebug, Deleting $$($1_BASENAME) because import library is missing)
|
||||
$$(shell $(RM) $$($1_TARGET))
|
||||
endif
|
||||
$$($1_IMPORT_LIBRARY): $$($1_TARGET)
|
||||
$(TOUCH) $$@
|
||||
|
||||
$1 += $$($1_IMPORT_LIBRARY)
|
||||
endif
|
||||
endif
|
||||
|
||||
$1_VARDEPS := $$($1_LD) $$($1_SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) \
|
||||
$$($1_LIBS) $$($1_EXTRA_LIBS) $$($1_MT) \
|
||||
$$($1_CREATE_DEBUGINFO_CMDS) $$($1_MANIFEST_VERSION) \
|
||||
$$($1_STRIP_CMD) $$($1_CREATE_DEBUGLINK_CMDS)
|
||||
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
|
||||
$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).vardeps)
|
||||
|
||||
$1_TARGET_DEPS := $$($1_ALL_OBJS) $$($1_RES) $$($1_MANIFEST) \
|
||||
$$($1_REAL_MAPFILE) $$($1_VARDEPS_FILE)
|
||||
|
||||
$$($1_TARGET): $$($1_TARGET_DEPS)
|
||||
ifneq ($$($1_OBJ_FILE_LIST), )
|
||||
ifeq ($$($1_LINK_OBJS_RELATIVE), true)
|
||||
$$(eval $$(call ListPathsSafely, $1_ALL_OBJS_RELATIVE, $$($1_OBJ_FILE_LIST)))
|
||||
else
|
||||
$$(eval $$(call ListPathsSafely, $1_ALL_OBJS, $$($1_OBJ_FILE_LIST)))
|
||||
endif
|
||||
endif
|
||||
# Keep as much as possible on one execution line for best performance
|
||||
# on Windows
|
||||
$$(call LogInfo, Linking $$($1_BASENAME))
|
||||
$$(call MakeDir, $$($1_OUTPUT_DIR) $$($1_SYMBOLS_DIR))
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
$$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
|
||||
$$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
|
||||
$(LD_OUT_OPTION)$$($1_TARGET) $$($1_LD_OBJ_ARG) $$($1_RES) \
|
||||
$$($1_LIBS) $$($1_EXTRA_LIBS)) \
|
||||
| $(GREP) -v "^ Creating library .*\.lib and object .*\.exp" || \
|
||||
test "$$$$?" = "1" ; \
|
||||
$$($1_CREATE_DEBUGINFO_CMDS)
|
||||
$$($1_STRIP_CMD)
|
||||
$$($1_CREATE_DEBUGLINK_CMDS)
|
||||
ifeq ($(call isBuildOsEnv, windows.wsl2), true)
|
||||
$$(CHMOD) +x $$($1_TARGET)
|
||||
endif
|
||||
else
|
||||
$$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
|
||||
$$(if $$($1_LINK_OBJS_RELATIVE), $$(CD) $$(OUTPUTDIR) ; ) \
|
||||
$$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
|
||||
$(LD_OUT_OPTION)$$($1_TARGET) $$($1_LD_OBJ_ARG) $$($1_RES) \
|
||||
$$($1_LIBS) $$($1_EXTRA_LIBS)) ; \
|
||||
$$($1_CREATE_DEBUGINFO_CMDS)
|
||||
$$($1_STRIP_CMD)
|
||||
$$($1_CREATE_DEBUGLINK_CMDS)
|
||||
endif
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
ifneq ($$($1_MANIFEST), )
|
||||
$$($1_MT) -nologo -manifest $$($1_MANIFEST) -identity:"$$($1_NAME).exe, version=$$($1_MANIFEST_VERSION)" -outputresource:$$@;#1
|
||||
endif
|
||||
endif
|
||||
# On macosx, optionally run codesign on every binary.
|
||||
# Remove signature explicitly first to avoid warnings if the linker
|
||||
# added a default adhoc signature.
|
||||
ifeq ($(MACOSX_CODESIGN_MODE), hardened)
|
||||
$(CODESIGN) --remove-signature $$@
|
||||
$(CODESIGN) -f -s "$(MACOSX_CODESIGN_IDENTITY)" --timestamp --options runtime \
|
||||
--entitlements $$(call GetEntitlementsFile, $$@) $$@
|
||||
else ifeq ($(MACOSX_CODESIGN_MODE), debug)
|
||||
$(CODESIGN) --remove-signature $$@
|
||||
$(CODESIGN) -f -s - --entitlements $$(call GetEntitlementsFile, $$@) $$@
|
||||
endif
|
||||
endef
|
||||
|
@ -113,7 +113,7 @@ else
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
define LocateSourceFiles
|
||||
define SetupSourceFiles
|
||||
$$(foreach d, $$($1_SRC), $$(if $$(wildcard $$d), , \
|
||||
$$(error SRC specified to SetupNativeCompilation $1 contains missing directory $$d)))
|
||||
|
||||
@ -143,10 +143,7 @@ define LocateSourceFiles
|
||||
$1_INCLUDE_FILES_PAT := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_INCLUDE_FILES)))
|
||||
$1_SRCS := $$(filter $$($1_INCLUDE_FILES_PAT), $$($1_SRCS))
|
||||
endif
|
||||
# There can be only a single bin dir root, no need to foreach over the roots.
|
||||
$1_BINS := $$(wildcard $$($1_OBJECT_DIR)/*$(OBJ_SUFFIX))
|
||||
# Now we have a list of all c/c++ files to compile: $$($1_SRCS)
|
||||
# and we have a list of all existing object files: $$($1_BINS)
|
||||
|
||||
# Prepend the source/bin path to the filter expressions. Then do the filtering.
|
||||
ifneq ($$($1_INCLUDES), )
|
||||
@ -184,12 +181,6 @@ 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))
|
||||
# Are there too many object files on disk? Perhaps because some source file was removed?
|
||||
$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
|
||||
# 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)
|
||||
@ -200,6 +191,17 @@ define SetupOutputFiles
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user