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