def ConfigureGCCProject(arch, project, cfg, workpath, inspath): # configure does not always have +x filepath = os.path.abspath(os.path.join(workpath, cfg[0])) st_info = os.stat(filepath) os.chmod(filepath, st_info.st_mode | stat.S_IEXEC) env = os.environ newpath = GetToolchainPath(arch, 'bionic', 'bin') + ':' + env['PATH'] proj = '%s %s' % (project, arch) setpath = ['/usr/bin/env', 'PATH=' + newpath] # Check if config changed or script is new config_path = os.path.join(workpath, 'config.info') updated = UpdateText(config_path, ' '.join(cfg)) updated |= NeedsUpdate(config_path, BUILD_SCRIPT) if updated: print 'Configure ' + proj if process.Run(setpath + cfg, cwd=workpath, env=env, outfile=sys.stdout): raise RuntimeError('Failed to configure %s.\n' % proj) else: print 'Reusing config for %s.' % proj
def CreateProject(arch, project, clobber=False): paths = GetProjectPaths(arch, project) MAKEFILE_TEMPLATE = """ # Copyright (c) 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # GNU Makefile based on shared rules provided by the Native Client SDK. # See README.Makefiles for more details. NATIVE_CLIENT_PATH?=$(nacl_path) TOOLCHAIN_PATH?=$(tc_path) TOOLCHAIN_PREFIX:=$(TOOLCHAIN_PATH)/bin/$GCC-nacl- CC:=$(TOOLCHAIN_PREFIX)gcc CXX:=$(TOOLCHAIN_PREFIX)g++ AR:=$(TOOLCHAIN_PREFIX)ar SRC_ROOT=$(src_path) DST_ROOT=$(dst_path) INS_ROOT=$(ins_path) NACL_ARCH=$NACL GCC_ARCH=$GCC MAKEFILE_DEPS:=$(build_tc_path)/tc_bionic.mk MAKEFILE_DEPS+=$(src_path)/Makefile include $(build_tc_path)/tc_bionic.mk include $(src_path)/Makefile """ remap = { '$(src_path)': paths['src'], '$(dst_path)': paths['work'], '$(ins_path)': paths['ins'], '$(tc_path)': GetBionicBuildPath(arch), '$(build_tc_path)': TOOLCHAIN_BUILD, '$(nacl_path)': NATIVE_CLIENT, } text = ReplaceText(MAKEFILE_TEMPLATE, [remap]) text = ReplaceArch(text, arch) if clobber: print 'Clobbering Bionic project directory: ' + paths['work'] Rmdir(paths['work']) Mkdir(paths['work']) Mkdir(paths['ins']) UpdateText(os.path.join(paths['work'], 'Makefile'), text)
def CreateProject(arch, src, dst, ins=None): MAKEFILE_TEMPLATE = """ # Copyright (c) 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # GNU Makefile based on shared rules provided by the Native Client SDK. # See README.Makefiles for more details. TOOLCHAIN_PATH?=$(tc_path)/linux_$ARCH_bionic TOOLCHAIN_PREFIX:=$(TOOLCHAIN_PATH)/bin/$GCC-nacl- CC:=$(TOOLCHAIN_PREFIX)gcc CXX:=$(TOOLCHAIN_PREFIX)g++ AR:=$(TOOLCHAIN_PREFIX)ar SRC_ROOT=$(src_path) DST_ROOT=$(dst_path) INS_ROOT=$(ins_path) NACL_ARCH=$NACL GCC_ARCH=$GCC include $(build_tc_path)/tc_bionic.mk include $(src_path)/Makefile """ remap = { '$(src_path)': src, '$(dst_path)': dst, '$(ins_path)': ins or dst, '$(tc_path)': TOOLCHAIN, '$(build_tc_path)': TOOLCHAIN_BUILD } text = ReplaceText(MAKEFILE_TEMPLATE, [remap]) text = ReplaceArch(text, arch) print 'Create dst dir: ' + dst Mkdir(dst) if ins: print 'Create ins dir: ' + ins Mkdir(ins) UpdateText(os.path.join(dst, 'Makefile'), text)
def ConfigureAndInstallForGCC(arch, project, cfg, workpath, inspath): # configure does not always have +x filepath = os.path.abspath(os.path.join(workpath, cfg[0])) st_info = os.stat(filepath) os.chmod(filepath, st_info.st_mode | stat.S_IEXEC) env = os.environ if arch == 'arm': newpath = os.path.join(ARM_BIONIC, 'bin') + ':' + env['PATH'] else: newpath = os.path.join(X86_BIONIC, 'bin') + ':' + env['PATH'] proj = '%s %s' % (project, arch) setpath = ['/usr/bin/env', 'PATH=' + newpath] # Check if config changed or script is new config_path = os.path.join(workpath, 'config.info') updated = UpdateText(config_path, ' '.join(cfg)) updated |= NeedsUpdate(config_path, BUILD_SCRIPT) if updated: print 'Configure ' + proj if process.Run(setpath + cfg, cwd=workpath, env=env, outfile=sys.stdout): raise RuntimeError('Failed to configure %s.\n' % proj) else: print 'Reusing config for %s.' % proj print 'Make ' + proj if process.Run(setpath + ['make', '-j16', 'V=1'], cwd=workpath, outfile=sys.stdout): raise RuntimeError('Failed to build %s.\n' % proj) print 'Install ' + proj if process.Run(setpath + ['make', '-j16', 'install', 'V=1'], cwd=workpath, outfile=sys.stdout): raise RuntimeError('Failed to install %s.\n' % proj) print 'Done ' + proj
def CreateBasicToolchain(): # Create a toolchain directory containing only the toolchain binaries and # basic files line nacl_arm_macros.s. arch = 'arm' UpdateFromTo( GetToolchainPath(arch, 'newlib'), GetToolchainPath(arch, 'bionic'), filters=['*arm-nacl/include*', '*arm-nacl/lib*', '*.a', '*.o']) UpdateFromTo(GetToolchainPath(arch, 'newlib'), GetToolchainPath(arch, 'bionic'), paterns=['*.s']) # Static build uses: # crt1.o crti.o 4.8.2/crtbeginT.o ... 4.8.2/crtend.o crtn.o # -shared build uses: # crti.o 4.8.2/crtbeginS.o ... 4.8.2/crtendS.o crtn.o crtn.o # However we only provide a crtbegin(S) and crtend(S) EMPTY = """/* * This is a dummy linker script. * libnacl.a, libcrt_common.a, crt0.o crt1.o crti.o and crtn.o are all * empty. Instead all the work is done by crtbegin(S).o and crtend(S).o and * the bionic libc. These are provided for compatability with the newlib * toolchain binaries. */""" EMPTY_FILES = [ 'crt0.o', 'crt1.o', 'crti.o', 'crtn.o', 'libnacl.a', 'libcrt_common.a', 'libpthread.a' ] # Bionic uses the following include paths BIONIC_PAIRS = [ ('bionic/libc/arch-nacl/syscalls/irt_poll.h', '$NACL-nacl/include/irt_poll.h'), ('bionic/libc/arch-nacl/syscalls/irt_socket.h', '$NACL-nacl/include/irt_socket.h'), ('bionic/libc/include', '$NACL-nacl/include'), ('bionic/libc/arch-nacl/syscalls/nacl_stat.h', '$NACL-nacl/include/nacl_stat.h'), ('bionic/libc/arch-$ARCH/include/machine', '$NACL-nacl/include/machine'), ('bionic/libc/kernel/common', '$NACL-nacl/include'), ('bionic/libc/kernel/arch-$ARCH/asm', '$NACL-nacl/include/asm'), ('bionic/libm/include', '$NACL-nacl/include'), ('bionic/libm/$CPU', '$NACL-nacl/include'), ('bionic/safe-iop/include', '$NACL-nacl/include'), ('bionic/libstdc++/nacl', '$NACL-nacl/include/c++/4.8.2/$NACL-nacl'), ('bionic/nacl/$ARCH', '.'), ] for arch in ARCHES: for name in ['irt.h', 'irt_dev.h']: src = os.path.join(NATIVE_CLIENT, 'src', 'untrusted', 'irt', name) dst = GetToolchainPath(arch, 'bionic', '$NACL-nacl', 'include', name) MungeIRT(src, ReplaceArch(dst, arch)) inspath = GetToolchainPath(arch, 'bionic') inspath = ReplaceArch(inspath, arch) # Create empty objects and libraries libpath = ReplaceArch(os.path.join(inspath, '$NACL-nacl', 'lib'), arch) for name in EMPTY_FILES: UpdateText(os.path.join(libpath, name), EMPTY) # Copy BIONIC files to toolchain for src, dst in BIONIC_PAIRS: srcpath = ReplaceArch(os.path.join(TOOLCHAIN_BUILD_SRC, src), arch) dstpath = ReplaceArch(os.path.join(inspath, dst), arch) UpdateFromTo(srcpath, dstpath) # Build specs file gcc = ReplaceArch(os.path.join(inspath, 'bin', '$NACL-nacl-gcc'), arch) lib = ReplaceArch(os.path.join(inspath, 'lib/gcc/$NACL-nacl/$VER'), arch) specs = os.path.join(lib, 'specs') with open(specs, 'w') as specfile: process.Run([gcc, '-dumpspecs'], cwd=None, shell=False, outfile=specfile, verbose=False) text = open(specs, 'r').read() # Replace items in the spec file text = ReplaceText(text, [{ '-lgcc': '-lgcc --as-needed %{!static: -lgcc_s} --no-as-needed %{!shared: -lgcc_eh}', '--hash-style=gnu': '--hash-style=sysv', }]) open(specs, 'w').write(text)
def CreateBasicToolchain(): # Create a toolchain directory containing only the toolchain binaries and # basic files line nacl_arm_macros.s. UpdateFromTo( ARM_NEWLIB, ARM_BIONIC, filters=['*arm-nacl/include*', '*arm-nacl/lib*', '*.a', '*.o']) UpdateFromTo(ARM_NEWLIB, ARM_BIONIC, paterns=['*.s']) UpdateFromTo(X86_NEWLIB, X86_BIONIC, filters=['*x86_64-nacl/include*', '*x86_64-nacl/lib*', '*.o']) UpdateFromTo(X86_NEWLIB, X86_BIONIC, paterns=['*.s']) # Static build uses: # crt1.o crti.o 4.8.2/crtbeginT.o ... 4.8.2/crtend.o crtn.o # -shared build uses: # crti.o 4.8.2/crtbeginS.o ... 4.8.2/crtendS.o crtn.o crtn.o # However we only provide a crtbegin(S) and crtend(S) EMPTY = """/* * This is a dummy linker script. * libnacl.a, libcrt_common.a, crt0.o crt1.o crti.o and crtn.o are all * empty. Instead all the work is done by crtbegin(S).o and crtend(S).o and * the bionic libc. These are provided for compatability with the newlib * toolchain binaries. */""" EMPTY_FILES = [ 'crt0.o', 'crt1.o', 'crti.o', 'crtn.o', 'libnacl.a', 'libcrt_common.a', 'libpthread.a' ] # Bionic uses the following include paths BIONIC_PAIRS = [ ('bionic/libc/include', '$NACL-nacl/include'), ('bionic/libc/arch-nacl/syscalls/irt.h', '$NACL-nacl/include/irt.h'), ('bionic/libc/arch-nacl/syscalls/irt_syscalls.h', '$NACL-nacl/include/irt_syscalls.h'), ('bionic/libc/arch-nacl/syscalls/nacl_stat.h', '$NACL-nacl/include/nacl_stat.h'), ('../../src/untrusted/irt/irt_dev.h', '$NACL-nacl/include/irt_dev.h'), ('bionic/libc/arch-$ARCH/include/machine', '$NACL-nacl/include/machine'), ('bionic/libc/kernel/common', '$NACL-nacl/include'), ('bionic/libc/kernel/arch-$ARCH/asm', '$NACL-nacl/include/asm'), ('bionic/libm/include', '$NACL-nacl/include'), ('bionic/libm/$CPU', '$NACL-nacl/include'), ('bionic/safe-iop/include', '$NACL-nacl/include'), ('bionic/libstdc++/nacl', '$NACL-nacl/include/c++/4.8.2/$NACL-nacl'), ('bionic/nacl/$ARCH', '.'), ] for arch in ARCHES: inspath = os.path.join(TOOLCHAIN, 'linux_$ARCH_bionic') inspath = ReplaceArch(inspath, arch) # Create empty objects and libraries libpath = ReplaceArch(os.path.join(inspath, '$NACL-nacl', 'lib'), arch) for name in EMPTY_FILES: UpdateText(os.path.join(libpath, name), EMPTY) # Copy BIONIC files to toolchain for src, dst in BIONIC_PAIRS: srcpath = ReplaceArch(os.path.join(TOOLCHAIN_BUILD_SRC, src), arch) dstpath = ReplaceArch(os.path.join(inspath, dst), arch) UpdateFromTo(srcpath, dstpath) workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_work') workpath = ReplaceArch(workpath, arch) ConfigureAndBuild(arch, 'bionic/libc', workpath, inspath) ConfigureAndBuild(arch, 'bionic/libm', workpath, inspath) # ConfigureAndBuild(arch, 'bionic/linker', workpath, inspath) # Build specs file gcc = ReplaceArch(os.path.join(inspath, 'bin', '$NACL-nacl-gcc'), arch) lib = ReplaceArch(os.path.join(inspath, 'lib/gcc/$NACL-nacl/$VER'), arch) specs = os.path.join(lib, 'specs') with open(specs, 'w') as specfile: process.Run([gcc, '-dumpspecs'], cwd=None, shell=False, outfile=specfile, verbose=False) text = open(specs, 'r').read() text = ReplaceText(text, [{'-lgcc': '-lgcc %{!shared: -lgcc_eh}'}]) open(specs, 'w').write(text)