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