OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2013 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2013 The Native Client Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Recipes for PNaCl toolchain packages. | 6 """Recipes for PNaCl toolchain packages. |
7 | 7 |
8 Recipes consist of specially-structured dictionaries, with keys for package | 8 Recipes consist of specially-structured dictionaries, with keys for package |
9 name, type, commands to execute, etc. The structure is documented in the | 9 name, type, commands to execute, etc. The structure is documented in the |
10 PackageBuilder docstring in toolchain_main.py. | 10 PackageBuilder docstring in toolchain_main.py. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 return options.host_flavor == 'debug' | 141 return options.host_flavor == 'debug' |
142 | 142 |
143 def ProgramPath(program): | 143 def ProgramPath(program): |
144 """Returns the path for the given program, or None if it doesn't exist.""" | 144 """Returns the path for the given program, or None if it doesn't exist.""" |
145 try: | 145 try: |
146 return pynacl.file_tools.Which(program) | 146 return pynacl.file_tools.Which(program) |
147 except pynacl.file_tools.ExecutableNotFound: | 147 except pynacl.file_tools.ExecutableNotFound: |
148 pass | 148 pass |
149 return None | 149 return None |
150 | 150 |
151 # Return a tuple (C compiler, C++ compiler) of the compilers to compile the host | 151 # Return a tuple (C compiler, C++ compiler, ar, ranlib) of the compilers and |
152 # toolchains | 152 # tools to compile the host toolchains. |
153 def CompilersForHost(host): | 153 def CompilersForHost(host): |
154 compiler = { | 154 compiler = { |
155 # For now we only do native builds for linux and mac | 155 # For now we only do native builds for linux and mac |
156 # treat 32-bit linux like a native build | 156 # treat 32-bit linux like a native build |
157 'i686-linux': (CHROME_CLANG, CHROME_CLANGXX, 'ar', 'ranlib'), | 157 'i686-linux': (CHROME_CLANG, CHROME_CLANGXX, 'ar', 'ranlib'), |
158 'x86_64-linux': (CHROME_CLANG, CHROME_CLANGXX, 'ar', 'ranlib'), | 158 'x86_64-linux': (CHROME_CLANG, CHROME_CLANGXX, 'ar', 'ranlib'), |
159 'x86_64-apple-darwin': (CHROME_CLANG, CHROME_CLANGXX, 'ar', 'ranlib'), | 159 'x86_64-apple-darwin': (CHROME_CLANG, CHROME_CLANGXX, 'ar', 'ranlib'), |
160 # Windows build should work for native and cross | 160 # Windows build should work for native and cross |
161 'i686-w64-mingw32': ( | 161 'i686-w64-mingw32': ( |
162 'i686-w64-mingw32-gcc', 'i686-w64-mingw32-g++', 'ar', 'ranlib'), | 162 'i686-w64-mingw32-gcc', 'i686-w64-mingw32-g++', 'ar', 'ranlib'), |
163 # TODO: add arm-hosted support | 163 # TODO: add arm-hosted support |
164 'i686-pc-cygwin': ('gcc', 'g++', 'ar', 'ranlib'), | 164 'i686-pc-cygwin': ('gcc', 'g++', 'ar', 'ranlib'), |
165 } | 165 } |
166 if host == 'le32-nacl': | 166 if host == 'le32-nacl': |
167 nacl_sdk = os.environ.get('NACL_SDK_ROOT') | 167 nacl_sdk = os.environ.get('NACL_SDK_ROOT') |
168 assert nacl_sdk, 'NACL_SDK_ROOT not set' | 168 assert nacl_sdk, 'NACL_SDK_ROOT not set' |
169 pnacl_bin_dir = os.path.join(nacl_sdk, 'toolchain/linux_pnacl/bin') | 169 pnacl_bin_dir = os.path.join(nacl_sdk, 'toolchain/linux_pnacl/bin') |
170 glibc_bin_dir = os.path.join(nacl_sdk, 'toolchain/linux_x86_glibc/bin') | |
171 compiler.update({ | 170 compiler.update({ |
172 'le32-nacl': (os.path.join(pnacl_bin_dir, 'pnacl-clang'), | 171 'le32-nacl': (os.path.join(pnacl_bin_dir, 'pnacl-clang'), |
173 os.path.join(pnacl_bin_dir, 'pnacl-clang++'), | 172 os.path.join(pnacl_bin_dir, 'pnacl-clang++'), |
174 os.path.join(pnacl_bin_dir, 'pnacl-ar'), | 173 os.path.join(pnacl_bin_dir, 'pnacl-ar'), |
175 os.path.join(pnacl_bin_dir, 'pnacl-ranlib')), | 174 os.path.join(pnacl_bin_dir, 'pnacl-ranlib')), |
176 }) | 175 }) |
177 return compiler[host] | 176 return compiler[host] |
178 | 177 |
179 | 178 |
180 def GSDJoin(*args): | 179 def GSDJoin(*args): |
181 return '_'.join([pynacl.gsd_storage.LegalizeName(arg) for arg in args]) | 180 return '_'.join([pynacl.gsd_storage.LegalizeName(arg) for arg in args]) |
182 | 181 |
183 # name of a build target, including build flavor (debug/release) | 182 # name of a build target, including build flavor (debug/release) |
184 def FlavoredName(component_name, host, options): | 183 def FlavoredName(component_name, host, options): |
185 joined_name = GSDJoin(component_name, host) | 184 joined_name = GSDJoin(component_name, host) |
186 if HostIsDebug(options): | 185 if HostIsDebug(options): |
187 joined_name= joined_name + '_debug' | 186 joined_name= joined_name + '_debug' |
188 return joined_name | 187 return joined_name |
189 | 188 |
| 189 |
| 190 def HostArchToolFlags(host, extra_cflags, opts): |
| 191 """Return the appropriate CFLAGS, CXXFLAGS, and LDFLAGS based on host |
| 192 and opts. Does not attempt to determine flags that are attached |
| 193 to CC and CXX directly. |
| 194 """ |
| 195 extra_cc_flags = list(extra_cflags) |
| 196 result = { 'LDFLAGS' : [], |
| 197 'CFLAGS' : [], |
| 198 'CXXFLAGS' : []} |
| 199 if TripleIsWindows(host): |
| 200 result['LDFLAGS'] += ['-L%(abs_libdl)s', '-ldl'] |
| 201 result['CFLAGS'] += ['-isystem','%(abs_libdl)s'] |
| 202 result['CXXFLAGS'] += ['-isystem', '%(abs_libdl)s'] |
| 203 else: |
| 204 if TripleIsLinux(host) and not TripleIsX8664(host): |
| 205 # Chrome clang defaults to 64-bit builds, even when run on 32-bit Linux. |
| 206 extra_cc_flags += ['-m32'] |
| 207 elif TripleIsMac(host): |
| 208 # This is required for building with recent libc++ against OSX 10.6 |
| 209 extra_cc_flags += ['-U__STRICT_ANSI__'] |
| 210 if opts.gcc or host == 'le32-nacl': |
| 211 result['CFLAGS'] += extra_cc_flags |
| 212 result['CXXFLAGS'] += extra_cc_flags |
| 213 else: |
| 214 result['CFLAGS'] += extra_cc_flags |
| 215 result['LDFLAGS'] += ['-L%(' + FlavoredName('abs_libcxx', |
| 216 host, opts) + ')s/lib'] |
| 217 result['CXXFLAGS'] += ([ |
| 218 '-stdlib=libc++', |
| 219 '-I%(' + FlavoredName('abs_libcxx', host, opts) + ')s/include/c++/v1'] + |
| 220 extra_cc_flags) |
| 221 return result |
| 222 |
| 223 |
190 def ConfigureHostArchFlags(host, extra_cflags, options, extra_configure=None): | 224 def ConfigureHostArchFlags(host, extra_cflags, options, extra_configure=None): |
191 """ Return flags passed to LLVM and binutils configure for compilers and | 225 """ Return flags passed to LLVM and binutils configure for compilers and |
192 compile flags. """ | 226 compile flags. """ |
193 configure_args = [] | 227 configure_args = [] |
194 extra_cc_args = [] | 228 extra_cc_args = [] |
195 | 229 |
196 configure_args += options.extra_configure_args | 230 configure_args += options.extra_configure_args |
197 if extra_configure is not None: | 231 if extra_configure is not None: |
198 configure_args += extra_configure | 232 configure_args += extra_configure |
199 if options.extra_cc_args is not None: | 233 if options.extra_cc_args is not None: |
200 extra_cc_args += [options.extra_cc_args] | 234 extra_cc_args += [options.extra_cc_args] |
201 | 235 |
202 native = pynacl.platform.PlatformTriple() | 236 native = pynacl.platform.PlatformTriple() |
203 is_cross = host != native | 237 is_cross = host != native |
204 if is_cross: | 238 if is_cross: |
205 if (pynacl.platform.IsLinux64() and | 239 if (pynacl.platform.IsLinux64() and |
206 fnmatch.fnmatch(host, '*-linux*')): | 240 fnmatch.fnmatch(host, '*-linux*')): |
207 # 64 bit linux can build 32 bit linux binaries while still being a native | 241 # 64 bit linux can build 32 bit linux binaries while still being a native |
208 # build for our purposes. But it's not what config.guess will yield, so | 242 # build for our purposes. But it's not what config.guess will yield, so |
209 # use --build to force it and make sure things build correctly. | 243 # use --build to force it and make sure things build correctly. |
210 configure_args.append('--build=' + host) | 244 configure_args.append('--build=' + host) |
211 else: | 245 else: |
212 configure_args.append('--host=' + host) | 246 configure_args.append('--host=' + host) |
213 if TripleIsLinux(host) and not TripleIsX8664(host): | |
214 # Chrome clang defaults to 64-bit builds, even when run on 32-bit Linux. | |
215 extra_cc_args += ['-m32'] | |
216 | 247 |
217 extra_cxx_args = list(extra_cc_args) | 248 extra_cxx_args = list(extra_cc_args) |
218 | 249 |
219 if not options.gcc: | 250 if not options.gcc: |
220 cc, cxx, ar, ranlib = CompilersForHost(host) | 251 cc, cxx, ar, ranlib = CompilersForHost(host) |
221 if ProgramPath('ccache'): | 252 if ProgramPath('ccache'): |
222 # Set CCACHE_CPP2 envvar, to avoid an error due to a strange | 253 # Set CCACHE_CPP2 envvar, to avoid an error due to a strange |
223 # ccache/clang++ interaction. Specifically, errors about | 254 # ccache/clang++ interaction. Specifically, errors about |
224 # "argument unused during compilation". | 255 # "argument unused during compilation". |
225 os.environ['CCACHE_CPP2'] = 'yes' | 256 os.environ['CCACHE_CPP2'] = 'yes' |
226 cc_list = ['ccache', cc] | 257 cc_list = ['ccache', cc] |
227 cxx_list = ['ccache', cxx] | 258 cxx_list = ['ccache', cxx] |
228 extra_cc_args += ['-Qunused-arguments'] | 259 extra_cc_args += ['-Qunused-arguments'] |
229 extra_cxx_args += ['-Qunused-arguments'] | 260 extra_cxx_args += ['-Qunused-arguments'] |
230 else: | 261 else: |
231 cc_list = [cc] | 262 cc_list = [cc] |
232 cxx_list = [cxx] | 263 cxx_list = [cxx] |
233 configure_args.append('CC=' + ' '.join(cc_list + extra_cc_args)) | 264 configure_args.append('CC=' + ' '.join(cc_list + extra_cc_args)) |
234 configure_args.append('CXX=' + ' '.join(cxx_list + extra_cxx_args)) | 265 configure_args.append('CXX=' + ' '.join(cxx_list + extra_cxx_args)) |
235 configure_args.append('AR=' + ar) | 266 configure_args.append('AR=' + ar) |
236 configure_args.append('RANLIB=' + ranlib) | 267 configure_args.append('RANLIB=' + ranlib) |
237 | 268 |
| 269 tool_flags = HostArchToolFlags(host, extra_cflags, options) |
| 270 configure_args.extend( |
| 271 ['CFLAGS=' + ' '.join(tool_flags['CFLAGS']), |
| 272 'CXXFLAGS=' + ' '.join(tool_flags['CXXFLAGS']), |
| 273 'LDFLAGS=' + ' '.join(tool_flags['LDFLAGS']), |
| 274 ]) |
238 if TripleIsWindows(host): | 275 if TripleIsWindows(host): |
239 # The i18n support brings in runtime dependencies on MinGW DLLs | 276 # The i18n support brings in runtime dependencies on MinGW DLLs |
240 # that we don't want to have to distribute alongside our binaries. | 277 # that we don't want to have to distribute alongside our binaries. |
241 # So just disable it, and compiler messages will always be in US English. | 278 # So just disable it, and compiler messages will always be in US English. |
242 configure_args.append('--disable-nls') | 279 configure_args.append('--disable-nls') |
243 configure_args.extend(['LDFLAGS=-L%(abs_libdl)s -ldl', | |
244 'CFLAGS=-isystem %(abs_libdl)s', | |
245 'CXXFLAGS=-isystem %(abs_libdl)s']) | |
246 if is_cross: | 280 if is_cross: |
247 # LLVM's linux->mingw cross build needs this | 281 # LLVM's linux->mingw cross build needs this |
248 configure_args.append('CC_FOR_BUILD=gcc') | 282 configure_args.append('CC_FOR_BUILD=gcc') |
249 else: | |
250 if TripleIsMac(host): | |
251 # This is required for building with recent libc++ against OSX 10.6 | |
252 extra_cflags.append('-U__STRICT_ANSI__') | |
253 if options.gcc or host == 'le32-nacl': | |
254 configure_args.extend(['CFLAGS=' + ' '.join(extra_cflags), | |
255 'CXXFLAGS=' + ' '.join(extra_cflags)]) | |
256 else: | |
257 configure_args.extend( | |
258 ['CFLAGS=' + ' '.join(extra_cflags), | |
259 'LDFLAGS=-L%(' + FlavoredName('abs_libcxx', | |
260 host, | |
261 options) + ')s/lib', | |
262 'CXXFLAGS=-stdlib=libc++ -I%(' + | |
263 FlavoredName('abs_libcxx', host, options) + | |
264 ')s/include/c++/v1 ' + ' '.join(extra_cflags)]) | |
265 | |
266 return configure_args | 283 return configure_args |
267 | 284 |
268 | 285 |
269 def LibCxxHostArchFlags(host): | 286 def LibCxxHostArchFlags(host): |
270 cc, cxx, _, _ = CompilersForHost(host) | 287 cc, cxx, _, _ = CompilersForHost(host) |
271 cmake_flags = [] | 288 cmake_flags = [] |
272 cmake_flags.extend(['-DCMAKE_C_COMPILER='+cc, '-DCMAKE_CXX_COMPILER='+cxx]) | 289 cmake_flags.extend(['-DCMAKE_C_COMPILER='+cc, '-DCMAKE_CXX_COMPILER='+cxx]) |
273 if TripleIsLinux(host) and not TripleIsX8664(host): | 290 if TripleIsLinux(host) and not TripleIsX8664(host): |
274 # Chrome clang defaults to 64-bit builds, even when run on 32-bit Linux | 291 # Chrome clang defaults to 64-bit builds, even when run on 32-bit Linux |
275 cmake_flags.extend(['-DCMAKE_C_FLAGS=-m32', | 292 cmake_flags.extend(['-DCMAKE_C_FLAGS=-m32', |
276 '-DCMAKE_CXX_FLAGS=-m32']) | 293 '-DCMAKE_CXX_FLAGS=-m32']) |
277 return cmake_flags | 294 return cmake_flags |
278 | 295 |
| 296 |
279 def CmakeHostArchFlags(host, options): | 297 def CmakeHostArchFlags(host, options): |
280 """ Set flags passed to LLVM cmake for compilers and compile flags. """ | 298 """ Set flags passed to LLVM cmake for compilers and compile flags. """ |
281 cmake_flags = [] | 299 cmake_flags = [] |
282 cc, cxx, _, _ = CompilersForHost(host) | 300 cc, cxx, _, _ = CompilersForHost(host) |
283 | 301 |
284 cmake_flags.extend(['-DCMAKE_C_COMPILER='+cc, '-DCMAKE_CXX_COMPILER='+cxx]) | 302 cmake_flags.extend(['-DCMAKE_C_COMPILER='+cc, '-DCMAKE_CXX_COMPILER='+cxx]) |
285 if ProgramPath('ccache'): | 303 if ProgramPath('ccache'): |
286 cmake_flags.extend(['-DSYSTEM_HAS_CCACHE=ON']) | 304 cmake_flags.extend(['-DSYSTEM_HAS_CCACHE=ON']) |
287 | 305 |
288 # There seems to be a bug in chrome clang where it exposes the msan interface | 306 # There seems to be a bug in chrome clang where it exposes the msan interface |
289 # (even when compiling without msan) but then does not link with an | 307 # (even when compiling without msan) but then does not link with an |
290 # msan-enabled compiler_rt, leaving references to __msan_allocated_memory | 308 # msan-enabled compiler_rt, leaving references to __msan_allocated_memory |
291 # undefined. | 309 # undefined. |
292 cmake_flags.append('-DHAVE_SANITIZER_MSAN_INTERFACE_H=FALSE') | 310 cmake_flags.append('-DHAVE_SANITIZER_MSAN_INTERFACE_H=FALSE') |
293 | 311 tool_flags = HostArchToolFlags(host, [], options) |
294 if options.sanitize: | 312 if options.sanitize: |
295 cmake_flags.extend(['-DCMAKE_%s_FLAGS=-fsanitize=%s' % (c, options.sanitize) | 313 for f in ['CFLAGS', 'CXXFLAGS', 'LDFLAGS']: |
296 for c in ('C', 'CXX')]) | 314 tool_flags[f] += '-fsanitize=%s' % options.sanitize |
297 cmake_flags.append('-DCMAKE_EXE_LINKER_FLAGS=-fsanitize=%s' % | 315 cmake_flags.extend(['-DCMAKE_C_FLAGS=' + ' '.join(tool_flags['CFLAGS'])]) |
298 options.sanitize) | 316 cmake_flags.extend(['-DCMAKE_CXX_FLAGS=' + ' '.join(tool_flags['CXXFLAGS'])]) |
299 | 317 for linker_type in ['EXE', 'SHARED', 'MODULE']: |
| 318 cmake_flags.extend([('-DCMAKE_%s_LINKER_FLAGS=' % linker_type) + |
| 319 ' '.join(tool_flags['LDFLAGS'])]) |
300 return cmake_flags | 320 return cmake_flags |
301 | 321 |
302 | 322 |
303 def ConfigureBinutilsCommon(): | 323 def ConfigureBinutilsCommon(): |
304 return ['--with-pkgversion=' + PACKAGE_NAME, | 324 return ['--with-pkgversion=' + PACKAGE_NAME, |
305 '--with-bugurl=' + BUG_URL, | 325 '--with-bugurl=' + BUG_URL, |
306 '--without-zlib', | 326 '--without-zlib', |
307 '--prefix=', | 327 '--prefix=', |
308 '--disable-silent-rules', | 328 '--disable-silent-rules', |
309 '--enable-deterministic-archives', | 329 '--enable-deterministic-archives', |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 '-DLLVM_BINUTILS_INCDIR=%(abs_binutils_pnacl_src)s/include', | 665 '-DLLVM_BINUTILS_INCDIR=%(abs_binutils_pnacl_src)s/include', |
646 '-DLLVM_BUILD_TESTS=ON', | 666 '-DLLVM_BUILD_TESTS=ON', |
647 '-DLLVM_ENABLE_ASSERTIONS=ON', | 667 '-DLLVM_ENABLE_ASSERTIONS=ON', |
648 '-DLLVM_ENABLE_LIBCXX=OFF', | 668 '-DLLVM_ENABLE_LIBCXX=OFF', |
649 '-LLVM_ENABLE_WERROR=' + ('ON' if llvm_do_werror else 'OFF'), | 669 '-LLVM_ENABLE_WERROR=' + ('ON' if llvm_do_werror else 'OFF'), |
650 '-DLLVM_ENABLE_ZLIB=OFF', | 670 '-DLLVM_ENABLE_ZLIB=OFF', |
651 '-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=%(clang_src)s', | 671 '-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=%(clang_src)s', |
652 '-DLLVM_EXTERNAL_SUBZERO_SOURCE_DIR=%(subzero_src)s', | 672 '-DLLVM_EXTERNAL_SUBZERO_SOURCE_DIR=%(subzero_src)s', |
653 '-DLLVM_INSTALL_UTILS=ON', | 673 '-DLLVM_INSTALL_UTILS=ON', |
654 '-DLLVM_TARGETS_TO_BUILD=X86;ARM;Mips;JSBackend', | 674 '-DLLVM_TARGETS_TO_BUILD=X86;ARM;Mips;JSBackend', |
655 '%(llvm_src)s']), | 675 '%(llvm_src)s'], |
656 command.Command(['ninja', '-v']), | 676 # Older CMake ignore CMAKE_*_LINKER_FLAGS during config step. |
657 command.Command(['ninja', 'install']), | 677 # https://public.kitware.com/Bug/view.php?id=14066 |
658 ] + | 678 # The workaround is to set LDFLAGS in the environment. |
659 CreateSymLinksToDirectToNaClTools(host) | 679 # TODO(jvoung): remove the ability to override env vars |
| 680 # from "command" once the CMake fix propagates and we can |
| 681 # stop using this env var hack. |
| 682 env={'LDFLAGS' : ' '.join( |
| 683 HostArchToolFlags(host, [], options)['LDFLAGS'])})] + |
| 684 CopyHostLibcxxForLLVMBuild(host, 'lib', options) + |
| 685 [command.Command(['ninja', '-v']), |
| 686 command.Command(['ninja', 'install'])] + |
| 687 CreateSymLinksToDirectToNaClTools(host) |
660 }, | 688 }, |
661 } | 689 } |
662 cleanup_static_libs = [] | 690 cleanup_static_libs = [] |
663 shared = [] | 691 shared = [] |
664 if host != 'le32-nacl': | 692 if host != 'le32-nacl': |
665 shared = ['--enable-shared'] | 693 shared = ['--enable-shared'] |
666 cleanup_static_libs = [ | 694 cleanup_static_libs = [ |
667 command.Remove(*[os.path.join('%(output)s', 'lib', f) for f | 695 command.Remove(*[os.path.join('%(output)s', 'lib', f) for f |
668 in '*.a', '*Hello.*', 'BugpointPasses.*']), | 696 in '*.a', '*Hello.*', 'BugpointPasses.*']), |
669 ] | 697 ] |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 'x86-32-%s' % pynacl.platform.GetOS(), unsandboxed_runtime_canonical)) | 1172 'x86-32-%s' % pynacl.platform.GetOS(), unsandboxed_runtime_canonical)) |
1145 | 1173 |
1146 if args.build_sbtc and not args.pnacl_in_pnacl: | 1174 if args.build_sbtc and not args.pnacl_in_pnacl: |
1147 packages.update(pnacl_sandboxed_translator.SandboxedTranslators( | 1175 packages.update(pnacl_sandboxed_translator.SandboxedTranslators( |
1148 SANDBOXED_TRANSLATOR_ARCHES)) | 1176 SANDBOXED_TRANSLATOR_ARCHES)) |
1149 | 1177 |
1150 tb = toolchain_main.PackageBuilder(packages, | 1178 tb = toolchain_main.PackageBuilder(packages, |
1151 upload_packages, | 1179 upload_packages, |
1152 leftover_args) | 1180 leftover_args) |
1153 tb.Main() | 1181 tb.Main() |
OLD | NEW |