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 5import("//build/config/nacl/config.gni") 6import("//build/config/sysroot.gni") 7import("//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. 16revisions = exec_script("//native_client/build/get_toolchain_revision.py", 17 [ 18 "nacl_x86_glibc", 19 "nacl_arm_glibc", 20 "pnacl_newlib", 21 "saigo_newlib", 22 ], 23 "trim list lines") 24nacl_x86_glibc_rev = revisions[0] 25nacl_arm_glibc_rev = revisions[1] 26 27pnacl_newlib_rev = revisions[2] 28saigo_newlib_rev = revisions[3] 29 30if (host_os == "win") { 31 toolsuffix = ".exe" 32} else { 33 toolsuffix = "" 34} 35 36# The PNaCl toolchain tools are all wrapper scripts rather than binary 37# executables. On POSIX systems, nobody cares what kind of executable 38# file you are. But on Windows, scripts (.bat files) cannot be run 39# directly and need the Windows shell (cmd.exe) specified explicily. 40if (host_os == "win") { 41 # NOTE! The //build/toolchain/gcc_*_wrapper.py scripts recognize 42 # this exact prefix string, so they must be updated if this string 43 # is changed in any way. 44 scriptprefix = "cmd /c call " 45 scriptsuffix = ".bat" 46} else { 47 scriptprefix = "" 48 scriptsuffix = "" 49} 50 51# When the compilers are run via goma, rbe or ccache rather than directly by 52# GN/Ninja, the rbe/goma/ccache wrapper handles .bat files but gets confused 53# by being given the scriptprefix. 54if (host_os == "win" && !use_goma && !use_remoteexec && cc_wrapper == "") { 55 compiler_scriptprefix = scriptprefix 56} else { 57 compiler_scriptprefix = "" 58} 59 60template("pnacl_toolchain") { 61 assert(defined(invoker.executable_extension), 62 "Must define executable_extension") 63 64 nacl_toolchain(target_name) { 65 toolchain_package = "pnacl_newlib" 66 toolchain_revision = pnacl_newlib_rev 67 toolprefix = 68 rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/pnacl-", 69 root_build_dir) 70 71 if (host_os == "win") { 72 # Flip the slashes so that copy/paste of the commands works. 73 # This is also done throughout build\toolchain\win\BUILD.gn 74 toolprefix = string_replace(toolprefix, "/", "\\") 75 } 76 77 cc = compiler_scriptprefix + toolprefix + "clang" + scriptsuffix 78 cxx = compiler_scriptprefix + toolprefix + "clang++" + scriptsuffix 79 ar = toolprefix + "ar" + scriptsuffix 80 readelf = scriptprefix + toolprefix + "readelf" + scriptsuffix 81 nm = scriptprefix + toolprefix + "nm" + scriptsuffix 82 if (defined(invoker.strip)) { 83 strip = scriptprefix + toolprefix + invoker.strip + scriptsuffix 84 } 85 forward_variables_from(invoker, 86 [ 87 "executable_extension", 88 "is_clang_analysis_supported", 89 "extra_cppflags", 90 ]) 91 92 # Note this is not the usual "ld = cxx" because "ld" uses are 93 # never run via goma, so this needs scriptprefix. 94 ld = scriptprefix + toolprefix + "clang++" + scriptsuffix 95 96 toolchain_args = { 97 is_clang = true 98 current_cpu = "pnacl" 99 use_lld = false 100 } 101 } 102} 103 104pnacl_toolchain("newlib_pnacl") { 105 executable_extension = ".pexe" 106 107 # The pnacl-finalize tool turns a .pexe.debug file into a .pexe file. 108 # It's very similar in purpose to the traditional "strip" utility: it 109 # turns what comes out of the linker into what you actually want to 110 # distribute and run. PNaCl doesn't have a "strip"-like utility that 111 # you ever actually want to use other than pnacl-finalize, so just 112 # make pnacl-finalize the strip tool rather than adding an additional 113 # step like "postlink" to run pnacl-finalize. 114 strip = "finalize" 115} 116 117template("nacl_glibc_toolchain") { 118 toolchain_cpu = target_name 119 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 120 assert(defined(invoker.toolchain_package), "Must define toolchain_package") 121 assert(defined(invoker.toolchain_revision), "Must define toolchain_revision") 122 forward_variables_from(invoker, 123 [ 124 "toolchain_package", 125 "toolchain_revision", 126 ]) 127 128 toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + 129 invoker.toolchain_tuple + "-", 130 root_build_dir) 131 132 if (host_os == "win") { 133 # Flip the slashes so that copy/paste of the commands works. 134 # This is also done throughout build\toolchain\win\BUILD.gn 135 toolprefix = string_replace(toolprefix, "/", "\\") 136 } 137 138 nacl_toolchain("glibc_" + toolchain_cpu) { 139 cc = toolprefix + "gcc" + toolsuffix 140 cxx = toolprefix + "g++" + toolsuffix 141 ar = toolprefix + "ar" + toolsuffix 142 ld = cxx 143 readelf = toolprefix + "readelf" + toolsuffix 144 nm = toolprefix + "nm" + toolsuffix 145 strip = toolprefix + "strip" + toolsuffix 146 147 toolchain_args = { 148 current_cpu = toolchain_cpu 149 150 # reclient does not support gcc. 151 use_remoteexec = false 152 is_clang = false 153 is_nacl_glibc = true 154 use_lld = false 155 } 156 } 157} 158 159nacl_glibc_toolchain("x86") { 160 toolchain_package = "nacl_x86_glibc" 161 toolchain_revision = nacl_x86_glibc_rev 162 163 # Rely on the :compiler_cpu_abi config adding the -m32 flag here rather 164 # than using the i686-nacl binary directly. This is a because i686-nacl-gcc 165 # is a shell script wrapper around x86_64-nacl-gcc and goma has trouble with 166 # compiler executables that are shell scripts (so the i686 'compiler' is not 167 # currently in goma). 168 toolchain_tuple = "x86_64-nacl" 169} 170 171nacl_glibc_toolchain("x64") { 172 toolchain_package = "nacl_x86_glibc" 173 toolchain_revision = nacl_x86_glibc_rev 174 toolchain_tuple = "x86_64-nacl" 175} 176 177nacl_glibc_toolchain("arm") { 178 toolchain_package = "nacl_arm_glibc" 179 toolchain_revision = nacl_arm_glibc_rev 180 toolchain_tuple = "arm-nacl" 181} 182 183template("nacl_clang_toolchain") { 184 toolchain_cpu = target_name 185 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 186 187 toolchain_package = "pnacl_newlib" 188 toolchain_revision = pnacl_newlib_rev 189 toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + 190 invoker.toolchain_tuple + "-", 191 root_build_dir) 192 193 if (host_os == "win") { 194 # Flip the slashes so that copy/paste of the commands works. 195 # This is also done throughout build\toolchain\win\BUILD.gn 196 toolprefix = string_replace(toolprefix, "/", "\\") 197 } 198 199 nacl_toolchain("clang_newlib_" + toolchain_cpu) { 200 cc = toolprefix + "clang" + toolsuffix 201 cxx = toolprefix + "clang++" + toolsuffix 202 ar = toolprefix + "ar" + toolsuffix 203 ld = cxx 204 readelf = toolprefix + "readelf" + toolsuffix 205 nm = toolprefix + "nm" + toolsuffix 206 strip = toolprefix + "strip" + toolsuffix 207 208 toolchain_args = { 209 current_cpu = toolchain_cpu 210 is_clang = true 211 use_lld = false 212 } 213 } 214} 215 216template("nacl_irt_toolchain") { 217 toolchain_cpu = target_name 218 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 219 220 toolchain_package = "saigo_newlib" 221 toolchain_revision = saigo_newlib_rev 222 toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + 223 invoker.toolchain_tuple + "-", 224 root_build_dir) 225 226 if (host_os == "win") { 227 # Flip the slashes so that copy/paste of the commands works. 228 # This is also done throughout build\toolchain\win\BUILD.gn 229 toolprefix = string_replace(toolprefix, "/", "\\") 230 } 231 232 link_irt = rebase_path("//native_client/build/link_irt.py", root_build_dir) 233 234 tls_edit_label = 235 "//native_client/src/tools/tls_edit:tls_edit($host_toolchain)" 236 host_toolchain_out_dir = 237 rebase_path(get_label_info(tls_edit_label, "root_out_dir"), 238 root_build_dir) 239 tls_edit = "${host_toolchain_out_dir}/tls_edit" 240 241 nacl_toolchain("irt_" + toolchain_cpu) { 242 cc = toolprefix + "clang" + toolsuffix 243 cxx = toolprefix + "clang++" + toolsuffix 244 ar = toolprefix + "ar" + toolsuffix 245 readelf = toolprefix + "readelf" + toolsuffix 246 nm = toolprefix + "nm" + toolsuffix 247 strip = toolprefix + "strip" + toolsuffix 248 249 # Some IRT implementations (notably, Chromium's) contain C++ code, 250 # so we need to link w/ the C++ linker. 251 ld = "${python_path} ${link_irt} --tls-edit=${tls_edit} --link-cmd=${cxx} --readelf-cmd=${readelf}" 252 253 toolchain_args = { 254 current_cpu = toolchain_cpu 255 is_clang = true 256 use_lld = false 257 is_nacl_saigo = true 258 } 259 260 # TODO(ncbray): depend on link script 261 deps = [ tls_edit_label ] 262 } 263} 264 265# This is essentially a clone of nacl_irt_toolchain above, except it uses the 266# standard ld. This toolchain can be used to build regular nexes for NaCl 267# browser tests. 268template("nacl_test_irt_toolchain") { 269 toolchain_cpu = target_name 270 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 271 272 toolchain_package = "saigo_newlib" 273 toolchain_revision = saigo_newlib_rev 274 toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + 275 invoker.toolchain_tuple + "-", 276 root_build_dir) 277 278 if (host_os == "win") { 279 # Flip the slashes so that copy/paste of the commands works. 280 # This is also done throughout build\toolchain\win\BUILD.gn 281 toolprefix = string_replace(toolprefix, "/", "\\") 282 } 283 284 nacl_toolchain("test_irt_" + toolchain_cpu) { 285 cc = toolprefix + "clang" + toolsuffix 286 cxx = toolprefix + "clang++" + toolsuffix 287 ar = toolprefix + "ar" + toolsuffix 288 ld = cxx 289 readelf = toolprefix + "readelf" + toolsuffix 290 nm = toolprefix + "nm" + toolsuffix 291 strip = toolprefix + "strip" + toolsuffix 292 293 toolchain_args = { 294 current_cpu = toolchain_cpu 295 is_clang = true 296 use_lld = false 297 is_nacl_saigo = true 298 } 299 } 300} 301 302template("nacl_clang_toolchains") { 303 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 304 nacl_clang_toolchain(target_name) { 305 toolchain_tuple = invoker.toolchain_tuple 306 } 307 nacl_irt_toolchain(target_name) { 308 toolchain_tuple = invoker.toolchain_tuple 309 } 310 nacl_test_irt_toolchain(target_name) { 311 toolchain_tuple = invoker.toolchain_tuple 312 } 313} 314 315nacl_clang_toolchains("x86") { 316 # Rely on :compiler_cpu_abi adding -m32. See nacl_x86_glibc above. 317 toolchain_tuple = "x86_64-nacl" 318} 319 320nacl_clang_toolchains("x64") { 321 toolchain_tuple = "x86_64-nacl" 322} 323 324nacl_clang_toolchains("arm") { 325 toolchain_tuple = "arm-nacl" 326} 327 328nacl_clang_toolchains("mipsel") { 329 toolchain_tuple = "mipsel-nacl" 330} 331