1#
2# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# This code is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 2 only, as
7# published by the Free Software Foundation.  Oracle designates this
8# particular file as subject to the "Classpath" exception as provided
9# by Oracle in the LICENSE file that accompanied this code.
10#
11# This code is distributed in the hope that it will be useful, but WITHOUT
12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14# version 2 for more details (a copy is included in the LICENSE file that
15# accompanied this code).
16#
17# You should have received a copy of the GNU General Public License version
18# 2 along with this work; if not, write to the Free Software Foundation,
19# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22# or visit www.oracle.com if you need additional information or have any
23# questions.
24#
25
26# When you read this source. Remember that $(sort ...) has the side effect
27# of removing duplicates. It is actually this side effect that is
28# desired whenever sort is used below!
29
30ifndef _NATIVE_COMPILATION_GMK
31_NATIVE_COMPILATION_GMK := 1
32
33ifeq ($(_MAKEBASE_GMK), )
34  $(error You must include MakeBase.gmk prior to including NativeCompilation.gmk)
35endif
36
37################################################################################
38# Create exported symbols file for static libraries
39################################################################################
40
41# get the exported symbols from mapfiles and if there
42# is no mapfile, get them from the archive
43define GetSymbols
44  $(RM) $$(@D)/$$(basename $$(@F)).symbols; \
45  if [ ! -z $$($1_MAPFILE) -a -e $$($1_MAPFILE) ]; then \
46    $(ECHO) "Getting symbols from mapfile $$($1_MAPFILE)"; \
47    $(AWK) '/global:/','/local:/' $$($1_MAPFILE) | \
48        $(SED) -e 's/#.*//;s/global://;s/local://;s/\;//;s/^[ 	]*/_/;/^_$$$$/d' | \
49        $(EGREP) -v "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" > \
50        $$(@D)/$$(basename $$(@F)).symbols || true; \
51    $(NM) $$($1_TARGET) | $(GREP)  " T " | \
52        $(EGREP) "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" | \
53        $(CUT) -d ' ' -f 3 >>  $$(@D)/$$(basename $$(@F)).symbols || true;\
54  else \
55    $(ECHO) "Getting symbols from nm"; \
56    $(NM) -m $$($1_TARGET) | $(GREP)  "__TEXT" | \
57        $(EGREP) -v "non-external|private extern|__TEXT,__eh_frame" | \
58        $(SED) -e  's/.* //' > $$(@D)/$$(basename $$(@F)).symbols; \
59  fi
60endef
61
62################################################################################
63# Creates a recipe that creates a compile_commands.json fragment. Remove any
64# occurences of FIXPATH programs from the command to show the actual invocation.
65#
66# Param 1: Name of file to create
67# Param 2: Working directory
68# Param 3: Source file
69# Param 4: Compile command
70################################################################################
71define WriteCompileCommandsFragment
72  $(call LogInfo, Creating compile commands fragment for $(notdir $3))
73  $(call MakeDir, $(dir $1))
74  $(call WriteFile,{ \
75      "directory": "$(strip $(call FixPath, $2))"$(COMMA) \
76      "file": "$(strip $(call FixPath, $3))"$(COMMA) \
77      "command": "$(strip $(subst $(DQUOTE),\$(DQUOTE),$(subst \,\\,\
78        $(subst $(FIXPATH),,$(call FixPath, $4)))))" \
79    }$(COMMA), \
80    $1)
81endef
82
83################################################################################
84# Define a native toolchain configuration that can be used by
85# SetupNativeCompilation calls
86#
87# Parameter 1 is the name of the toolchain definition
88#
89# Remaining parameters are named arguments:
90#   EXTENDS - Optional parent definition to get defaults from
91#   CC - The C compiler
92#   CXX - The C++ compiler
93#   LD - The Linker
94#   AR - Static linker
95#   AS - Assembler
96#   MT - Windows MT tool
97#   RC - Windows RC tool
98#   OBJCOPY - The objcopy tool for debug symbol handling
99#   STRIP - The tool to use for stripping debug symbols
100#   SYSROOT_CFLAGS - Compiler flags for using the specific sysroot
101#   SYSROOT_LDFLAGS - Linker flags for using the specific sysroot
102DefineNativeToolchain = $(NamedParamsMacroTemplate)
103define DefineNativeToolchainBody
104  # If extending another definition, get default values from that,
105  # otherwise, nothing more needs to be done as variable assignments
106  # already happened in NamedParamsMacroTemplate.
107  ifneq ($$($1_EXTENDS), )
108    $$(call SetIfEmpty, $1_CC, $$($$($1_EXTENDS)_CC))
109    $$(call SetIfEmpty, $1_CXX, $$($$($1_EXTENDS)_CXX))
110    $$(call SetIfEmpty, $1_LD, $$($$($1_EXTENDS)_LD))
111    $$(call SetIfEmpty, $1_AR, $$($$($1_EXTENDS)_AR))
112    $$(call SetIfEmpty, $1_AS, $$($$($1_EXTENDS)_AS))
113    $$(call SetIfEmpty, $1_MT, $$($$($1_EXTENDS)_MT))
114    $$(call SetIfEmpty, $1_RC, $$($$($1_EXTENDS)_RC))
115    $$(call SetIfEmpty, $1_OBJCOPY, $$($$($1_EXTENDS)_OBJCOPY))
116    $$(call SetIfEmpty, $1_STRIP, $$($$($1_EXTENDS)_STRIP))
117    $$(call SetIfEmpty, $1_SYSROOT_CFLAGS, $$($$($1_EXTENDS)_SYSROOT_CFLAGS))
118    $$(call SetIfEmpty, $1_SYSROOT_LDFLAGS, $$($$($1_EXTENDS)_SYSROOT_LDFLAGS))
119  endif
120endef
121
122# Create a default toolchain with the main compiler and linker
123$(eval $(call DefineNativeToolchain, TOOLCHAIN_DEFAULT, \
124    CC := $(CC), \
125    CXX := $(CXX), \
126    LD := $(LD), \
127    AR := $(AR), \
128    AS := $(AS), \
129    MT := $(MT), \
130    RC := $(RC), \
131    OBJCOPY := $(OBJCOPY), \
132    STRIP := $(STRIP), \
133    SYSROOT_CFLAGS := $(SYSROOT_CFLAGS), \
134    SYSROOT_LDFLAGS := $(SYSROOT_LDFLAGS), \
135))
136
137# Create a toolchain where linking is done with the C++ linker
138$(eval $(call DefineNativeToolchain, TOOLCHAIN_LINK_CXX, \
139    EXTENDS := TOOLCHAIN_DEFAULT, \
140    LD := $(LDCXX), \
141))
142
143# Create a toolchain with the BUILD compiler, used for build tools that
144# are to be run during the build.
145$(eval $(call DefineNativeToolchain, TOOLCHAIN_BUILD, \
146    CC := $(BUILD_CC), \
147    CXX := $(BUILD_CXX), \
148    LD := $(BUILD_LD), \
149    AR := $(BUILD_AR), \
150    AS := $(BUILD_AS), \
151    OBJCOPY := $(BUILD_OBJCOPY), \
152    STRIP := $(BUILD_STRIP), \
153    SYSROOT_CFLAGS := $(BUILD_SYSROOT_CFLAGS), \
154    SYSROOT_LDFLAGS := $(BUILD_SYSROOT_LDFLAGS), \
155))
156
157# BUILD toolchain with the C++ linker
158$(eval $(call DefineNativeToolchain, TOOLCHAIN_BUILD_LINK_CXX, \
159    EXTENDS := TOOLCHAIN_BUILD, \
160    LD := $(BUILD_LDCXX), \
161))
162
163################################################################################
164
165# Extensions of files handled by this macro.
166NATIVE_SOURCE_EXTENSIONS := %.S %.c %.cpp %.cc %.m %.mm
167
168# Replaces native source extensions with the object file extension in a string.
169# Param 1: the string containing source file names with extensions
170# The surrounding strip is needed to keep additional whitespace out
171define replace_with_obj_extension
172$(strip \
173  $(foreach extension, $(NATIVE_SOURCE_EXTENSIONS), \
174      $(patsubst $(extension),%$(OBJ_SUFFIX), $(filter $(extension), $1))) \
175)
176endef
177
178# This pattern is used to transform the output of the microsoft CL compiler
179# into a make syntax dependency file (.d)
180WINDOWS_SHOWINCLUDE_SED_PATTERN := \
181    -e '/^Note: including file:/!d' \
182    -e 's|Note: including file: *||' \
183    -e 's|\r||g' \
184    -e 's|\\|/|g' \
185    -e 's|^\([a-zA-Z]\):|$(WINENV_PREFIX)/\1|g' \
186    -e '\|$(TOPDIR)|I !d' \
187    -e 's|$$$$| \\|g' \
188    #
189
190# This pattern is used to transform a dependency file (.d) to a list
191# of make targets for dependent files (.d.targets)
192DEPENDENCY_TARGET_SED_PATTERN := \
193    -e 's/\#.*//' \
194    -e 's/^[^:]*: *//' \
195    -e 's/ *\\$$$$//' \
196    -e 's/^[	 ]*//' \
197    -e '/^$$$$/ d' \
198    -e 's/$$$$/ :/' \
199    #
200
201################################################################################
202# When absolute paths are not allowed in the output, and the compiler does not
203# support any options to avoid it, we need to rewrite compile commands to use
204# relative paths. By doing this, the __FILE__ macro will resolve to relative
205# paths. The relevant input paths on the command line are the -I flags and the
206# path to the source file itself.
207#
208# The macro MakeCommandRelative is used to rewrite the command line like this:
209# 'CD $(WORKSPACE_ROOT) && <cmd>'
210# and changes all paths in cmd to be relative to the workspace root. This only
211# works properly if the build dir is inside the workspace root. If it's not,
212# relative paths are still calculated, but depending on the distance between the
213# dirs, paths in the build dir may end up as essentially absolute anyway.
214#
215# The fix-deps-file macro is used to adjust the contents of the generated make
216# dependency files to contain paths compatible with make.
217#
218ifeq ($(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT)-$(FILE_MACRO_CFLAGS), false-)
219  # Need to handle -I flags as both '-Ifoo' and '-I foo'.
220  MakeCommandRelative = \
221      $(CD) $(WORKSPACE_ROOT) && \
222      $(foreach o, $1, \
223        $(if $(filter $(WORKSPACE_ROOT)/% $(OUTPUTDIR)/%, $o), \
224          $(call RelativePath, $o, $(WORKSPACE_ROOT)) \
225        , \
226          $(if $(filter -I$(WORKSPACE_ROOT)/%, $o), \
227            -I$(call RelativePath, $(patsubst -I%, %, $o), $(WORKSPACE_ROOT)) \
228          , \
229            $o \
230          ) \
231        ) \
232      )
233
234  # When compiling with relative paths, the deps file may come out with relative
235  # paths, and that path may start with './'. First remove any leading ./, then
236  # add WORKSPACE_ROOT to any line not starting with /, while allowing for
237  # leading spaces. There may also be multiple entries on the same line, so start
238  # with splitting such lines.
239  # Non GNU sed (BSD on macosx) cannot substitue in literal \n using regex.
240  # Instead use a bash escaped literal newline. To avoid having unmatched quotes
241  # ruin the ability for an editor to properly syntax highlight this file, define
242  # that newline sequence as a separate variable and add the closing quote behind
243  # a comment.
244  sed_newline := \'$$'\n''#'
245  define fix-deps-file
246	$(SED) \
247	    -e 's|\([^ ]\) \{1,\}\([^\\:]\)|\1 \\$(sed_newline) \2|g' \
248	    $1.tmp \
249	    | $(SED) \
250	        -e 's|^\([ ]*\)\./|\1|' \
251	        -e '/^[ ]*[^/ ]/s|^\([ ]*\)|\1$(WORKSPACE_ROOT)/|' \
252	        > $1
253  endef
254else
255  # By default the MakeCommandRelative macro does nothing.
256  MakeCommandRelative = $1
257
258  # No adjustment is needed.
259  define fix-deps-file
260	$(MV) $1.tmp $1
261  endef
262endif
263
264################################################################################
265# GetEntitlementsFile
266# Find entitlements file for executable when signing on macosx. If no
267# specialized file is found, returns the default file.
268# $1 Executable to find entitlements file for.
269ENTITLEMENTS_DIR := $(TOPDIR)/make/data/macosxsigning
270DEFAULT_ENTITLEMENTS_FILE := $(ENTITLEMENTS_DIR)/default.plist
271
272GetEntitlementsFile = \
273    $(foreach f, $(ENTITLEMENTS_DIR)/$(strip $(notdir $1)).plist, \
274      $(if $(wildcard $f), $f, $(DEFAULT_ENTITLEMENTS_FILE)) \
275    )
276
277################################################################################
278# Create the recipe needed to compile a single native source file.
279#
280# Parameter 1 is the name of the rule, based on the name of the library/
281# program being build and the name of the source code file, e.g.
282# BUILD_LIBFOO_fooMain.cpp.
283#
284# Remaining parameters are named arguments:
285#   FILE - The full path of the source file to compiler
286#   BASE - The name of the rule for the entire binary to build ($1)
287#
288SetupCompileNativeFile = $(NamedParamsMacroTemplate)
289define SetupCompileNativeFileBody
290  $1_FILENAME := $$(notdir $$($1_FILE))
291
292  # The target file to be generated.
293  $1_OBJ := $$($$($1_BASE)_OBJECT_DIR)/$$(call replace_with_obj_extension, \
294      $$($1_FILENAME))
295
296  # Generate the corresponding compile_commands.json fragment.
297  $1_OBJ_JSON = $$(MAKESUPPORT_OUTPUTDIR)/compile-commands/$$(subst /,_,$$(subst \
298      $$(OUTPUTDIR)/,,$$($1_OBJ))).json
299  $$($1_BASE)_ALL_OBJS_JSON += $$($1_OBJ_JSON)
300
301  # Only continue if this object file hasn't been processed already. This lets
302  # the first found source file override any other with the same name.
303  ifeq ($$($1_OBJ_PROCESSED), )
304    $1_OBJ_PROCESSED := true
305    # This is the definite source file to use for $1_FILENAME.
306    $1_SRC_FILE := $$($1_FILE)
307
308    ifeq ($$($1_OPTIMIZATION), )
309      $1_OPT_CFLAGS := $$($$($1_BASE)_OPT_CFLAGS)
310      $1_OPT_CXXFLAGS := $$($$($1_BASE)_OPT_CXXFLAGS)
311    else
312      ifeq ($$($1_OPTIMIZATION), NONE)
313        $1_OPT_CFLAGS := $(C_O_FLAG_NONE)
314        $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
315      else ifeq ($$($1_OPTIMIZATION), LOW)
316        $1_OPT_CFLAGS := $(C_O_FLAG_NORM)
317        $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
318      else ifeq ($$($1_OPTIMIZATION), HIGH)
319        $1_OPT_CFLAGS := $(C_O_FLAG_HI)
320        $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
321      else ifeq ($$($1_OPTIMIZATION), HIGHEST)
322        $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
323        $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
324      else ifeq ($$($1_OPTIMIZATION), HIGHEST_JVM)
325        $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
326        $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
327      else ifeq ($$($1_OPTIMIZATION), SIZE)
328        $1_OPT_CFLAGS := $(C_O_FLAG_SIZE)
329        $1_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
330      else
331        $$(error Unknown value for file OPTIMIZATION: $$($1_OPTIMIZATION))
332      endif
333    endif
334
335    ifneq ($$($$($1_BASE)_PRECOMPILED_HEADER), )
336      ifeq ($$(filter $$($1_FILENAME), $$($$($1_BASE)_PRECOMPILED_HEADER_EXCLUDE)), )
337        $1_USE_PCH_FLAGS := $$($$($1_BASE)_USE_PCH_FLAGS)
338      endif
339    endif
340
341    $1_BASE_CFLAGS :=  $$($$($1_BASE)_CFLAGS) $$($$($1_BASE)_EXTRA_CFLAGS) \
342        $$($$($1_BASE)_SYSROOT_CFLAGS)
343    $1_BASE_CXXFLAGS := $$($$($1_BASE)_CXXFLAGS) $$($$($1_BASE)_EXTRA_CXXFLAGS) \
344        $$($$($1_BASE)_SYSROOT_CFLAGS) $$($1_EXTRA_CXXFLAGS)
345    $1_BASE_ASFLAGS := $$($$($1_BASE)_ASFLAGS) $$($$($1_BASE)_EXTRA_ASFLAGS)
346
347    ifneq ($$(filter %.c, $$($1_FILENAME)), )
348      # Compile as a C file
349      $1_FLAGS := $(CFLAGS_CCACHE) $$($1_USE_PCH_FLAGS) $$($1_BASE_CFLAGS) \
350          $$($1_OPT_CFLAGS) $$($1_CFLAGS) -c
351      $1_COMPILER := $$($$($1_BASE)_CC)
352    else ifneq ($$(filter %.m, $$($1_FILENAME)), )
353      # Compile as an Objective-C file
354      $1_FLAGS := -x objective-c $(CFLAGS_CCACHE) $$($1_USE_PCH_FLAGS) \
355          $$($1_BASE_CFLAGS) $$($1_OPT_CFLAGS) $$($1_CFLAGS) -c
356      $1_COMPILER := $$($$($1_BASE)_CC)
357    else ifneq ($$(filter %.S, $$($1_FILENAME)), )
358      # Compile as preprocessed assembler file
359      $1_FLAGS := $(BASIC_ASFLAGS) $$($1_BASE_ASFLAGS)
360      $1_COMPILER := $(AS)
361    else ifneq ($$(filter %.cpp %.cc %.mm, $$($1_FILENAME)), )
362      # Compile as a C++ or Objective-C++ file
363      $1_FLAGS := $(CFLAGS_CCACHE) $$($1_USE_PCH_FLAGS) $$($1_BASE_CXXFLAGS) \
364          $$($1_OPT_CXXFLAGS) $$($1_CXXFLAGS) -c
365      $1_COMPILER := $$($$($1_BASE)_CXX)
366    else
367      $$(error Internal error in NativeCompilation.gmk: no compiler for file $$($1_FILENAME))
368    endif
369
370    # And this is the dependency file for this obj file.
371    $1_DEPS_FILE := $$(patsubst %$(OBJ_SUFFIX),%.d,$$($1_OBJ))
372    # The dependency target file lists all dependencies as empty targets to
373    # avoid make error "No rule to make target" for removed files
374    $1_DEPS_TARGETS_FILE := $$(patsubst %$(OBJ_SUFFIX),%.d.targets,$$($1_OBJ))
375
376    # Only try to load individual dependency information files if the global
377    # file hasn't been loaded (could happen if make was interrupted).
378    ifneq ($$($$($1_BASE)_DEPS_FILE_LOADED), true)
379      # Include previously generated dependency information. (if it exists)
380      -include $$($1_DEPS_FILE)
381      -include $$($1_DEPS_TARGETS_FILE)
382    endif
383
384    ifneq ($$(strip $$($1_CFLAGS) $$($1_CXXFLAGS) $$($1_OPTIMIZATION)), )
385      $1_VARDEPS := $$($1_CFLAGS) $$($1_CXXFLAGS) $$($1_OPTIMIZATION)
386      $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$($1_OBJ).vardeps)
387    endif
388
389    $1_OBJ_DEPS := $$($1_SRC_FILE) $$($$($1_BASE)_COMPILE_VARDEPS_FILE) \
390        $$($$($1_BASE)_EXTRA_DEPS) $$($1_VARDEPS_FILE)
391    $1_COMPILE_OPTIONS := $$($1_FLAGS) $(CC_OUT_OPTION)$$($1_OBJ) $$($1_SRC_FILE)
392
393    $$($1_OBJ_JSON): $$($1_OBJ_DEPS)
394	$$(call WriteCompileCommandsFragment, $$@, $$(PWD), $$($1_SRC_FILE), \
395	    $$($1_COMPILER) $$($1_COMPILE_OPTIONS))
396
397    $$($1_OBJ): $$($1_OBJ_DEPS) | $$($$($1_BASE)_BUILD_INFO)
398	$$(call LogInfo, Compiling $$($1_FILENAME) (for $$($$($1_BASE)_BASENAME)))
399	$$(call MakeDir, $$(@D))
400        ifneq ($(TOOLCHAIN_TYPE), microsoft)
401	  $$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \
402	      $$($1_COMPILER) $$(GENDEPS_FLAGS) \
403	      $$(addsuffix .tmp, $$($1_DEPS_FILE)) \
404	      $$($1_COMPILE_OPTIONS)))
405          ifneq ($$($1_DEPS_FILE), )
406	    $$(call fix-deps-file, $$($1_DEPS_FILE))
407            # Create a dependency target file from the dependency file.
408            # Solution suggested by:
409            # http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
410	    $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_DEPS_FILE) \
411	        > $$($1_DEPS_TARGETS_FILE)
412          endif
413        else
414          # The Visual Studio compiler lacks a feature for generating make
415          # dependencies, but by setting -showIncludes, all included files are
416          # printed. These are filtered out and parsed into make dependences.
417          #
418          # Keep as much as possible on one execution line for best performance
419          # on Windows. No need to save exit code from compilation since
420          # pipefail is always active on Windows.
421          ifeq ($$(filter %.S, $$($1_FILENAME)), )
422	    $$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \
423	        $$($1_COMPILER) -showIncludes $$($1_COMPILE_OPTIONS))) \
424	        | $(TR) -d '\r' | $(GREP) -v -e "^Note: including file:" \
425	            -e "^$$($1_FILENAME)$$$$" || test "$$$$?" = "1" ; \
426	    $(ECHO) $$@: \\ > $$($1_DEPS_FILE) ; \
427	    $(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_OBJ).log \
428	        | $(SORT) -u >> $$($1_DEPS_FILE) ; \
429	    $(ECHO) >> $$($1_DEPS_FILE) ; \
430	    $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_DEPS_FILE) > $$($1_DEPS_TARGETS_FILE)
431          else
432            # For assembler calls just create empty dependency lists
433	    $$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \
434	        $$($1_COMPILER) $$($1_FLAGS) \
435	        $(CC_OUT_OPTION)$$($1_OBJ) -Ta $$($1_SRC_FILE))) \
436	        | $(TR) -d '\r' | $(GREP) -v -e "Assembling:" || test "$$$$?" = "1" ; \
437	    $(ECHO) > $$($1_DEPS_FILE) ; \
438	    $(ECHO) > $$($1_DEPS_TARGETS_FILE)
439          endif
440        endif
441  endif
442endef
443
444# Setup make rules for creating a native binary (a shared library or an
445# executable).
446#
447# Parameter 1 is the name of the rule. This name is used as variable prefix,
448# and the targets generated are listed in a variable by that name.
449#
450# Remaining parameters are named arguments. These include:
451#   NAME The base name for the resulting binary, excluding decorations (like *.exe)
452#   TYPE Type of binary (EXECUTABLE, LIBRARY or STATIC_LIBRARY). Default is LIBRARY.
453#   SUFFIX Override the default suffix for the output file
454#   TOOLCHAIN Name of toolchain setup to use. Defaults to TOOLCHAIN_DEFAULT.
455#   SRC one or more directory roots to scan for C/C++ files.
456#   CFLAGS the compiler flags to be used, used both for C and C++.
457#   CXXFLAGS the compiler flags to be used for c++, if set overrides CFLAGS.
458#   LDFLAGS the linker flags to be used, used both for C and C++.
459#   LIBS the libraries to link to
460#   ARFLAGS the archiver flags to be used
461#   OBJECT_DIR the directory where we store the object files
462#   OUTPUT_DIR the directory where the resulting binary is put
463#   SYMBOLS_DIR the directory where the debug symbols are put, defaults to OUTPUT_DIR
464#   INCLUDES only pick source from these directories
465#   EXCLUDES do not pick source from these directories
466#   INCLUDE_FILES only compile exactly these files!
467#   EXCLUDE_FILES with these names
468#   EXCLUDE_PATTERN exclude files matching any of these substrings
469#   EXTRA_FILES List of extra files not in any of the SRC dirs
470#   EXTRA_OBJECT_FILES List of extra object files to include when linking
471#   EXTRA_DEPS List of extra dependencies to be added to each compiled file
472#   VERSIONINFO_RESOURCE Input file for RC. Setting this implies that RC will be run
473#   RCFLAGS flags for RC.
474#   EMBED_MANIFEST if true, embed manifest on Windows.
475#   MAPFILE mapfile
476#   USE_MAPFILE_FOR_SYMBOLS if true and this is a STATIC_BUILD, just copy the
477#       mapfile for the output symbols file
478#   CC the compiler to use, default is $(CC)
479#   LD the linker to use, default is $(LD)
480#   OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST, HIGHEST_JVM, SIZE
481#   DISABLED_WARNINGS_<toolchain> Disable the given warnings for the specified toolchain
482#   DISABLED_WARNINGS_C_<toolchain> Disable the given warnings for the specified toolchain
483#       when compiling C code
484#   DISABLED_WARNINGS_CXX_<toolchain> Disable the given warnings for the specified
485#       toolchain when compiling C++ code
486#   STRIP_SYMBOLS Set to false to override global strip policy and always leave
487#       symbols in the binary, if the toolchain allows for it
488#   DEBUG_SYMBOLS Set to false to disable generation of debug symbols
489#   COPY_DEBUG_SYMBOLS Set to false to override global setting of debug symbol copying
490#   ZIP_EXTERNAL_DEBUG_SYMBOLS Set to false to override global setting of debug symbol
491#       zipping
492#   STRIPFLAGS Optionally change the flags given to the strip command
493#   PRECOMPILED_HEADER Header file to use as precompiled header
494#   PRECOMPILED_HEADER_EXCLUDE List of source files that should not use PCH
495#
496# After being called, some variables are exported from this macro, all prefixed
497# with parameter 1 followed by a '_':
498#   TARGET The library or executable created by the macro
499#   TARGET_DEPS All prerequisites for the target calculated by the macro
500#   ALL_OBJS All object files
501#   IMPORT_LIBRARY The import library created for a shared library on Windows
502SetupNativeCompilation = $(NamedParamsMacroTemplate)
503define SetupNativeCompilationBody
504
505  # If type is unspecified, default to LIBRARY
506  ifeq ($$($1_TYPE), )
507    $1_TYPE := LIBRARY
508  endif
509
510  # If we're doing a static build and producing a library
511  # force it to be a static library and remove the -l libraries
512  ifeq ($(STATIC_BUILD), true)
513    ifeq ($$($1_TYPE), LIBRARY)
514      $1_TYPE := STATIC_LIBRARY
515    endif
516  endif
517
518  $$(call SetIfEmpty, $1_COMPILE_WITH_DEBUG_SYMBOLS, $$(COMPILE_WITH_DEBUG_SYMBOLS))
519
520  # STATIC_LIBS is set from Main.gmk when building static versions of certain
521  # native libraries.
522  ifeq ($(STATIC_LIBS), true)
523    $1_TYPE := STATIC_LIBRARY
524    # The static versions need to be redirected to different output dirs, both
525    # to not interfere with the main build as well as to not end up inside the
526    # jmods.
527    $1_OBJECT_DIR := $$($1_OBJECT_DIR)/static
528    $1_OUTPUT_DIR := $$($1_OBJECT_DIR)
529    # For release builds where debug symbols are configured to be moved to
530    # separate debuginfo files, disable debug symbols for static libs instead.
531    # We don't currently support this configuration and we don't want symbol
532    # information in release builds unless explicitly asked to provide it.
533    ifeq ($(DEBUG_LEVEL), release)
534      ifeq ($(COPY_DEBUG_SYMBOLS), true)
535        $1_COMPILE_WITH_DEBUG_SYMBOLS := false
536      endif
537    endif
538  endif
539
540  ifeq ($$($1_TYPE), EXECUTABLE)
541    $1_PREFIX :=
542    ifeq ($$($1_SUFFIX), )
543      $1_SUFFIX := $(EXECUTABLE_SUFFIX)
544    endif
545  else
546    $1_PREFIX := $(LIBRARY_PREFIX)
547    ifeq ($$($1_TYPE), LIBRARY)
548      ifeq ($$($1_SUFFIX), )
549        $1_SUFFIX := $(SHARED_LIBRARY_SUFFIX)
550      endif
551    else ifeq ($$($1_TYPE), STATIC_LIBRARY)
552      ifeq ($$($1_SUFFIX), )
553        $1_SUFFIX := $(STATIC_LIBRARY_SUFFIX)
554      endif
555    endif
556  endif
557
558  ifneq ($$($1_NAME), $(basename $$($1_NAME)))
559    $$(error NAME must not contain any directory path in $1)
560  endif
561  ifneq ($(findstring $$($1_SUFFIX), $$($1_NAME)), )
562    $$(error NAME should be specified without suffix: $$($1_SUFFIX) in $1)
563  endif
564  ifneq ($(findstring $$($1_PREFIX), $$($1_NAME)), )
565    $$(error NAME should be specified without prefix: $$($1_PREFIX) in $1)
566  endif
567  ifeq ($$($1_OUTPUT_DIR), )
568    $$(error OUTPUT_DIR is missing in $1)
569  endif
570  ifneq ($$($1_MANIFEST), )
571    ifeq ($$($1_MANIFEST_VERSION), )
572      $$(error If MANIFEST is provided, then MANIFEST_VERSION is required in $1)
573    endif
574  endif
575
576  $1_BASENAME := $$($1_PREFIX)$$($1_NAME)$$($1_SUFFIX)
577  $1_TARGET := $$($1_OUTPUT_DIR)/$$($1_BASENAME)
578  $1_NOSUFFIX := $$($1_PREFIX)$$($1_NAME)
579  $1_SAFE_NAME := $$(strip $$(subst /,_, $1))
580
581# Need to make sure TARGET is first on list
582  $1 := $$($1_TARGET)
583
584  # Setup the toolchain to be used
585  $$(call SetIfEmpty, $1_TOOLCHAIN, TOOLCHAIN_DEFAULT)
586  $$(call SetIfEmpty, $1_CC, $$($$($1_TOOLCHAIN)_CC))
587  $$(call SetIfEmpty, $1_CXX, $$($$($1_TOOLCHAIN)_CXX))
588  $$(call SetIfEmpty, $1_LD, $$($$($1_TOOLCHAIN)_LD))
589  $$(call SetIfEmpty, $1_AR, $$($$($1_TOOLCHAIN)_AR))
590  $$(call SetIfEmpty, $1_AS, $$($$($1_TOOLCHAIN)_AS))
591  $$(call SetIfEmpty, $1_MT, $$($$($1_TOOLCHAIN)_MT))
592  $$(call SetIfEmpty, $1_RC, $$($$($1_TOOLCHAIN)_RC))
593  $$(call SetIfEmpty, $1_OBJCOPY, $$($$($1_TOOLCHAIN)_OBJCOPY))
594  $$(call SetIfEmpty, $1_STRIP, $$($$($1_TOOLCHAIN)_STRIP))
595  $$(call SetIfEmpty, $1_SYSROOT_CFLAGS, $$($$($1_TOOLCHAIN)_SYSROOT_CFLAGS))
596  $$(call SetIfEmpty, $1_SYSROOT_LDFLAGS, $$($$($1_TOOLCHAIN)_SYSROOT_LDFLAGS))
597
598  $$(foreach d, $$($1_SRC), $$(if $$(wildcard $$d), , \
599      $$(error SRC specified to SetupNativeCompilation $1 contains missing directory $$d)))
600
601  $1_SRCS_RAW := $$(call FindFiles, $$($1_SRC))
602  # Order src files according to the order of the src dirs
603  $1_SRCS := $$(foreach d, $$($1_SRC), $$(filter $$d%, $$($1_SRCS_RAW)))
604  $1_SRCS := $$(filter $$(NATIVE_SOURCE_EXTENSIONS), $$($1_SRCS))
605  # Extract the C/C++ files.
606  ifneq ($$($1_EXCLUDE_PATTERNS), )
607    # We must not match the exclude pattern against the src root(s).
608    $1_SRCS_WITHOUT_ROOTS := $$($1_SRCS)
609    $$(foreach i, $$($1_SRC), $$(eval $1_SRCS_WITHOUT_ROOTS := $$(patsubst \
610        $$i/%,%, $$($1_SRCS_WITHOUT_ROOTS))))
611    $1_ALL_EXCLUDE_FILES :=  $$(call containing, $$($1_EXCLUDE_PATTERNS), \
612        $$($1_SRCS_WITHOUT_ROOTS))
613  endif
614  ifneq ($$($1_EXCLUDE_FILES), )
615    $1_ALL_EXCLUDE_FILES += $$($1_EXCLUDE_FILES)
616  endif
617  ifneq ($$($1_ALL_EXCLUDE_FILES), )
618    $1_EXCLUDE_FILES_PAT := $$($1_ALL_EXCLUDE_FILES) \
619        $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_ALL_EXCLUDE_FILES)))
620    $1_EXCLUDE_FILES_PAT := $$(addprefix %, $$($1_EXCLUDE_FILES_PAT))
621    $1_SRCS := $$(filter-out $$($1_EXCLUDE_FILES_PAT), $$($1_SRCS))
622  endif
623  ifneq ($$($1_INCLUDE_FILES), )
624    $1_INCLUDE_FILES_PAT := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_INCLUDE_FILES)))
625    $1_SRCS := $$(filter $$($1_INCLUDE_FILES_PAT), $$($1_SRCS))
626  endif
627  # There can be only a single bin dir root, no need to foreach over the roots.
628  $1_BINS := $$(wildcard $$($1_OBJECT_DIR)/*$(OBJ_SUFFIX))
629  # Now we have a list of all c/c++ files to compile: $$($1_SRCS)
630  # and we have a list of all existing object files: $$($1_BINS)
631
632  # Prepend the source/bin path to the filter expressions. Then do the filtering.
633  ifneq ($$($1_INCLUDES), )
634    $1_SRC_INCLUDES := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_INCLUDES))))
635    $1_SRCS := $$(filter $$($1_SRC_INCLUDES), $$($1_SRCS))
636  endif
637  ifneq ($$($1_EXCLUDES), )
638    $1_SRC_EXCLUDES := $$(addsuffix /%, $$($1_EXCLUDES))
639    $1_SRC_EXCLUDES += $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_EXCLUDES))))
640    $1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES), $$($1_SRCS))
641  endif
642
643  $1_SRCS += $$($1_EXTRA_FILES)
644
645  ifeq ($$($1_SRCS), )
646    $$(error No sources found for $1 when looking inside the dirs $$($1_SRC))
647  endif
648
649  # Calculate the expected output from compiling the sources
650  $1_EXPECTED_OBJS_FILENAMES := $$(call replace_with_obj_extension, $$(notdir $$($1_SRCS)))
651  $1_EXPECTED_OBJS := $$(addprefix $$($1_OBJECT_DIR)/, $$($1_EXPECTED_OBJS_FILENAMES))
652  # Are there too many object files on disk? Perhaps because some source file was removed?
653  $1_SUPERFLOUS_OBJS := $$(sort $$(filter-out $$($1_EXPECTED_OBJS), $$($1_BINS)))
654  # Clean out the superfluous object files.
655  ifneq ($$($1_SUPERFLUOUS_OBJS), )
656    $$(shell $(RM) -f $$($1_SUPERFLUOUS_OBJS))
657  endif
658  # Sort to remove dupliates and provide a reproducable order on the input files to the linker.
659  $1_ALL_OBJS := $$(sort $$($1_EXPECTED_OBJS) $$($1_EXTRA_OBJECT_FILES))
660
661  # Pickup extra OPENJDK_TARGET_OS_TYPE, OPENJDK_TARGET_OS, and/or OPENJDK_TARGET_OS plus
662  # OPENJDK_TARGET_CPU pair dependent variables for CFLAGS.
663  $1_EXTRA_CFLAGS := $$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_CFLAGS_$(OPENJDK_TARGET_OS)) \
664      $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU))
665  ifneq ($(DEBUG_LEVEL), release)
666    # Pickup extra debug dependent variables for CFLAGS
667    $1_EXTRA_CFLAGS += $$($1_CFLAGS_debug)
668    $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)_debug)
669    $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_debug)
670    $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU)_debug)
671  else
672    $1_EXTRA_CFLAGS += $$($1_CFLAGS_release)
673    $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS_TYPE)_release)
674    $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_release)
675    $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU)_release)
676  endif
677  ifeq ($(STATIC_LIBS), true)
678    $1_EXTRA_CFLAGS += $$(STATIC_LIBS_CFLAGS)
679  endif
680
681  # Pickup extra OPENJDK_TARGET_OS_TYPE and/or OPENJDK_TARGET_OS dependent variables for CXXFLAGS.
682  $1_EXTRA_CXXFLAGS := $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS))
683  ifneq ($(DEBUG_LEVEL), release)
684    # Pickup extra debug dependent variables for CXXFLAGS
685    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_debug)
686    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)_debug)
687    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_debug)
688  else
689    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_release)
690    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)_release)
691    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_release)
692  endif
693  ifeq ($(STATIC_LIBS), true)
694    $1_EXTRA_CXXFLAGS += $$(STATIC_LIB_CFLAGS)
695  endif
696
697  # If no C++ flags are explicitly set, default to using the C flags.
698  # After that, we can set additional C++ flags that should not interfere
699  # with the mechanism for copying the C flags by default.
700  ifeq ($$($1_CXXFLAGS), )
701    $1_CXXFLAGS := $$($1_CFLAGS)
702  endif
703  ifeq ($$(strip $$($1_EXTRA_CXXFLAGS)), )
704    $1_EXTRA_CXXFLAGS := $$($1_EXTRA_CFLAGS)
705  endif
706
707  ifeq ($$($1_COMPILE_WITH_DEBUG_SYMBOLS), true)
708    $1_EXTRA_CFLAGS += $$(CFLAGS_DEBUG_SYMBOLS)
709    $1_EXTRA_CXXFLAGS += $$(CFLAGS_DEBUG_SYMBOLS)
710    $1_EXTRA_ASFLAGS += $$(ASFLAGS_DEBUG_SYMBOLS)
711  endif
712
713  # Pass the library name for static JNI library naming
714  ifeq ($$($1_TYPE), STATIC_LIBRARY)
715    $1_EXTRA_CFLAGS += -DLIBRARY_NAME=$$($1_NAME)
716    $1_EXTRA_CXXFLAGS += -DLIBRARY_NAME=$$($1_NAME)
717  endif
718
719  # Pick up disabled warnings, if possible on this platform.
720  ifneq ($(DISABLE_WARNING_PREFIX), )
721    $1_EXTRA_CFLAGS += $$(addprefix $(DISABLE_WARNING_PREFIX), \
722        $$(DISABLED_WARNINGS) \
723        $$(DISABLED_WARNINGS_C) \
724        $$($1_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)) \
725        $$($1_DISABLED_WARNINGS_C_$(TOOLCHAIN_TYPE)))
726    $1_EXTRA_CXXFLAGS += $$(addprefix $(DISABLE_WARNING_PREFIX), \
727        $$(DISABLED_WARNINGS) \
728        $$(DISABLED_WARNINGS_CXX) \
729        $$($1_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)) \
730        $$($1_DISABLED_WARNINGS_CXX_$(TOOLCHAIN_TYPE)))
731  endif
732
733  # Check if warnings should be considered errors.
734  # Pick first binary and toolchain specific, then binary specific, then general setting.
735  ifeq ($$($1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE)), )
736    ifeq ($$($1_WARNINGS_AS_ERRORS), )
737      $1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE) := $$(WARNINGS_AS_ERRORS)
738    else
739      $1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE) := $$($1_WARNINGS_AS_ERRORS)
740    endif
741  endif
742
743  ifeq ($$($1_WARNINGS_AS_ERRORS_$(TOOLCHAIN_TYPE)), true)
744    $1_EXTRA_CFLAGS += $(CFLAGS_WARNINGS_ARE_ERRORS)
745    $1_EXTRA_CXXFLAGS += $(CFLAGS_WARNINGS_ARE_ERRORS)
746  endif
747
748  ifeq (NONE, $$($1_OPTIMIZATION))
749    $1_OPT_CFLAGS := $(C_O_FLAG_NONE)
750    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
751  else ifeq (LOW, $$($1_OPTIMIZATION))
752    $1_OPT_CFLAGS := $(C_O_FLAG_NORM)
753    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
754  else ifeq (HIGH, $$($1_OPTIMIZATION))
755    $1_OPT_CFLAGS := $(C_O_FLAG_HI)
756    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
757  else ifeq (HIGHEST, $$($1_OPTIMIZATION))
758    $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
759    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
760  else ifeq (HIGHEST_JVM, $$($1_OPTIMIZATION))
761    $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
762    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
763  else ifeq (SIZE, $$($1_OPTIMIZATION))
764    $1_OPT_CFLAGS := $(C_O_FLAG_SIZE)
765    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
766  else ifneq (, $$($1_OPTIMIZATION))
767    $$(error Unknown value for OPTIMIZATION: $$($1_OPTIMIZATION))
768  endif
769
770  $1_BUILD_INFO := $$($1_OBJECT_DIR)/_build-info.marker
771
772  # Track variable changes for all variables that affect the compilation command
773  # lines for all object files in this setup. This includes at least all the
774  # variables used in the call to add_native_source below.
775  $1_COMPILE_VARDEPS := $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
776      $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_OPT_CFLAGS) $$($1_OPT_CXXFLAGS) \
777      $$($1_CC) $$($1_CXX) $$($1_AS) $$($1_ASFLAGS)
778  $1_COMPILE_VARDEPS_FILE := $$(call DependOnVariable, $1_COMPILE_VARDEPS, \
779      $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).comp.vardeps)
780
781  ifneq ($$($1_PRECOMPILED_HEADER), )
782    ifeq ($(USE_PRECOMPILED_HEADER), true)
783      ifeq ($(TOOLCHAIN_TYPE), microsoft)
784        $1_PCH_FILE := $$($1_OBJECT_DIR)/$1.pch
785        $1_GENERATED_PCH_SRC := $$($1_OBJECT_DIR)/$1_pch.cpp
786        $1_GENERATED_PCH_OBJ := $$($1_OBJECT_DIR)/$1_pch.obj
787
788        $$(eval $$(call SetupCompileNativeFile, $1_$$(notdir $$($1_GENERATED_PCH_SRC)), \
789            FILE := $$($1_GENERATED_PCH_SRC), \
790            BASE := $1, \
791            EXTRA_CXXFLAGS := -Fp$$($1_PCH_FILE) -Yc$$(notdir $$($1_PRECOMPILED_HEADER)), \
792        ))
793
794        $1_USE_PCH_FLAGS := \
795            -Fp$$($1_PCH_FILE) -Yu$$(notdir $$($1_PRECOMPILED_HEADER))
796
797        $$($1_ALL_OBJS): $$($1_GENERATED_PCH_OBJ)
798
799        # Explicitly add the pch obj file first to ease comparing to old
800        # hotspot build.
801        $1_ALL_OBJS := $$($1_GENERATED_PCH_OBJ) $$($1_ALL_OBJS)
802
803        $$($1_GENERATED_PCH_SRC):
804		$(ECHO) "#include \"$$(notdir $$($1_PRECOMPILED_HEADER))\"" > $$@
805
806      else ifneq ($(findstring $(TOOLCHAIN_TYPE), gcc clang), )
807        ifeq ($(TOOLCHAIN_TYPE), gcc)
808          $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).gch
809          $1_USE_PCH_FLAGS := -I$$($1_OBJECT_DIR)/precompiled
810        else ifeq ($(TOOLCHAIN_TYPE), clang)
811          $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).pch
812          $1_USE_PCH_FLAGS := -include-pch $$($1_PCH_FILE)
813        endif
814        $1_PCH_DEPS_FILE := $$($1_PCH_FILE).d
815        $1_PCH_DEPS_TARGETS_FILE := $$($1_PCH_FILE).d.targets
816
817        -include $$($1_PCH_DEPS_FILE)
818        -include $$($1_PCH_DEPS_TARGETS_FILE)
819
820        $1_PCH_COMMAND := $$($1_CC) $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
821            $$($1_OPT_CFLAGS) -x c++-header -c $(GENDEPS_FLAGS) \
822            $$(addsuffix .tmp, $$($1_PCH_DEPS_FILE))
823
824        $$($1_PCH_FILE): $$($1_PRECOMPILED_HEADER) $$($1_COMPILE_VARDEPS_FILE)
825		$$(call LogInfo, Generating precompiled header)
826		$$(call MakeDir, $$(@D))
827		$$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \
828		    $$($1_PCH_COMMAND) $$< -o $$@))
829		$$(call fix-deps-file, $$($1_PCH_DEPS_FILE))
830		$(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_PCH_DEPS_FILE) \
831		    > $$($1_PCH_DEPS_TARGETS_FILE)
832
833        $$($1_ALL_OBJS): $$($1_PCH_FILE)
834
835        # Generate the corresponding compile_commands.json fragment.
836        $1_PCH_FILE_JSON := $$(MAKESUPPORT_OUTPUTDIR)/compile-commands/$$(subst /,_,$$(subst \
837            $$(OUTPUTDIR)/,,$$($1_PCH_FILE))).json
838        $1_ALL_OBJS_JSON += $$($1_PCH_FILE_JSON)
839
840        $$($1_PCH_FILE_JSON): $$($1_PRECOMPILED_HEADER) $$($1_COMPILE_VARDEPS_FILE)
841		$$(call WriteCompileCommandsFragment, $$@, $$(PWD), $$<, \
842		    $$($1_PCH_COMMAND) $$< -o $$($1_PCH_FILE))
843      endif
844    endif
845  endif
846
847  # Now call SetupCompileNativeFile for each source file we are going to compile.
848  $$(foreach file, $$($1_SRCS), \
849      $$(eval $$(call SetupCompileNativeFile, $1_$$(notdir $$(file)),\
850          FILE := $$(file), \
851          BASE := $1, \
852      )) \
853  )
854
855  # Setup rule for printing progress info when compiling source files.
856  # This is a rough heuristic and may not always print accurate information.
857  $$($1_BUILD_INFO): $$($1_SRCS) $$($1_COMPILE_VARDEPS_FILE)
858        ifeq ($$(wildcard $$($1_TARGET)), )
859	  $$(call LogWarn, Creating $$(subst $$(OUTPUTDIR)/,,$$($1_TARGET)) from $$(words \
860	      $$(filter-out %.vardeps, $$?)) file(s))
861        else
862	  $$(call LogWarn, $$(strip Updating $$(subst $$(OUTPUTDIR)/,,$$($1_TARGET)) \
863	      $$(if $$(filter-out %.vardeps, $$?), \
864	        due to $$(words $$(filter-out %.vardeps, $$?)) file(s), \
865	      $$(if $$(filter %.vardeps, $$?), due to makefile changes))))
866        endif
867	$(TOUCH) $$@
868
869  # On windows we need to create a resource file
870  ifeq ($(call isTargetOs, windows), true)
871    ifneq ($$($1_VERSIONINFO_RESOURCE), )
872      $1_RES := $$($1_OBJECT_DIR)/$$($1_BASENAME).res
873      $1_RES_DEPS_FILE := $$($1_RES).d
874      $1_RES_DEPS_TARGETS_FILE := $$($1_RES).d.targets
875      -include $$($1_RES_DEPS_FILE)
876      -include $$($1_RES_DEPS_TARGETS_FILE)
877
878      $1_RES_VARDEPS := $$($1_RC) $$($1_RCFLAGS)
879      $1_RES_VARDEPS_FILE := $$(call DependOnVariable, $1_RES_VARDEPS, \
880          $$($1_RES).vardeps)
881
882      $$($1_RES): $$($1_VERSIONINFO_RESOURCE) $$($1_RES_VARDEPS_FILE)
883		$$(call LogInfo, Compiling resource $$(notdir $$($1_VERSIONINFO_RESOURCE)) (for $$($1_BASENAME)))
884		$$(call MakeDir, $$(@D) $$($1_OBJECT_DIR))
885		$$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \
886		    $$($1_RC) $$($1_RCFLAGS) $$($1_SYSROOT_CFLAGS) $(CC_OUT_OPTION)$$@ \
887		    $$($1_VERSIONINFO_RESOURCE) 2>&1 ))
888                # Windows RC compiler does not support -showIncludes, so we mis-use CL
889                # for this. Filter out RC specific arguments that are unknown to CL.
890                # For some unknown reason, in this case CL actually outputs the show
891                # includes to stderr so need to redirect it to hide the output from the
892                # main log.
893		$$(call ExecuteWithLog, $$($1_RES_DEPS_FILE).obj, \
894		    $$($1_CC) $$(filter-out -l%, $$($1_RCFLAGS)) \
895		        $$($1_SYSROOT_CFLAGS) -showIncludes -nologo -TC \
896		        $(CC_OUT_OPTION)$$($1_RES_DEPS_FILE).obj -P -Fi$$($1_RES_DEPS_FILE).pp \
897		        $$($1_VERSIONINFO_RESOURCE)) 2>&1 \
898		    | $(TR) -d '\r' | $(GREP) -v -e "^Note: including file:" \
899		        -e "^$$(notdir $$($1_VERSIONINFO_RESOURCE))$$$$" || test "$$$$?" = "1" ; \
900		$(ECHO) $$($1_RES): \\ > $$($1_RES_DEPS_FILE) ; \
901		$(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_RES_DEPS_FILE).obj.log \
902		    >> $$($1_RES_DEPS_FILE) ; \
903		$(ECHO) >> $$($1_RES_DEPS_FILE) ;\
904		$(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_RES_DEPS_FILE) \
905		    > $$($1_RES_DEPS_TARGETS_FILE)
906    endif
907  endif
908
909  # Create a rule to collect all the individual make dependency files into a
910  # single makefile.
911  $1_DEPS_FILE := $$($1_OBJECT_DIR)/$1.d
912
913  $$($1_DEPS_FILE): $$($1_ALL_OBJS) $$($1_RES)
914	$(RM) $$@
915        # CD into dir to reduce risk of hitting command length limits, which
916        # could otherwise happen if TOPDIR is a very long path.
917	$(CD) $$($1_OBJECT_DIR) && $(CAT) *.d > $$@.tmp
918	$(CD) $$($1_OBJECT_DIR) && $(CAT) *.d.targets | $(SORT) -u >> $$@.tmp
919        # After generating the file, which happens after all objects have been
920        # compiled, copy it to .old extension. On the next make invocation, this
921        # .old file will be included by make.
922	$(CP) $$@.tmp $$@.old
923	$(MV) $$@.tmp $$@
924
925  $1 += $$($1_DEPS_FILE)
926
927  # The include must be on the .old file, which represents the state from the
928  # previous invocation of make. The file being included must not have a rule
929  # defined for it as otherwise make will think it has to run the rule before
930  # being able to include the file, which would be wrong since we specifically
931  # need the file as it was generated by a previous make invocation.
932  ifneq ($$(wildcard $$($1_DEPS_FILE).old), )
933    $1_DEPS_FILE_LOADED := true
934    -include $$($1_DEPS_FILE).old
935  endif
936
937  ifneq ($(DISABLE_MAPFILES), true)
938    $1_REAL_MAPFILE := $$($1_MAPFILE)
939  endif
940
941  # Pickup extra OPENJDK_TARGET_OS_TYPE and/or OPENJDK_TARGET_OS dependent variables
942  # for LDFLAGS and LIBS
943  $1_EXTRA_LDFLAGS += $$($1_LDFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LDFLAGS_$(OPENJDK_TARGET_OS))
944  $1_EXTRA_LIBS += $$($1_LIBS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LIBS_$(OPENJDK_TARGET_OS))
945  ifneq ($$($1_REAL_MAPFILE), )
946    $1_EXTRA_LDFLAGS += $(call SET_SHARED_LIBRARY_MAPFILE,$$($1_REAL_MAPFILE))
947  endif
948
949  ifneq ($$($1_COPY_DEBUG_SYMBOLS), false)
950    $1_COPY_DEBUG_SYMBOLS := $(COPY_DEBUG_SYMBOLS)
951  endif
952
953  ifneq ($$($1_ZIP_EXTERNAL_DEBUG_SYMBOLS), false)
954    $1_ZIP_EXTERNAL_DEBUG_SYMBOLS := $(ZIP_EXTERNAL_DEBUG_SYMBOLS)
955  endif
956
957  ifeq ($$($1_COPY_DEBUG_SYMBOLS), true)
958    ifneq ($$($1_DEBUG_SYMBOLS), false)
959      $$(call SetIfEmpty, $1_SYMBOLS_DIR, $$($1_OUTPUT_DIR))
960      # Only copy debug symbols for dynamic libraries and programs.
961      ifneq ($$($1_TYPE), STATIC_LIBRARY)
962        # Generate debuginfo files.
963        ifeq ($(call isTargetOs, windows), true)
964          $1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb" \
965              "-map:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map"
966          ifeq ($(SHIP_DEBUG_SYMBOLS), public)
967            $1_EXTRA_LDFLAGS += "-pdbstripped:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).stripped.pdb"
968          endif
969          $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb \
970              $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map
971
972        else ifeq ($(call isTargetOs, linux bsd), true)
973          $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).debuginfo
974          # Setup the command line creating debuginfo files, to be run after linking.
975          # It cannot be run separately since it updates the original target file
976          $1_CREATE_DEBUGINFO_CMDS := \
977              $$($1_OBJCOPY) --only-keep-debug $$($1_TARGET) $$($1_DEBUGINFO_FILES) $$(NEWLINE) \
978              $(CD) $$($1_SYMBOLS_DIR) && \
979                  $$($1_OBJCOPY) --add-gnu-debuglink=$$($1_DEBUGINFO_FILES) $$($1_TARGET)
980
981        else ifeq ($(call isTargetOs, aix), true)
982          # AIX does not provide the equivalent of OBJCOPY to extract debug symbols,
983          # so we copy the compiled object with symbols to the .debuginfo file, which
984          # happens prior to the STRIP_CMD on the original target object file.
985          $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).debuginfo
986          $1_CREATE_DEBUGINFO_CMDS := $(CP) $$($1_TARGET) $$($1_DEBUGINFO_FILES)
987
988        else ifeq ($(call isTargetOs, macosx), true)
989          $1_DEBUGINFO_FILES := \
990              $$($1_SYMBOLS_DIR)/$$($1_BASENAME).dSYM/Contents/Info.plist \
991              $$($1_SYMBOLS_DIR)/$$($1_BASENAME).dSYM/Contents/Resources/DWARF/$$($1_BASENAME)
992          $1_CREATE_DEBUGINFO_CMDS := \
993              $(DSYMUTIL) --out $$($1_SYMBOLS_DIR)/$$($1_BASENAME).dSYM $$($1_TARGET)
994        endif
995
996        # Since the link rule creates more than one file that we want to track,
997        # we have to use some tricks to get make to cooperate. To properly
998        # trigger downstream dependants of $$($1_DEBUGINFO_FILES), we must have
999        # a recipe in the rule below. To avoid rerunning the recipe every time
1000        # have it touch the target. If a debuginfo file is deleted by something
1001        # external, explicitly delete the TARGET to trigger a rebuild of both.
1002        ifneq ($$(wildcard $$($1_DEBUGINFO_FILES)), $$($1_DEBUGINFO_FILES))
1003          $$(call LogDebug, Deleting $$($1_BASENAME) because debuginfo files are missing)
1004          $$(shell $(RM) $$($1_TARGET))
1005        endif
1006        $$($1_DEBUGINFO_FILES): $$($1_TARGET)
1007		$$(if $$(CORRECT_FUNCTION_IN_RECIPE_EVALUATION), \
1008		  $$(if $$(wildcard $$@), , $$(error $$@ was not created for $$<)) \
1009		)
1010		$(TOUCH) $$@
1011
1012        $1 += $$($1_DEBUGINFO_FILES)
1013
1014        ifeq ($$($1_ZIP_EXTERNAL_DEBUG_SYMBOLS), true)
1015          $1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).diz
1016          $1 += $$($1_DEBUGINFO_ZIP)
1017
1018          # The dependency on TARGET is needed for debuginfo files
1019          # to be rebuilt properly.
1020          $$($1_DEBUGINFO_ZIP): $$($1_DEBUGINFO_FILES) $$($1_TARGET)
1021		$(CD) $$($1_SYMBOLS_DIR) && \
1022		    $(ZIPEXE) -q -r $$@ $$(subst $$($1_SYMBOLS_DIR)/,, $$($1_DEBUGINFO_FILES))
1023
1024        endif
1025       endif # !STATIC_LIBRARY
1026    endif # $1_DEBUG_SYMBOLS != false
1027  endif # COPY_DEBUG_SYMBOLS
1028
1029  # Unless specifically set, stripping should only happen if symbols are also
1030  # being copied.
1031  $$(call SetIfEmpty, $1_STRIP_SYMBOLS, $$($1_COPY_DEBUG_SYMBOLS))
1032
1033  ifneq ($$($1_STRIP_SYMBOLS), false)
1034    ifneq ($$($1_STRIP), )
1035      # Default to using the global STRIPFLAGS. Allow for overriding with an empty value
1036      $1_STRIPFLAGS ?= $(STRIPFLAGS)
1037      $1_STRIP_CMD := $$($1_STRIP) $$($1_STRIPFLAGS) $$($1_TARGET)
1038    endif
1039  endif
1040
1041  ifeq ($$($1_TYPE), STATIC_LIBRARY)
1042    $1_VARDEPS := $$($1_AR) $$(ARFLAGS) $$($1_ARFLAGS) $$($1_LIBS) \
1043        $$($1_EXTRA_LIBS)
1044    $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
1045        $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).vardeps)
1046
1047    # Generating a static library, ie object file archive.
1048    ifeq ($(STATIC_BUILD), true)
1049      ifeq ($$($1_USE_MAPFILE_FOR_SYMBOLS), true)
1050        STATIC_MAPFILE_DEP := $$($1_MAPFILE)
1051      endif
1052    endif
1053
1054    $1_TARGET_DEPS := $$($1_ALL_OBJS) $$($1_RES) $$($1_VARDEPS_FILE) $$(STATIC_MAPFILE_DEP)
1055
1056    $$($1_TARGET): $$($1_TARGET_DEPS)
1057	$$(call LogInfo, Building static library $$($1_BASENAME))
1058	$$(call MakeDir, $$($1_OUTPUT_DIR) $$($1_SYMBOLS_DIR))
1059	$$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
1060	    $$($1_AR) $$(ARFLAGS) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_ALL_OBJS) \
1061	        $$($1_RES))
1062        ifeq ($(STATIC_BUILD), true)
1063          ifeq ($$($1_USE_MAPFILE_FOR_SYMBOLS), true)
1064	    $(CP) $$($1_MAPFILE) $$(@D)/$$(basename $$(@F)).symbols
1065          else
1066	    $(GetSymbols)
1067          endif
1068        endif
1069  else
1070    # A shared dynamic library or an executable binary has been specified
1071    ifeq ($$($1_TYPE), LIBRARY)
1072      # Generating a dynamic library.
1073      $1_EXTRA_LDFLAGS += $$(call SET_SHARED_LIBRARY_NAME,$$($1_BASENAME))
1074
1075      # Create loadmap on AIX. Helps in diagnosing some problems.
1076      ifneq ($(COMPILER_BINDCMD_FILE_FLAG), )
1077        $1_EXTRA_LDFLAGS += $(COMPILER_BINDCMD_FILE_FLAG)$$($1_OBJECT_DIR)/$$($1_NOSUFFIX).loadmap
1078      endif
1079    endif
1080
1081    ifeq ($(call isTargetOs, windows), true)
1082      ifeq ($$($1_EMBED_MANIFEST), true)
1083        $1_EXTRA_LDFLAGS += -manifest:embed
1084      endif
1085
1086      $1_IMPORT_LIBRARY := $$($1_OBJECT_DIR)/$$($1_NAME).lib
1087      $1_EXTRA_LDFLAGS += "-implib:$$($1_IMPORT_LIBRARY)"
1088      ifeq ($$($1_TYPE), LIBRARY)
1089        # To properly trigger downstream dependants of the import library, just as
1090        # for debug files, we must have a recipe in the rule. To avoid rerunning
1091        # the recipe every time have it touch the target. If an import library
1092        # file is deleted by something external, explicitly delete the target to
1093        # trigger a rebuild of both.
1094        ifneq ($$(wildcard $$($1_IMPORT_LIBRARY)), $$($1_IMPORT_LIBRARY))
1095          $$(call LogDebug, Deleting $$($1_BASENAME) because import library is missing)
1096          $$(shell $(RM) $$($1_TARGET))
1097        endif
1098        $$($1_IMPORT_LIBRARY): $$($1_TARGET)
1099		$(TOUCH) $$@
1100
1101        $1 += $$($1_IMPORT_LIBRARY)
1102      endif
1103    endif
1104
1105    $1_VARDEPS := $$($1_LD) $$($1_SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) \
1106        $$($1_LIBS) $$($1_EXTRA_LIBS) $$($1_MT) \
1107        $$($1_CREATE_DEBUGINFO_CMDS) $$($1_MANIFEST_VERSION) \
1108        $$($1_STRIP_CMD)
1109    $1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, \
1110        $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).vardeps)
1111
1112    $1_LD_OBJ_ARG := $$($1_ALL_OBJS)
1113
1114    # If there are many object files, use an @-file...
1115    ifneq ($$(word 17, $$($1_ALL_OBJS)), )
1116      $1_OBJ_FILE_LIST := $$($1_OBJECT_DIR)/_$1_objectfilenames.txt
1117      ifneq ($(COMPILER_COMMAND_FILE_FLAG), )
1118        $1_LD_OBJ_ARG := $(COMPILER_COMMAND_FILE_FLAG)$$($1_OBJ_FILE_LIST)
1119      else
1120        # ...except for toolchains which don't support them.
1121        $1_LD_OBJ_ARG := `cat $$($1_OBJ_FILE_LIST)`
1122      endif
1123    endif
1124
1125    # Unfortunately the @-file trick does not work reliably when using clang.
1126    # Clang does not propagate the @-file parameter to the ld sub process, but
1127    # instead puts the full content on the command line. At least the llvm ld
1128    # does not even support an @-file.
1129    #
1130    # When linking a large amount of object files, we risk hitting the limit
1131    # of the command line length even on posix systems if the path length of
1132    # the output dir is very long due to our use of absolute paths. To
1133    # mitigate this, use paths relative to the output dir when linking over
1134    # 500 files with clang and the output dir path is deep.
1135    ifneq ($$(word 500, $$($1_ALL_OBJS)), )
1136      ifeq ($$(TOOLCHAIN_TYPE), clang)
1137        # There is no strlen function in make, but checking path depth is a
1138        # reasonable approximation.
1139        ifneq ($$(word 10, $$(subst /, ,$$(OUTPUTDIR))), )
1140          $1_LINK_OBJS_RELATIVE := true
1141          $1_ALL_OBJS_RELATIVE := $$(patsubst $$(OUTPUTDIR)/%, %, $$($1_ALL_OBJS))
1142        endif
1143      endif
1144    endif
1145
1146    $1_TARGET_DEPS := $$($1_ALL_OBJS) $$($1_RES) $$($1_MANIFEST) \
1147        $$($1_REAL_MAPFILE) $$($1_VARDEPS_FILE)
1148
1149    $$($1_TARGET): $$($1_TARGET_DEPS)
1150                ifneq ($$($1_OBJ_FILE_LIST), )
1151                  ifeq ($$($1_LINK_OBJS_RELATIVE), true)
1152		    $$(eval $$(call ListPathsSafely, $1_ALL_OBJS_RELATIVE, $$($1_OBJ_FILE_LIST)))
1153                  else
1154		    $$(eval $$(call ListPathsSafely, $1_ALL_OBJS, $$($1_OBJ_FILE_LIST)))
1155                  endif
1156                endif
1157                # Keep as much as possible on one execution line for best performance
1158                # on Windows
1159		$$(call LogInfo, Linking $$($1_BASENAME))
1160		$$(call MakeDir, $$($1_OUTPUT_DIR) $$($1_SYMBOLS_DIR))
1161                ifeq ($(call isTargetOs, windows), true)
1162
1163		  $$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
1164		      $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
1165		          $(LD_OUT_OPTION)$$($1_TARGET) $$($1_LD_OBJ_ARG) $$($1_RES) \
1166		          $$($1_LIBS) $$($1_EXTRA_LIBS)) \
1167		      | $(GREP) -v "^   Creating library .*\.lib and object .*\.exp" || \
1168		          test "$$$$?" = "1" ; \
1169		  $$($1_CREATE_DEBUGINFO_CMDS)
1170		  $$($1_STRIP_CMD)
1171                 ifeq ($(call isBuildOsEnv, windows.wsl2), true)
1172		    $$(CHMOD) +x $$($1_TARGET)
1173                 endif
1174                else
1175		  $$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link, \
1176		      $$(if $$($1_LINK_OBJS_RELATIVE), $$(CD) $$(OUTPUTDIR) ; ) \
1177		      $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
1178		          $(LD_OUT_OPTION)$$($1_TARGET) $$($1_LD_OBJ_ARG) $$($1_RES) \
1179		          $$($1_LIBS) $$($1_EXTRA_LIBS)) ; \
1180		  $$($1_CREATE_DEBUGINFO_CMDS)
1181		  $$($1_STRIP_CMD)
1182                endif
1183                ifeq ($(call isTargetOs, windows), true)
1184                  ifneq ($$($1_MANIFEST), )
1185		    $$($1_MT) -nologo -manifest $$($1_MANIFEST) -identity:"$$($1_NAME).exe, version=$$($1_MANIFEST_VERSION)" -outputresource:$$@;#1
1186                  endif
1187                endif
1188                # This only works if the openjdk_codesign identity is present on the system. Let
1189                # silently fail otherwise.
1190                ifneq ($(CODESIGN), )
1191		  $(CODESIGN) -f -s "$(MACOSX_CODESIGN_IDENTITY)" --timestamp --options runtime \
1192		      --entitlements $$(call GetEntitlementsFile, $$@) $$@
1193                endif
1194  endif
1195
1196  ifeq ($(GENERATE_COMPILE_COMMANDS_ONLY), true)
1197    $1 := $$($1_ALL_OBJS_JSON)
1198  endif
1199endef
1200
1201endif # _NATIVE_COMPILATION_GMK
1202