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 reclient or ccache rather than directly by 52# GN/Ninja, the reclient/ccache wrapper handles .bat files but gets confused 53# by being given the scriptprefix. 54if (host_os == "win" && !use_reclient && 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 rbe, 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. 165 toolchain_tuple = "x86_64-nacl" 166} 167 168nacl_glibc_toolchain("x64") { 169 toolchain_package = "nacl_x86_glibc" 170 toolchain_revision = nacl_x86_glibc_rev 171 toolchain_tuple = "x86_64-nacl" 172} 173 174nacl_glibc_toolchain("arm") { 175 toolchain_package = "nacl_arm_glibc" 176 toolchain_revision = nacl_arm_glibc_rev 177 toolchain_tuple = "arm-nacl" 178} 179 180template("nacl_clang_toolchain") { 181 toolchain_cpu = target_name 182 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 183 184 toolchain_package = "pnacl_newlib" 185 toolchain_revision = pnacl_newlib_rev 186 toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + 187 invoker.toolchain_tuple + "-", 188 root_build_dir) 189 190 if (host_os == "win") { 191 # Flip the slashes so that copy/paste of the commands works. 192 # This is also done throughout build\toolchain\win\BUILD.gn 193 toolprefix = string_replace(toolprefix, "/", "\\") 194 } 195 196 nacl_toolchain("clang_newlib_" + toolchain_cpu) { 197 cc = toolprefix + "clang" + toolsuffix 198 cxx = toolprefix + "clang++" + toolsuffix 199 ar = toolprefix + "ar" + toolsuffix 200 ld = cxx 201 readelf = toolprefix + "readelf" + toolsuffix 202 nm = toolprefix + "nm" + toolsuffix 203 strip = toolprefix + "strip" + toolsuffix 204 205 toolchain_args = { 206 current_cpu = toolchain_cpu 207 is_clang = true 208 use_lld = false 209 } 210 } 211} 212 213template("nacl_irt_toolchain") { 214 toolchain_cpu = target_name 215 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 216 217 toolchain_package = "saigo_newlib" 218 toolchain_revision = saigo_newlib_rev 219 toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + 220 invoker.toolchain_tuple + "-", 221 root_build_dir) 222 223 if (host_os == "win") { 224 # Flip the slashes so that copy/paste of the commands works. 225 # This is also done throughout build\toolchain\win\BUILD.gn 226 toolprefix = string_replace(toolprefix, "/", "\\") 227 } 228 229 link_irt = rebase_path("//native_client/build/link_irt.py", root_build_dir) 230 231 tls_edit_label = 232 "//native_client/src/tools/tls_edit:tls_edit($host_toolchain)" 233 host_toolchain_out_dir = 234 rebase_path(get_label_info(tls_edit_label, "root_out_dir"), 235 root_build_dir) 236 tls_edit = "${host_toolchain_out_dir}/tls_edit" 237 238 nacl_toolchain("irt_" + toolchain_cpu) { 239 cc = toolprefix + "clang" + toolsuffix 240 cxx = toolprefix + "clang++" + toolsuffix 241 ar = toolprefix + "ar" + toolsuffix 242 readelf = toolprefix + "readelf" + toolsuffix 243 nm = toolprefix + "nm" + toolsuffix 244 strip = toolprefix + "strip" + toolsuffix 245 246 # Some IRT implementations (notably, Chromium's) contain C++ code, 247 # so we need to link w/ the C++ linker. 248 ld = "${python_path} ${link_irt} --tls-edit=${tls_edit} --link-cmd=${cxx} --readelf-cmd=${readelf}" 249 250 # reclient requires explicit upload of toolchain lib 251 if (is_chromeos_ash && use_remoteexec) { 252 if (defined(invoker.extra_cppflags) && invoker.extra_cppflags != "") { 253 extra_cppflags = " " + invoker.extra_cppflags 254 } else { 255 extra_cppflags = "" 256 } 257 258 libdir = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/lib", 259 root_build_dir) 260 extra_cppflags += " -B${libdir}" 261 } 262 263 toolchain_args = { 264 current_cpu = toolchain_cpu 265 is_clang = true 266 use_lld = false 267 is_nacl_saigo = true 268 } 269 270 # TODO(ncbray): depend on link script 271 deps = [ tls_edit_label ] 272 } 273} 274 275# This is essentially a clone of nacl_irt_toolchain above, except it uses the 276# standard ld. This toolchain can be used to build regular nexes for NaCl 277# browser tests. 278template("nacl_test_irt_toolchain") { 279 toolchain_cpu = target_name 280 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 281 282 toolchain_package = "saigo_newlib" 283 toolchain_revision = saigo_newlib_rev 284 toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + 285 invoker.toolchain_tuple + "-", 286 root_build_dir) 287 288 if (host_os == "win") { 289 # Flip the slashes so that copy/paste of the commands works. 290 # This is also done throughout build\toolchain\win\BUILD.gn 291 toolprefix = string_replace(toolprefix, "/", "\\") 292 } 293 294 nacl_toolchain("test_irt_" + toolchain_cpu) { 295 cc = toolprefix + "clang" + toolsuffix 296 cxx = toolprefix + "clang++" + toolsuffix 297 ar = toolprefix + "ar" + toolsuffix 298 ld = cxx 299 readelf = toolprefix + "readelf" + toolsuffix 300 nm = toolprefix + "nm" + toolsuffix 301 strip = toolprefix + "strip" + toolsuffix 302 303 toolchain_args = { 304 current_cpu = toolchain_cpu 305 is_clang = true 306 use_lld = false 307 is_nacl_saigo = true 308 } 309 } 310} 311 312template("nacl_clang_toolchains") { 313 assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") 314 nacl_clang_toolchain(target_name) { 315 toolchain_tuple = invoker.toolchain_tuple 316 } 317 nacl_irt_toolchain(target_name) { 318 toolchain_tuple = invoker.toolchain_tuple 319 } 320 nacl_test_irt_toolchain(target_name) { 321 toolchain_tuple = invoker.toolchain_tuple 322 } 323} 324 325nacl_clang_toolchains("x86") { 326 # Rely on :compiler_cpu_abi adding -m32. See nacl_x86_glibc above. 327 toolchain_tuple = "x86_64-nacl" 328} 329 330nacl_clang_toolchains("x64") { 331 toolchain_tuple = "x86_64-nacl" 332} 333 334nacl_clang_toolchains("arm") { 335 toolchain_tuple = "arm-nacl" 336} 337 338nacl_clang_toolchains("mipsel") { 339 toolchain_tuple = "mipsel-nacl" 340} 341