Home | History | Annotate | Download | only in nacl
      1 # Copyright (c) 2014 The Native Client Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import("//build/config/sysroot.gni")
      6 import("//build/config/nacl/config.gni")
      7 import("//build/toolchain/nacl_toolchain.gni")
      8 
      9 # Add the toolchain revision as a preprocessor define so that sources are
     10 # rebuilt when a toolchain is updated.
     11 # Idea we could use the toolchain deps feature, but currently that feature is
     12 # bugged and does not trigger a rebuild.
     13 # https://code.google.com/p/chromium/issues/detail?id=431880
     14 # Calls to get the toolchain revision are relatively slow, so do them all in a
     15 # single batch to amortize python startup, etc.
     16 revisions = exec_script("//native_client/build/get_toolchain_revision.py",
     17                         [
     18                           "nacl_x86_glibc",
     19                           "nacl_arm_glibc",
     20                           "pnacl_newlib",
     21                         ],
     22                         "trim list lines")
     23 nacl_x86_glibc_rev = revisions[0]
     24 nacl_arm_glibc_rev = revisions[1]
     25 
     26 # TODO(mcgrathr): Uncomment this when
     27 # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed.
     28 #pnacl_newlib_rev = revisions[2]
     29 
     30 template("pnacl_toolchain") {
     31   assert(defined(invoker.executable_extension),
     32          "Must define executable_extension")
     33 
     34   # TODO(mcgrathr): See above.
     35   pnacl_newlib_rev = revisions[2]
     36 
     37   # The PNaCl toolchain tools are all wrapper scripts rather than binary
     38   # executables.  On POSIX systems, nobody cares what kind of executable
     39   # file you are.  But on Windows, scripts (.bat files) cannot be run
     40   # directly and need the Windows shell (cmd.exe) specified explicily.
     41   # TODO(mcgrathr): Hoist this to top level when
     42   # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed.
     43   if (host_os == "win") {
     44     # NOTE!  The //build/toolchain/gcc_*_wrapper.py scripts recognize
     45     # this exact prefix string, so they must be updated if this string
     46     # is changed in any way.
     47     scriptprefix = "cmd /c call "
     48     scriptsuffix = ".bat"
     49   } else {
     50     scriptprefix = ""
     51     scriptsuffix = ""
     52   }
     53 
     54   # When the compilers are run via goma or ccache rather than directly by
     55   # GN/Ninja, the goma/ccache wrapper handles .bat files but gets confused
     56   # by being given the scriptprefix.
     57   if (host_os == "win" && !use_goma && cc_wrapper == "") {
     58     compiler_scriptprefix = scriptprefix
     59   } else {
     60     compiler_scriptprefix = ""
     61   }
     62 
     63   nacl_toolchain(target_name) {
     64     toolchain_package = "pnacl_newlib"
     65     toolchain_revision = pnacl_newlib_rev
     66     toolchain_cpu = "pnacl"
     67     toolprefix =
     68         rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/pnacl-",
     69                     root_build_dir)
     70 
     71     is_clang = true
     72     cc = compiler_scriptprefix + toolprefix + "clang" + scriptsuffix
     73     cxx = compiler_scriptprefix + toolprefix + "clang++" + scriptsuffix
     74     ar = scriptprefix + toolprefix + "ar" + scriptsuffix
     75     readelf = scriptprefix + toolprefix + "readelf" + scriptsuffix
     76     nm = scriptprefix + toolprefix + "nm" + scriptsuffix
     77     if (defined(invoker.strip)) {
     78       strip = scriptprefix + toolprefix + invoker.strip + scriptsuffix
     79     }
     80 
     81     # Note this is not the usual "ld = cxx" because "ld" uses are
     82     # never run via goma, so this needs scriptprefix.
     83     ld = scriptprefix + toolprefix + "clang++" + scriptsuffix
     84 
     85     executable_extension = invoker.executable_extension
     86   }
     87 }
     88 
     89 pnacl_toolchain("newlib_pnacl") {
     90   executable_extension = ".pexe"
     91 
     92   # The pnacl-finalize tool turns a .pexe.debug file into a .pexe file.
     93   # It's very similar in purpose to the traditional "strip" utility: it
     94   # turns what comes out of the linker into what you actually want to
     95   # distribute and run.  PNaCl doesn't have a "strip"-like utility that
     96   # you ever actually want to use other than pnacl-finalize, so just
     97   # make pnacl-finalize the strip tool rather than adding an additional
     98   # step like "postlink" to run pnacl-finalize.
     99   strip = "finalize"
    100 }
    101 
    102 pnacl_toolchain("newlib_pnacl_nonsfi") {
    103   executable_extension = ""
    104   strip = "strip"
    105 }
    106 
    107 template("nacl_glibc_toolchain") {
    108   toolchain_cpu = target_name
    109   assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple")
    110   assert(defined(invoker.toolchain_package), "Must define toolchain_package")
    111   assert(defined(invoker.toolchain_revision), "Must define toolchain_revision")
    112   forward_variables_from(invoker,
    113                          [
    114                            "toolchain_package",
    115                            "toolchain_revision",
    116                          ])
    117 
    118   toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" +
    119                                invoker.toolchain_tuple + "-",
    120                            root_build_dir)
    121 
    122   # TODO(mcgrathr): Hoist this to top level when
    123   # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed.
    124   if (host_os == "win") {
    125     toolsuffix = ".exe"
    126   } else {
    127     toolsuffix = ""
    128   }
    129 
    130   nacl_toolchain("glibc_" + toolchain_cpu) {
    131     is_clang = false
    132     is_nacl_glibc = true
    133 
    134     cc = toolprefix + "gcc" + toolsuffix
    135     cxx = toolprefix + "g++" + toolsuffix
    136     ar = toolprefix + "ar" + toolsuffix
    137     ld = cxx
    138     readelf = toolprefix + "readelf" + toolsuffix
    139     nm = toolprefix + "nm" + toolsuffix
    140     strip = toolprefix + "strip" + toolsuffix
    141   }
    142 }
    143 
    144 nacl_glibc_toolchain("x86") {
    145   toolchain_package = "nacl_x86_glibc"
    146   toolchain_revision = nacl_x86_glibc_rev
    147 
    148   # Rely on the :compiler_cpu_abi config adding the -m32 flag here rather
    149   # than using the i686-nacl binary directly.  This is a because i686-nacl-gcc
    150   # is a shell script wrapper around x86_64-nacl-gcc and goma has trouble with
    151   # compiler executables that are shell scripts (so the i686 'compiler' is not
    152   # currently in goma).
    153   toolchain_tuple = "x86_64-nacl"
    154 }
    155 
    156 nacl_glibc_toolchain("x64") {
    157   toolchain_package = "nacl_x86_glibc"
    158   toolchain_revision = nacl_x86_glibc_rev
    159   toolchain_tuple = "x86_64-nacl"
    160 }
    161 
    162 nacl_glibc_toolchain("arm") {
    163   toolchain_package = "nacl_arm_glibc"
    164   toolchain_revision = nacl_arm_glibc_rev
    165   toolchain_tuple = "arm-nacl"
    166 }
    167 
    168 template("nacl_clang_toolchain") {
    169   toolchain_cpu = target_name
    170   assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple")
    171 
    172   # TODO(mcgrathr): See above.
    173   pnacl_newlib_rev = revisions[2]
    174 
    175   toolchain_package = "pnacl_newlib"
    176   toolchain_revision = pnacl_newlib_rev
    177   toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" +
    178                                invoker.toolchain_tuple + "-",
    179                            root_build_dir)
    180 
    181   # TODO(mcgrathr): Hoist this to top level when
    182   # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed.
    183   if (host_os == "win") {
    184     toolsuffix = ".exe"
    185   } else {
    186     toolsuffix = ""
    187   }
    188 
    189   nacl_toolchain("clang_newlib_" + toolchain_cpu) {
    190     is_clang = true
    191     cc = toolprefix + "clang" + toolsuffix
    192     cxx = toolprefix + "clang++" + toolsuffix
    193     ar = toolprefix + "ar" + toolsuffix
    194     ld = cxx
    195     readelf = toolprefix + "readelf" + toolsuffix
    196     nm = toolprefix + "nm" + toolsuffix
    197     strip = toolprefix + "strip" + toolsuffix
    198   }
    199 }
    200 
    201 template("nacl_irt_toolchain") {
    202   toolchain_cpu = target_name
    203   assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple")
    204 
    205   # TODO(mcgrathr): See above.
    206   pnacl_newlib_rev = revisions[2]
    207 
    208   toolchain_package = "pnacl_newlib"
    209   toolchain_revision = pnacl_newlib_rev
    210   toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" +
    211                                invoker.toolchain_tuple + "-",
    212                            root_build_dir)
    213 
    214   # TODO(mcgrathr): Hoist this to top level when
    215   # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed.
    216   if (host_os == "win") {
    217     toolsuffix = ".exe"
    218   } else {
    219     toolsuffix = ""
    220   }
    221 
    222   link_irt = rebase_path("//native_client/build/link_irt.py", root_build_dir)
    223 
    224   tls_edit_label =
    225       "//native_client/src/tools/tls_edit:tls_edit($host_toolchain)"
    226   host_toolchain_out_dir =
    227       rebase_path(get_label_info(tls_edit_label, "root_out_dir"),
    228                   root_build_dir)
    229   tls_edit = "${host_toolchain_out_dir}/tls_edit"
    230 
    231   nacl_toolchain("irt_" + toolchain_cpu) {
    232     is_clang = true
    233     cc = toolprefix + "clang" + toolsuffix
    234     cxx = toolprefix + "clang++" + toolsuffix
    235     ar = toolprefix + "ar" + toolsuffix
    236     readelf = toolprefix + "readelf" + toolsuffix
    237     nm = toolprefix + "nm" + toolsuffix
    238     strip = toolprefix + "strip" + toolsuffix
    239 
    240     # Always build the IRT with full debugging symbols, regardless of
    241     # how Chromium itself is being built (or other NaCl executables).
    242     symbol_level = 2
    243 
    244     # Some IRT implementations (notably, Chromium's) contain C++ code,
    245     # so we need to link w/ the C++ linker.
    246     ld = "${python_path} ${link_irt} --tls-edit=${tls_edit} --link-cmd=${cxx} --readelf-cmd=${readelf}"
    247 
    248     # TODO(ncbray): depend on link script
    249     deps = [
    250       tls_edit_label,
    251     ]
    252   }
    253 }
    254 
    255 template("nacl_clang_toolchains") {
    256   assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple")
    257   nacl_clang_toolchain(target_name) {
    258     toolchain_tuple = invoker.toolchain_tuple
    259   }
    260   nacl_irt_toolchain(target_name) {
    261     toolchain_tuple = invoker.toolchain_tuple
    262   }
    263 }
    264 
    265 nacl_clang_toolchains("x86") {
    266   # Rely on :compiler_cpu_abi adding -m32.  See nacl_x86_glibc above.
    267   toolchain_tuple = "x86_64-nacl"
    268 }
    269 
    270 nacl_clang_toolchains("x64") {
    271   toolchain_tuple = "x86_64-nacl"
    272 }
    273 
    274 nacl_clang_toolchains("arm") {
    275   toolchain_tuple = "arm-nacl"
    276 }
    277