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 UnpackSrc(is_gzip): if is_gzip: extract = EXTRACT_STRIP_TGZ else: extract = EXTRACT_STRIP_TBZ2 return [ command.Mkdir('src'), command.Command(extract + ['%(src)s'], cwd='src'), ]
def InstallDocFiles(subdir, files): doc_dir = os.path.join('%(output)s', 'share', 'doc', subdir) dirs = sorted(set([os.path.dirname(os.path.join(doc_dir, file)) for file in files])) commands = ([command.Mkdir(dir, parents=True) for dir in dirs] + [command.Copy(os.path.join('%(src)s', file), os.path.join(doc_dir, file)) for file in files]) return commands
def test_Mkdir(self): # Test the Mkdir convenience wrapper works. with working_directory.TemporaryWorkingDirectory() as work_dir: self.GenerateTestData('Mkdir', work_dir) foo = os.path.join(work_dir, 'foo') o = once.Once(storage=fake_storage.FakeStorage(), cache_results=False, system_summary='test') o.Run('test', self._input_dirs, foo, [command.Mkdir('%(output)s/hi')]) self.assertTrue(os.path.isdir(os.path.join(foo, 'hi')))
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 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 D2NLibsSupportCommands(bias_arch, clang_libdir): def TL(lib): return GSDJoin(lib, pynacl.platform.GetArch3264(bias_arch)) def TranslatorFile(lib, filename): return os.path.join('%(' + TL(lib) + ')s', filename) commands = [ # Build compiler_rt which is now also used for the PNaCl # translator. command.Command(MakeCommand() + [ '-C', '%(abs_compiler_rt_src)s', 'ProjObjRoot=%(cwd)s', 'VERBOSE=1', 'AR=' + PnaclTool('ar', arch=bias_arch), 'RANLIB=' + PnaclTool('ranlib', arch=bias_arch), 'CC=' + PnaclTool('clang', arch=bias_arch), 'clang_nacl', 'EXTRA_CFLAGS=' + NewlibIsystemCflags(bias_arch) ]), command.Mkdir(clang_libdir, parents=True), command.Copy( os.path.join( 'clang_nacl', 'full-' + bias_arch.replace('i686', 'i386').replace('mipsel', 'mips32'), 'libcompiler_rt.a'), os.path.join('%(output)s', clang_libdir, 'libgcc.a')), command.Copy(TranslatorFile('libgcc_eh', 'libgcc_eh.a'), os.path.join('%(output)s', clang_libdir, 'libgcc_eh.a')), BuildTargetObjectCmd('clang_direct/crtbegin.c', 'crtbeginT.o', bias_arch, output_dir=clang_libdir), BuildTargetObjectCmd('crtend.c', 'crtend.o', bias_arch, output_dir=clang_libdir), ] if bias_arch == "mipsel": commands.extend([ BuildTargetObjectCmd('bitcode/pnaclmm.c', 'pnaclmm.o', bias_arch), BuildTargetObjectCmd('clang_direct/nacl-tp-offset.c', 'nacl_tp_offset.o', bias_arch, extra_flags=['-I%(top_srcdir)s/..']), command.Command([ PnaclTool('ar'), 'rc', command.path.join(clang_libdir, 'libpnacl_legacy.a'), command.path.join('pnaclmm.o'), command.path.join('nacl_tp_offset.o') ]) ]) return commands
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' ]) ]
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 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 TargetLibs(bias_arch, is_canonical): def T(component_name): return GSDJoin(component_name, bias_arch) target_triple = TripleFromArch(bias_arch) newlib_triple = target_triple if not IsBCArch(bias_arch) else 'le32-nacl' newlib_cpp_flags = '' if IsBCArch(bias_arch): # This avoids putting the body of memcpy in libc for bitcode newlib_cpp_flags = ' -DPNACL_BITCODE' elif bias_arch == 'arm': # This ensures that nacl gets the asm version of memcpy (gcc defines this # macro for armv7a but clang does not) newlib_cpp_flags = ' -D__ARM_FEATURE_UNALIGNED' clang_libdir = os.path.join( '%(output)s', 'lib', 'clang', CLANG_VER, 'lib', target_triple) libc_libdir = os.path.join('%(output)s', MultilibLibDir(bias_arch)) libs = { T('newlib'): { 'type': TargetLibBuildType(is_canonical), 'dependencies': [ 'newlib_src', 'target_lib_compiler'], 'commands' : [ command.SkipForIncrementalCommand( ['sh', '%(newlib_src)s/configure'] + TargetTools(bias_arch) + ['CFLAGS_FOR_TARGET=' + TargetLibCflags(bias_arch) + newlib_cpp_flags, '--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=' + newlib_triple ]), command.Command(MakeCommand()), command.Command(['make', 'DESTDIR=%(abs_output)s', 'install']), ] + NewlibDirectoryCmds(bias_arch, newlib_triple) }, T('libcxx'): { 'type': TargetLibBuildType(is_canonical), 'dependencies': ['libcxx_src', 'libcxxabi_src', 'llvm_src', 'gcc_src', 'target_lib_compiler', T('newlib'), GSDJoin('newlib', MultilibArch(bias_arch)), T('libs_support')], 'commands' : [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', bias_arch), '-DCMAKE_CXX_COMPILER=' + PnaclTool('clang++', bias_arch), '-DCMAKE_SYSTEM_NAME=nacl', '-DCMAKE_AR=' + PnaclTool('ar', bias_arch), '-DCMAKE_NM=' + PnaclTool('nm', bias_arch), '-DCMAKE_RANLIB=' + PnaclTool('ranlib', bias_arch), '-DCMAKE_LD=' + PnaclTool('illegal', bias_arch), '-DCMAKE_AS=' + PnaclTool('as', bias_arch), '-DCMAKE_OBJDUMP=' + PnaclTool('illegal', bias_arch), '-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'), # The lit flags are used by the libcxx testsuite, which is # currenty driven by an external script. '-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 cxx_under_test="' + os.path.join(NACL_DIR, 'toolchain/linux_x86/pnacl_newlib', 'bin/pnacl-clang++') + '" '+ '--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=' + os.path.join('%(abs_output)s', target_triple), 'VERBOSE=1', 'install']), ] + LibcxxDirectoryCmds(bias_arch) }, } if IsBCArch(bias_arch): libs.update({ T('compiler_rt_bc'): { 'type': TargetLibBuildType(is_canonical), 'dependencies': ['compiler_rt_src', 'target_lib_compiler'], 'commands': [ command.Mkdir(clang_libdir, parents=True), command.Command(MakeCommand() + [ '-f', command.path.join('%(compiler_rt_src)s', 'lib', 'builtins', 'Makefile-pnacl-bitcode'), 'libgcc.a', 'CC=' + PnaclTool('clang'), 'AR=' + PnaclTool('ar')] + ['SRC_DIR=' + command.path.join('%(abs_compiler_rt_src)s', 'lib', 'builtins'), 'CFLAGS=' + ' '.join([ '-DPNACL_' + TargetArch(bias_arch).replace('-', '_')]) ]), command.Copy('libgcc.a', os.path.join(clang_libdir, 'libgcc.a')), ], }, T('libs_support'): { 'type': TargetLibBuildType(is_canonical), 'dependencies': [ T('newlib'), 'target_lib_compiler'], 'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'support', 'bitcode')}, 'commands': [ command.Mkdir(clang_libdir, parents=True), command.Mkdir(libc_libdir, parents=True), # 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(libc_libdir, 'crt1.x')), command.Copy(command.path.join('%(src)s', 'crt1_for_eh.x'), command.path.join(libc_libdir, 'crt1_for_eh.x')), # Install crti.bc (empty _init/_fini) BuildTargetObjectCmd('crti.c', 'crti.bc', bias_arch, output_dir=libc_libdir), # Install crtbegin bitcode (__cxa_finalize for C++) BuildTargetObjectCmd('crtbegin.c', 'crtbegin.bc', bias_arch, output_dir=clang_libdir), # Stubs for _Unwind_* functions when libgcc_eh is not included in # the native link). BuildTargetObjectCmd('unwind_stubs.c', 'unwind_stubs.bc', bias_arch, output_dir=clang_libdir), BuildTargetObjectCmd('sjlj_eh_redirect.cc', 'sjlj_eh_redirect.bc', bias_arch, output_dir=clang_libdir), # libpnaclmm.a (__atomic_* library functions). BuildTargetObjectCmd('pnaclmm.c', 'pnaclmm.bc', bias_arch), command.Command([ PnaclTool('ar'), 'rc', command.path.join(clang_libdir, 'libpnaclmm.a'), 'pnaclmm.bc']), ] } }) else: # For now some of the D2N support libs currently come from our native # translator libs (libgcc_eh). crti/crtn and crt1 # come from libnacl, built by scons/gyp. TODO(dschuff): Do D2N libgcc_eh. # Translate from bias_arch's triple-style (i686) names to the translator's # style (x86-32). We don't change the translator's naming scheme to avoid # churning the in-browser translator. def TL(lib): return GSDJoin(lib, pynacl.platform.GetArch3264(bias_arch)) libs.update({ T('libs_support'): { 'type': TargetLibBuildType(is_canonical), 'dependencies': [ 'compiler_rt_src', GSDJoin('newlib', MultilibArch(bias_arch)), TL('libgcc_eh'), 'target_lib_compiler'], 'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'support'), 'tls_params': os.path.join(NACL_DIR, 'src', 'untrusted', 'nacl', 'tls_params.h')}, 'commands': D2NLibsSupportCommands(bias_arch, clang_libdir), } }) return libs
def CommandsInBuild(command_lines): return [command.Mkdir('build')] + [command.Command(cmd, cwd='build') for cmd in command_lines]
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 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 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 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'] + [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 CommandsInBuild(command_lines): return [ command.RemoveDirectory('build'), command.Mkdir('build'), ] + [command.Command(cmd, cwd='build') for cmd in command_lines]
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