def ConfigureTargetPrep(arch): script_file = 'strip_for_target' config_target = arch + '-nacl' script_contents = """\ #!/bin/sh mode=--strip-all for arg; do case "$arg" in -*) ;; *) type=`file --brief --mime-type "$arg"` case "$type" in application/x-executable|application/x-sharedlib) ;; application/x-archive|application/x-object) mode=--strip-debug ;; *) exit 0 ;; esac ;; esac done exec %s-strip $mode --remove-section=.comment "$@" """ % config_target return [ command.WriteData(script_contents, script_file), command.Command(['chmod', '+x', script_file]), ]
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
def Metadata(): data = { 'metadata': { 'type': 'build', 'inputs': { 'readme': os.path.join(NACL_DIR, 'pnacl', 'README') }, 'commands': [ command.Copy('%(readme)s', os.path.join('%(output)s', 'README')), command.WriteData(str(FEATURE_VERSION), os.path.join('%(output)s', 'FEATURE_VERSION')), ], } } return data
def GetTestPackages(change_readme): def ShouldChangeReadme(_): return change_readme return { 'newlib': { 'type': 'source', 'commands': [ command.WriteData(INITIAL_README_TEXT, '%(output)s/README'), command.WriteData(LATER_README_TEXT, '%(output)s/README', run_cond=ShouldChangeReadme), ], }, 'newlib_build': { 'type': 'build', 'dependencies': ['newlib'], 'commands': [ command.Copy('%(newlib)s/README', '%(output)s/test1'), ], }, }
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 BuildLibgccEhCmd(sourcefile, output, arch, no_nacl_gcc): # Return a command to compile a file from libgcc_eh (see comments in at the # rule definition below). flags_common = [ '-DENABLE_RUNTIME_CHECKING', '-g', '-O2', '-W', '-Wall', '-Wwrite-strings', '-Wcast-qual', '-Wstrict-prototypes', '-Wmissing-prototypes', '-Wold-style-definition', '-DIN_GCC', '-DCROSS_DIRECTORY_STRUCTURE', '-DIN_LIBGCC2', '-D__GCC_FLOAT_NOT_NEEDED', '-Dinhibit_libc', '-DHAVE_CC_TLS', '-DHIDE_EXPORTS', '-fno-stack-protector', '-fexceptions', '-fvisibility=hidden', '-I.', '-I../.././gcc', '-I%(abs_gcc_src)s/gcc/libgcc', '-I%(abs_gcc_src)s/gcc', '-I%(abs_gcc_src)s/include', '-isystem', './include' ] # For x86 we use nacl-gcc to build libgcc_eh because of some issues with # LLVM's handling of the gcc intrinsics used in the library. See # https://code.google.com/p/nativeclient/issues/detail?id=1933 # and http://llvm.org/bugs/show_bug.cgi?id=8541 # For ARM, LLVM does work and we use it to avoid dealing with the fact that # arm-nacl-gcc uses different libgcc support functions than PNaCl. if arch in ('arm', 'mips32'): cc = PnaclTool('clang', arch=TranslatorArchToBiasArch(arch), msys=False) flags_naclcc = [] else: if no_nacl_gcc: return command.WriteData('', output) os_name = pynacl.platform.GetOS() arch_name = pynacl.platform.GetArch() platform_dir = '%s_%s' % (os_name, arch_name) newlib_dir = 'nacl_x86_newlib_raw' nnacl_dir = os.path.join(NACL_DIR, 'toolchain', platform_dir, newlib_dir, 'bin') gcc_binaries = { 'x86-32': 'i686-nacl-gcc', 'x86-64': 'x86_64-nacl-gcc', } cc = os.path.join(nnacl_dir, gcc_binaries[arch]) flags_naclcc = [] return command.Command([cc] + flags_naclcc + flags_common + [ '-c', command.path.join('%(gcc_src)s', 'gcc', sourcefile), '-o', output ])
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 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 TargetLibs(host, target): lib_deps = [ ForHost(component + '_' + target, host) for component in ['binutils', 'gcc'] ] # The 'minisdk_<target>' component is a workalike subset of what the full # NaCl SDK provides. The glibc build uses a handful of things from the # SDK (ncval, sel_ldr, etc.), and expects them relative to $NACL_SDK_ROOT # in the layout that the SDK uses. We provide a small subset built here # using SCons (and explicit copying, below), containing only the things # the build actually needs. def SconsCommand(args): return command.Command([ sys.executable, '%(scons.py)s', '--verbose', '-j%(cores)s', 'DESTINATION_ROOT=%(abs_work_dir)s' ] + args, cwd=NACL_DIR) scons_target = pynacl.platform.GetArch3264(target) sdk_target = scons_target.replace('-', '_') nacl_scons_out = 'nacl-' + scons_target irt_scons_out = 'nacl_irt-' + scons_target trusted_scons_out = 'opt-linux-' + scons_target host_scons_out = 'opt-%s-%s' % (pynacl.platform.GetOS(), pynacl.platform.GetArch3264()) support = { 'minisdk_' + target: { 'type': 'work', 'inputs': { 'src': os.path.join(NACL_DIR, 'src'), 'sconstruct': os.path.join(NACL_DIR, 'SConstruct'), 'scons.py': os.path.join(NACL_DIR, 'scons.py'), 'site_scons': os.path.join(NACL_DIR, 'site_scons'), 'arm_trusted': os.path.join(NACL_DIR, 'toolchain', 'linux_x86', 'arm_trusted'), }, 'commands': [ SconsCommand([ 'platform=' + scons_target, 'nacl_helper_bootstrap', 'sel_ldr', 'irt_core', 'elf_loader' ]), command.Mkdir(command.path.join('%(output)s', 'tools')), command.Copy( command.path.join(irt_scons_out, 'staging', 'irt_core.nexe'), command.path.join('%(output)s', 'tools', 'irt_core_' + sdk_target + '.nexe')), command.Copy( command.path.join(nacl_scons_out, 'staging', 'elf_loader.nexe'), command.path.join('%(output)s', 'tools', 'elf_loader_' + sdk_target + '.nexe')), ] + [ command.Copy(command.path.join(trusted_scons_out, 'staging', name), command.path.join('%(output)s', 'tools', name + '_' + sdk_target), permissions=True) for name in ['sel_ldr', 'nacl_helper_bootstrap'] ] + [ SconsCommand([ 'platform=' + pynacl.platform.GetArch3264(), 'ncval_new' ]), command.Copy(command.path.join(host_scons_out, 'staging', 'ncval_new'), command.path.join('%(output)s', 'tools', 'ncval'), permissions=True), command.Mkdir(command.path.join('%(output)s', 'tools', 'arm_trusted', 'lib'), parents=True), ] + [ command.Copy( command.path.join('%(arm_trusted)s', *(dir + [name])), command.path.join('%(output)s', 'tools', 'arm_trusted', 'lib', name)) for dir, name in [ (['lib', 'arm-linux-gnueabihf'], 'librt.so.1'), (['lib', 'arm-linux-gnueabihf'], 'libpthread.so.0'), (['lib', 'arm-linux-gnueabihf'], 'libgcc_s.so.1'), (['lib', 'arm-linux-gnueabihf'], 'libc.so.6'), (['lib', 'arm-linux-gnueabihf'], 'ld-linux-armhf.so.3'), (['lib', 'arm-linux-gnueabihf'], 'libm.so.6'), (['usr', 'lib', 'arm-linux-gnueabihf'], 'libstdc++.so.6'), ] ] }, } minisdk_root = 'NACL_SDK_ROOT=%(abs_minisdk_' + target + ')s' glibc_configparms = """ # Avoid -lgcc_s, which we do not have yet. override gnulib-tests := -lgcc # Work around a compiler bug. CFLAGS-doasin.c = -mtune=generic-armv7-a """ glibc_sysroot = '%(abs_glibc_' + target + ')s' glibc_tooldir = '%s/%s-nacl' % (glibc_sysroot, target) libs = { # The glibc build needs a libgcc.a (and the unwind.h header). # This is never going to be installed, only used to build glibc. # So it could be a 'work' target. But it's a 'build' target instead # so it can benefit from memoization when glibc has changed but # binutils and gcc have not. 'bootstrap_libgcc_' + target: { 'type': 'build', 'dependencies': ['gcc_libs'] + lib_deps + HostGccLibsDeps(host), # This actually builds the compiler again and uses that compiler # to build libgcc. That's by far the easiest thing to get going # given the interdependencies of 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. 'commands': ConfigureTargetPrep(target) + [ ConfigureGccCommand( 'gcc_libs', host, target, [ #'--with-build-sysroot=' + glibc_tooldir, '--disable-dlopen', '--disable-shared', # This doesn't really have anything to with newlib. # It says to build a libgcc that does not refer to # any header files or functions from any C library. '--with-newlib', ]), GccCommand( host, target, MakeCommand(host) + [ #'build_tooldir=' + glibc_tooldir, #'MAKEOVERRIDES=NATIVE_SYSTEM_HEADER_DIR=/include', 'all-target-libgcc', ]), GccCommand(host, target, MAKE_DESTDIR_CMD + ['install-strip-target-libgcc']), REMOVE_INFO_DIR, ], }, 'glibc_' + target: { 'type': 'build', 'dependencies': ['glibc', 'minisdk_' + target, 'bootstrap_libgcc_' + target] + lib_deps, 'commands': ( ConfigureTargetPrep(target) + [command.WriteData(glibc_configparms, 'configparms')] + TargetCommands( host, target, [ # The bootstrap libgcc.a we built above contains # the unwinder code. But the GCC driver expects # the split style used for the static archives when # building libgcc_s.so, which we will do later. # So just provide a dummy libgcc_eh.a to be found # by the static links done while building libc. [target + '-nacl-ar', 'crs', 'libgcc_eh.a'], ConfigureCommand('glibc') + CONFIGURE_COMMON + [ '--host=%s-nacl' % target, '--with-headers=%(abs_top_srcdir)s/..', 'STRIP=%(cwd)s/strip_for_target', ], MakeCommand(host) + [minisdk_root], # TODO(mcgrathr): Can drop check-abi when # check is enabled; check includes check-abi. MakeCommand(host) + [minisdk_root, 'check-abi'], # TODO(mcgrathr): Enable test suite later. #MakeCommand(host) + [minisdk_root, 'check'], [ 'make', 'install', minisdk_root, # glibc's install rules always use a layout # appropriate for a native installation. # To install it in a cross-compilation layout # we have to explicitly point it at the target # subdirectory. However, documentation files # should not go there. 'install_root=%(abs_output)s/' + target + '-nacl', 'inst_infodir=%(abs_output)s/share/info', ], ], target_deps=['bootstrap_libgcc']) + InstallDocFiles('glibc', ['COPYING.LIB']) + [ REMOVE_INFO_DIR, ]), }, 'gcc_libs_' + target: { 'type': 'build', 'dependencies': (['gcc_libs'] + lib_deps + ['glibc_' + target] + HostGccLibsDeps(host)), # 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('gcc_libs', host, target, [ '--with-build-sysroot=' + glibc_tooldir, ]), GccCommand( host, target, MakeCommand(host) + [ 'build_tooldir=' + glibc_tooldir, 'MAKEOVERRIDES=NATIVE_SYSTEM_HEADER_DIR=/include', 'all-target', ]), GccCommand(host, target, MAKE_DESTDIR_CMD + ['install-strip-target']), REMOVE_INFO_DIR, ], }, } libs.update(support) return libs
def TargetLibs(host, target): lib_deps = [ ForHost(component + '_' + target, host) for component in ['binutils', 'gcc'] ] def NewlibFile(subdir, name): return command.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_newlib)s/install-sh', '-c', '-s', '-m', '644' ]) iconv_encodings = 'UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4' newlib_configure_args = [ '--disable-libgloss', '--enable-newlib-iconv', '--enable-newlib-iconv-from-encodings=' + iconv_encodings, '--enable-newlib-iconv-to-encodings=' + iconv_encodings, '--enable-newlib-io-long-long', '--enable-newlib-io-long-double', '--enable-newlib-io-c99-formats', '--enable-newlib-mb', 'CFLAGS=-O2', 'CFLAGS_FOR_TARGET=' + ' '.join(CommonTargetCflags(target)), 'INSTALL_DATA=' + newlib_install_data, ] newlib_post_install = [ command.Rename(NewlibFile('lib', 'libc.a'), NewlibFile('lib', 'libcrt_common.a')), command.WriteData(NewlibLibcScript(target), NewlibFile( 'lib', 'libc.a')), ] + [ command.Copy(command.path.join('%(pthread_headers)s', header), NewlibFile('include', header)) for header in ('pthread.h', 'semaphore.h') ] libs = { 'newlib_' + target: { 'type': 'build', 'dependencies': ['newlib'] + lib_deps, 'inputs': { 'pthread_headers': os.path.join(NACL_DIR, 'src', 'untrusted', 'pthread') }, 'commands': (ConfigureTargetPrep(target) + TargetCommands(host, target, [ ConfigureCommand('newlib') + ConfigureHostTool(host) + ConfigureTargetArgs(target) + newlib_configure_args, MakeCommand(host), MAKE_DESTDIR_CMD + ['install-strip'], ]) + newlib_post_install + InstallDocFiles('newlib', ['COPYING.NEWLIB'])), }, 'gcc_libs_' + target: { 'type': 'build', 'dependencies': (['gcc_libs'] + lib_deps + ['newlib_' + target] + HostGccLibsDeps(host)), # 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('gcc_libs', host, target, [ '--with-build-sysroot=' + newlib_sysroot, ]), GccCommand( host, target, MakeCommand(host) + [ 'build_tooldir=' + newlib_tooldir, 'all-target', ]), GccCommand(host, target, MAKE_DESTDIR_CMD + ['install-strip-target']), REMOVE_INFO_DIR, ], }, } return libs
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