summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmorphlib/app.py18
-rw-r--r--morphlib/buildcommand.py7
-rw-r--r--morphlib/buildenvironment.py22
-rw-r--r--morphlib/buildenvironment_tests.py27
-rw-r--r--morphlib/cachekeycomputer.py3
-rw-r--r--morphlib/cachekeycomputer_tests.py12
-rw-r--r--morphlib/util.py11
7 files changed, 60 insertions, 40 deletions
diff --git a/morphlib/app.py b/morphlib/app.py
index c8b9b911..d3136b43 100755
--- a/morphlib/app.py
+++ b/morphlib/app.py
@@ -42,7 +42,6 @@ defaults = {
'cachedir': os.path.expanduser('~/.cache/morph'),
'max-jobs': morphlib.util.make_concurrency(),
'prefix': '/usr',
- 'toolchain-target': '%s-baserock-linux-gnu' % os.uname()[4],
'build-ref-prefix': 'baserock/builds'
}
@@ -137,23 +136,6 @@ class Morph(cliapp.Application):
default=os.environ.get('TMPDIR'),
group=group_build)
- # Would be better to have a separate tool to cross-bootstrap
- # because it's completely outside normal Morph usage
- group_bootstrap = 'Bootstrap Options'
- self.settings.string(['target-cflags'],
- 'inject additional CFLAGS into the environment '
- 'that is used to build chunks',
- metavar='CFLAGS',
- default='',
- group=group_bootstrap)
- self.settings.string(['toolchain-target'],
- 'set the TOOLCHAIN_TARGET variable which is used '
- 'in some chunks to determine which architecture '
- 'to build tools for',
- metavar='TOOLCHAIN_TARGET',
- default=defaults['toolchain-target'],
- group=group_bootstrap)
-
# These cannot be removed just yet because existing morph.conf files
# would fail to parse.
group_obsolete = 'Obsolete Options'
diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py
index 56c7fae8..ca097145 100644
--- a/morphlib/buildcommand.py
+++ b/morphlib/buildcommand.py
@@ -33,12 +33,14 @@ class BuildCommand(object):
'''
def __init__(self, app):
+ self.supports_local_build = True
+ self.target = morphlib.util.target(app.runcmd)
+
self.app = app
self.build_env = self.new_build_env()
self.ckc = self.new_cache_key_computer(self.build_env)
self.lac, self.rac = self.new_artifact_caches()
self.lrc, self.rrc = self.new_repo_caches()
- self.supports_local_build = True
def build(self, args):
'''Build triplets specified on command line.'''
@@ -55,7 +57,8 @@ class BuildCommand(object):
def new_build_env(self):
'''Create a new BuildEnvironment instance.'''
- return morphlib.buildenvironment.BuildEnvironment(self.app.settings)
+ return morphlib.buildenvironment.BuildEnvironment(self.app.settings,
+ self.target)
def new_cache_key_computer(self, build_env):
'''Create a new cache key computer.'''
diff --git a/morphlib/buildenvironment.py b/morphlib/buildenvironment.py
index fce98da4..29561220 100644
--- a/morphlib/buildenvironment.py
+++ b/morphlib/buildenvironment.py
@@ -13,6 +13,7 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+import cliapp
import os
import morphlib
@@ -20,9 +21,11 @@ import morphlib
class BuildEnvironment():
- def __init__(self, settings, arch=None):
- self.extra_path = []
+ def __init__(self, settings, target, arch=None):
+ '''Create a new BuildEnvironment object'''
+ self.extra_path = []
+ self.target = target
self.arch = morphlib.util.arch() if arch is None else arch
self.env = self._clean_env(settings)
@@ -34,6 +37,15 @@ class BuildEnvironment():
_override_term = 'dumb'
_override_username = 'tomjon'
+ def get_bootstrap_target(self, target):
+ '''Set 'vendor' field of the given machine triplet as 'bootstrap' '''
+
+ parts = target.split('-')
+ if len(parts) < 2:
+ raise morphlib.Error('Failed to parse machine triplet returned by '
+ 'host compiler: %s' % target)
+ return '-'.join([parts[0], 'bootstrap'] + parts[2:])
+
def _clean_env(self, settings):
'''Create a fresh set of environment variables for a clean build.
@@ -69,7 +81,11 @@ class BuildEnvironment():
env['HOME'] = self._override_home
env['PREFIX'] = settings['prefix']
- env['BOOTSTRAP'] = 'false'
+ env['BUILD'] = self.target
+ env['TARGET'] = self.target
+ env['TARGET_STAGE1'] = self.get_bootstrap_target(self.target)
+ env['TARGET_GCC_CONFIG'] = ''
+
if not settings['no-ccache']:
self.extra_path.append(self._ccache_path)
diff --git a/morphlib/buildenvironment_tests.py b/morphlib/buildenvironment_tests.py
index 2af3f605..03799190 100644
--- a/morphlib/buildenvironment_tests.py
+++ b/morphlib/buildenvironment_tests.py
@@ -29,20 +29,28 @@ class BuildEnvironmentTests(unittest.TestCase):
'no-ccache': True,
'no-distcc': True
}
+ self.target = '%s-baserock-linux-gnu' % morphlib.util.arch()
self.fake_env = {
'PATH': '/fake_bin',
}
self.default_path = 'no:such:path'
+ def new_build_env(self, settings=None, target=None, **kws):
+ settings = settings or self.settings
+ target = target or self.target
+ return buildenvironment.BuildEnvironment(settings, target, **kws)
+
def test_arch_defaults_to_host(self):
- buildenv = buildenvironment.BuildEnvironment(self.settings)
+ buildenv = self.new_build_env()
self.assertEqual(buildenv.arch, morphlib.util.arch())
def test_arch_overridable(self):
- buildenv = buildenvironment.BuildEnvironment(self.settings,
- arch='noarch')
+ buildenv = self.new_build_env(arch='noarch')
self.assertEqual(buildenv.arch, 'noarch')
+ def test_target_always_valid(self):
+ self.assertRaises(morphlib.Error, self.new_build_env, target="invalid")
+
def test_copies_whitelist_vars(self):
env = self.fake_env
safe = {
@@ -57,19 +65,19 @@ class BuildEnvironmentTests(unittest.TestCase):
old_osenv = buildenvironment.BuildEnvironment._osenv
buildenvironment.BuildEnvironment._osenv = env
- buildenv = buildenvironment.BuildEnvironment(self.settings)
+ buildenv = self.new_build_env()
self.assertEqual(sorted(safe.items()),
sorted([(k, buildenv.env[k]) for k in safe.keys()]))
buildenvironment.BuildEnvironment._osenv = old_osenv
def test_user_spellings_equal(self):
- buildenv = buildenvironment.BuildEnvironment(self.settings)
+ buildenv = self.new_build_env()
self.assertTrue(buildenv.env['USER'] == buildenv.env['USERNAME'] ==
buildenv.env['LOGNAME'])
def test_environment_overrides(self):
- buildenv = buildenvironment.BuildEnvironment(self.settings)
+ buildenv = self.new_build_env()
self.assertEqual(buildenv.env['TERM'], buildenv._override_term)
self.assertEqual(buildenv.env['SHELL'], buildenv._override_shell)
self.assertEqual(buildenv.env['USER'], buildenv._override_username)
@@ -79,14 +87,13 @@ class BuildEnvironmentTests(unittest.TestCase):
self.assertEqual(buildenv.env['HOME'], buildenv._override_home)
def test_environment_settings_set(self):
- buildenv = buildenvironment.BuildEnvironment(self.settings)
- #self.assertEqual(buildenv.env['TOOLCHAIN_TARGET'],
- # self.settings['toolchain-target'])
+ buildenv = self.new_build_env()
+ self.assertEqual(buildenv.env['TARGET'], self.target)
def test_ccache_vars_set(self):
new_settings = copy.copy(self.settings)
new_settings['no-ccache'] = False
new_settings['no-distcc'] = False
- buildenv = buildenvironment.BuildEnvironment(new_settings)
+ buildenv = self.new_build_env(settings=new_settings)
self.assertTrue(buildenv._ccache_path in buildenv.extra_path)
self.assertEqual(buildenv.env['CCACHE_PREFIX'], 'distcc')
diff --git a/morphlib/cachekeycomputer.py b/morphlib/cachekeycomputer.py
index 15dc5ae9..d9ad5762 100644
--- a/morphlib/cachekeycomputer.py
+++ b/morphlib/cachekeycomputer.py
@@ -27,7 +27,8 @@ class CacheKeyComputer(object):
self._calculated = {}
def _filterenv(self, env):
- keys = ["BOOTSTRAP", "LOGNAME", "PREFIX", "USER", "USERNAME"]
+ keys = ["LOGNAME", "PREFIX", "TARGET", "TARGET_STAGE1",
+ "TARGET_GCC_CONFIG", "USER", "USERNAME"]
return dict([(k, env[k]) for k in keys])
def compute_key(self, artifact):
diff --git a/morphlib/cachekeycomputer_tests.py b/morphlib/cachekeycomputer_tests.py
index cc0b3ab8..1dba80c2 100644
--- a/morphlib/cachekeycomputer_tests.py
+++ b/morphlib/cachekeycomputer_tests.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 Codethink Limited
+# Copyright (C) 2012-2013 Codethink Limited
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -104,13 +104,13 @@ class CacheKeyComputerTests(unittest.TestCase):
elif m['kind'] == 'chunk':
m.builds_artifacts = [m['name']]
self.build_env = DummyBuildEnvironment({
- "USER": "foouser",
- "USERNAME": "foouser",
"LOGNAME": "foouser",
- "TOOLCHAIN_TARGET": "dummy-baserock-linux-gnu",
"PREFIX": "/baserock",
- "BOOTSTRAP": "false",
- "CFLAGS": "-O4"})
+ "TARGET": "dummy-baserock-linux-gnu",
+ "TARGET_STAGE1": "dummy-baserock-linux-gnu",
+ "TARGET_GCC_CONFIG": "",
+ "USER": "foouser",
+ "USERNAME": "foouser"})
self.artifact_resolver = morphlib.artifactresolver.ArtifactResolver()
self.artifacts = self.artifact_resolver.resolve_artifacts(
self.source_pool)
diff --git a/morphlib/util.py b/morphlib/util.py
index 16063f45..c3a7ac9f 100644
--- a/morphlib/util.py
+++ b/morphlib/util.py
@@ -42,6 +42,17 @@ def arch():
'''Return the CPU architecture of the current host.'''
return os.uname()[4]
+
+def target(runcmd): # pragma: no cover
+ '''Returns the machine triplet of the current host'''
+ try:
+ target = runcmd(['cc', '-dumpmachine']).strip()
+ except cliapp.AppException as e:
+ raise morphlib.Error(
+ 'Failed to execute host compiler \'cc\': %s' % e)
+ return target
+
+
def indent(string, spaces=4):
'''Return ``string`` indented by ``spaces`` spaces.