Home | History | Annotate | Download | only in toolchain
      1 declare_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 
     25 if (host_os == "win") {
     26   stamp = "cmd.exe /c echo >"
     27 } else {
     28   stamp = "touch"
     29 }
     30 
     31 toolchain("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 
    192 template("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 
    335 gcc_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 
    343 gcc_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