| # |
| # Copyright (c) 2011, 2025, 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. |
| # |
| |
| include MakeIncludeStart.gmk |
| ifeq ($(INCLUDE), true) |
| |
| ################################################################################ |
| # 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. |
| ################################################################################ |
| |
| 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_<toolchain> the linker flags to be used for the specified toolchain, |
| # used both for C and C++. |
| # LDFLAGS_<OS> the linker flags to be used for the specified target OS, |
| # used both for C and C++. |
| # LDFLAGS_<toolchain>_<OS> 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_<OS> the libraries to link to for the specified target OS, |
| # used both for C and C++. |
| # LIBS_<toolchain> the libraries to link to for the specified toolchain, |
| # used both for C and C++. |
| # LIBS_<toolchain>_<OS> 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_<toolchain> Disable the given warnings for the specified toolchain |
| # DISABLED_WARNINGS_<toolchain>_<OS> Disable the given warnings for the specified |
| # toolchain and target OS |
| # DISABLED_WARNINGS_C_<toolchain> Disable the given warnings for the specified toolchain |
| # when compiling C code |
| # DISABLED_WARNINGS_C_<toolchain>_<OS> Disable the given warnings for the specified |
| # toolchain and target OS when compiling C code |
| # DISABLED_WARNINGS_CXX_<toolchain> Disable the given warnings for the specified |
| # toolchain when compiling C++ code |
| # DISABLED_WARNINGS_CXX_<toolchain>_<OS> Disable the given warnings for the specified |
| # toolchain and target OS when compiling C++ code |
| # DISABLED_WARNINGS_<toolchain>_<filename> Disable the given warnings for the specified |
| # toolchain when compiling the file specified by filename |
| # DISABLED_WARNINGS_<toolchain>_<OS>_<filename> 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<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. |
| |
| ### |
| ### 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) |
| TARGETS := $(filter $(MAKESUPPORT_OUTPUTDIR)/compile-commands/%, $(TARGETS)) |
| 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 # include guard |
| include MakeIncludeEnd.gmk |