import command
import gsd_storage
import toolchain_main
+import repo_tools
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
NACL_DIR = os.path.dirname(SCRIPT_DIR)
+# See command.GenerateGitPatches for the schema of entries in this dict.
+# Additionally, each may contain a 'repo' key whose value is the name
+# to use in place of the package name when calling GitUrl (below).
GIT_REVISIONS = {
- 'binutils': '38dbda270a4248ab5b7facc012b9c8d8527f6fb2',
- 'gcc': '145a627d95b98f54915d037dddbcbb0f7b283494',
- 'newlib': 'cc9ce45891a45ecfbc671f4a6f1b06ba60a55ad9',
+ 'binutils': {
+ 'rev': '38dbda270a4248ab5b7facc012b9c8d8527f6fb2',
+ 'upstream-branch': 'upstream/binutils-2_24-branch',
+ 'upstream-name': 'binutils-2.24',
+ # This is tag binutils-2_24, but Gerrit won't let us push
+ # non-annotated tags, and the upstream tag is not annotated.
+ 'upstream-base': '237df3fa4a1d939e6fd1af0c3e5029a25a137310',
+ },
+ 'gcc': {
+ 'rev': '145a627d95b98f54915d037dddbcbb0f7b283494',
+ 'upstream-branch': 'upstream/gcc-4_8-branch',
+ 'upstream-name': 'gcc-4.8.2',
+ # Upstream tag gcc-4_8_2-release:
+ 'upstream-base': '9bcca88e24e64d4e23636aafa3404088b13bcb0e',
+ },
+ 'newlib': {
+ 'rev': 'a9ae3c60b36dea3d8a10e18b1b6db952d21268c2',
+ 'upstream-branch': 'upstream/master',
+ 'upstream-name': 'newlib-2.0.0',
+ # Upstream tag newlib_2_0_0:
+ 'upstream-base': 'c3fc84e062cacc2b3e13c1f6b9151d0cc85392ba',
+ },
+ 'gdb': {
+ 'rev': '41afdf9d511d95073c4403c838d8ccba582d8eed',
+ 'repo': 'binutils',
+ 'upstream-branch': 'upstream/gdb-7.7-branch',
+ 'upstream-name': 'gdb-7.7',
+ # Upstream tag gdb-7.7-release:
+ 'upstream-base': 'fe284cd86ba9761655a9281fef470d364e27eb85',
+ },
}
TAR_FILES = {
'gmp': command.path.join('gmp', 'gmp-5.1.3.tar.bz2'),
'mpfr': command.path.join('mpfr', 'mpfr-3.1.2.tar.bz2'),
'mpc': command.path.join('mpc', 'mpc-1.0.2.tar.gz'),
- 'isl': command.path.join('cloog', 'isl-0.12.1.tar.bz2'),
+ 'isl': command.path.join('cloog', 'isl-0.12.2.tar.bz2'),
'cloog': command.path.join('cloog', 'cloog-0.18.1.tar.gz'),
+ 'expat': command.path.join('expat', 'expat-2.0.1.tar.gz'),
}
GIT_BASE_URL = 'https://chromium.googlesource.com/native_client'
+def GitUrl(package):
+ repo = GIT_REVISIONS[package].get('repo', package)
+ return '%s/nacl-%s.git' % (GIT_BASE_URL, repo)
+
+
def CollectSources():
sources = {}
],
}
- for package in GIT_REVISIONS:
+ patch_packages = []
+ patch_commands = []
+ for package, info in GIT_REVISIONS.iteritems():
sources[package] = {
'type': 'source',
- 'commands': [
- command.SyncGitRepo('%s/nacl-%s.git' % (GIT_BASE_URL, package),
- '%(output)s', GIT_REVISIONS[package])
- ]
+ 'commands': [command.SyncGitRepo(GitUrl(package), '%(output)s',
+ info['rev'])],
}
+ patch_packages.append(package)
+ patch_commands.append(
+ command.GenerateGitPatches('%(' + package + ')s/.git', info))
+
+ sources['patches'] = {
+ 'type': 'build',
+ 'dependencies': patch_packages,
+ 'commands': patch_commands,
+ }
# The gcc_libs component gets the whole GCC source tree.
sources['gcc_libs'] = sources['gcc']
return sources
+# Canonical tuples we use for hosts.
+WINDOWS_HOST_TUPLE = 'i686-w64-mingw32'
+MAC_HOST_TUPLE = 'x86_64-apple-darwin'
+ARM_HOST_TUPLE = 'arm-linux-gnueabihf'
+LINUX_X86_32_TUPLE = 'i686-linux'
+LINUX_X86_64_TUPLE = 'x86_64-linux'
+
# Map of native host tuple to extra tuples that it cross-builds for.
EXTRA_HOSTS_MAP = {
- 'i686-linux': [
- 'arm-linux-gnueabihf',
- # TODO(mcgrathr): Enable this if the binaries are proven to
- # actually work, and bots get needed mingw* packages installed.
- #'i686-w64-mingw32',
+ LINUX_X86_64_TUPLE: [
+ LINUX_X86_32_TUPLE,
+ ARM_HOST_TUPLE,
+ WINDOWS_HOST_TUPLE,
],
}
+# Map of native host tuple to host tuples that are "native enough".
+# For these hosts, we will do a native-style build even though it's
+# not the native tuple, just passing some extra compiler flags.
+NATIVE_ENOUGH_MAP = {
+ LINUX_X86_64_TUPLE: {
+ LINUX_X86_32_TUPLE: ['-m32'],
+ },
+ }
+
+
# The list of targets to build toolchains for.
TARGET_LIST = ['arm', 'i686']
def ConfigureHostArch(host):
configure_args = []
- native, extra_cc_args = NativeTuple()
- is_cross = host != native
+ is_cross = CrossCompiling(host)
if is_cross:
extra_cc_args = []
configure_args.append('--host=' + host)
- elif extra_cc_args:
- # The host we've chosen is "native enough", such as x86-32 on x86-64.
- # But it's not what config.guess will yield, so we need to supply
- # a --build switch to ensure things build correctly.
- configure_args.append('--build=' + host)
+ else:
+ extra_cc_args = NATIVE_ENOUGH_MAP.get(NATIVE_TUPLE, {}).get(host, [])
+ if extra_cc_args:
+ # The host we've chosen is "native enough", such as x86-32 on x86-64.
+ # But it's not what config.guess will yield, so we need to supply
+ # a --build switch to ensure things build correctly.
+ configure_args.append('--build=' + host)
extra_cxx_args = list(extra_cc_args)
if fnmatch.fnmatch(host, '*-linux*'):
# Return the 'make check' command to run.
# When cross-compiling, don't try to run test suites.
def MakeCheckCommand(host):
- native, _ = NativeTuple()
- if host != native:
+ if CrossCompiling(host):
return ['true']
return MAKE_CHECK_CMD
'%(output)s', 'lib', 'pkgconfig')),
],
},
+ H('expat'): {
+ 'type': 'build',
+ 'dependencies': ['expat'],
+ 'commands': [
+ command.Command(ConfigureCommand('expat') +
+ ConfigureHostLib(host)),
+ command.Command(MakeCommand(host)),
+ command.Command(MakeCheckCommand(host)),
+ command.Command(MAKE_DESTDIR_CMD + [
+ # expat does not support the install-strip target.
+ 'installlib',
+ 'INSTALL=%(expat)s/conftools/install-sh -c -s',
+ 'INSTALL_DATA=%(expat)s/conftools/install-sh -c -m 644',
+ ]),
+ ],
+ },
}
return host_gcc_libs
# When doing a Canadian cross, we need native-hosted cross components
# to do the GCC build.
def GccDeps(host, target):
- native, _ = NativeTuple()
components = ['binutils_' + target]
- if host != native:
+ if CrossCompiling(host):
components.append('gcc_' + target)
- host = native
+ host = NATIVE_TUPLE
return [ForHost(component, host) for component in components]
def ConfigureGccCommand(source_component, host, target, extra_args=[]):
- target_cflagstr = ' '.join(CommonTargetCflags(target))
return GccCommand(
host,
target,
'--with-linker-hash-style=gnu',
'--enable-linker-build-id',
'--enable-languages=c,c++,lto',
- 'CFLAGS_FOR_TARGET=' + target_cflagstr,
- 'CXXFLAGS_FOR_TARGET=' + target_cflagstr,
] + extra_args)
# Note we include COPYING.RUNTIME here and not with gcc_libs.
] + InstallDocFiles('gcc', ['COPYING3', 'COPYING.RUNTIME']),
},
- }
- return tools
+ # 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'),
+ ]),
+ },
+ }
-# configure defaults to -g -O2 but passing an explicit option overrides that.
-# So we have to list -g -O2 explicitly since we need to add -mtp=soft.
-def CommonTargetCflags(target):
- options = ['-g', '-O2']
- if target == 'arm':
- options.append('-mtp=soft')
- return options
+ # 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 TargetCommands(host, target, command_list):
# First we have to copy the host tools into a common directory.
'--enable-newlib-io-c99-formats',
'--enable-newlib-mb',
'CFLAGS=-O2',
- 'CFLAGS_FOR_TARGET=' + ' '.join(CommonTargetCflags(target)),
'INSTALL_DATA=' + newlib_install_data,
]
if sys.platform.startswith('linux'):
machine = platform.machine().lower()
if machine.startswith('arm'):
- return ('arm-linux-gnueabihf', [])
+ # TODO(mcgrathr): How to distinguish gnueabi vs gnueabihf?
+ return ARM_HOST_TUPLE
+ if fnmatch.fnmatch(machine, 'i?86*'):
+ return LINUX_X86_32_TUPLE
if any(fnmatch.fnmatch(machine, pattern) for pattern in
- ['x86_64*', 'amd64*', 'x64*', 'i?86*']):
- # We build the tools for x86-32 hosts so they will run on either x86-32
- # or x86-64 hosts (with the right compatibility libraries installed).
- # So for an x86-64 host, we call x86-32 the "native" machine.
- return ('i686-linux', ['-m32'])
+ ['x86_64*', 'amd64*', 'x64*']):
+ return LINUX_X86_64_TUPLE
raise Exception('Machine %s not recognized' % machine)
elif sys.platform.startswith('win'):
- return ('i686-w64-mingw32', [])
+ return WINDOWS_HOST_TUPLE
elif sys.platform.startswith('darwin'):
- return ('x86_64-apple-darwin', [])
+ return MAC_HOST_TUPLE
raise Exception('Platform %s not recognized' % sys.platform)
+# Compute it once.
+NATIVE_TUPLE = NativeTuple()
+
+
+# For our purposes, "cross-compiling" means not literally that we are
+# targetting a host that does not match NATIVE_TUPLE, but that we are
+# targetting a host whose binaries we cannot run locally. So x86-32
+# on x86-64 does not count as cross-compiling. See NATIVE_ENOUGH_MAP, above.
+def CrossCompiling(host):
+ return (host != NATIVE_TUPLE and
+ host not in NATIVE_ENOUGH_MAP.get(NATIVE_TUPLE, {}))
+
def HostIsWindows(host):
- return host == 'i686-w64-mingw32'
+ return host == WINDOWS_HOST_TUPLE
+
+
+def HostIsMac(host):
+ return host == MAC_HOST_TUPLE
# We build target libraries only on Linux for two reasons:
# official builder bot. That will serve as a test of the host tools
# on the other host platforms.
def BuildTargetLibsOn(host):
- return host == 'i686-linux'
+ return host == LINUX_X86_64_TUPLE
def CollectPackagesForHost(host, targets):
def CollectPackages(targets):
packages = CollectSources()
- native, _ = NativeTuple()
- packages.update(CollectPackagesForHost(native, targets))
+ packages.update(CollectPackagesForHost(NATIVE_TUPLE, targets))
- for host in EXTRA_HOSTS_MAP.get(native, []):
+ for host in EXTRA_HOSTS_MAP.get(NATIVE_TUPLE, []):
packages.update(CollectPackagesForHost(host, targets))
return packages