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