def NewlibDirectoryCmds(bias_arch, newlib_triple): commands = [] def NewlibLib(name): return os.path.join('%(output)s', newlib_triple, 'lib', name) if not IsBCArch(bias_arch): commands.extend([ command.Rename(NewlibLib('libc.a'), NewlibLib('libcrt_common.a')), command.WriteData(NewlibLibcScript(bias_arch, 'elf64'), NewlibLib('libc.a')) ]) target_triple = TripleFromArch(bias_arch) if bias_arch != 'i686': commands.extend([ # For biased bitcode builds, we configured newlib with target=le32-nacl # to get its pure C implementation, so rename its output dir (which # matches the target to the output dir for the package we are building) command.Rename(os.path.join('%(output)s', newlib_triple), os.path.join('%(output)s', target_triple)), # Copy nacl_random.h, used by libc++. It uses the IRT, so should # be safe to include in the toolchain. command.Mkdir( os.path.join('%(output)s', target_triple, 'include', 'nacl')), command.Copy( os.path.join('%(top_srcdir)s', 'src', 'untrusted', 'nacl', 'nacl_random.h'), os.path.join('%(output)s', target_triple, 'include', 'nacl', 'nacl_random.h')) ]) else: # Use multilib-style directories for i686 multilib_triple = TripleFromArch(MultilibArch(bias_arch)) commands.extend([ command.Rename(os.path.join('%(output)s', newlib_triple), os.path.join('%(output)s', multilib_triple)), command.RemoveDirectory( os.path.join('%(output)s', multilib_triple, 'include')), command.Rename( os.path.join('%(output)s', multilib_triple, 'lib'), os.path.join('%(output)s', multilib_triple, 'lib32')), ]) # Remove the 'share' directory from the biased builds; the data is # duplicated exactly and takes up 2MB per package. if bias_arch != 'le32': commands.append( command.RemoveDirectory(os.path.join('%(output)s', 'share'))) return commands
def PopulateDeps(dep_dirs): commands = [command.RemoveDirectory('all_deps'), command.Mkdir('all_deps')] commands += [ command.Command('cp -r "%s/"* all_deps' % dirname, shell=True) for dirname in dep_dirs ] return commands
def TargetLibsSrc(GitSyncCmds): newlib_sys_nacl = command.path.join('%(output)s', 'newlib', 'libc', 'sys', 'nacl') source = { 'newlib_src': { 'type': 'source', 'output_dirname': 'pnacl-newlib', 'commands': [ # Clean any headers exported from the NaCl tree before syncing. command.CleanGitWorkingDir('%(output)s', reset=False, path=os.path.join( 'newlib', 'libc', 'include')) ] + GitSyncCmds('nacl-newlib') + # Remove newlib versions of headers that will be replaced by # headers from the NaCl tree. [ command.RemoveDirectory( command.path.join(newlib_sys_nacl, dirname)) for dirname in ['bits', 'sys', 'machine'] ] + [ command.Command( [ sys.executable, command.path.join('%(top_srcdir)s', 'src', 'trusted', 'service_runtime', 'export_header.py'), command.path.join('%(top_srcdir)s', 'src', 'trusted', 'service_runtime', 'include'), newlib_sys_nacl ], cwd='%(abs_output)s', ) ] + [ command.Copy( os.path.join('%(top_srcdir)s', 'src', 'untrusted', 'pthread', header), os.path.join('%(output)s', 'newlib', 'libc', 'include', header)) for header in ('pthread.h', 'semaphore.h') ] }, 'compiler_rt_src': { 'type': 'source', 'output_dirname': 'compiler-rt', 'commands': GitSyncCmds('compiler-rt'), }, 'gcc_src': { 'type': 'source', 'output_dirname': 'pnacl-gcc', 'commands': GitSyncCmds('gcc'), }, } return source
def LibcxxDirectoryCmds(bias_arch): if bias_arch != 'i686': return [] lib_dir = os.path.join('%(output)s', MultilibLibDir(bias_arch)) return [ # Use the multlib-style lib dir and shared headers for i686 command.Mkdir(os.path.dirname(lib_dir)), command.Rename(os.path.join('%(output)s', 'i686-nacl', 'lib'), lib_dir), # The only thing left in i686-nacl is the headers command.RemoveDirectory(os.path.join('%(output)s', 'i686-nacl')), ]
def CopyDriverForTargetLib(host): return [ command.RemoveDirectory('driver'), command.Mkdir('driver'), command.Runnable( pnacl_commands.InstallDriverScripts, '%(driver)s', '%(cwd)s/driver', host_windows=TripleIsWindows(host), host_64bit=fnmatch.fnmatch(host, '*x86_64*'), extra_config=[ 'BPREFIXES=%(abs_' + Mangle('llvm', host) + ')s %(abs_' + Mangle('binutils_pnacl', host) + ')s' ]) ]
'tar_src': 'third_party/cloog/isl-0.11.1.tar.bz2', 'unpack_commands': UnpackSrc(False) + PopulateDeps(['%(gmp)s']), 'hashed_inputs': {'src': 'src', 'all_deps': 'all_deps'}, 'commands': CommandsInBuild([ CONFIGURE_CMD + CONFIGURE_HOST_LIB + WithDepsOptions([ 'sysroot', 'gmp-prefix', ]), MAKE_PARALLEL_CMD, MAKE_CHECK_CMD, MAKE_DESTDIR_CMD + ['install-strip'], ]) + [ # The .pc files wind up containing some absolute paths # that make the output depend on the build directory name. # The dependents' configure scripts don't need them anyway. command.RemoveDirectory(os.path.join('%(output)s', 'lib', 'pkgconfig')), ], }, 'cloog': { 'dependencies': ['gmp', 'isl'], 'tar_src': 'third_party/cloog/cloog-0.18.0.tar.gz', 'unpack_commands': UnpackSrc(True) + PopulateDeps(['%(gmp)s', '%(isl)s']), 'hashed_inputs': {'src': 'src', 'all_deps': 'all_deps'}, 'commands': CommandsInBuild([ CONFIGURE_CMD + CONFIGURE_HOST_LIB + [ '--with-bits=gmp', '--with-isl=system', ] + WithDepsOptions(['sysroot', 'gmp-prefix', 'isl-prefix']),
def HostTools(host, options): def H(component_name): # Return a package name for a component name with a host triple. return component_name + '_' + pynacl.gsd_storage.LegalizeName(host) def IsHost64(host): return fnmatch.fnmatch(host, 'x86_64*') def HostSubdir(host): return 'host_x86_64' if IsHost64(host) else 'host_x86_32' def BinSubdir(host): return 'bin64' if host == 'x86_64-linux' else 'bin' # Return the file name with the appropriate suffix for an executable file. def Exe(file): if TripleIsWindows(host): return file + '.exe' else: return file tools = { H('binutils_pnacl'): { 'dependencies': ['binutils_pnacl_src'], 'type': 'build', 'output_subdir': HostSubdir(host), 'commands': [ command.SkipForIncrementalCommand([ 'sh', '%(binutils_pnacl_src)s/configure' ] + ConfigureHostArchFlags(host) + [ '--prefix=', '--disable-silent-rules', '--target=arm-pc-nacl', '--program-prefix=le32-nacl-', '--enable-targets=arm-pc-nacl,i686-pc-nacl,x86_64-pc-nacl,' + 'mipsel-pc-nacl', '--enable-deterministic-archives', '--enable-shared=no', '--enable-gold=default', '--enable-ld=no', '--enable-plugins', '--without-gas', '--without-zlib', '--with-sysroot=/arm-pc-nacl' ]), command.Command(MakeCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']) ] + [ command.RemoveDirectory(os.path.join('%(output)s', dir)) for dir in ('arm-pc-nacl', 'lib', 'lib32') ] }, H('driver'): { 'type': 'build', 'output_subdir': BinSubdir(host), 'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': [ command.Runnable(pnacl_commands.InstallDriverScripts, '%(src)s', '%(output)s', host_windows=TripleIsWindows(host), host_64bit=IsHost64(host)) ], }, } llvm_cmake = { H('llvm'): { 'dependencies': ['clang_src', 'llvm_src', 'binutils_pnacl_src'], 'type': 'build', 'output_subdir': HostSubdir(host), 'commands': [ command.SkipForIncrementalCommand([ 'cmake', '-G', 'Ninja' ] + CmakeHostArchFlags(host, options) + [ '-DCMAKE_BUILD_TYPE=RelWithDebInfo', '-DCMAKE_INSTALL_PREFIX=%(output)s', '-DCMAKE_INSTALL_RPATH=$ORIGIN/../lib', '-DBUILD_SHARED_LIBS=ON', '-DLLVM_ENABLE_ASSERTIONS=ON', '-DLLVM_ENABLE_ZLIB=OFF', '-DLLVM_BUILD_TESTS=ON', '-DLLVM_APPEND_VC_REV=ON', '-DLLVM_BINUTILS_INCDIR=%(abs_binutils_pnacl_src)s/include', '-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=%(clang_src)s', '%(llvm_src)s' ]), command.Command(['ninja', '-v']), command.Command(['ninja', 'install']), ], }, } llvm_autoconf = { H('llvm'): { 'dependencies': ['clang_src', 'llvm_src', 'binutils_pnacl_src'], 'type': 'build', 'output_subdir': HostSubdir(host), 'commands': [ command.SkipForIncrementalCommand([ 'sh', '%(llvm_src)s/configure' ] + ConfigureHostArchFlags(host) + [ '--prefix=/', '--enable-shared', '--disable-zlib', '--disable-terminfo', '--disable-jit', '--disable-bindings', # ocaml is currently the only binding. '--with-binutils-include=%(abs_binutils_pnacl_src)s/include', '--enable-targets=x86,arm,mips', '--program-prefix=', '--enable-optimized', '--with-clang-srcdir=%(abs_clang_src)s' ]), command.Command( MakeCommand(host) + ['VERBOSE=1', 'NACL_SANDBOX=0', 'all']), command.Command(MAKE_DESTDIR_CMD + ['install']), command.Remove(*[ os.path.join('%(output)s', 'lib', f) for f in '*.a', '*Hello.*', 'BugpointPasses.*' ]), command.Remove(*[ os.path.join('%(output)s', 'bin', f) for f in Exe('clang-format'), Exe('clang-check'), Exe('c-index-test'), Exe('clang-tblgen'), Exe('llvm-tblgen') ]) ] + CopyWindowsHostLibs(host), }, } if options.cmake: tools.update(llvm_cmake) else: tools.update(llvm_autoconf) if TripleIsWindows(host): tools[H('binutils_pnacl')]['dependencies'].append('libdl') tools[H('llvm')]['dependencies'].append('libdl') return tools
def HostTools(host): def H(component_name): # Return a package name for a component name with a host triple. return component_name + '_' + gsd_storage.LegalizeName(host) def IsHost64(host): return fnmatch.fnmatch(host, 'x86_64*') def HostSubdir(host): return 'host_x86_64' if IsHost64(host) else 'host_x86_32' def BinSubdir(host): return 'bin64' if host == 'x86_64-linux' else 'bin' tools = { H('binutils_pnacl'): { 'dependencies': ['binutils_pnacl_src'], 'type': 'build', 'output_subdir': HostSubdir(host), 'commands': [ command.SkipForIncrementalCommand([ 'sh', '%(binutils_pnacl_src)s/configure'] + ConfigureHostArchFlags(host) + ['--prefix=', '--disable-silent-rules', '--target=arm-pc-nacl', '--program-prefix=le32-nacl-', '--enable-targets=arm-pc-nacl,i686-pc-nacl,x86_64-pc-nacl,' + 'mipsel-pc-nacl', '--enable-deterministic-archives', '--enable-shared=no', '--enable-gold=default', '--enable-ld=no', '--enable-plugins', '--without-gas', '--without-zlib', '--with-sysroot=/arm-pc-nacl']), command.Command(MakeCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip'])] + [command.RemoveDirectory(os.path.join('%(output)s', dir)) for dir in ('arm-pc-nacl', 'lib', 'lib32')] }, H('llvm'): { 'dependencies': ['clang_src', 'llvm_src', 'binutils_pnacl_src'], 'type': 'build', 'output_subdir': HostSubdir(host), 'commands': [ command.SkipForIncrementalCommand([ 'sh', '%(llvm_src)s/configure'] + ConfigureHostArchFlags(host) + ['--prefix=/', '--enable-shared', '--disable-zlib', '--disable-jit', '--disable-bindings', # ocaml is currently the only binding. '--with-binutils-include=%(abs_binutils_pnacl_src)s/include', '--enable-targets=x86,arm,mips', '--program-prefix=', '--enable-optimized', '--with-clang-srcdir=%(abs_clang_src)s']), command.Command(MakeCommand(host) + [ 'VERBOSE=1', 'NACL_SANDBOX=0', 'all']), command.Command(MAKE_DESTDIR_CMD + ['install'])] + CopyWindowsHostLibs(host), }, H('driver'): { 'type': 'build', 'output_subdir': BinSubdir(host), 'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'driver')}, 'commands': [ command.Runnable(pnacl_commands.InstallDriverScripts, '%(src)s', '%(output)s', host_windows=TripleIsWindows(host), host_64bit=IsHost64(host)) ], }, } if TripleIsWindows(host) and not command.Runnable.use_cygwin: tools[H('binutils_pnacl')]['dependencies'].append('libdl') tools[H('llvm')]['dependencies'].append('libdl') return tools
def NativeLibs(host, arch): def H(component_name): return Mangle(component_name, host) setjmp_arch = arch if setjmp_arch == 'x86-32-nonsfi': setjmp_arch = 'x86-32' libs = { Mangle('libs_support_native', arch): { 'type': 'build', 'output_subdir': 'lib-' + arch, 'dependencies': ['newlib_src', 'newlib_portable', H('llvm'), H('binutils_pnacl')], # These libs include # arbitrary stuff from native_client/src/{include,untrusted,trusted} 'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'support'), 'include': os.path.join(NACL_DIR, 'src'), 'newlib_subset': os.path.join(NACL_DIR, 'src', 'third_party_mod', 'pnacl_native_newlib_subset'), 'driver': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': CopyDriverForTargetLib(host) + [ BuildTargetNativeCmd( 'crtbegin.c', 'crtbegin.o', arch, output_dir='%(output)s'), BuildTargetNativeCmd('crtbegin.c', 'crtbegin_for_eh.o', arch, ['-DLINKING_WITH_LIBGCC_EH'], output_dir='%(output)s'), BuildTargetNativeCmd( 'crtend.c', 'crtend.o', arch, output_dir='%(output)s'), # libcrt_platform.a BuildTargetNativeCmd('pnacl_irt.c', 'pnacl_irt.o', arch), BuildTargetNativeCmd( 'setjmp_%s.S' % setjmp_arch.replace('-', '_'), 'setjmp.o', arch), BuildTargetNativeCmd('string.c', 'string.o', arch, ['-std=c99'], source_dir='%(newlib_subset)s'), # Pull in non-errno __ieee754_fmod from newlib and rename it to # fmod. This is to support the LLVM frem instruction. BuildTargetNativeCmd( 'e_fmod.c', 'e_fmod.o', arch, [ '-std=c99', '-I%(abs_newlib_src)s/newlib/libm/common/', '-D__ieee754_fmod=fmod' ], source_dir='%(abs_newlib_src)s/newlib/libm/math'), BuildTargetNativeCmd( 'ef_fmod.c', 'ef_fmod.o', arch, [ '-std=c99', '-I%(abs_newlib_src)s/newlib/libm/common/', '-D__ieee754_fmodf=fmodf' ], source_dir='%(abs_newlib_src)s/newlib/libm/math') ] + AeabiReadTpCmd(arch) + [ command.Command(' '.join([ PnaclTool('ar'), 'rc', command.path.join('%(output)s', 'libcrt_platform.a'), '*.o' ]), shell=True), # Dummy IRT shim BuildTargetNativeCmd('dummy_shim_entry.c', 'dummy_shim_entry.o', arch), command.Command([ PnaclTool('ar'), 'rc', command.path.join('%(output)s', 'libpnacl_irt_shim_dummy.a'), 'dummy_shim_entry.o' ]), ], }, Mangle('compiler_rt', arch): { 'type': 'build', 'output_subdir': 'lib-' + arch, 'dependencies': ['compiler_rt_src', H('llvm'), H('binutils_pnacl')], 'inputs': { 'driver': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': CopyDriverForTargetLib(host) + [ command.Command(MakeCommand() + [ '-f', command.path.join('%(compiler_rt_src)s', 'lib', 'Makefile-pnacl'), 'libgcc.a', 'CC=' + PnaclTool('clang'), 'AR=' + PnaclTool('ar') ] + [ 'SRC_DIR=' + command.path.join('%(abs_compiler_rt_src)s', 'lib'), 'CFLAGS=-arch ' + arch + ' -DPNACL_' + arch.replace('-', '_') + ' --pnacl-allow-translate -O3' ]), command.Copy('libgcc.a', os.path.join('%(output)s', 'libgcc.a')), ], }, } if arch != 'x86-32-nonsfi': libs.update({ Mangle('libgcc_eh', arch): { 'type': 'build', 'output_subdir': 'lib-' + arch, 'dependencies': ['gcc_src', H('llvm'), H('binutils_pnacl')], 'inputs': { 'scripts': os.path.join(NACL_DIR, 'pnacl', 'scripts'), 'driver': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': # Instead of trying to use gcc's build system to build only # libgcc_eh, we just build the C files and archive them manually. CopyDriverForTargetLib(host) + [ command.RemoveDirectory('include'), command.Mkdir('include'), command.Copy( os.path.join('%(gcc_src)s', 'gcc', 'unwind-generic.h'), os.path.join('include', 'unwind.h')), command.Copy( os.path.join('%(scripts)s', 'libgcc-tconfig.h'), 'tconfig.h'), command.WriteData('', 'tm.h'), BuildLibgccEhCmd('unwind-dw2.c', 'unwind-dw2.o', arch), BuildLibgccEhCmd('unwind-dw2-fde-glibc.c', 'unwind-dw2-fde-glibc.o', arch), command.Command([ PnaclTool('ar'), 'rc', command.path.join('%(output)s', 'libgcc_eh.a'), 'unwind-dw2.o', 'unwind-dw2-fde-glibc.o' ]), ], }, }) return libs
def BitcodeLibs(host, bias_arch): def H(component_name): return Mangle(component_name, host) def B(component_name): return Mangle(component_name, bias_arch) def BcSubdir(subdir, bias_arch): if bias_arch == 'portable': return subdir else: return subdir + '-bc-' + bias_arch libs = { B('newlib'): { 'type': 'build', 'output_subdir': BcSubdir('usr', bias_arch), 'dependencies': ['newlib_src', H('llvm'), H('binutils_pnacl')], 'inputs': { 'driver': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': CopyDriverForTargetLib(host) + [ command.SkipForIncrementalCommand( ['sh', '%(newlib_src)s/configure'] + TARGET_TOOLS + [ 'CFLAGS_FOR_TARGET=' + TargetBCLibCflags(bias_arch) + ' -allow-asm', '--disable-multilib', '--prefix=', '--disable-newlib-supplied-syscalls', '--disable-texinfo', '--disable-libgloss', '--enable-newlib-iconv', '--enable-newlib-iconv-from-encodings=' + 'UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4', '--enable-newlib-iconv-to-encodings=' + 'UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4', '--enable-newlib-io-long-long', '--enable-newlib-io-long-double', '--enable-newlib-io-c99-formats', '--enable-newlib-mb', '--target=le32-nacl' ]), command.Command(MakeCommand()), command.Command(['make', 'DESTDIR=%(abs_output)s', 'install']), command.CopyTree( command.path.join('%(output)s', 'le32-nacl', 'lib'), command.path.join('%(output)s', 'lib')), command.CopyTree( command.path.join('%(output)s', 'le32-nacl', 'include'), command.path.join('%(output)s', 'include')), command.RemoveDirectory( command.path.join('%(output)s', 'le32-nacl')), command.Mkdir(os.path.join('%(output)s', 'include', 'nacl')), # Copy nacl_random.h, used by libc++. It uses the IRT, so should # be safe to include in the toolchain. command.Copy( os.path.join('%(top_srcdir)s', 'src', 'untrusted', 'nacl', 'nacl_random.h'), os.path.join('%(output)s', 'include', 'nacl', 'nacl_random.h')), ], }, B('libcxx'): { 'type': 'build', 'output_subdir': BcSubdir('usr', bias_arch), 'dependencies': [ 'libcxx_src', 'libcxxabi_src', 'llvm_src', 'gcc_src', H('llvm'), H('binutils_pnacl'), B('newlib') ], 'inputs': { 'driver': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': CopyDriverForTargetLib(host) + [ command.SkipForIncrementalCommand([ 'cmake', '-G', 'Unix Makefiles', '-DCMAKE_C_COMPILER_WORKS=1', '-DCMAKE_CXX_COMPILER_WORKS=1', '-DCMAKE_INSTALL_PREFIX=', '-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_C_COMPILER=' + PnaclTool('clang'), '-DCMAKE_CXX_COMPILER=' + PnaclTool('clang++'), '-DCMAKE_AR=' + PnaclTool('ar'), '-DCMAKE_NM=' + PnaclTool('nm'), '-DCMAKE_RANLIB=' + PnaclTool('ranlib'), '-DCMAKE_LD=' + PnaclTool('illegal'), '-DCMAKE_AS=' + PnaclTool('illegal'), '-DCMAKE_OBJDUMP=' + PnaclTool('illegal'), '-DCMAKE_C_FLAGS=-std=gnu11 ' + LibCxxCflags(bias_arch), '-DCMAKE_CXX_FLAGS=-std=gnu++11 ' + LibCxxCflags(bias_arch), '-DLIT_EXECUTABLE=' + command.path.join( '%(llvm_src)s', 'utils', 'lit', 'lit.py'), '-DLLVM_LIT_ARGS=--verbose --param shell_prefix="' + os.path.join(NACL_DIR, 'run.py') + '-arch env --retries=1" ' + '--param exe_suffix=".pexe" --param use_system_lib=true ' + '--param link_flags="-std=gnu++11 --pnacl-exceptions=sjlj"', '-DLIBCXX_ENABLE_CXX0X=0', '-DLIBCXX_ENABLE_SHARED=0', '-DLIBCXX_CXX_ABI=libcxxabi', '-DLIBCXX_LIBCXXABI_INCLUDE_PATHS=' + command.path.join( '%(abs_libcxxabi_src)s', 'include'), '%(libcxx_src)s' ]), command.Copy( os.path.join('%(gcc_src)s', 'gcc', 'unwind-generic.h'), os.path.join('include', 'unwind.h')), command.Command(MakeCommand() + ['VERBOSE=1']), command.Command([ 'make', 'DESTDIR=%(abs_output)s', 'VERBOSE=1', 'install' ]), ], }, B('libstdcxx'): { 'type': 'build', 'output_subdir': BcSubdir('usr', bias_arch), 'dependencies': [ 'gcc_src', 'gcc_src', H('llvm'), H('binutils_pnacl'), B('newlib') ], 'inputs': { 'driver': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': CopyDriverForTargetLib(host) + [ command.SkipForIncrementalCommand([ 'sh', command.path.join('%(gcc_src)s', 'libstdc++-v3', 'configure') ] + TARGET_TOOLS + [ 'CC_FOR_BUILD=cc', 'CC=' + PnaclTool('clang'), 'CXX=' + PnaclTool('clang++'), 'AR=' + PnaclTool('ar'), 'NM=' + PnaclTool('nm'), 'RAW_CXX_FOR_TARGET=' + PnaclTool('clang++'), 'LD=' + PnaclTool('illegal'), 'RANLIB=' + PnaclTool('ranlib'), 'CFLAGS=' + LibStdcxxCflags(bias_arch), 'CXXFLAGS=' + LibStdcxxCflags(bias_arch), 'CPPFLAGS=' + NewlibIsystemCflags(bias_arch), 'CFLAGS_FOR_TARGET=' + LibStdcxxCflags(bias_arch), 'CXXFLAGS_FOR_TARGET=' + LibStdcxxCflags(bias_arch), '--host=armv7-none-linux-gnueabi', '--prefix=', '--enable-cxx-flags=-D__SIZE_MAX__=4294967295', '--disable-multilib', '--disable-linux-futex', '--disable-libstdcxx-time', '--disable-sjlj-exceptions', '--disable-libstdcxx-pch', '--with-newlib', '--disable-shared', '--disable-rpath' ]), command.Copy( os.path.join('%(gcc_src)s', 'gcc', 'unwind-generic.h'), os.path.join('include', 'unwind.h')), command.Command(MakeCommand()), command.Command( ['make', 'DESTDIR=%(abs_output)s', 'install-data']), command.RemoveDirectory(os.path.join('%(output)s', 'share')), command.Remove( os.path.join('%(output)s', 'lib', 'libstdc++*-gdb.py')), command.Copy(os.path.join('src', '.libs', 'libstdc++.a'), os.path.join('%(output)s', 'lib', 'libstdc++.a')), ], }, B('libs_support_bitcode'): { 'type': 'build', 'output_subdir': BcSubdir('lib', bias_arch), 'dependencies': [B('newlib'), H('llvm'), H('binutils_pnacl')], 'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'support', 'bitcode'), 'driver': os.path.join(NACL_DIR, 'pnacl', 'driver') }, 'commands': CopyDriverForTargetLib(host) + [ # Two versions of crt1.x exist, for different scenarios (with and # without EH). See: # https://code.google.com/p/nativeclient/issues/detail?id=3069 command.Copy(command.path.join('%(src)s', 'crt1.x'), command.path.join('%(output)s', 'crt1.x')), command.Copy(command.path.join('%(src)s', 'crt1_for_eh.x'), command.path.join('%(output)s', 'crt1_for_eh.x')), # Install crti.bc (empty _init/_fini) BuildTargetBitcodeCmd('crti.c', 'crti.bc', bias_arch), # Install crtbegin bitcode (__cxa_finalize for C++) BuildTargetBitcodeCmd('crtbegin.c', 'crtbegin.bc', bias_arch), # Stubs for _Unwind_* functions when libgcc_eh is not included in # the native link). BuildTargetBitcodeCmd('unwind_stubs.c', 'unwind_stubs.bc', bias_arch), BuildTargetBitcodeCmd('sjlj_eh_redirect.c', 'sjlj_eh_redirect.bc', bias_arch), # libpnaclmm.a (__atomic_* library functions). BuildTargetBitcodeCmd('pnaclmm.c', 'pnaclmm.bc', bias_arch), command.Command([ PnaclTool('ar'), 'rc', command.path.join('%(output)s', 'libpnaclmm.a'), command.path.join('%(output)s', 'pnaclmm.bc') ]), ], }, } return libs
def HostTools(host, target): def H(component_name): return ForHost(component_name, host) def WindowsAlternate(if_windows, if_not_windows, if_mac=None): if if_mac is not None and HostIsMac(host): return if_mac elif HostIsWindows(host): return if_windows else: return if_not_windows # Return the file name with the appropriate suffix for an executable file. def Exe(file): return file + WindowsAlternate('.exe', '') # The binutils git checkout includes all the directories in the # upstream binutils-gdb.git repository, but some of these # directories are not included in a binutils release tarball. The # top-level Makefile will try to build whichever of the whole set # exist, but we don't want these extra directories built. So we # stub them out by creating dummy <subdir>/Makefile files; having # these exist before the configure-<subdir> target in the # top-level Makefile runs prevents it from doing anything. binutils_dummy_dirs = ['gdb', 'libdecnumber', 'readline', 'sim'] def DummyDirCommands(dirs): dummy_makefile = """\ .DEFAULT:;@echo Ignoring $@ """ commands = [] for dir in dirs: commands.append(command.Mkdir(command.path.join('%(cwd)s', dir))) commands.append( command.WriteData( dummy_makefile, command.path.join('%(cwd)s', dir, 'Makefile'))) return commands tools = { H('binutils_' + target): { 'type': 'build', 'dependencies': ['binutils'], 'commands': ConfigureTargetPrep(target) + [ command.Command( ConfigureCommand('binutils') + ConfigureHostTool(host) + # The Mac compiler is too warning-happy for -Werror. WindowsAlternate([], [], ['--disable-werror']) + ConfigureTargetArgs(target) + [ # Ensure that all the NaCl backends get included, # just for convenience of using the same tools for # whatever target machine. The upstream default # includes all the 32-bit *-nacl targets when any # *-nacl target is selected (via --target), but only # includes 64-bit secondary targets for 64-bit hosts. '--enable-targets=arm-nacl,i686-nacl,x86_64-nacl', '--enable-deterministic-archives', '--enable-gold', ] + WindowsAlternate([], ['--enable-plugins'])) ] + DummyDirCommands(binutils_dummy_dirs) + [ command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), REMOVE_INFO_DIR, ] + InstallDocFiles('binutils', ['COPYING3'] + [ command.path.join(subdir, 'NEWS') for subdir in ['binutils', 'gas', 'ld', 'gold'] ]) + # The top-level lib* directories contain host libraries # that we don't want to include in the distribution. [ command.RemoveDirectory(command.path.join('%(output)s', name)) for name in ['lib', 'lib32', 'lib64'] ], }, H('gcc_' + target): { 'type': 'build', 'dependencies': (['gcc'] + HostGccLibsDeps(host) + GccDeps(host, target)), 'commands': ConfigureTargetPrep(target) + [ ConfigureGccCommand('gcc', host, target), # GCC's configure step writes configargs.h with some strings # including the configure command line, which get embedded # into the gcc driver binary. The build only works if we use # absolute paths in some of the configure switches, but # embedding those paths makes the output differ in repeated # builds done in different directories, which we do not want. # So force the generation of that file early and then edit it # in place to replace the absolute paths with something that # never varies. Note that the 'configure-gcc' target will # actually build some components before running gcc/configure. GccCommand(host, target, MakeCommand(host, ['configure-gcc'])), command.Command([ 'sed', '-i', '-e', ';'.join([ 's@%%(abs_%s)s@.../%s_install@g' % (component, component) for component in HostGccLibsDeps(host) ] + ['s@%(cwd)s@...@g']), command.path.join('gcc', 'configargs.h') ]), # gcc/Makefile's install rules ordinarily look at the # installed include directory for a limits.h to decide # whether the lib/gcc/.../include-fixed/limits.h header # should be made to expect a libc-supplied limits.h or not. # Since we're doing this build in a clean environment without # any libc installed, we need to force its hand here. GccCommand( host, target, MakeCommand(host, [ 'all-gcc', 'LIMITS_H_TEST=true', 'MAKEOVERRIDES=inhibit_libc=true', ])), # gcc/Makefile's install targets populate this directory # only if it already exists. command.Mkdir( command.path.join('%(output)s', target + '-nacl', 'bin'), True), GccCommand(host, target, MAKE_DESTDIR_CMD + ['install-strip-gcc']), REMOVE_INFO_DIR, # Note we include COPYING.RUNTIME here and not with gcc_libs. ] + InstallDocFiles('gcc', ['COPYING3', 'COPYING.RUNTIME']), }, # GDB can support all the targets in one host tool. H('gdb'): { 'type': 'build', 'dependencies': ['gdb', H('expat')], 'commands': [ command.Command( ConfigureCommand('gdb') + ConfigureHostTool(host) + [ '--target=x86_64-nacl', '--enable-targets=arm-none-eabi-nacl', '--with-expat', # Windows (MinGW) is missing ncurses; we need to # build one here and link it in statically for # --enable-tui. See issue nativeclient:3911. '--%s-tui' % WindowsAlternate('disable', 'enable'), 'CPPFLAGS=-I%(abs_' + H('expat') + ')s/include', 'LDFLAGS=-L%(abs_' + H('expat') + ')s/lib', ] + # TODO(mcgrathr): Should use --with-python to ensure # we have it on Linux/Mac. WindowsAlternate(['--without-python'], []) + # TODO(mcgrathr): The default -Werror only breaks because # the OSX default compiler is an old front-end that does # not understand all the GCC options. Maybe switch to # using clang (system or Chromium-supplied) on Mac. (['--disable-werror'] if HostIsMac(host) else [])), command.Command(MakeCommand(host) + ['all-gdb']), command.Command(MAKE_DESTDIR_CMD + [ '-C', 'gdb', 'install-strip', ]), REMOVE_INFO_DIR, ] + [ command.Command([ 'ln', '-f', command.path.join('%(abs_output)s', 'bin', Exe('x86_64-nacl-gdb')), command.path.join('%(abs_output)s', 'bin', Exe(arch + '-nacl-gdb')) ]) for arch in ['i686', 'arm'] ] + InstallDocFiles('gdb', [ 'COPYING3', command.path.join('gdb', 'NEWS'), ]), }, } # TODO(mcgrathr): The ARM cross environment does not supply a termcap # library, so it cannot build GDB. if host.startswith('arm') and CrossCompiling(host): del tools[H('gdb')] return tools
def HostTools(target): tools = { 'binutils_' + target: { 'git_url': GIT_BASE_URL + '/nacl-binutils.git', 'git_revision': GIT_REVISIONS['binutils'], 'commands': ConfigureTargetPrep(target) + [ command.Command( CONFIGURE_CMD + CONFIGURE_HOST_TOOL + ConfigureTargetArgs(target) + [ '--enable-deterministic-archives', '--enable-gold', ] + ([] if sys.platform == 'win32' else [ '--enable-plugins', ])), command.Command(MAKE_PARALLEL_CMD), command.Command(MAKE_CHECK_CMD), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), REMOVE_INFO_DIR, ] + InstallDocFiles('binutils', ['COPYING3'] + [os.path.join(subdir, 'NEWS') for subdir in ['binutils', 'gas', 'ld', 'gold']]) + # The top-level lib* directories contain host libraries # that we don't want to include in the distribution. [command.RemoveDirectory(os.path.join('%(output)s', name)) for name in ['lib', 'lib32', 'lib64']], }, 'gcc_' + target: { 'dependencies': HOST_GCC_LIBS_DEPS + ['binutils_' + target], 'git_url': GCC_GIT_URL, 'git_revision': GIT_REVISIONS['gcc'], # Remove all the source directories that are used solely for # building target libraries. We don't want those included in the # input hash calculation so that we don't rebuild the compiler # when the the only things that have changed are target libraries. 'unpack_commands': [command.RemoveDirectory(dirname) for dirname in [ 'boehm-gc', 'libada', 'libffi', 'libgcc', 'libgfortran', 'libgo', 'libgomp', 'libitm', 'libjava', 'libmudflap', 'libobjc', 'libquadmath', 'libssp', 'libstdc++-v3', ]], 'commands': ConfigureTargetPrep(target) + [ ConfigureGccCommand(target), # gcc/Makefile's install rules ordinarily look at the # installed include directory for a limits.h to decide # whether the lib/gcc/.../include-fixed/limits.h header # should be made to expect a libc-supplied limits.h or not. # Since we're doing this build in a clean environment without # any libc installed, we need to force its hand here. GccCommand(target, MAKE_PARALLEL_CMD + ['all-gcc', 'LIMITS_H_TEST=true']), # gcc/Makefile's install targets populate this directory # only if it already exists. command.Mkdir(os.path.join('%(output)s', target + '-nacl', 'bin'), True), GccCommand(target, MAKE_DESTDIR_CMD + ['install-strip-gcc']), REMOVE_INFO_DIR, # Note we include COPYING.RUNTIME here and not with gcc_libs. ] + InstallDocFiles('gcc', ['COPYING3', 'COPYING.RUNTIME']), }, } return tools
def CommandsInBuild(command_lines): return [ command.RemoveDirectory('build'), command.Mkdir('build'), ] + [command.Command(cmd, cwd='build') for cmd in command_lines]
def CollectSources(): sources = {} for package in TAR_FILES: tar_file = TAR_FILES[package] if fnmatch.fnmatch(tar_file, '*.bz2'): extract = EXTRACT_STRIP_TBZ2 elif fnmatch.fnmatch(tar_file, '*.gz'): extract = EXTRACT_STRIP_TGZ else: raise Exception('unexpected file name pattern in TAR_FILES[%r]' % package) sources[package] = { 'type': 'source', 'commands': [ command.Command(extract + [ command.path.join('%(abs_top_srcdir)s', '..', 'third_party', tar_file) ], cwd='%(output)s'), ], } patch_packages = [] patch_commands = [] for package, info in GIT_REVISIONS.iteritems(): sources[package] = { 'type': 'source', 'commands': [command.SyncGitRepo(GitUrl(package), '%(output)s', info['rev'])], } patch_packages.append(package) patch_commands.append( command.GenerateGitPatches('%(' + package + ')s/.git', info)) sources['patches'] = { 'type': 'build', 'dependencies': patch_packages, 'commands': patch_commands, } # The gcc_libs component gets the whole GCC source tree. sources['gcc_libs'] = sources['gcc'] # The gcc component omits all the source directories that are used solely # for building target libraries. We don't want those included in the # input hash calculation so that we don't rebuild the compiler when the # the only things that have changed are target libraries. sources['gcc'] = { 'type': 'source', 'dependencies': ['gcc_libs'], 'commands': [ command.CopyTree('%(gcc_libs)s', '%(output)s', [ 'boehm-gc', 'libada', 'libatomic', 'libffi', 'libgcc', 'libgfortran', 'libgo', 'libgomp', 'libitm', 'libjava', 'libmudflap', 'libobjc', 'libquadmath', 'libsanitizer', 'libssp', 'libstdc++-v3', ]) ] } # We have to populate the newlib source tree with the "exported" form of # some headers from the native_client source tree. The newlib build # needs these to be in the expected place. By doing this in the source # target, these files will be part of the input hash and so we don't need # to do anything else to keep track of when they might have changed in # the native_client source tree. newlib_sys_nacl = command.path.join('%(output)s', 'newlib', 'libc', 'sys', 'nacl') newlib_unpack = [ command.RemoveDirectory(command.path.join(newlib_sys_nacl, dirname)) for dirname in ['bits', 'sys', 'machine'] ] newlib_unpack.append( command.Command([ 'python', command.path.join('%(top_srcdir)s', 'src', 'trusted', 'service_runtime', 'export_header.py'), command.path.join('%(top_srcdir)s', 'src', 'trusted', 'service_runtime', 'include'), newlib_sys_nacl, ])) sources['newlib']['commands'] += newlib_unpack return sources
def HostTools(host, target): def H(component_name): return ForHost(component_name, host) tools = { H('binutils_' + target): { 'type': 'build', 'dependencies': ['binutils'], 'commands': ConfigureTargetPrep(target) + [ command.Command( ConfigureCommand('binutils') + ConfigureHostTool(host) + ConfigureTargetArgs(target) + [ '--enable-deterministic-archives', '--enable-gold', ] + ([] if HostIsWindows(host) else [ '--enable-plugins', ])), command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), REMOVE_INFO_DIR, ] + InstallDocFiles('binutils', ['COPYING3'] + [ command.path.join(subdir, 'NEWS') for subdir in ['binutils', 'gas', 'ld', 'gold'] ]) + # The top-level lib* directories contain host libraries # that we don't want to include in the distribution. [ command.RemoveDirectory(command.path.join('%(output)s', name)) for name in ['lib', 'lib32', 'lib64'] ], }, H('gcc_' + target): { 'type': 'build', 'dependencies': (['gcc'] + HostGccLibsDeps(host) + GccDeps(host, target)), 'commands': ConfigureTargetPrep(target) + [ ConfigureGccCommand('gcc', host, target), # GCC's configure step writes configargs.h with some strings # including the configure command line, which get embedded # into the gcc driver binary. The build only works if we use # absolute paths in some of the configure switches, but # embedding those paths makes the output differ in repeated # builds done in different directories, which we do not want. # So force the generation of that file early and then edit it # in place to replace the absolute paths with something that # never varies. Note that the 'configure-gcc' target will # actually build some components before running gcc/configure. GccCommand(host, target, MakeCommand(host, ['configure-gcc'])), command.Command([ 'sed', '-i', '-e', ';'.join([ 's@%%(abs_%s)s@.../%s_install@g' % (component, component) for component in HostGccLibsDeps(host) ] + ['s@%(cwd)s@...@g']), command.path.join('gcc', 'configargs.h') ]), # gcc/Makefile's install rules ordinarily look at the # installed include directory for a limits.h to decide # whether the lib/gcc/.../include-fixed/limits.h header # should be made to expect a libc-supplied limits.h or not. # Since we're doing this build in a clean environment without # any libc installed, we need to force its hand here. GccCommand( host, target, MakeCommand(host, ['all-gcc', 'LIMITS_H_TEST=true'])), # gcc/Makefile's install targets populate this directory # only if it already exists. command.Mkdir( command.path.join('%(output)s', target + '-nacl', 'bin'), True), GccCommand(host, target, MAKE_DESTDIR_CMD + ['install-strip-gcc']), REMOVE_INFO_DIR, # Note we include COPYING.RUNTIME here and not with gcc_libs. ] + InstallDocFiles('gcc', ['COPYING3', 'COPYING.RUNTIME']), }, # GDB can support all the targets in one host tool. H('gdb'): { 'type': 'build', 'dependencies': ['gdb', H('expat')], 'commands': [ command.Command( ConfigureCommand('gdb') + ConfigureHostTool(host) + [ '--target=x86_64-nacl', '--enable-targets=arm-none-eabi-nacl', '--with-expat', 'CPPFLAGS=-I%(abs_' + H('expat') + ')s/include', 'LDFLAGS=-L%(abs_' + H('expat') + ')s/lib', ] + (['--without-python'] if HostIsWindows(host) else []) + # TODO(mcgrathr): The default -Werror only breaks because # the OSX default compiler is an old front-end that does # not understand all the GCC options. Maybe switch to # using clang (system or Chromium-supplied) on Mac. (['--disable-werror'] if HostIsMac(host) else [])), command.Command(MakeCommand(host) + ['all-gdb']), command.Command(MAKE_DESTDIR_CMD + [ '-C', 'gdb', 'install-strip', ]), REMOVE_INFO_DIR, ] + InstallDocFiles('gdb', [ 'COPYING3', command.path.join('gdb', 'NEWS'), ]), }, } # TODO(mcgrathr): The ARM cross environment does not supply a termcap # library, so it cannot build GDB. if host.startswith('arm'): native, _ = NativeTuple() is_cross = host != native if is_cross: del tools[H('gdb')] return tools
def HostTools(target): tools = { 'binutils_' + target: { 'git_url': GIT_BASE_URL + '/nacl-binutils.git', 'git_revision': GIT_REVISIONS['binutils'], 'commands': ConfigureTargetPrep(target) + [ command.Command( CONFIGURE_CMD + CONFIGURE_HOST_TOOL + ConfigureTargetArgs(target) + [ '--enable-deterministic-archives', '--enable-gold', ] + ([] if sys.platform == 'win32' else [ '--enable-plugins', ])), command.Command(MAKE_PARALLEL_CMD), command.Command(MAKE_CHECK_CMD), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), REMOVE_INFO_DIR, ] + InstallDocFiles('binutils', ['COPYING3'] + [command.path.join(subdir, 'NEWS') for subdir in ['binutils', 'gas', 'ld', 'gold']]) + # The top-level lib* directories contain host libraries # that we don't want to include in the distribution. [command.RemoveDirectory(command.path.join('%(output)s', name)) for name in ['lib', 'lib32', 'lib64']], }, 'gcc_' + target: { 'dependencies': HOST_GCC_LIBS_DEPS + ['binutils_' + target], 'git_url': GCC_GIT_URL, 'git_revision': GIT_REVISIONS['gcc'], # Remove all the source directories that are used solely for # building target libraries. We don't want those included in the # input hash calculation so that we don't rebuild the compiler # when the the only things that have changed are target libraries. 'unpack_commands': [command.RemoveDirectory(dirname) for dirname in [ 'boehm-gc', 'libada', 'libffi', 'libgcc', 'libgfortran', 'libgo', 'libgomp', 'libitm', 'libjava', 'libmudflap', 'libobjc', 'libquadmath', 'libssp', 'libstdc++-v3', ]], 'commands': ConfigureTargetPrep(target) + [ ConfigureGccCommand(target), # GCC's configure step writes configargs.h with some strings # including the configure command line, which get embedded # into the gcc driver binary. The build only works if we use # absolute paths in some of the configure switches, but # embedding those paths makes the output differ in repeated # builds done in different directories, which we do not want. # So force the generation of that file early and then edit it # in place to replace the absolute paths with something that # never varies. Note that the 'configure-gcc' target will # actually build some components before running gcc/configure. GccCommand(target, MAKE_PARALLEL_CMD + ['configure-gcc']), command.Command(['sed', '-i', '-e', ';'.join(['s@%%(abs_%s)s@.../%s_install@g' % (component, component) for component in HOST_GCC_LIBS_DEPS] + ['s@%(cwd)s@...@g']), command.path.join('gcc', 'configargs.h')]), # gcc/Makefile's install rules ordinarily look at the # installed include directory for a limits.h to decide # whether the lib/gcc/.../include-fixed/limits.h header # should be made to expect a libc-supplied limits.h or not. # Since we're doing this build in a clean environment without # any libc installed, we need to force its hand here. GccCommand(target, MAKE_PARALLEL_CMD + ['all-gcc', 'LIMITS_H_TEST=true']), # gcc/Makefile's install targets populate this directory # only if it already exists. command.Mkdir(command.path.join('%(output)s', target + '-nacl', 'bin'), True), GccCommand(target, MAKE_DESTDIR_CMD + ['install-strip-gcc']), REMOVE_INFO_DIR, # Note we include COPYING.RUNTIME here and not with gcc_libs. ] + InstallDocFiles('gcc', ['COPYING3', 'COPYING.RUNTIME']), }, } return tools
def TranslatorLibs(arch, is_canonical, no_nacl_gcc): setjmp_arch = arch if setjmp_arch.endswith('-nonsfi'): setjmp_arch = setjmp_arch[:-len('-nonsfi')] bias_arch = TranslatorArchToBiasArch(arch) translator_lib_dir = os.path.join('translator', arch, 'lib') arch_cmds = [] if arch == 'arm': arch_cmds.append( BuildTargetTranslatorCmd('aeabi_read_tp.S', 'aeabi_read_tp.o', arch)) elif arch == 'x86-32-nonsfi': arch_cmds.extend( [BuildTargetTranslatorCmd('entry_linux.c', 'entry_linux.o', arch), BuildTargetTranslatorCmd('entry_linux_x86_32.S', 'entry_linux_asm.o', arch)]) elif arch == 'arm-nonsfi': arch_cmds.extend( [BuildTargetTranslatorCmd('entry_linux.c', 'entry_linux.o', arch), BuildTargetTranslatorCmd('entry_linux_arm.S', 'entry_linux_asm.o', arch)]) if not IsNonSFIArch(arch): def ClangLib(lib): return GSDJoin(lib, bias_arch) clang_deps = [ ClangLib('newlib'), ClangLib('libs_support') ] # Extract the object files from the newlib archive into our working dir. # libcrt_platform.a is later created by archiving all the object files # there. crt_objs = ['memmove', 'memcmp', 'memset', 'memcpy'] if arch == 'mips32': crt_objs.extend(['memset-stub', 'memcpy-stub']) libcrt_platform_string_cmds = [command.Command([ PnaclTool('ar'), 'x', os.path.join('%(' + ClangLib('newlib') + ')s', MultilibLibDir(bias_arch), 'libcrt_common.a'), ] + ['lib_a-%s.o' % f for f in crt_objs])] # Copy compiler_rt from nacl-clang clang_libdir = os.path.join( 'lib', 'clang', CLANG_VER, 'lib', TripleFromArch(bias_arch)) compiler_rt_cmds = [command.Copy( os.path.join('%(' + ClangLib('libs_support') + ')s', clang_libdir, 'libgcc.a'), os.path.join('%(output)s', 'libgcc.a'))] else: clang_deps = [] extra_flags = NonSFITargetLibCflags(bias_arch).split() libcrt_platform_string_cmds = [BuildTargetTranslatorCmd( 'string.c', 'string.o', arch, ['-std=c99'], source_dir='%(newlib_subset)s')] # Build compiler_rt with PNaCl compiler_rt_cmds = [ command.Command(MakeCommand() + [ '-C', '%(abs_compiler_rt_src)s', 'ProjObjRoot=%(cwd)s', 'VERBOSE=1', 'CC=' + PnaclTool('clang', arch=bias_arch), 'clang_nacl', 'EXTRA_CFLAGS=' + (NewlibIsystemCflags('le32') + ' ' + ' '.join(extra_flags))]), command.Copy(os.path.join( 'clang_nacl', 'full-' + bias_arch.replace('i686', 'i386') .replace('mipsel', 'mips32'), 'libcompiler_rt.a'), os.path.join('%(output)s', 'libgcc.a')), ] libs = { GSDJoin('libs_support_translator', arch): { 'type': TargetLibBuildType(is_canonical), 'output_subdir': translator_lib_dir, 'dependencies': [ 'newlib_src', 'compiler_rt_src', 'subzero_src', 'target_lib_compiler', 'newlib_le32'] + clang_deps, # These libs include # arbitrary stuff from native_client/src/{include,untrusted,trusted} 'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'support'), 'include': os.path.join(NACL_DIR, 'src'), 'newlib_subset': os.path.join( NACL_DIR, 'src', 'third_party', 'pnacl_native_newlib_subset')}, 'commands': SubzeroRuntimeCommands(arch, '.') + [ BuildTargetTranslatorCmd('crtbegin.c', 'crtbegin.o', arch, output_dir='%(output)s'), BuildTargetTranslatorCmd('crtbegin.c', 'crtbegin_for_eh.o', arch, ['-DLINKING_WITH_LIBGCC_EH'], output_dir='%(output)s'), BuildTargetTranslatorCmd('crtend.c', 'crtend.o', arch, output_dir='%(output)s'), # libcrt_platform.a BuildTargetTranslatorCmd('pnacl_irt.c', 'pnacl_irt.o', arch), BuildTargetTranslatorCmd('relocate.c', 'relocate.o', arch), BuildTargetTranslatorCmd( 'setjmp_%s.S' % setjmp_arch.replace('-', '_'), 'setjmp.o', arch), # Pull in non-errno __ieee754_fmod from newlib and rename it to # fmod. This is to support the LLVM frem instruction. BuildTargetTranslatorCmd( 'e_fmod.c', 'e_fmod.o', arch, ['-std=c99', '-I%(abs_newlib_src)s/newlib/libm/common/', '-D__ieee754_fmod=fmod'], source_dir='%(abs_newlib_src)s/newlib/libm/math'), BuildTargetTranslatorCmd( 'ef_fmod.c', 'ef_fmod.o', arch, ['-std=c99', '-I%(abs_newlib_src)s/newlib/libm/common/', '-D__ieee754_fmodf=fmodf'], source_dir='%(abs_newlib_src)s/newlib/libm/math')] + arch_cmds + libcrt_platform_string_cmds + [ command.Command(' '.join([ PnaclTool('ar'), 'rc', command.path.join('%(output)s', 'libcrt_platform.a'), '*.o']), shell=True), # Dummy IRT shim BuildTargetTranslatorCmd( 'dummy_shim_entry.c', 'dummy_shim_entry.o', arch), command.Command([PnaclTool('ar'), 'rc', command.path.join('%(output)s', 'libpnacl_irt_shim_dummy.a'), 'dummy_shim_entry.o']), ] + compiler_rt_cmds, }, } if not arch.endswith('-nonsfi'): libs.update({ GSDJoin('libgcc_eh', arch): { 'type': TargetLibBuildType(is_canonical), 'output_subdir': translator_lib_dir, 'dependencies': [ 'gcc_src', 'target_lib_compiler'], 'inputs': { 'scripts': os.path.join(NACL_DIR, 'pnacl', 'scripts')}, 'commands': [ # Instead of trying to use gcc's build system to build only # libgcc_eh, we just build the C files and archive them manually. command.RemoveDirectory('include'), command.Mkdir('include'), command.Copy(os.path.join('%(gcc_src)s', 'gcc', 'unwind-generic.h'), os.path.join('include', 'unwind.h')), command.Copy(os.path.join('%(scripts)s', 'libgcc-tconfig.h'), 'tconfig.h'), command.WriteData('', 'tm.h'), BuildLibgccEhCmd('unwind-dw2.c', 'unwind-dw2.o', arch, no_nacl_gcc), BuildLibgccEhCmd('unwind-dw2-fde-glibc.c', 'unwind-dw2-fde-glibc.o', arch, no_nacl_gcc), command.Command([PnaclTool('ar'), 'rc', command.path.join('%(output)s', 'libgcc_eh.a'), 'unwind-dw2.o', 'unwind-dw2-fde-glibc.o']), ], }, }) return libs
def TargetLibs(target): lib_deps = ['binutils_' + target, 'gcc_' + target] # We have to populate the newlib source tree with the "exported" form of # some headers from the native_client source tree. The newlib build # needs these to be in the expected place. By doing this in the # 'unpack_commands' stage, these files will be part of the input hash and # so we don't need to do anything else to keep track of when they might # have changed in the native_client source tree. newlib_sys_nacl = os.path.join('%(src)s', 'newlib', 'libc', 'sys', 'nacl') newlib_unpack = [command.RemoveDirectory(os.path.join(newlib_sys_nacl, dirname)) for dirname in ['bits', 'sys', 'machine']] newlib_unpack.append(command.Command([ 'python', os.path.join('%(top_srcdir)s', 'src', 'trusted', 'service_runtime', 'export_header.py'), os.path.join('%(top_srcdir)s', 'src', 'trusted', 'service_runtime', 'include'), newlib_sys_nacl, ])) def NewlibFile(subdir, name): return os.path.join('%(output)s', target + '-nacl', subdir, name) newlib_sysroot = '%(abs_newlib_' + target + ')s' newlib_tooldir = '%s/%s-nacl' % (newlib_sysroot, target) # See the comment at ConfigureTargetPrep, above. newlib_install_data = ' '.join(['STRIPPROG=%(cwd)s/strip_for_target', '%(abs_src)s/install-sh', '-c', '-s', '-m', '644']) libs = { 'newlib_' + target: { 'dependencies': lib_deps, 'git_url': GIT_BASE_URL + '/nacl-newlib.git', 'git_revision': GIT_REVISIONS['newlib'], 'unpack_commands': newlib_unpack, 'commands': ConfigureTargetPrep(target) + TargetCommands(target, [ CONFIGURE_CMD + CONFIGURE_HOST_TOOL + ConfigureTargetArgs(target) + [ '--disable-libgloss', '--enable-newlib-iconv', '--enable-newlib-io-long-long', '--enable-newlib-io-long-double', '--enable-newlib-io-c99-formats', '--enable-newlib-mb', 'CFLAGS=-O2', 'CFLAGS_FOR_TARGET=' + NewlibTargetCflags(target), 'INSTALL_DATA=' + newlib_install_data, ], MAKE_PARALLEL_CMD, MAKE_DESTDIR_CMD + ['install-strip'], ]) + [ command.Remove(NewlibFile('include', 'pthread.h')), command.Rename(NewlibFile('lib', 'libc.a'), NewlibFile('lib', 'libcrt_common.a')), command.WriteData(NewlibLibcScript(target), NewlibFile('lib', 'libc.a')), ] + InstallDocFiles('newlib', ['COPYING.NEWLIB']), }, 'gcc_libs_' + target: { 'dependencies': lib_deps + ['newlib_' + target] + HOST_GCC_LIBS_DEPS, 'git_url': GCC_GIT_URL, 'git_revision': GIT_REVISIONS['gcc'], # This actually builds the compiler again and uses that compiler # to build the target libraries. That's by far the easiest thing # to get going given the interdependencies of the target # libraries (especially libgcc) on the gcc subdirectory, and # building the compiler doesn't really take all that long in the # grand scheme of things. # TODO(mcgrathr): If upstream ever cleans up all their # interdependencies better, unpack the compiler, configure with # --disable-gcc, and just build all-target. 'commands': ConfigureTargetPrep(target) + [ ConfigureGccCommand(target, [ '--with-build-sysroot=' + newlib_sysroot, ]), GccCommand(target, MAKE_PARALLEL_CMD + [ 'build_tooldir=' + newlib_tooldir, 'all-target', ]), GccCommand(target, MAKE_DESTDIR_CMD + ['install-strip-target']), REMOVE_INFO_DIR, ], }, } return libs
def HostGccLibs(host): def H(component_name): return ForHost(component_name, host) host_gcc_libs = { H('gmp'): { 'type': 'build', 'dependencies': ['gmp'], 'commands': [ command.Command( ConfigureCommand('gmp') + ConfigureHostLib(host) + [ '--with-sysroot=%(abs_output)s', '--enable-cxx', # Without this, the built library will # assume the instruction set details # available on the build machine. With # this, it dynamically chooses what code # to use based on the details of the # actual host CPU at runtime. '--enable-fat', ]), command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), ], }, H('mpfr'): { 'type': 'build', 'dependencies': ['mpfr', H('gmp')], 'commands': [ command.Command( ConfigureCommand('mpfr') + ConfigureHostLib(host) + WithDepsOptions(['sysroot', 'gmp'], H('gmp'))), command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), ], }, H('mpc'): { 'type': 'build', 'dependencies': ['mpc', H('gmp'), H('mpfr')], 'commands': PopulateDeps(['%(' + H('gmp') + ')s', '%(' + H('mpfr') + ')s']) + [ command.Command( ConfigureCommand('mpc') + ConfigureHostLib(host) + WithDepsOptions(['sysroot', 'gmp', 'mpfr'])), command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), ], }, H('isl'): { 'type': 'build', 'dependencies': ['isl', H('gmp')], 'commands': [ command.Command( ConfigureCommand('isl') + ConfigureHostLib(host) + WithDepsOptions(['sysroot', 'gmp-prefix'], H('gmp'))), command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), # The .pc files wind up containing some absolute paths # that make the output depend on the build directory name. # The dependents' configure scripts don't need them anyway. command.RemoveDirectory( command.path.join('%(output)s', 'lib', 'pkgconfig')), ], }, H('cloog'): { 'type': 'build', 'dependencies': ['cloog', H('gmp'), H('isl')], 'commands': PopulateDeps(['%(' + H('gmp') + ')s', '%(' + H('isl') + ')s']) + [ command.Command( ConfigureCommand('cloog') + ConfigureHostLib(host) + [ '--with-bits=gmp', '--with-isl=system', ] + WithDepsOptions(['sysroot', 'gmp-prefix', 'isl-prefix'])), command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + ['install-strip']), # The .pc files wind up containing some absolute paths # that make the output depend on the build directory name. # The dependents' configure scripts don't need them anyway. command.RemoveDirectory( command.path.join('%(output)s', 'lib', 'pkgconfig')), ], }, H('expat'): { 'type': 'build', 'dependencies': ['expat'], 'commands': [ command.Command( ConfigureCommand('expat') + ConfigureHostLib(host)), command.Command(MakeCommand(host)), command.Command(MakeCheckCommand(host)), command.Command(MAKE_DESTDIR_CMD + [ # expat does not support the install-strip target. 'installlib', 'INSTALL=%(expat)s/conftools/install-sh -c -s', 'INSTALL_DATA=%(expat)s/conftools/install-sh -c -m 644', ]), ], }, } return host_gcc_libs