diff options
-rwxr-xr-x | morphlib/app.py | 18 | ||||
-rw-r--r-- | morphlib/buildcommand.py | 7 | ||||
-rw-r--r-- | morphlib/buildenvironment.py | 22 | ||||
-rw-r--r-- | morphlib/buildenvironment_tests.py | 27 | ||||
-rw-r--r-- | morphlib/cachekeycomputer.py | 3 | ||||
-rw-r--r-- | morphlib/cachekeycomputer_tests.py | 12 | ||||
-rw-r--r-- | morphlib/util.py | 11 |
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. |