xref: /aosp_15_r20/external/pigweed/pw_toolchain/generate_toolchain.gni (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker# Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker#
3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker# the License at
6*61c4878aSAndroid Build Coastguard Worker#
7*61c4878aSAndroid Build Coastguard Worker#     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker#
9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker# the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Workerimport("//build_overrides/pigweed.gni")
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_toolchain/static_analysis_toolchain.gni")
18*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_toolchain/toolchain_args.gni")
19*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_toolchain/universal_tools.gni")
20*61c4878aSAndroid Build Coastguard Worker
21*61c4878aSAndroid Build Coastguard Worker# Creates a toolchain target.
22*61c4878aSAndroid Build Coastguard Worker#
23*61c4878aSAndroid Build Coastguard Worker# Args:
24*61c4878aSAndroid Build Coastguard Worker#   ar: (required) String indicating the archive tool to use.
25*61c4878aSAndroid Build Coastguard Worker#   cc: (required) String indicating the C compiler to use.
26*61c4878aSAndroid Build Coastguard Worker#   cxx: (required) String indicating the C++ compiler to use.
27*61c4878aSAndroid Build Coastguard Worker#   ld: (optional) String indicating the linking binary to use.
28*61c4878aSAndroid Build Coastguard Worker#   is_host_toolchain: (optional) Boolean indicating if the outputs are meant
29*61c4878aSAndroid Build Coastguard Worker#     for the $host_os.
30*61c4878aSAndroid Build Coastguard Worker#   final_binary_extension: (optional) The extension to apply to final linked
31*61c4878aSAndroid Build Coastguard Worker#     binaries.
32*61c4878aSAndroid Build Coastguard Worker#   link_whole_archive: (optional) Boolean indicating if the linker should load
33*61c4878aSAndroid Build Coastguard Worker#     all object files when resolving symbols.
34*61c4878aSAndroid Build Coastguard Worker#   link_group: (optional) Boolean indicating if the linker should use
35*61c4878aSAndroid Build Coastguard Worker#     a group to resolve circular dependencies between artifacts.
36*61c4878aSAndroid Build Coastguard Worker#   link_generate_map_file: (optional) Boolean indicating if to add linker
37*61c4878aSAndroid Build Coastguard Worker#     flags to generate a mapfile. Defaults to true.
38*61c4878aSAndroid Build Coastguard Worker#   generate_from: (optional) The full target name of the toolchain that can
39*61c4878aSAndroid Build Coastguard Worker#     trigger this toolchain to be generated. GN only allows one toolchain to
40*61c4878aSAndroid Build Coastguard Worker#     be generated at a given target path, so if multiple toolchains parse the
41*61c4878aSAndroid Build Coastguard Worker#     same generate_toolchain target only one should declare a toolchain. This
42*61c4878aSAndroid Build Coastguard Worker#     is primarily to allow generating sub-toolchains. Defaults to
43*61c4878aSAndroid Build Coastguard Worker#     default_toolchain.
44*61c4878aSAndroid Build Coastguard Worker#   defaults: (required) A scope setting GN build arg values to apply to GN
45*61c4878aSAndroid Build Coastguard Worker#     targets in this toolchain. These take precedence over args.gni settings.
46*61c4878aSAndroid Build Coastguard Worker#   static_analysis: (optional) A scope defining args to apply to the
47*61c4878aSAndroid Build Coastguard Worker#     static_analysis toolchain. If the scope is not defined, static analysis
48*61c4878aSAndroid Build Coastguard Worker#     will be disabled. If provided, static_analysis will be enabled iff
49*61c4878aSAndroid Build Coastguard Worker#     required enabled field in scope is declared true. See
50*61c4878aSAndroid Build Coastguard Worker#     static_analysis_toolchain.gni for more information on scope members.
51*61c4878aSAndroid Build Coastguard Worker#
52*61c4878aSAndroid Build Coastguard Worker# The defaults scope should contain values for builtin GN arguments:
53*61c4878aSAndroid Build Coastguard Worker#   current_cpu: The CPU of the toolchain.
54*61c4878aSAndroid Build Coastguard Worker#     Well known values include "arm", "arm64", "x64", "x86", and "mips".
55*61c4878aSAndroid Build Coastguard Worker#   current_os: The OS of the toolchain. Defaults to "".
56*61c4878aSAndroid Build Coastguard Worker#     Well known values include "win", "mac", "linux", "android", and "ios".
57*61c4878aSAndroid Build Coastguard Worker#
58*61c4878aSAndroid Build Coastguard Worker# TODO: b/234891809 - This should be renamed to pw_generate_toolchain.
59*61c4878aSAndroid Build Coastguard Workertemplate("generate_toolchain") {
60*61c4878aSAndroid Build Coastguard Worker  assert(defined(invoker.defaults), "toolchain is missing 'defaults'")
61*61c4878aSAndroid Build Coastguard Worker
62*61c4878aSAndroid Build Coastguard Worker  # On the default toolchain invocation, you typically need to generate all
63*61c4878aSAndroid Build Coastguard Worker  # toolchains you encounter. For sub-toolchains, they must be generated from
64*61c4878aSAndroid Build Coastguard Worker  # the context of their parent.
65*61c4878aSAndroid Build Coastguard Worker  if (defined(invoker.generate_from)) {
66*61c4878aSAndroid Build Coastguard Worker    _generate_toolchain =
67*61c4878aSAndroid Build Coastguard Worker        get_label_info(invoker.generate_from, "label_no_toolchain") ==
68*61c4878aSAndroid Build Coastguard Worker        current_toolchain
69*61c4878aSAndroid Build Coastguard Worker  } else {
70*61c4878aSAndroid Build Coastguard Worker    _generate_toolchain = default_toolchain == current_toolchain
71*61c4878aSAndroid Build Coastguard Worker  }
72*61c4878aSAndroid Build Coastguard Worker
73*61c4878aSAndroid Build Coastguard Worker  if (_generate_toolchain) {
74*61c4878aSAndroid Build Coastguard Worker    # TODO(amontanez): This should be renamed to build_args as "defaults" isn't
75*61c4878aSAndroid Build Coastguard Worker    # sufficiently descriptive.
76*61c4878aSAndroid Build Coastguard Worker    invoker_toolchain_args = invoker.defaults
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard Worker    # These values should always be set as they influence toolchain
79*61c4878aSAndroid Build Coastguard Worker    # behavior, but allow them to be unset as a transitional measure.
80*61c4878aSAndroid Build Coastguard Worker    if (!defined(invoker_toolchain_args.current_cpu)) {
81*61c4878aSAndroid Build Coastguard Worker      invoker_toolchain_args.current_cpu = ""
82*61c4878aSAndroid Build Coastguard Worker    }
83*61c4878aSAndroid Build Coastguard Worker    if (!defined(invoker_toolchain_args.current_os)) {
84*61c4878aSAndroid Build Coastguard Worker      invoker_toolchain_args.current_os = ""
85*61c4878aSAndroid Build Coastguard Worker    }
86*61c4878aSAndroid Build Coastguard Worker
87*61c4878aSAndroid Build Coastguard Worker    # Determine OS of toolchain, which is the builtin argument "current_os".
88*61c4878aSAndroid Build Coastguard Worker    toolchain_os = invoker_toolchain_args.current_os
89*61c4878aSAndroid Build Coastguard Worker
90*61c4878aSAndroid Build Coastguard Worker    toolchain(target_name) {
91*61c4878aSAndroid Build Coastguard Worker      # Uncomment this line to see which toolchains generate other toolchains.
92*61c4878aSAndroid Build Coastguard Worker      # print("Generating toolchain: ${target_name} by ${current_toolchain}")
93*61c4878aSAndroid Build Coastguard Worker
94*61c4878aSAndroid Build Coastguard Worker      assert(defined(invoker.cc), "toolchain is missing 'cc'")
95*61c4878aSAndroid Build Coastguard Worker      tool("asm") {
96*61c4878aSAndroid Build Coastguard Worker        if (pw_command_launcher != "") {
97*61c4878aSAndroid Build Coastguard Worker          command_launcher = pw_command_launcher
98*61c4878aSAndroid Build Coastguard Worker        }
99*61c4878aSAndroid Build Coastguard Worker        depfile = "{{output}}.d"
100*61c4878aSAndroid Build Coastguard Worker        command = string_join(" ",
101*61c4878aSAndroid Build Coastguard Worker                              [
102*61c4878aSAndroid Build Coastguard Worker                                invoker.cc,
103*61c4878aSAndroid Build Coastguard Worker                                "-MMD -MF $depfile",  # Write out dependencies.
104*61c4878aSAndroid Build Coastguard Worker                                "{{asmflags}}",
105*61c4878aSAndroid Build Coastguard Worker                                "{{cflags}}",
106*61c4878aSAndroid Build Coastguard Worker                                "{{defines}}",
107*61c4878aSAndroid Build Coastguard Worker                                "{{include_dirs}}",
108*61c4878aSAndroid Build Coastguard Worker                                "-c {{source}}",
109*61c4878aSAndroid Build Coastguard Worker                                "-o {{output}}",
110*61c4878aSAndroid Build Coastguard Worker                              ])
111*61c4878aSAndroid Build Coastguard Worker        depsformat = "gcc"
112*61c4878aSAndroid Build Coastguard Worker        description = "as {{output}}"
113*61c4878aSAndroid Build Coastguard Worker        outputs = [
114*61c4878aSAndroid Build Coastguard Worker          # Use {{source_file_part}}, which includes the extension, instead of
115*61c4878aSAndroid Build Coastguard Worker          # {{source_name_part}} so that object files created from <file_name>.c
116*61c4878aSAndroid Build Coastguard Worker          # and <file_name>.cc sources are unique.
117*61c4878aSAndroid Build Coastguard Worker          "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o",
118*61c4878aSAndroid Build Coastguard Worker        ]
119*61c4878aSAndroid Build Coastguard Worker      }
120*61c4878aSAndroid Build Coastguard Worker
121*61c4878aSAndroid Build Coastguard Worker      tool("cc") {
122*61c4878aSAndroid Build Coastguard Worker        if (pw_command_launcher != "") {
123*61c4878aSAndroid Build Coastguard Worker          command_launcher = pw_command_launcher
124*61c4878aSAndroid Build Coastguard Worker        }
125*61c4878aSAndroid Build Coastguard Worker        depfile = "{{output}}.d"
126*61c4878aSAndroid Build Coastguard Worker        command = string_join(" ",
127*61c4878aSAndroid Build Coastguard Worker                              [
128*61c4878aSAndroid Build Coastguard Worker                                invoker.cc,
129*61c4878aSAndroid Build Coastguard Worker                                "-MMD -MF $depfile",  # Write out dependencies.
130*61c4878aSAndroid Build Coastguard Worker                                "{{cflags}}",
131*61c4878aSAndroid Build Coastguard Worker                                "{{cflags_c}}",  # Must come after {{cflags}}.
132*61c4878aSAndroid Build Coastguard Worker                                "{{defines}}",
133*61c4878aSAndroid Build Coastguard Worker                                "{{include_dirs}}",
134*61c4878aSAndroid Build Coastguard Worker                                "-c {{source}}",
135*61c4878aSAndroid Build Coastguard Worker                                "-o {{output}}",
136*61c4878aSAndroid Build Coastguard Worker                              ])
137*61c4878aSAndroid Build Coastguard Worker        depsformat = "gcc"
138*61c4878aSAndroid Build Coastguard Worker        description = "cc {{output}}"
139*61c4878aSAndroid Build Coastguard Worker        outputs = [
140*61c4878aSAndroid Build Coastguard Worker          "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o",
141*61c4878aSAndroid Build Coastguard Worker        ]
142*61c4878aSAndroid Build Coastguard Worker      }
143*61c4878aSAndroid Build Coastguard Worker
144*61c4878aSAndroid Build Coastguard Worker      assert(defined(invoker.cxx), "toolchain is missing 'cxx'")
145*61c4878aSAndroid Build Coastguard Worker      tool("cxx") {
146*61c4878aSAndroid Build Coastguard Worker        if (pw_command_launcher != "") {
147*61c4878aSAndroid Build Coastguard Worker          command_launcher = pw_command_launcher
148*61c4878aSAndroid Build Coastguard Worker        }
149*61c4878aSAndroid Build Coastguard Worker        depfile = "{{output}}.d"
150*61c4878aSAndroid Build Coastguard Worker        command = string_join(" ",
151*61c4878aSAndroid Build Coastguard Worker                              [
152*61c4878aSAndroid Build Coastguard Worker                                invoker.cxx,
153*61c4878aSAndroid Build Coastguard Worker                                "-MMD -MF $depfile",  # Write out dependencies.
154*61c4878aSAndroid Build Coastguard Worker                                "{{cflags}}",
155*61c4878aSAndroid Build Coastguard Worker                                "{{cflags_cc}}",  # Must come after {{cflags}}.
156*61c4878aSAndroid Build Coastguard Worker                                "{{defines}}",
157*61c4878aSAndroid Build Coastguard Worker                                "{{include_dirs}}",
158*61c4878aSAndroid Build Coastguard Worker                                "-c {{source}}",
159*61c4878aSAndroid Build Coastguard Worker                                "-o {{output}}",
160*61c4878aSAndroid Build Coastguard Worker                              ])
161*61c4878aSAndroid Build Coastguard Worker        depsformat = "gcc"
162*61c4878aSAndroid Build Coastguard Worker        description = "c++ {{output}}"
163*61c4878aSAndroid Build Coastguard Worker        outputs = [
164*61c4878aSAndroid Build Coastguard Worker          "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o",
165*61c4878aSAndroid Build Coastguard Worker        ]
166*61c4878aSAndroid Build Coastguard Worker      }
167*61c4878aSAndroid Build Coastguard Worker
168*61c4878aSAndroid Build Coastguard Worker      tool("objc") {
169*61c4878aSAndroid Build Coastguard Worker        if (pw_command_launcher != "") {
170*61c4878aSAndroid Build Coastguard Worker          command_launcher = pw_command_launcher
171*61c4878aSAndroid Build Coastguard Worker        }
172*61c4878aSAndroid Build Coastguard Worker        depfile = "{{output}}.d"
173*61c4878aSAndroid Build Coastguard Worker        command =
174*61c4878aSAndroid Build Coastguard Worker            string_join(" ",
175*61c4878aSAndroid Build Coastguard Worker                        [
176*61c4878aSAndroid Build Coastguard Worker                          invoker.cc,
177*61c4878aSAndroid Build Coastguard Worker                          "-MMD -MF $depfile",  # Write out dependencies.
178*61c4878aSAndroid Build Coastguard Worker                          "{{cflags}}",
179*61c4878aSAndroid Build Coastguard Worker                          "{{cflags_objc}}",  # Must come after {{cflags}}.
180*61c4878aSAndroid Build Coastguard Worker                          "{{defines}}",
181*61c4878aSAndroid Build Coastguard Worker                          "{{include_dirs}}",
182*61c4878aSAndroid Build Coastguard Worker                          "{{framework_dirs}}",
183*61c4878aSAndroid Build Coastguard Worker                          "-c {{source}}",
184*61c4878aSAndroid Build Coastguard Worker                          "-o {{output}}",
185*61c4878aSAndroid Build Coastguard Worker                        ])
186*61c4878aSAndroid Build Coastguard Worker        depsformat = "gcc"
187*61c4878aSAndroid Build Coastguard Worker        description = "objc {{output}}"
188*61c4878aSAndroid Build Coastguard Worker        outputs = [
189*61c4878aSAndroid Build Coastguard Worker          "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o",
190*61c4878aSAndroid Build Coastguard Worker        ]
191*61c4878aSAndroid Build Coastguard Worker      }
192*61c4878aSAndroid Build Coastguard Worker
193*61c4878aSAndroid Build Coastguard Worker      tool("objcxx") {
194*61c4878aSAndroid Build Coastguard Worker        if (pw_command_launcher != "") {
195*61c4878aSAndroid Build Coastguard Worker          command_launcher = pw_command_launcher
196*61c4878aSAndroid Build Coastguard Worker        }
197*61c4878aSAndroid Build Coastguard Worker        depfile = "{{output}}.d"
198*61c4878aSAndroid Build Coastguard Worker        command =
199*61c4878aSAndroid Build Coastguard Worker            string_join(" ",
200*61c4878aSAndroid Build Coastguard Worker                        [
201*61c4878aSAndroid Build Coastguard Worker                          invoker.cxx,
202*61c4878aSAndroid Build Coastguard Worker                          "-MMD -MF $depfile",  # Write out dependencies.
203*61c4878aSAndroid Build Coastguard Worker                          "{{cflags}}",
204*61c4878aSAndroid Build Coastguard Worker                          "{{cflags_objcc}}",  # Must come after {{cflags}}.
205*61c4878aSAndroid Build Coastguard Worker                          "{{defines}}",
206*61c4878aSAndroid Build Coastguard Worker                          "{{include_dirs}}",
207*61c4878aSAndroid Build Coastguard Worker                          "{{framework_dirs}}",
208*61c4878aSAndroid Build Coastguard Worker                          "-c {{source}}",
209*61c4878aSAndroid Build Coastguard Worker                          "-o {{output}}",
210*61c4878aSAndroid Build Coastguard Worker                        ])
211*61c4878aSAndroid Build Coastguard Worker        depsformat = "gcc"
212*61c4878aSAndroid Build Coastguard Worker        description = "objc++ {{output}}"
213*61c4878aSAndroid Build Coastguard Worker        outputs = [
214*61c4878aSAndroid Build Coastguard Worker          "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o",
215*61c4878aSAndroid Build Coastguard Worker        ]
216*61c4878aSAndroid Build Coastguard Worker      }
217*61c4878aSAndroid Build Coastguard Worker
218*61c4878aSAndroid Build Coastguard Worker      assert(defined(invoker.ar), "toolchain is missing 'ar'")
219*61c4878aSAndroid Build Coastguard Worker      tool("alink") {
220*61c4878aSAndroid Build Coastguard Worker        if (host_os == "win") {
221*61c4878aSAndroid Build Coastguard Worker          rspfile = "{{output}}.rsp"
222*61c4878aSAndroid Build Coastguard Worker          rspfile_content = "{{inputs}}"
223*61c4878aSAndroid Build Coastguard Worker          rm_command = "del /F /Q \"{{output}}\" 2> NUL"
224*61c4878aSAndroid Build Coastguard Worker          command = "cmd /c \"($rm_command) & ${invoker.ar} {{arflags}} rcs {{output}} @$rspfile\""
225*61c4878aSAndroid Build Coastguard Worker        } else {
226*61c4878aSAndroid Build Coastguard Worker          command = "rm -f {{output}} && ${invoker.ar} {{arflags}} rcs {{output}} {{inputs}}"
227*61c4878aSAndroid Build Coastguard Worker        }
228*61c4878aSAndroid Build Coastguard Worker
229*61c4878aSAndroid Build Coastguard Worker        description = "ar {{target_output_name}}{{output_extension}}"
230*61c4878aSAndroid Build Coastguard Worker        outputs =
231*61c4878aSAndroid Build Coastguard Worker            [ "{{output_dir}}/{{target_output_name}}{{output_extension}}" ]
232*61c4878aSAndroid Build Coastguard Worker        default_output_extension = ".a"
233*61c4878aSAndroid Build Coastguard Worker        default_output_dir = "{{target_out_dir}}/lib"
234*61c4878aSAndroid Build Coastguard Worker      }
235*61c4878aSAndroid Build Coastguard Worker
236*61c4878aSAndroid Build Coastguard Worker      lib_switch = "-l"
237*61c4878aSAndroid Build Coastguard Worker      lib_dir_switch = "-L"
238*61c4878aSAndroid Build Coastguard Worker
239*61c4878aSAndroid Build Coastguard Worker      _link_outfile =
240*61c4878aSAndroid Build Coastguard Worker          "{{output_dir}}/{{target_output_name}}{{output_extension}}"
241*61c4878aSAndroid Build Coastguard Worker      if (defined(invoker.ld)) {
242*61c4878aSAndroid Build Coastguard Worker        _link_flags = [
243*61c4878aSAndroid Build Coastguard Worker          invoker.ld,
244*61c4878aSAndroid Build Coastguard Worker          "{{ldflags}}",
245*61c4878aSAndroid Build Coastguard Worker        ]
246*61c4878aSAndroid Build Coastguard Worker      } else {
247*61c4878aSAndroid Build Coastguard Worker        _link_flags = [
248*61c4878aSAndroid Build Coastguard Worker          invoker.cxx,
249*61c4878aSAndroid Build Coastguard Worker          "{{ldflags}}",
250*61c4878aSAndroid Build Coastguard Worker        ]
251*61c4878aSAndroid Build Coastguard Worker      }
252*61c4878aSAndroid Build Coastguard Worker
253*61c4878aSAndroid Build Coastguard Worker      if (defined(invoker.link_generate_map_file)) {
254*61c4878aSAndroid Build Coastguard Worker        _link_generate_map_file = invoker.link_generate_map_file
255*61c4878aSAndroid Build Coastguard Worker      } else {
256*61c4878aSAndroid Build Coastguard Worker        _link_generate_map_file = true
257*61c4878aSAndroid Build Coastguard Worker      }
258*61c4878aSAndroid Build Coastguard Worker
259*61c4878aSAndroid Build Coastguard Worker      _link_outputs = [ _link_outfile ]
260*61c4878aSAndroid Build Coastguard Worker
261*61c4878aSAndroid Build Coastguard Worker      if (_link_generate_map_file) {
262*61c4878aSAndroid Build Coastguard Worker        _link_mapfile = "{{output_dir}}/{{target_output_name}}.map"
263*61c4878aSAndroid Build Coastguard Worker
264*61c4878aSAndroid Build Coastguard Worker        if (toolchain_os == "mac" || toolchain_os == "ios") {
265*61c4878aSAndroid Build Coastguard Worker          _link_flags += [
266*61c4878aSAndroid Build Coastguard Worker            # Output a map file that shows symbols and their location.
267*61c4878aSAndroid Build Coastguard Worker            "-Wl,-map,$_link_mapfile",
268*61c4878aSAndroid Build Coastguard Worker          ]
269*61c4878aSAndroid Build Coastguard Worker        } else {
270*61c4878aSAndroid Build Coastguard Worker          _link_flags += [
271*61c4878aSAndroid Build Coastguard Worker            # Output a map file that shows symbols and their location.
272*61c4878aSAndroid Build Coastguard Worker            "-Wl,-Map,$_link_mapfile",
273*61c4878aSAndroid Build Coastguard Worker            "-Wl,--cref",
274*61c4878aSAndroid Build Coastguard Worker          ]
275*61c4878aSAndroid Build Coastguard Worker        }
276*61c4878aSAndroid Build Coastguard Worker        _link_outputs += [ _link_mapfile ]
277*61c4878aSAndroid Build Coastguard Worker      }
278*61c4878aSAndroid Build Coastguard Worker
279*61c4878aSAndroid Build Coastguard Worker      _rsp_file = "$_link_outfile.rsp"
280*61c4878aSAndroid Build Coastguard Worker      _rsp_contents = []
281*61c4878aSAndroid Build Coastguard Worker
282*61c4878aSAndroid Build Coastguard Worker      _link_group = defined(invoker.link_group) && invoker.link_group
283*61c4878aSAndroid Build Coastguard Worker      if (_link_group) {
284*61c4878aSAndroid Build Coastguard Worker        _rsp_contents += [ "-Wl,--start-group" ]
285*61c4878aSAndroid Build Coastguard Worker      }
286*61c4878aSAndroid Build Coastguard Worker      _rsp_contents += [ "{{inputs}}" ]
287*61c4878aSAndroid Build Coastguard Worker      _rsp_contents += [ "{{frameworks}}" ]
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker      if (defined(invoker.link_whole_archive) && invoker.link_whole_archive) {
290*61c4878aSAndroid Build Coastguard Worker        # Load all object files from all libraries to resolve symbols.
291*61c4878aSAndroid Build Coastguard Worker        # Short of living in the ideal world where all dependency graphs
292*61c4878aSAndroid Build Coastguard Worker        # among static libs are acyclic and all developers diligently
293*61c4878aSAndroid Build Coastguard Worker        # express such graphs in terms that GN understands, this is the
294*61c4878aSAndroid Build Coastguard Worker        # safest option.
295*61c4878aSAndroid Build Coastguard Worker        # Make sure you use this with --gc-sections, otherwise the
296*61c4878aSAndroid Build Coastguard Worker        # resulting binary will contain every symbol defined in every
297*61c4878aSAndroid Build Coastguard Worker        # input file and every static library. That could be quite a lot.
298*61c4878aSAndroid Build Coastguard Worker        _rsp_contents += [
299*61c4878aSAndroid Build Coastguard Worker          "-Wl,--whole-archive",
300*61c4878aSAndroid Build Coastguard Worker          "{{libs}}",
301*61c4878aSAndroid Build Coastguard Worker          "-Wl,--no-whole-archive",
302*61c4878aSAndroid Build Coastguard Worker        ]
303*61c4878aSAndroid Build Coastguard Worker      } else {
304*61c4878aSAndroid Build Coastguard Worker        _rsp_contents += [ "{{libs}}" ]
305*61c4878aSAndroid Build Coastguard Worker      }
306*61c4878aSAndroid Build Coastguard Worker
307*61c4878aSAndroid Build Coastguard Worker      if (_link_group) {
308*61c4878aSAndroid Build Coastguard Worker        _rsp_contents += [ "-Wl,--end-group" ]
309*61c4878aSAndroid Build Coastguard Worker      }
310*61c4878aSAndroid Build Coastguard Worker      _rsp_command = string_join(" ", _rsp_contents)
311*61c4878aSAndroid Build Coastguard Worker
312*61c4878aSAndroid Build Coastguard Worker      _link_flags += [ "@$_rsp_file" ]
313*61c4878aSAndroid Build Coastguard Worker      _link_flags += [ "-o $_link_outfile" ]
314*61c4878aSAndroid Build Coastguard Worker
315*61c4878aSAndroid Build Coastguard Worker      _link_command = string_join(" ", _link_flags)
316*61c4878aSAndroid Build Coastguard Worker
317*61c4878aSAndroid Build Coastguard Worker      tool("link") {
318*61c4878aSAndroid Build Coastguard Worker        command = _link_command
319*61c4878aSAndroid Build Coastguard Worker        rspfile = _rsp_file
320*61c4878aSAndroid Build Coastguard Worker        rspfile_content = _rsp_command
321*61c4878aSAndroid Build Coastguard Worker        description = "ld $_link_outfile"
322*61c4878aSAndroid Build Coastguard Worker        outputs = _link_outputs
323*61c4878aSAndroid Build Coastguard Worker        default_output_dir = "{{target_out_dir}}/bin"
324*61c4878aSAndroid Build Coastguard Worker
325*61c4878aSAndroid Build Coastguard Worker        if (defined(invoker.final_binary_extension)) {
326*61c4878aSAndroid Build Coastguard Worker          default_output_extension = invoker.final_binary_extension
327*61c4878aSAndroid Build Coastguard Worker        } else if (toolchain_os == "win") {
328*61c4878aSAndroid Build Coastguard Worker          default_output_extension = ".exe"
329*61c4878aSAndroid Build Coastguard Worker        } else {
330*61c4878aSAndroid Build Coastguard Worker          default_output_extension = ""
331*61c4878aSAndroid Build Coastguard Worker        }
332*61c4878aSAndroid Build Coastguard Worker      }
333*61c4878aSAndroid Build Coastguard Worker
334*61c4878aSAndroid Build Coastguard Worker      tool("solink") {
335*61c4878aSAndroid Build Coastguard Worker        command = _link_command + " -shared"
336*61c4878aSAndroid Build Coastguard Worker        rspfile = _rsp_file
337*61c4878aSAndroid Build Coastguard Worker        rspfile_content = _rsp_command
338*61c4878aSAndroid Build Coastguard Worker        description = "ld -shared $_link_outfile"
339*61c4878aSAndroid Build Coastguard Worker        outputs = _link_outputs
340*61c4878aSAndroid Build Coastguard Worker        default_output_dir = "{{target_out_dir}}/lib"
341*61c4878aSAndroid Build Coastguard Worker        default_output_extension = ".so"
342*61c4878aSAndroid Build Coastguard Worker      }
343*61c4878aSAndroid Build Coastguard Worker
344*61c4878aSAndroid Build Coastguard Worker      tool("stamp") {
345*61c4878aSAndroid Build Coastguard Worker        # GN-ism: GN gets mad if you directly forward the contents of
346*61c4878aSAndroid Build Coastguard Worker        # pw_universal_stamp.
347*61c4878aSAndroid Build Coastguard Worker        _stamp = pw_universal_stamp
348*61c4878aSAndroid Build Coastguard Worker        forward_variables_from(_stamp, "*")
349*61c4878aSAndroid Build Coastguard Worker      }
350*61c4878aSAndroid Build Coastguard Worker
351*61c4878aSAndroid Build Coastguard Worker      tool("copy") {
352*61c4878aSAndroid Build Coastguard Worker        # GN-ism: GN gets mad if you directly forward the contents of
353*61c4878aSAndroid Build Coastguard Worker        # pw_universal_copy.
354*61c4878aSAndroid Build Coastguard Worker        _copy = pw_universal_copy
355*61c4878aSAndroid Build Coastguard Worker        forward_variables_from(_copy, "*")
356*61c4878aSAndroid Build Coastguard Worker      }
357*61c4878aSAndroid Build Coastguard Worker
358*61c4878aSAndroid Build Coastguard Worker      # Build arguments to be overridden when compiling cross-toolchain:
359*61c4878aSAndroid Build Coastguard Worker      #
360*61c4878aSAndroid Build Coastguard Worker      #   pw_toolchain_defaults: A scope setting defaults to apply to GN targets
361*61c4878aSAndroid Build Coastguard Worker      #     in this toolchain. It is analogous to $pw_target_defaults in
362*61c4878aSAndroid Build Coastguard Worker      #     $dir_pigweed/pw_vars_default.gni.
363*61c4878aSAndroid Build Coastguard Worker      #
364*61c4878aSAndroid Build Coastguard Worker      #   pw_toolchain_SCOPE: A copy of the invoker scope that defines the
365*61c4878aSAndroid Build Coastguard Worker      #     toolchain. Used for generating derivative toolchains.
366*61c4878aSAndroid Build Coastguard Worker      #
367*61c4878aSAndroid Build Coastguard Worker      toolchain_args = {
368*61c4878aSAndroid Build Coastguard Worker        pw_toolchain_SCOPE = {
369*61c4878aSAndroid Build Coastguard Worker        }
370*61c4878aSAndroid Build Coastguard Worker        pw_toolchain_SCOPE = {
371*61c4878aSAndroid Build Coastguard Worker          forward_variables_from(invoker, "*")
372*61c4878aSAndroid Build Coastguard Worker          name = target_name
373*61c4878aSAndroid Build Coastguard Worker        }
374*61c4878aSAndroid Build Coastguard Worker        forward_variables_from(invoker_toolchain_args, "*")
375*61c4878aSAndroid Build Coastguard Worker      }
376*61c4878aSAndroid Build Coastguard Worker
377*61c4878aSAndroid Build Coastguard Worker      _generate_rust_tools = defined(invoker.rustc)
378*61c4878aSAndroid Build Coastguard Worker      if (_generate_rust_tools) {
379*61c4878aSAndroid Build Coastguard Worker        if (defined(invoker.ld)) {
380*61c4878aSAndroid Build Coastguard Worker          _rustc_linker = "-Clinker=${invoker.ld}"
381*61c4878aSAndroid Build Coastguard Worker        } else {
382*61c4878aSAndroid Build Coastguard Worker          _rustc_linker = ""
383*61c4878aSAndroid Build Coastguard Worker        }
384*61c4878aSAndroid Build Coastguard Worker
385*61c4878aSAndroid Build Coastguard Worker        _rustc_command = string_join(
386*61c4878aSAndroid Build Coastguard Worker                " ",
387*61c4878aSAndroid Build Coastguard Worker                [
388*61c4878aSAndroid Build Coastguard Worker                  # TODO: b/234872510 - Ensure this works with Windows.
389*61c4878aSAndroid Build Coastguard Worker                  "RUST_BACKTRACE=1",
390*61c4878aSAndroid Build Coastguard Worker                  "{{rustenv}}",
391*61c4878aSAndroid Build Coastguard Worker                  invoker.rustc,
392*61c4878aSAndroid Build Coastguard Worker                  "{{source}}",
393*61c4878aSAndroid Build Coastguard Worker                  "--crate-name {{crate_name}}",
394*61c4878aSAndroid Build Coastguard Worker                  "--crate-type {{crate_type}}",
395*61c4878aSAndroid Build Coastguard Worker                  _rustc_linker,
396*61c4878aSAndroid Build Coastguard Worker                  "{{externs}}",
397*61c4878aSAndroid Build Coastguard Worker                  "{{rustdeps}}",
398*61c4878aSAndroid Build Coastguard Worker                  "{{rustflags}}",
399*61c4878aSAndroid Build Coastguard Worker                  "-D warnings",
400*61c4878aSAndroid Build Coastguard Worker                  "--color always",
401*61c4878aSAndroid Build Coastguard Worker                  "--emit=dep-info={{output}}.d,link",
402*61c4878aSAndroid Build Coastguard Worker                  "-o {{output_dir}}/{{target_output_name}}{{output_extension}}",
403*61c4878aSAndroid Build Coastguard Worker                ])
404*61c4878aSAndroid Build Coastguard Worker
405*61c4878aSAndroid Build Coastguard Worker        _output = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
406*61c4878aSAndroid Build Coastguard Worker
407*61c4878aSAndroid Build Coastguard Worker        tool("rust_bin") {
408*61c4878aSAndroid Build Coastguard Worker          description = "rustc {{output}}"
409*61c4878aSAndroid Build Coastguard Worker          default_output_dir = "{{target_out_dir}}/bin"
410*61c4878aSAndroid Build Coastguard Worker          depfile = "{{output}}.d"
411*61c4878aSAndroid Build Coastguard Worker          command = _rustc_command
412*61c4878aSAndroid Build Coastguard Worker          outputs = [ _output ]
413*61c4878aSAndroid Build Coastguard Worker        }
414*61c4878aSAndroid Build Coastguard Worker
415*61c4878aSAndroid Build Coastguard Worker        tool("rust_rlib") {
416*61c4878aSAndroid Build Coastguard Worker          description = "rustc {{output}}"
417*61c4878aSAndroid Build Coastguard Worker          default_output_dir = "{{target_out_dir}}/lib"
418*61c4878aSAndroid Build Coastguard Worker          depfile = "{{output}}.d"
419*61c4878aSAndroid Build Coastguard Worker          output_prefix = "lib"
420*61c4878aSAndroid Build Coastguard Worker          default_output_extension = ".rlib"
421*61c4878aSAndroid Build Coastguard Worker          command = _rustc_command
422*61c4878aSAndroid Build Coastguard Worker          outputs = [ _output ]
423*61c4878aSAndroid Build Coastguard Worker        }
424*61c4878aSAndroid Build Coastguard Worker
425*61c4878aSAndroid Build Coastguard Worker        tool("rust_staticlib") {
426*61c4878aSAndroid Build Coastguard Worker          description = "rustc {{output}}"
427*61c4878aSAndroid Build Coastguard Worker          default_output_dir = "{{target_out_dir}}/lib"
428*61c4878aSAndroid Build Coastguard Worker          depfile = "{{output}}.d"
429*61c4878aSAndroid Build Coastguard Worker          output_prefix = "lib"
430*61c4878aSAndroid Build Coastguard Worker          default_output_extension = ".a"
431*61c4878aSAndroid Build Coastguard Worker          command = _rustc_command
432*61c4878aSAndroid Build Coastguard Worker          outputs = [ _output ]
433*61c4878aSAndroid Build Coastguard Worker        }
434*61c4878aSAndroid Build Coastguard Worker
435*61c4878aSAndroid Build Coastguard Worker        if (defined(invoker.is_host_toolchain) && invoker.is_host_toolchain) {
436*61c4878aSAndroid Build Coastguard Worker          if (toolchain_os == "mac") {
437*61c4878aSAndroid Build Coastguard Worker            _dylib_extension = ".dylib"
438*61c4878aSAndroid Build Coastguard Worker          } else if (toolchain_os == "win") {
439*61c4878aSAndroid Build Coastguard Worker            _dylib_extension = ".dll"
440*61c4878aSAndroid Build Coastguard Worker          } else {
441*61c4878aSAndroid Build Coastguard Worker            _dylib_extension = ".so"
442*61c4878aSAndroid Build Coastguard Worker          }
443*61c4878aSAndroid Build Coastguard Worker
444*61c4878aSAndroid Build Coastguard Worker          tool("rust_macro") {
445*61c4878aSAndroid Build Coastguard Worker            description = "rustc {{output}}"
446*61c4878aSAndroid Build Coastguard Worker            default_output_dir = "{{target_out_dir}}/lib"
447*61c4878aSAndroid Build Coastguard Worker            depfile = "{{output}}.d"
448*61c4878aSAndroid Build Coastguard Worker            output_prefix = "lib"
449*61c4878aSAndroid Build Coastguard Worker            default_output_extension = _dylib_extension
450*61c4878aSAndroid Build Coastguard Worker            command = _rustc_command
451*61c4878aSAndroid Build Coastguard Worker            outputs = [ _output ]
452*61c4878aSAndroid Build Coastguard Worker          }
453*61c4878aSAndroid Build Coastguard Worker        }
454*61c4878aSAndroid Build Coastguard Worker      }
455*61c4878aSAndroid Build Coastguard Worker    }
456*61c4878aSAndroid Build Coastguard Worker
457*61c4878aSAndroid Build Coastguard Worker    _generate_static_analysis_toolchain = false
458*61c4878aSAndroid Build Coastguard Worker    if (defined(invoker.static_analysis)) {
459*61c4878aSAndroid Build Coastguard Worker      _static_analysis_args = invoker.static_analysis
460*61c4878aSAndroid Build Coastguard Worker      assert(defined(_static_analysis_args.enabled),
461*61c4878aSAndroid Build Coastguard Worker             "static_analysis.enabled missing from scope.")
462*61c4878aSAndroid Build Coastguard Worker      _generate_static_analysis_toolchain = _static_analysis_args.enabled
463*61c4878aSAndroid Build Coastguard Worker    }
464*61c4878aSAndroid Build Coastguard Worker    if (_generate_static_analysis_toolchain) {
465*61c4878aSAndroid Build Coastguard Worker      pw_static_analysis_toolchain(target_name + ".static_analysis") {
466*61c4878aSAndroid Build Coastguard Worker        forward_variables_from(invoker, "*")
467*61c4878aSAndroid Build Coastguard Worker      }
468*61c4878aSAndroid Build Coastguard Worker    }
469*61c4878aSAndroid Build Coastguard Worker  } else {
470*61c4878aSAndroid Build Coastguard Worker    not_needed(invoker, "*")
471*61c4878aSAndroid Build Coastguard Worker    group(target_name) {
472*61c4878aSAndroid Build Coastguard Worker    }
473*61c4878aSAndroid Build Coastguard Worker  }
474*61c4878aSAndroid Build Coastguard Worker}
475*61c4878aSAndroid Build Coastguard Worker
476*61c4878aSAndroid Build Coastguard Worker# Creates a series of toolchain targets with common compiler options.
477*61c4878aSAndroid Build Coastguard Worker#
478*61c4878aSAndroid Build Coastguard Worker# Args:
479*61c4878aSAndroid Build Coastguard Worker#   toolchains: List of scopes defining each of the desired toolchains.
480*61c4878aSAndroid Build Coastguard Worker#     The scope must contain a "name" variable; other variables are forwarded to
481*61c4878aSAndroid Build Coastguard Worker#     $generate_toolchain.
482*61c4878aSAndroid Build Coastguard Workertemplate("generate_toolchains") {
483*61c4878aSAndroid Build Coastguard Worker  not_needed([ "target_name" ])
484*61c4878aSAndroid Build Coastguard Worker  assert(defined(invoker.toolchains),
485*61c4878aSAndroid Build Coastguard Worker         "generate_toolchains must be called with a list of toolchains")
486*61c4878aSAndroid Build Coastguard Worker
487*61c4878aSAndroid Build Coastguard Worker  # Create a target for each of the desired toolchains, appending its own cflags
488*61c4878aSAndroid Build Coastguard Worker  # and ldflags to the common ones.
489*61c4878aSAndroid Build Coastguard Worker  foreach(_toolchain, invoker.toolchains) {
490*61c4878aSAndroid Build Coastguard Worker    generate_toolchain(_toolchain.name) {
491*61c4878aSAndroid Build Coastguard Worker      forward_variables_from(_toolchain, "*", [ "name" ])
492*61c4878aSAndroid Build Coastguard Worker    }
493*61c4878aSAndroid Build Coastguard Worker  }
494*61c4878aSAndroid Build Coastguard Worker}
495