1if (is_fuchsia) { 2 import("//build/fuchsia/sdk.gni") 3} 4 5declare_args() { 6 host_ar = ar 7 host_cc = cc 8 host_cxx = cxx 9 10 if (is_android) { 11 _prefix = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin" 12 if (host_os == "win") { 13 target_ar = "$_prefix/llvm-ar.exe" 14 target_cc = "$_prefix/clang.exe --target=$ndk_target$ndk_api -fno-addrsig" 15 target_cxx = 16 "$_prefix/clang++.exe --target=$ndk_target$ndk_api -fno-addrsig" 17 } else { 18 target_ar = "$_prefix/llvm-ar" 19 target_cc = "$_prefix/$ndk_target$ndk_api-clang" 20 target_cxx = "$_prefix/$ndk_target$ndk_api-clang++" 21 } 22 } else if (is_fuchsia && using_fuchsia_sdk) { 23 target_ar = rebase_path("$fuchsia_toolchain_path/bin/llvm-ar") 24 target_cc = rebase_path("$fuchsia_toolchain_path/bin/clang") 25 target_cxx = rebase_path("$fuchsia_toolchain_path/bin/clang++") 26 cflags = "--sysroot=" + 27 rebase_path("$fuchsia_toolchain_path/$target_cpu/sysroot") 28 link = rebase_path("$fuchsia_toolchain_path/bin/ld.lld") 29 } else { 30 target_ar = ar 31 target_cc = cc 32 target_cxx = cxx 33 } 34 35 cc_wrapper = "" 36 37 # dsymutil seems to kill the machine when too many processes are run in 38 # parallel, so we need to use a pool to limit the concurrency when passing 39 # large -j to Ninja (e.g. Goma build). Unfortunately this is also one of the 40 # slowest steps in a build, so we don't want to limit too much. Use the number 41 # of CPUs as a default. 42 dlsymutil_pool_depth = exec_script("num_cpus.py", [], "value") 43} 44 45if (host_os == "win") { 46 stamp = "cmd.exe /c echo >" 47} else { 48 stamp = "touch" 49} 50 51if (current_toolchain == default_toolchain) { 52 pool("dsymutil_pool") { 53 depth = dlsymutil_pool_depth 54 } 55} 56 57toolchain("msvc") { 58 lib_dir_switch = "/LIBPATH:" 59 60 bin = "$win_vc/Tools/MSVC/$win_toolchain_version/bin/HostX64/$target_cpu" 61 62 env_setup = "" 63 if (target_cpu == "x86") { 64 # Toolchain asset includes a script that configures for x86 building. 65 # We don't support x86 builds with local MSVC installations. 66 env_setup = "cmd /c $win_sdk/bin/SetEnv.cmd /x86 && " 67 } else if (target_cpu == "arm64") { 68 # ARM64 compiler is incomplete - it relies on DLLs located in the host toolchain directory. 69 env_setup = "cmd /C set \"PATH=%PATH%;$win_vc\\Tools\\MSVC\\$win_toolchain_version\\bin\\HostX64\\x64\" && " 70 } 71 72 cl_m32_flag = "" 73 74 if (clang_win != "") { 75 if (target_cpu == "x86") { 76 # cl.exe knows implicitly by the choice of executable that it's targeting 77 # x86, but clang-cl.exe needs to be told when targeting non-host 78 # platforms. (All our builders are x86-64, so x86 is always non-host.) 79 cl_m32_flag = "-m32" 80 } 81 if (host_os == "win") { 82 cl = "\"$clang_win/bin/clang-cl.exe\"" 83 lib = "\"$clang_win/bin/lld-link.exe\" /lib" 84 link = "\"$clang_win/bin/lld-link.exe\"" 85 } else { 86 cl = "\"$clang_win/bin/clang-cl\"" 87 lib = "\"$clang_win/bin/lld-link\" /lib" 88 link = "\"$clang_win/bin/lld-link\"" 89 } 90 } else { 91 cl = "\"$bin/cl.exe\"" 92 lib = "\"$bin/lib.exe\"" 93 link = "\"$bin/link.exe\"" 94 } 95 96 tool("asm") { 97 _ml = "ml" 98 if (target_cpu == "x64") { 99 _ml += "64" 100 } 101 command = "$env_setup \"$bin/$_ml.exe\" {{asmflags}} /nologo /c /Fo {{output}} {{source}}" 102 outputs = [ 103 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj", 104 ] 105 description = "assemble {{source}}" 106 } 107 108 tool("cc") { 109 precompiled_header_type = "msvc" 110 pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" 111 112 # Label names may have spaces so pdbname must be quoted. 113 command = "$env_setup $cc_wrapper $cl /nologo /showIncludes /FC {{defines}} {{include_dirs}} {{cflags}} $cl_m32_flag {{cflags_c}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" 114 depsformat = "msvc" 115 outputs = [ 116 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj", 117 ] 118 description = "compile {{source}}" 119 } 120 121 tool("cxx") { 122 precompiled_header_type = "msvc" 123 pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" 124 125 # Label names may have spaces so pdbname must be quoted. 126 command = "$env_setup $cc_wrapper $cl /nologo /showIncludes /FC {{defines}} {{include_dirs}} {{cflags}} $cl_m32_flag {{cflags_cc}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" 127 depsformat = "msvc" 128 outputs = [ 129 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj", 130 ] 131 description = "compile {{source}}" 132 } 133 134 tool("alink") { 135 rspfile = "{{output}}.rsp" 136 137 command = "$env_setup $lib /nologo /ignore:4221 {{arflags}} /OUT:{{output}} @$rspfile" 138 outputs = [ 139 # Ignore {{output_extension}} and always use .lib, there's no reason to 140 # allow targets to override this extension on Windows. 141 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", 142 ] 143 default_output_extension = ".lib" 144 default_output_dir = "{{target_out_dir}}" 145 146 # inputs_newline works around a fixed per-line buffer size in the linker. 147 rspfile_content = "{{inputs_newline}}" 148 description = "link {{output}}" 149 } 150 151 tool("solink") { 152 dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" 153 libname = "${dllname}.lib" 154 pdbname = "${dllname}.pdb" 155 rspfile = "${dllname}.rsp" 156 157 command = "$env_setup $link /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" 158 outputs = [ 159 dllname, 160 libname, 161 pdbname, 162 ] 163 default_output_extension = ".dll" 164 default_output_dir = "{{root_out_dir}}" 165 166 link_output = libname 167 depend_output = libname 168 runtime_outputs = [ 169 dllname, 170 pdbname, 171 ] 172 173 # I don't quite understand this. Aping Chrome's toolchain/win/BUILD.gn. 174 restat = true 175 176 # inputs_newline works around a fixed per-line buffer size in the linker. 177 rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" 178 description = "link {{output}}" 179 } 180 181 tool("link") { 182 exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" 183 pdbname = "$exename.pdb" 184 rspfile = "$exename.rsp" 185 186 command = "$env_setup $link /nologo /OUT:$exename /PDB:$pdbname @$rspfile" 187 default_output_extension = ".exe" 188 default_output_dir = "{{root_out_dir}}" 189 outputs = [ 190 exename, 191 ] 192 193 # inputs_newline works around a fixed per-line buffer size in the linker. 194 rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" 195 description = "link {{output}}" 196 } 197 198 tool("stamp") { 199 command = "$stamp {{output}}" 200 description = "stamp {{output}}" 201 } 202 203 tool("copy") { 204 cp_py = rebase_path("../cp.py") 205 command = "python $cp_py {{source}} {{output}}" 206 description = "copy {{source}} {{output}}" 207 } 208} 209 210template("gcc_like_toolchain") { 211 toolchain(target_name) { 212 ar = invoker.ar 213 cc = invoker.cc 214 cxx = invoker.cxx 215 lib_switch = "-l" 216 lib_dir_switch = "-L" 217 218 tool("cc") { 219 depfile = "{{output}}.d" 220 command = "$cc_wrapper $cc -MD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" 221 depsformat = "gcc" 222 outputs = [ 223 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 224 ] 225 description = "compile {{source}}" 226 } 227 228 tool("cxx") { 229 depfile = "{{output}}.d" 230 command = "$cc_wrapper $cxx -MD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" 231 depsformat = "gcc" 232 outputs = [ 233 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 234 ] 235 description = "compile {{source}}" 236 } 237 238 tool("objc") { 239 depfile = "{{output}}.d" 240 command = "$cc_wrapper $cc -MD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}" 241 depsformat = "gcc" 242 outputs = [ 243 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 244 ] 245 description = "compile {{source}}" 246 } 247 248 tool("objcxx") { 249 depfile = "{{output}}.d" 250 command = "$cc_wrapper $cxx -MD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}" 251 depsformat = "gcc" 252 outputs = [ 253 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 254 ] 255 description = "compile {{source}}" 256 } 257 258 tool("asm") { 259 depfile = "{{output}}.d" 260 command = "$cc_wrapper $cc -MD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}" 261 depsformat = "gcc" 262 outputs = [ 263 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 264 ] 265 description = "assemble {{source}}" 266 } 267 268 if (is_mac || is_ios) { 269 not_needed([ "ar" ]) # We use libtool instead. 270 } 271 272 tool("alink") { 273 if (is_mac || is_ios) { 274 command = "libtool -static -o {{output}} -no_warning_for_no_symbols {{inputs}}" 275 } else { 276 rspfile = "{{output}}.rsp" 277 rspfile_content = "{{inputs}}" 278 command = "$ar rcs {{output}} @$rspfile" 279 } 280 281 outputs = [ 282 "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", 283 ] 284 default_output_extension = ".a" 285 output_prefix = "lib" 286 description = "link {{output}}" 287 } 288 289 tool("solink") { 290 soname = "{{target_output_name}}{{output_extension}}" 291 292 rpath = "-Wl,-soname,$soname" 293 if (is_mac || is_ios) { 294 rpath = "-Wl,-install_name,@rpath/$soname" 295 } 296 297 rspfile = "{{output}}.rsp" 298 rspfile_content = "{{inputs}}" 299 300 # --start-group/--end-group let us link multiple .a {{inputs}} 301 # without worrying about their relative order on the link line. 302 # 303 # This is mostly important for traditional linkers like GNU ld and Gold. 304 # The Mac/iOS linker neither needs nor accepts these flags. 305 # LLD doesn't need these flags, but accepts and ignores them. 306 _start_group = "-Wl,--start-group" 307 _end_group = "-Wl,--end-group" 308 if (is_mac || is_ios || is_fuchsia) { 309 _start_group = "" 310 _end_group = "" 311 } 312 313 command = "$cxx -shared {{ldflags}} $_start_group @$rspfile {{solibs}} $_end_group {{libs}} $rpath -o {{output}}" 314 outputs = [ 315 "{{root_out_dir}}/$soname", 316 ] 317 output_prefix = "lib" 318 default_output_extension = ".so" 319 description = "link {{output}}" 320 } 321 322 tool("link") { 323 exe_name = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" 324 rspfile = "$exe_name.rsp" 325 rspfile_content = "{{inputs}}" 326 327 # --start-group/--end-group let us link multiple .a {{inputs}} 328 # without worrying about their relative order on the link line. 329 # 330 # This is mostly important for traditional linkers like GNU ld and Gold. 331 # The Mac/iOS linker neither needs nor accepts these flags. 332 # LLD doesn't need these flags, but accepts and ignores them. 333 _start_group = "-Wl,--start-group" 334 _end_group = "-Wl,--end-group" 335 if (is_mac || is_ios || is_fuchsia) { 336 _start_group = "" 337 _end_group = "" 338 } 339 command = "$cxx {{ldflags}} $_start_group @$rspfile {{solibs}} $_end_group {{libs}} -o $exe_name" 340 341 outputs = [ 342 "$exe_name", 343 ] 344 description = "link {{output}}" 345 } 346 347 tool("stamp") { 348 command = "$stamp {{output}}" 349 description = "stamp {{output}}" 350 } 351 352 tool("copy") { 353 cp_py = rebase_path("../cp.py") 354 command = "python $cp_py {{source}} {{output}}" 355 description = "copy {{source}} {{output}}" 356 } 357 358 tool("copy_bundle_data") { 359 cp_py = rebase_path("../cp.py") 360 command = "python $cp_py {{source}} {{output}}" 361 description = "copy_bundle_data {{source}} {{output}}" 362 } 363 364 # We don't currently have any xcasset files so make this a NOP 365 tool("compile_xcassets") { 366 command = "true" 367 description = "compile_xcassets {{output}}" 368 } 369 370 toolchain_args = { 371 current_cpu = invoker.cpu 372 current_os = invoker.os 373 } 374 } 375} 376 377gcc_like_toolchain("gcc_like") { 378 cpu = current_cpu 379 os = current_os 380 ar = target_ar 381 cc = target_cc 382 cxx = target_cxx 383} 384 385gcc_like_toolchain("gcc_like_host") { 386 cpu = host_cpu 387 os = host_os 388 ar = host_ar 389 cc = host_cc 390 cxx = host_cxx 391} 392