The real entry plumbing is in toolchain_main.py.
"""
+import argparse
import fnmatch
import os
-import optparse
import process
import stat
import shutil
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import pynacl.gsd_storage
import pynacl.hashing_tools
import pynacl.platform
import pynacl.repo_tools
+BUILD_SCRIPT = os.path.abspath(__file__)
+TOOLCHAIN_BUILD = os.path.dirname(BUILD_SCRIPT)
+NATIVE_CLIENT = os.path.dirname(TOOLCHAIN_BUILD)
+PKG_VERSION = os.path.join(NATIVE_CLIENT, 'build', 'package_version')
+sys.path.append(PKG_VERSION)
+import archive_info
+import package_info
+
import toolchain_build
import toolchain_main
from file_update import NeedsUpdate, UpdateFromTo, UpdateText
-BIONIC_VERSION = '9ee77ccedbf569083d141bcb215ff0d5037fbd71'
+BIONIC_VERSION = '17f8f59d2fbdcd72a57e94ffaeff465601d68450'
ARCHES = ['arm']
-
-BUILD_SCRIPT = os.path.abspath(__file__)
-TOOLCHAIN_BUILD = os.path.dirname(BUILD_SCRIPT)
TOOLCHAIN_BUILD_SRC = os.path.join(TOOLCHAIN_BUILD, 'src')
TOOLCHAIN_BUILD_OUT = os.path.join(TOOLCHAIN_BUILD, 'out')
BIONIC_SRC = os.path.join(TOOLCHAIN_BUILD_SRC, 'bionic')
-NATIVE_CLIENT = os.path.dirname(TOOLCHAIN_BUILD)
TOOLCHAIN = os.path.join(NATIVE_CLIENT, 'toolchain')
-PROJECTS = [
- 'bionic_%s_work',
- 'gcc_%s_work',
-]
def GetToolchainPath(target_arch, libc, *extra_paths):
*extra_paths)
+def GetBionicBuildPath(target_arch, *extra_paths):
+ os_name = pynacl.platform.GetOS()
+ return os.path.join(TOOLCHAIN_BUILD_OUT,
+ "%s_%s_bionic" % (os_name, target_arch),
+ *extra_paths)
+
+
def ReplaceText(text, maplist):
for m in maplist:
for key in m:
def ReplaceArch(text, arch, subarch=None):
NACL_ARCHES = {
'arm': 'arm',
- 'x86': 'x86_64'
+ 'x86': 'x86_64',
+ 'pnacl': 'pnacl'
}
GCC_ARCHES = {
'arm': 'arm',
- 'x86': 'i686'
+ 'x86': 'i686',
+ 'pnacl': 'pnacl'
}
CPU_ARCHES = {
'arm': 'arm',
- 'x86': 'amd64'
+ 'x86': 'amd64',
+ 'pnacl': 'pnacl'
}
VERSION_MAP = {
'arm': '4.8.2',
return ReplaceText(text, [REPLACE_MAP])
-def Clobber():
- Rmdir(os.path.join(TOOLCHAIN_BUILD, 'cache'))
+def Clobber(fast=False):
+ if not fast:
+ Rmdir(os.path.join(TOOLCHAIN_BUILD, 'cache'))
+ Rmdir(os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_arm_work'))
+
+ BUILD_DIRS = [
+ 'linux_%s_bionic',
+ 'bionic_%s_work',
+ ]
+
for arch in ARCHES:
Rmdir(GetToolchainPath(arch, 'bionic'))
- for workdir in PROJECTS:
+ for workdir in BUILD_DIRS:
Rmdir(os.path.join(TOOLCHAIN_BUILD_OUT, workdir % arch))
def FetchAndBuild_gcc_libs():
tc_args = ['-y', '--no-use-remote-cache', 'gcc_libs_arm']
- toolchain_main.PackageBuilder(toolchain_build.PACKAGES, tc_args).Main()
+ # Call toolchain_build to build the gcc libs. We do not need to fill in
+ # any package targets since we are using toolchain_build as an
+ # intermediate step.
+ toolchain_main.PackageBuilder(toolchain_build.PACKAGES, {}, tc_args).Main()
def FetchBionicSources():
def MungeIRT(src, dst):
replace_map = {
- 'off_t': 'int64_t'
+ 'off_t': 'int64_t',
+ 'native_client/src/untrusted/irt/' : '',
}
with open(src, 'r') as srcf:
# basic files line nacl_arm_macros.s.
arch = 'arm'
UpdateFromTo(GetToolchainPath(arch, 'newlib'),
- GetToolchainPath(arch, 'bionic'),
+ GetBionicBuildPath(arch),
filters=['*arm-nacl/include*', '*arm-nacl/lib*','*.a', '*.o'])
UpdateFromTo(GetToolchainPath(arch, 'newlib'),
- GetToolchainPath(arch, 'bionic'),
+ GetBionicBuildPath(arch),
paterns=['*.s'])
# Static build uses:
('bionic/libc/arch-nacl/syscalls/irt_socket.h',
'$NACL-nacl/include/irt_socket.h'),
('bionic/libc/include', '$NACL-nacl/include'),
+ ('bionic/libc/arch-nacl/syscalls/nacl_socket.h',
+ '$NACL-nacl/include/nacl_socket.h'),
('bionic/libc/arch-nacl/syscalls/nacl_stat.h',
'$NACL-nacl/include/nacl_stat.h'),
('bionic/libc/arch-$ARCH/include/machine',
for arch in ARCHES:
for name in ['irt.h', 'irt_dev.h']:
src = os.path.join(NATIVE_CLIENT, 'src', 'untrusted', 'irt', name)
- dst = GetToolchainPath(arch, 'bionic', '$NACL-nacl', 'include', name)
+ dst = GetBionicBuildPath(arch, '$NACL-nacl', 'include', name)
MungeIRT(src, ReplaceArch(dst, arch))
- inspath = GetToolchainPath(arch, 'bionic')
- inspath = ReplaceArch(inspath, arch)
+ inspath = GetBionicBuildPath(arch)
# Create empty objects and libraries
libpath = ReplaceArch(os.path.join(inspath, '$NACL-nacl', 'lib'), arch)
'-lgcc': '-lgcc --as-needed %{!static: -lgcc_s} --no-as-needed %{!shared: -lgcc_eh}',
'--hash-style=gnu': '--hash-style=sysv',
}])
-
open(specs, 'w').write(text)
def ConfigureAndBuild_libc():
for arch in ARCHES:
- inspath = GetToolchainPath(arch, 'bionic')
+ inspath = GetBionicBuildPath(arch)
workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_work')
workpath = ReplaceArch(workpath, arch)
ConfigureAndBuild(arch, 'bionic/libc', workpath, inspath, )
def ConfigureAndBuild_libc():
for arch in ARCHES:
- inspath = GetToolchainPath(arch, 'bionic')
+ inspath = GetBionicBuildPath(arch)
workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_work')
workpath = ReplaceArch(workpath, arch)
ConfigureAndBuild(arch, 'bionic/libc', workpath, inspath)
def ConfigureAndBuildLinker():
for arch in ARCHES:
- inspath = GetToolchainPath(arch, 'bionic')
+ inspath = GetBionicBuildPath(arch)
workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_work')
workpath = ReplaceArch(workpath, arch)
ConfigureAndBuild(arch, 'bionic/linker', workpath, inspath)
os.chmod(filepath, st_info.st_mode | stat.S_IEXEC)
env = os.environ
- newpath = GetToolchainPath(arch, 'bionic', 'bin') + ':' + env['PATH']
+ newpath = GetBionicBuildPath(arch, 'bin') + ':' + env['PATH']
proj = '%s %s' % (project, arch)
setpath = ['/usr/bin/env', 'PATH=' + newpath]
def MakeGCCProject(arch, project, workpath, targets=[]):
env = os.environ
- newpath = GetToolchainPath(arch, 'bionic', 'bin') + ':' + env['PATH']
+ newpath = GetBionicBuildPath(arch, 'bin') + ':' + env['PATH']
proj = '%s %s' % (project, arch)
setpath = ['/usr/bin/env', 'PATH=' + newpath]
print 'Done ' + proj
-def ConfigureAndBuild_libgcc(config=False):
+def ConfigureAndBuild_libgcc(skip_build=False):
arch = 'arm'
project = 'libgcc'
- tcpath = GetToolchainPath(arch, 'bionic')
+ tcpath = GetBionicBuildPath(arch)
# Prep work path
workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_work')
workpath = ReplaceArch(workpath, arch)
- Mkdir(workpath)
- Symlink('../gcc_libs_arm_work/gcc' , os.path.join(workpath, 'gcc'))
+
+ if not skip_build:
+ Mkdir(workpath)
+ Symlink('../gcc_libs_arm_work/gcc' , os.path.join(workpath, 'gcc'))
# Prep install path
inspath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_install')
'--prefix=' + inspath,
'CFLAGS=-I../../../gcc_lib_arm_work'
]
- ConfigureGCCProject(arch, project, cfg, dstpath, inspath)
- MakeGCCProject(arch, project, dstpath, ['libgcc.a'])
+
+ if not skip_build:
+ ConfigureGCCProject(arch, project, cfg, dstpath, inspath)
+ MakeGCCProject(arch, project, dstpath, ['libgcc.a'])
# Copy temp version of libgcc.a for linking libc.so
UpdateFromTo(os.path.join(dstpath, 'libgcc.a'),
os.path.join(tcpath, 'arm-nacl', 'lib', 'libgcc.a'))
-def BuildAndInstall_libgcc_s():
+def BuildAndInstall_libgcc_s(skip_build=False):
arch = 'arm'
project = 'libgcc'
- tcpath = GetToolchainPath(arch, 'bionic')
+ tcpath = GetBionicBuildPath(arch)
# Remove temp copy of libgcc.a, it get's installed at the end
os.remove(os.path.join(tcpath, 'arm-nacl', 'lib', 'libgcc.a'))
inspath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_install')
inspath = ReplaceArch(inspath, arch)
- MakeGCCProject(arch, project, dstpath)
- MakeGCCProject(arch, project, dstpath, ['install'])
+ if not skip_build:
+ MakeGCCProject(arch, project, dstpath)
+ MakeGCCProject(arch, project, dstpath, ['install'])
UpdateFromTo(os.path.join(inspath, 'lib', 'gcc'),
os.path.join(tcpath, 'lib', 'gcc'),
def ConfigureAndBuild_libstdcpp():
arch = 'arm'
project = 'libstdc++'
- tcpath = GetToolchainPath(arch, 'bionic')
+ tcpath = GetBionicBuildPath(arch)
# Prep work path
workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_work')
MakeGCCProject(arch, project, dstpath)
MakeGCCProject(arch, project, dstpath, ['install'])
- UpdateFromTo(os.path.join(inspath, 'lib'),
- os.path.join(tcpath, 'arm-nacl', 'lib'))
+ filelist = [
+ 'libstdc++.a',
+ 'libstdc++.la',
+ 'libstdc++.so',
+ 'libstdc++.so.6',
+ 'libstdc++.so.6.0.18',
+ 'libstdc++.so.6.0.18-gdb.py',
+ 'libsupc++.a',
+ 'libsupc++.la'
+ ]
+ for filename in filelist:
+ UpdateFromTo(os.path.join(inspath, 'lib', filename),
+ os.path.join(tcpath, 'arm-nacl', 'lib', filename))
+
UpdateFromTo(os.path.join(inspath, 'include'),
os.path.join(tcpath, 'arm-nacl', 'include'))
workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_work')
instpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_install')
- toolpath = GetToolchainPath(arch, 'bionic')
+ toolpath = GetBionicBuildPath(arch)
workpath = ReplaceArch(os.path.join(workpath, 'bionic', project), arch)
instpath = ReplaceArch(os.path.join(toolpath, '$NACL-nacl', 'lib'), arch)
out = {
paths = GetProjectPaths(arch, project)
MAKEFILE_TEMPLATE = """
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# GNU Makefile based on shared rules provided by the Native Client SDK.
# See README.Makefiles for more details.
+NATIVE_CLIENT_PATH?=$(nacl_path)
TOOLCHAIN_PATH?=$(tc_path)
TOOLCHAIN_PREFIX:=$(TOOLCHAIN_PATH)/bin/$GCC-nacl-
'$(src_path)': paths['src'],
'$(dst_path)': paths['work'],
'$(ins_path)': paths['ins'],
- '$(tc_path)': GetToolchainPath(arch, 'bionic'),
- '$(build_tc_path)': TOOLCHAIN_BUILD
+ '$(tc_path)': GetBionicBuildPath(arch),
+ '$(build_tc_path)': TOOLCHAIN_BUILD,
+ '$(nacl_path)': NATIVE_CLIENT,
}
text = ReplaceText(MAKEFILE_TEMPLATE, [remap])
text = ReplaceArch(text, arch)
if clobber:
- print 'Clobering Bionic project directories.'
+ print 'Clobbering Bionic project directory: ' + paths['work']
Rmdir(paths['work'])
Mkdir(paths['work'])
def ConfigureBionicProjects(clobber=False):
- PROJECTS = ['libc', 'libm', 'linker', 'tests']
+ PROJECTS = ['libc', 'libm', 'linker', 'tests', 'newlinker', 'newtests']
arch = 'arm'
for project in PROJECTS:
print 'Configure %s for %s.' % (project, arch)
print 'Done with %s for %s.\n' % (project, arch)
-def ArchiveAndUpload(version, zipname, zippath):
- if 'BUILDBOT_BUILDERNAME' in os.environ:
- GSUTIL = '../buildbot/gsutil.sh'
- else:
- GSUTIL = 'gsutil'
- GSUTIL_ARGS = [GSUTIL, 'cp', '-a', 'public-read']
- GSUTIL_PATH = 'gs://nativeclient-archive2/toolchain'
+def ArchiveAndUpload(version, zipname, zippath, packages_file):
+ sys.stdout.flush()
+ print >>sys.stderr, '@@@BUILD_STEP archive_and_upload@@@'
- urldir = os.path.join(GSUTIL_PATH, version)
- zipurl = os.path.join(urldir, zipname)
- zipname = os.path.join(TOOLCHAIN_BUILD_OUT, zipname)
+ bucket_path = 'nativeclient-archive2/toolchain/%s' % version
+ gsd_store = pynacl.gsd_storage.GSDStorage(bucket_path, [bucket_path])
+ zipname = os.path.join(TOOLCHAIN_BUILD_OUT, zipname)
try:
os.remove(zipname)
except:
pass
- sys.stdout.flush()
- print >>sys.stderr, '@@@STEP_LINK@download@%s@@@' % urldir
-
+ # Archive the zippath to the zipname.
if process.Run(['tar', '-czf', zipname, zippath],
- cwd=TOOLCHAIN,
+ cwd=TOOLCHAIN_BUILD_OUT,
outfile=sys.stdout):
raise RuntimeError('Failed to zip %s from %s.\n' % (zipname, zippath))
+ # Create Zip Hash file using the hash of the zip file.
hashzipname = zipname + '.sha1hash'
- hashzipurl = zipurl + '.sha1hash'
hashval = pynacl.hashing_tools.HashFileContents(zipname)
-
with open(hashzipname, 'w') as f:
f.write(hashval)
- if process.Run(GSUTIL_ARGS + [zipname, zipurl],
- cwd=TOOLCHAIN_BUILD,
- outfile=sys.stdout):
- err = 'Failed to upload zip %s to %s.\n' % (zipname, zipurl)
- raise RuntimeError(err)
+ # Upload the Zip file.
+ zipurl = gsd_store.PutFile(zipname, os.path.basename(zipname))
+ sys.stdout.flush()
+ print >>sys.stderr, ('@@@STEP_LINK@download (%s)@%s@@@' %
+ (os.path.basename(zipname), zipurl))
- if process.Run(GSUTIL_ARGS + [hashzipname, hashzipurl],
- cwd=TOOLCHAIN_BUILD,
- outfile=sys.stdout):
- err = 'Failed to upload hash %s to %s.\n' % (hashzipname, hashzipurl)
- raise RuntimeError(err)
+ # Upload the Zip Hash file.
+ hashurl = gsd_store.PutFile(hashzipname, os.path.basename(hashzipname))
+ sys.stdout.flush()
+ print >>sys.stderr, ('@@@STEP_LINK@download (%s)@%s@@@' %
+ (os.path.basename(hashzipname), hashurl))
+
+ # Create a package info file for the nacl_arm_bionic package.
+ archive_desc = archive_info.ArchiveInfo(name=os.path.basename(zipname),
+ archive_hash=hashval,
+ tar_src_dir='linux_arm_bionic',
+ url=zipurl)
+ package_desc = package_info.PackageInfo()
+ package_desc.AppendArchive(archive_desc)
+
+ os_name = pynacl.platform.GetOS()
+ arch_name = pynacl.platform.GetArch()
+ package_info_file = os.path.join(TOOLCHAIN_BUILD_OUT,
+ 'packages',
+ '%s_%s' % (os_name, arch_name),
+ 'nacl_arm_bionic.json')
+ package_desc.SavePackageFile(package_info_file)
+
+ # If packages_file is specified, write out our packages file of 1 package.
+ if packages_file:
+ with open(packages_file, 'wt') as f:
+ f.write(package_info_file)
def main(argv):
- parser = optparse.OptionParser()
- parser.add_option(
+ parser = argparse.ArgumentParser(add_help=False)
+ parser.add_argument(
'-v', '--verbose', dest='verbose',
default=False, action='store_true',
help='Produce more output.')
- parser.add_option(
+
+ parser.add_argument(
'-c', '--clobber', dest='clobber',
default=False, action='store_true',
help='Clobber working directories before building.')
- parser.add_option(
+
+ parser.add_argument(
+ '-f', '--fast-clobber', dest='fast_clobber',
+ default=False, action='store_true',
+ help='Clobber bionic working directories before building.')
+
+ parser.add_argument(
'-s', '--sync', dest='sync',
default=False, action='store_true',
help='Sync sources first.')
- parser.add_option(
+ parser.add_argument(
'-b', '--buildbot', dest='buildbot',
default=False, action='store_true',
help='Running on the buildbot.')
- parser.add_option(
+ parser.add_argument(
+ '-l', '--llvm', dest='llvm',
+ default=False, action='store_true',
+ help='Enable building via llvm.')
+
+ parser.add_argument(
'-u', '--upload', dest='upload',
default=False, action='store_true',
help='Upload build artifacts.')
- parser.add_option(
+ parser.add_argument(
+ '--packages-file', dest='packages_file',
+ default=None,
+ help='Output packages file describing list of package files built.')
+
+ parser.add_argument(
'--skip-gcc', dest='skip_gcc',
default=False, action='store_true',
help='Skip building GCC components.')
- options, args = parser.parse_args(argv)
+ options, leftover_args = parser.parse_known_args()
+ if '-h' in leftover_args or '--help' in leftover_args:
+ print 'The following arguments are specific to toolchain_build_bionic.py:'
+ parser.print_help()
+ print 'The rest of the arguments are generic, in toolchain_main.py'
+ return 1
+
+ if options.llvm:
+ ARCHES.append('pnacl')
+
if options.buildbot or options.upload:
version = os.environ['BUILDBOT_REVISION']
- if options.clobber:
- Clobber()
+ if options.clobber or options.fast_clobber:
+ Clobber(fast=options.fast_clobber)
if options.sync or options.buildbot:
FetchBionicSources()
# Configure Bionic Projects, libc, libm, linker, tests, ...
ConfigureBionicProjects(clobber=options.buildbot)
+ # Build and install IRT header before building GCC
+ MakeBionicProject('libc', ['irt'])
+
if not options.skip_gcc:
# Build newlib gcc_libs for use by bionic
FetchAndBuild_gcc_libs()
# Configure and build libgcc.a
- ConfigureAndBuild_libgcc()
+ ConfigureAndBuild_libgcc(skip_build=options.skip_gcc)
# With libgcc.a, we can now build libc.so
MakeBionicProject('libc')
# With libc.so, we can build libgcc_s.so
- BuildAndInstall_libgcc_s()
+ BuildAndInstall_libgcc_s(skip_build=options.skip_gcc)
# With libc and libgcc_s, we can now build libm
MakeBionicProject('libm')
ConfigureAndBuild_libstdcpp()
# Now we can build the linker
- MakeBionicProject('linker')
+ #MakeBionicProject('linker')
+ MakeBionicProject('newlinker')
# Now we have a full toolchain, so test it
- MakeBionicProject('tests')
+ #MakeBionicProject('tests')
+ MakeBionicProject('newtests')
# We can run only off buildbots
if not options.buildbot:
+ process.Run(['./scons', 'platform=arm', '--mode=nacl,dbg-linux', '-j20'],
+ cwd=NATIVE_CLIENT)
MakeBionicProject('tests', ['run'])
+ MakeBionicProject('newtests', ['run'])
+
+ dst = os.path.join(TOOLCHAIN_BUILD_OUT, 'linux_arm_bionic', 'log.txt')
+ with open(dst, 'w') as dstf:
+ process.Run(['git', 'log', '-n', '1'],
+ cwd=os.path.join(TOOLCHAIN_BUILD_SRC, 'bionic'),
+ outfile=dstf,
+ verbose=False)
if options.buildbot or options.upload:
zipname = 'naclsdk_linux_arm_bionic.tgz'
- ArchiveAndUpload(version, zipname, 'linux_arm_bionic')
+ ArchiveAndUpload(version, zipname, 'linux_arm_bionic',
+ options.packages_file)
if __name__ == '__main__':