# # 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 is the top-level entry point for our native compilation and linking. # It contains the SetupNativeCompilation macro, but is supported by helper # macros in the make/common/native directory. ################################################################################ ifndef _NATIVE_COMPILATION_GMK _NATIVE_COMPILATION_GMK := 1 ifeq ($(_MAKEBASE_GMK), ) $(error You must include MakeBase.gmk prior to including NativeCompilation.gmk) endif include MakeIO.gmk include native/CompileFile.gmk include native/DebugSymbols.gmk include native/Flags.gmk include native/Link.gmk include native/LinkMicrosoft.gmk include native/Paths.gmk ################################################################################ # Setup make rules for creating a native binary (a shared library or an # executable). # # Parameter 1 is the name of the rule. This name is used as variable prefix, # and the targets generated are listed in a variable by that name. # # Remaining parameters are named arguments. These include: # NAME The base name for the resulting binary, excluding decorations (like *.exe) # TYPE Type of binary (EXECUTABLE, LIBRARY or STATIC_LIBRARY). Default is LIBRARY. # SUFFIX Override the default suffix for the output file # TARGET_TYPE The type to target, BUILD or TARGET. Defaults to TARGET. # LINK_TYPE The language to use for the linker, C or C++. Defaults to C. # SRC one or more directory roots to scan for C/C++ files. # CFLAGS the compiler flags to be used, used both for C and C++. # CXXFLAGS the compiler flags to be used for c++, if set overrides CFLAGS. # LDFLAGS the linker flags to be used, used both for C and C++. # LDFLAGS_ the linker flags to be used for the specified toolchain, # used both for C and C++. # LDFLAGS_ the linker flags to be used for the specified target OS, # used both for C and C++. # LDFLAGS__ the linker flags to be used for the specified # toolchain and target OS, used both for C and C++. # LIBS the libraries to link to # LIBS_ the libraries to link to for the specified target OS, # used both for C and C++. # LIBS_ the libraries to link to for the specified toolchain, # used both for C and C++. # LIBS__ the libraries to link to for the specified target # OS and toolchain, used both for C and C++. # OBJECT_DIR the directory where we store the object files # OUTPUT_DIR the directory where the resulting binary is put # SYMBOLS_DIR the directory where the debug symbols are put, defaults to OUTPUT_DIR # INCLUDES only pick source from these directories # EXCLUDES do not pick source from these directories # INCLUDE_FILES only compile exactly these files! # EXCLUDE_FILES with these names # EXCLUDE_PATTERN exclude files matching any of these substrings # EXTRA_FILES List of extra files not in any of the SRC dirs # EXTRA_OBJECT_FILES List of extra object files to include when linking # EXTRA_DEPS List of extra dependencies to be added to each compiled file # EXTRA_LINK_DEPS List of extra dependencies to be added to the link stage # VERSIONINFO_RESOURCE Input file for RC. Setting this implies that RC will be run # RCFLAGS flags for RC. # EMBED_MANIFEST if true, embed manifest on Windows. # CC the C compiler to use # CXX the C++ compiler to use # LD the Linker to use # AR the static linker to use # LIB the Windows lib tool to use for creating static libraries # AS the assembler to use # MT the Windows MT tool to use # RC the Windows RC tool to use # OBJCOPY the objcopy tool for debug symbol handling # STRIP the tool to use for stripping debug symbols # SYSROOT_CFLAGS the compiler flags for using the specific sysroot # SYSROOT_LDFLAGS the linker flags for using the specific sysroot # OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST, HIGHEST_JVM, SIZE # DISABLED_WARNINGS_ Disable the given warnings for the specified toolchain # DISABLED_WARNINGS__ Disable the given warnings for the specified # toolchain and target OS # DISABLED_WARNINGS_C_ Disable the given warnings for the specified toolchain # when compiling C code # DISABLED_WARNINGS_C__ Disable the given warnings for the specified # toolchain and target OS when compiling C code # DISABLED_WARNINGS_CXX_ Disable the given warnings for the specified # toolchain when compiling C++ code # DISABLED_WARNINGS_CXX__ Disable the given warnings for the specified # toolchain and target OS when compiling C++ code # DISABLED_WARNINGS__ Disable the given warnings for the specified # toolchain when compiling the file specified by filename # DISABLED_WARNINGS___ Disable the given warnings for the specified # toolchain and target OS when compiling the file specified by filename # STRIP_SYMBOLS Set to false to override global strip policy and always leave # symbols in the binary, if the toolchain allows for it # DEBUG_SYMBOLS Set to false to disable generation of debug symbols # COPY_DEBUG_SYMBOLS Set to false to override global setting of debug symbol copying # ZIP_EXTERNAL_DEBUG_SYMBOLS Set to false to override global setting of debug symbol # zipping # STRIPFLAGS Optionally change the flags given to the strip command # PRECOMPILED_HEADER Header file to use as precompiled header # PRECOMPILED_HEADER_EXCLUDE List of source files that should not use PCH # BUILD_INFO_LOG_MACRO Overrides log level of the build info log message, default LogWarn # STATIC_LIB_EXCLUDE_OBJS exclude objects that matches from static library # # After being called, some variables are exported from this macro, all prefixed # with parameter 1 followed by a '_': # TARGET The library or executable created by the macro # TARGET_DEPS All prerequisites for the target calculated by the macro # ALL_OBJS All object files # IMPORT_LIBRARY The import library created for a shared library on Windows # SetupNativeCompilation = $(NamedParamsMacroTemplate) define SetupNativeCompilationBody # When reading this code, note that macros named Setup are just setting # variables, and macros called Create 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. ### ### 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)) # 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. $$(eval $$(call SetupCompilerFlags,$1)) # 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 CreateCompiledNativeFile for each source file we are going to compile. $$(foreach file, $$($1_SRCS), \ $$(eval $$(call CreateCompiledNativeFile,$1_$$(notdir $$(file)), \ FILE := $$(file), \ BASE := $1, \ )) \ ) ifeq ($(call isTargetOs, windows), true) # On windows we need to create a resource file $$(eval $$(call CreateWindowsResourceFile,$1)) endif # Setup a library-wide dependency file from individual object file dependency # files, and import it in the makefile. $$(eval $$(call CreateDependencyFile,$1)) $$(eval $$(call ImportDependencyFile,$1)) ### ### Link the object files into a native output library/executable ### # Handle native debug symbols $$(eval $$(call CreateDebugSymbols,$1)) # Prepare for linking $$(eval $$(call SetupLinkerFlags,$1)) ifneq ($(TOOLCHAIN_TYPE), microsoft) $$(eval $$(call SetupLinking,$1)) endif $$(eval $$(call SetupObjectFileList,$1)) # Link the individually compiled files into a single unit ifneq ($(TOOLCHAIN_TYPE), microsoft) $$(eval $$(call CreateLinkedResult,$1)) else $$(eval $$(call CreateLinkedResultMicrosoft,$1)) endif ifeq ($(GENERATE_COMPILE_COMMANDS_ONLY), true) # Override all targets (this is a hack) $1 := $$($1_ALL_OBJS_JSON) $$($1_LDFLAGS_FILE) endif endef ################################################################################ # Verify that user passed arguments are valid define VerifyArguments ifeq ($$($1_NAME), ) $$(error NAME must not be empty in $1) endif 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 endif # STATIC_LIBS is set from Main.gmk when building static versions of certain # native libraries. ifeq ($(STATIC_LIBS), true) $1_TYPE := STATIC_LIBRARY # The static versions need to be redirected to different output dirs, both # to not interfere with the main build as well as to not end up inside the # jmods. $1_OBJECT_DIR := $$($1_OBJECT_DIR)/static $1_OUTPUT_DIR := $$($1_OBJECT_DIR) endif ifeq ($$($1_TYPE), EXECUTABLE) $1_PREFIX := ifeq ($$($1_SUFFIX), ) $1_SUFFIX := $(EXECUTABLE_SUFFIX) endif else $1_PREFIX := $(LIBRARY_PREFIX) ifeq ($$($1_TYPE), LIBRARY) ifeq ($$($1_SUFFIX), ) $1_SUFFIX := $(SHARED_LIBRARY_SUFFIX) endif else ifeq ($$($1_TYPE), STATIC_LIBRARY) ifeq ($$($1_SUFFIX), ) $1_SUFFIX := $(STATIC_LIBRARY_SUFFIX) endif endif endif $1_BASENAME := $$($1_PREFIX)$$($1_NAME)$$($1_SUFFIX) $1_TARGET := $$($1_OUTPUT_DIR)/$$($1_BASENAME) $1_NOSUFFIX := $$($1_PREFIX)$$($1_NAME) $1_SAFE_NAME := $$(strip $$(subst /,_, $1)) $1_UNIQUE_NAME = $$($1_TYPE)_$$(subst /,_,$$(patsubst $$(OUTPUTDIR)/%/,%,$$(dir $$($1_OBJECT_DIR))))_$$($1_NOSUFFIX) endef ################################################################################ # Setup the toolchain variables define SetupToolchain ifeq ($$($1_TARGET_TYPE), BUILD) $$(call SetIfEmpty, $1_CC, $$(BUILD_CC)) $$(call SetIfEmpty, $1_CXX, $$(BUILD_CXX)) $$(call SetIfEmpty, $1_AR, $$(BUILD_AR)) $$(call SetIfEmpty, $1_LIB, $$(BUILD_LIB)) $$(call SetIfEmpty, $1_AS, $$(BUILD_AS)) $$(call SetIfEmpty, $1_OBJCOPY, $$(BUILD_OBJCOPY)) $$(call SetIfEmpty, $1_STRIP, $$(BUILD_STRIP)) $$(call SetIfEmpty, $1_SYSROOT_CFLAGS, $$(BUILD_SYSROOT_CFLAGS)) $$(call SetIfEmpty, $1_SYSROOT_LDFLAGS, $$(BUILD_SYSROOT_LDFLAGS)) ifeq ($$($1_LINK_TYPE), C++) $$(call SetIfEmpty, $1_LD, $$(BUILD_LDCXX)) else $$(call SetIfEmpty, $1_LD, $$(BUILD_LD)) endif else $$(call SetIfEmpty, $1_CC, $$(CC)) $$(call SetIfEmpty, $1_CXX, $$(CXX)) $$(call SetIfEmpty, $1_AR, $$(AR)) $$(call SetIfEmpty, $1_LIB, $$(LIB)) $$(call SetIfEmpty, $1_AS, $$(AS)) $$(call SetIfEmpty, $1_MT, $$(MT)) $$(call SetIfEmpty, $1_RC, $$(RC)) $$(call SetIfEmpty, $1_OBJCOPY, $$(OBJCOPY)) $$(call SetIfEmpty, $1_STRIP, $$(STRIP)) $$(call SetIfEmpty, $1_SYSROOT_CFLAGS, $$(SYSROOT_CFLAGS)) $$(call SetIfEmpty, $1_SYSROOT_LDFLAGS, $$(SYSROOT_LDFLAGS)) ifeq ($$($1_LINK_TYPE), C++) $$(call SetIfEmpty, $1_LD, $$(LDCXX)) else $$(call SetIfEmpty, $1_LD, $$(LD)) endif endif endef ################################################################################ # Setup machinery needed by the build system define SetupBuildSystemSupport # 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. $1_COMPILE_VARDEPS := $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \ $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_OPT_CFLAGS) $$($1_OPT_CXXFLAGS) \ $$($1_CC) $$($1_CXX) $$($1_AS) $$($1_ASFLAGS) $1_COMPILE_VARDEPS_FILE := $$(call DependOnVariable, $1_COMPILE_VARDEPS, \ $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).comp.vardeps) endef ################################################################################ # Have make print information about the library when we start compiling 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), \ Creating $$(subst $$(OUTPUTDIR)/,,$$($1_TARGET)) from $$(words \ $$(filter-out %.vardeps, $$?)) file(s)) else $$(call $$($1_BUILD_INFO_LOG_MACRO), \ $$(strip Updating $$(subst $$(OUTPUTDIR)/,,$$($1_TARGET)) \ $$(if $$(filter-out %.vardeps, $$?), \ due to $$(words $$(filter-out %.vardeps, $$?)) file(s), \ $$(if $$(filter %.vardeps, $$?), due to makefile changes)))) endif $(TOUCH) $$@ endef ################################################################################ # Setup a library-wide dependency file from individual object file dependency # files define CreateDependencyFile # Create a rule to collect all the individual make dependency files into a # single makefile. $1_DEPS_FILE := $$($1_OBJECT_DIR)/$1.d $$($1_DEPS_FILE): $$($1_ALL_OBJS) $$($1_RES) $(RM) $$@ # CD into dir to reduce risk of hitting command length limits, which # could otherwise happen if TOPDIR is a very long path. $(CD) $$($1_OBJECT_DIR) && $(CAT) *.d > $$@.tmp $(CD) $$($1_OBJECT_DIR) && $(CAT) *.d.targets | $(SORT) -u >> $$@.tmp # After generating the file, which happens after all objects have been # compiled, copy it to .old extension. On the next make invocation, this # .old file will be included by make. $(CP) $$@.tmp $$@.old $(MV) $$@.tmp $$@ $1 += $$($1_DEPS_FILE) endef ################################################################################ # Import the dependency file into the makefile define ImportDependencyFile # The include must be on the .old file, which represents the state from the # previous invocation of make. The file being included must not have a rule # defined for it as otherwise make will think it has to run the rule before # being able to include the file, which would be wrong since we specifically # need the file as it was generated by a previous make invocation. ifneq ($$(wildcard $$($1_DEPS_FILE).old), ) $1_DEPS_FILE_LOADED := true -include $$($1_DEPS_FILE).old endif endef endif # _NATIVE_COMPILATION_GMK