| # | |
| # 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 |