Exemple #1
0
    def test_UseCachedResultsFalse(self):
        # Check that the use_cached_results=False does indeed cause computations
        # to be redone, even when present in the cache.
        with working_directory.TemporaryWorkingDirectory() as work_dir:
            self.GenerateTestData('UseCachedResultsFalse', work_dir)
            self._tally = 0

            def check_call(cmd, **kwargs):
                subprocess.check_call(cmd, **kwargs)
                self._tally += 1

            o = once.Once(storage=fake_storage.FakeStorage(),
                          use_cached_results=False,
                          check_call=check_call)
            o.Run('test', self._input_dirs, self._output_dirs[0], [
                command.Copy('%(input0)s/in0', '%(output)s/out', cwd=work_dir)
            ])
            o.Run('test', self._input_dirs, self._output_dirs[1], [
                command.Copy('%(input0)s/in0', '%(output)s/out', cwd=work_dir)
            ])
            self.assertEquals(2, self._tally)
            self.assertEquals(file_tools.ReadFile(self._input_files[0]),
                              file_tools.ReadFile(self._output_files[0]))
            self.assertEquals(file_tools.ReadFile(self._input_files[0]),
                              file_tools.ReadFile(self._output_files[1]))
Exemple #2
0
def HostLibs(host):
    libs = {}
    if TripleIsWindows(host):
        if pynacl.platform.IsWindows():
            ar = 'ar'
        else:
            ar = 'i686-w64-mingw32-ar'

        libs.update({
            'libdl': {
                'type':
                'build',
                'inputs': {
                    'src':
                    os.path.join(NACL_DIR, '..', 'third_party', 'dlfcn-win32')
                },
                'commands': [
                    command.CopyTree('%(src)s', '.'),
                    command.Command([
                        'i686-w64-mingw32-gcc', '-o', 'dlfcn.o', '-c',
                        'dlfcn.c', '-Wall', '-O3', '-fomit-frame-pointer'
                    ]),
                    command.Command([ar, 'cru', 'libdl.a', 'dlfcn.o']),
                    command.Copy('libdl.a',
                                 os.path.join('%(output)s', 'libdl.a')),
                    command.Copy('dlfcn.h',
                                 os.path.join('%(output)s', 'dlfcn.h')),
                ],
            },
        })
    return libs
Exemple #3
0
    def test_HitsCacheSecondTime(self):
        # Test that the computation is not performed on a second instance.
        with working_directory.TemporaryWorkingDirectory() as work_dir:
            self.GenerateTestData('HitsCacheSecondTime', work_dir)
            self._tally = 0

            def check_call(cmd, **kwargs):
                self._tally += 1
                subprocess.check_call(cmd, **kwargs)

            self._url = None

            def stash_url(urls):
                self._url = urls

            o = once.Once(storage=fake_storage.FakeStorage(),
                          check_call=check_call,
                          print_url=stash_url)
            o.Run('test', self._input_dirs, self._output_dirs[0], [
                command.Copy('%(input0)s/in0', '%(output)s/out', cwd=work_dir)
            ])
            initial_url = self._url
            self._url = None
            o.Run('test', self._input_dirs, self._output_dirs[1], [
                command.Copy('%(input0)s/in0', '%(output)s/out', cwd=work_dir)
            ])
            self.assertEquals(file_tools.ReadFile(self._input_files[0]),
                              file_tools.ReadFile(self._output_files[0]))
            self.assertEquals(file_tools.ReadFile(self._input_files[0]),
                              file_tools.ReadFile(self._output_files[1]))
            self.assertEquals(1, self._tally)
            self.assertEquals(initial_url, self._url)
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
Exemple #5
0
 def test_CachedCommandRecorded(self):
     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
         self.GenerateTestData('CachedCommand', work_dir)
         o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
                       system_summary='test')
         o.Run('test', self._input_dirs, self._output_dirs[0],
               [command.Copy('%(input0)s/in0', '%(output)s/out')])
         self.assertEquals(len(o.GetCachedCloudItems()), 1)
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 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 test_FirstTime(self):
     # Test that the computation is always performed if the cache is empty.
     with working_directory.TemporaryWorkingDirectory() as work_dir:
         self.GenerateTestData('FirstTime', work_dir)
         o = once.Once(storage=fake_storage.FakeStorage(),
                       system_summary='test')
         o.Run('test', self._input_dirs, self._output_dirs[0],
               [command.Copy('%(input0)s/in0', '%(output)s/out')])
         self.assertEquals('FirstTimedata0',
                           file_tools.ReadFile(self._output_files[0]))
Exemple #9
0
 def test_OutputsFlushPathHashCache(self):
     # Test that commands that output to a directory that has an input hash
     # value cached raise an error indicating an input output cycle.
     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
         self.GenerateTestData('CacheFlush', work_dir)
         o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
                       system_summary='test')
         self.assertRaises(
             once.UserError, o.Run, 'test', self._input_dirs,
             self._input_dirs['input0'],
             [command.Copy('%(input0)s/in0', '%(output)s/out')])
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
Exemple #11
0
 def test_CacheResultsFalse(self):
     # Check that setting cache_results=False prevents results from being written
     # to the cache.
     with working_directory.TemporaryWorkingDirectory() as work_dir:
         self.GenerateTestData('CacheResultsFalse', work_dir)
         storage = fake_storage.FakeStorage()
         o = once.Once(storage=storage, cache_results=False)
         o.Run('test', self._input_dirs, self._output_dirs[0], [
             command.Copy('%(input0)s/in0', '%(output)s/out', cwd=work_dir)
         ])
         self.assertEquals(0, storage.ItemCount())
         self.assertEquals(file_tools.ReadFile(self._input_files[0]),
                           file_tools.ReadFile(self._output_files[0]))
def CopyWindowsHostLibs(host):
  if not TripleIsWindows(host):
    return []
  if command.Runnable.use_cygwin:
    libs = ('cyggcc_s-1.dll', 'cygiconv-2.dll', 'cygwin1.dll', 'cygintl-8.dll',
            'cygstdc++-6.dll', 'cygz.dll')
    return [command.Copy(
                    os.path.join(CYGWIN_PATH, 'bin', lib),
                    os.path.join('%(output)s', 'bin', lib))
                for lib in libs]
  if pynacl.platform.IsWindows():
    lib_path = os.path.join(MINGW_PATH, 'bin')
    # The native minGW compiler uses winpthread, but the Ubuntu cross compiler
    # does not.
    libs = ('libgcc_s_sjlj-1.dll', 'libstdc++-6.dll', 'libwinpthread-1.dll')
  else:
    lib_path = os.path.join(CROSS_MINGW_LIBPATH)
    libs = ('libgcc_s_sjlj-1.dll', 'libstdc++-6.dll')
  return [command.Copy(
                  os.path.join(lib_path, lib),
                  os.path.join('%(output)s', 'bin', lib))
               for lib in libs]
Exemple #13
0
    def test_UnpackCommands(self):
        # Test that unpack commnds get run first and hashed_inputs get
        # used when present.
        with working_directory.TemporaryWorkingDirectory() as work_dir:
            self.GenerateTestData('UnpackCommands', work_dir)
            self._tally = 0

            def check_call(cmd, **kwargs):
                self._tally += 1
                subprocess.check_call(cmd, **kwargs)

            o = once.Once(storage=fake_storage.FakeStorage(),
                          check_call=check_call)
            alt_inputs = {'input0': os.path.join(work_dir, 'alt_input')}
            unpack_commands = [
                command.Copy('%(input0)s/in0', alt_inputs['input0'])
            ]
            commands = [
                command.Copy('%(input0)s', '%(output)s/out', cwd=work_dir)
            ]
            o.Run('test',
                  self._input_dirs,
                  self._output_dirs[0],
                  commands=commands,
                  unpack_commands=unpack_commands,
                  hashed_inputs=alt_inputs)
            o.Run('test',
                  self._input_dirs,
                  self._output_dirs[1],
                  commands=commands,
                  unpack_commands=unpack_commands,
                  hashed_inputs=alt_inputs)
            self.assertEquals(file_tools.ReadFile(self._input_files[0]),
                              file_tools.ReadFile(self._output_files[0]))
            self.assertEquals(file_tools.ReadFile(self._input_files[0]),
                              file_tools.ReadFile(self._output_files[1]))
            self.assertEquals(3, self._tally)
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 test_FailsWhenWritingFails(self):
        # Check that once doesn't eat the storage layer failures for writes.
        with working_directory.TemporaryWorkingDirectory() as work_dir:
            self.GenerateTestData('FailsWhenWritingFails', work_dir)

            def call(cmd, **kwargs):
                # Cause gsutil commands to fail.
                return 1

            bad_storage = gsd_storage.GSDStorage(gsutil=['mygsutil'],
                                                 write_bucket='mybucket',
                                                 read_buckets=[],
                                                 call=call)
            o = once.Once(storage=bad_storage, system_summary='test')
            self.assertRaises(
                gsd_storage.GSDStorageError, o.Run, 'test', self._input_dirs,
                self._output_dirs[0],
                [command.Copy('%(input0)s/in0', '%(output)s/out')])
Exemple #16
0
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 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
Exemple #18
0
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
Exemple #19
0
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 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