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