summaryrefslogtreecommitdiff
path: root/morphlib
diff options
context:
space:
mode:
Diffstat (limited to 'morphlib')
-rw-r--r--morphlib/app.py41
-rw-r--r--morphlib/buildcommand.py22
-rwxr-xr-xmorphlib/exts/sysroot.check30
-rwxr-xr-xmorphlib/exts/sysroot.write4
-rw-r--r--morphlib/stagingarea.py13
-rw-r--r--morphlib/util.py4
6 files changed, 86 insertions, 28 deletions
diff --git a/morphlib/app.py b/morphlib/app.py
index eb0ff3b7..177bce45 100644
--- a/morphlib/app.py
+++ b/morphlib/app.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2014 Codethink Limited
+# Copyright (C) 2011-2015 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
@@ -309,6 +309,11 @@ class Morph(cliapp.Application):
if (submod.url, submod.commit) not in done:
subs_to_process.add((submod.url, submod.commit))
+ def _write_status(self, text):
+ timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
+ self.output.write('%s %s\n' % (timestamp, text))
+ self.output.flush()
+
def status(self, **kwargs):
'''Show user a status update.
@@ -345,9 +350,20 @@ class Morph(cliapp.Application):
ok = verbose or error or (not quiet and not chatty)
if ok:
- timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
- self.output.write('%s %s\n' % (timestamp, text))
- self.output.flush()
+ self._write_status(text)
+
+ def _commandline_as_message(self, argv, args):
+ '''Create a status string for a command that's about to be executed.'''
+
+ commands = []
+ for command in [argv] + list(args):
+ if isinstance(command, list):
+ command_str = ' '.join(map(pipes.quote, command))
+ else:
+ command_str = pipes.quote(command)
+ commands.append(command_str)
+
+ return '# ' + ' | '.join(commands)
def _prepare_for_runcmd(self, argv, args, kwargs):
if 'env' not in kwargs:
@@ -359,18 +375,11 @@ class Morph(cliapp.Application):
else:
print_command = True
- if print_command:
- # Print the command line
- commands = [argv] + list(args)
- for command in commands:
- if isinstance(command, list):
- for i in xrange(0, len(command)):
- command[i] = str(command[i])
- commands = ' '.join(map(pipes.quote, command))
-
- self.status(msg='# %(cmdline)s',
- cmdline=' | '.join(commands),
- chatty=True)
+ if print_command and self.settings['verbose']:
+ # Don't call self.status() here, to avoid writing the message to
+ # the log as well as to the console. The cliapp.runcmd() function
+ # will also log the command, and it's messy having it logged twice.
+ self._write_status(self._commandline_as_message(argv, args))
# Log the environment.
prev = getattr(self, 'prev_env', {})
diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py
index 68fce693..5c7d5c5e 100644
--- a/morphlib/buildcommand.py
+++ b/morphlib/buildcommand.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2014 Codethink Limited
+# Copyright (C) 2011-2015 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
@@ -126,11 +126,21 @@ class BuildCommand(object):
root_arch = root_artifact.source.morphology['arch']
host_arch = morphlib.util.get_host_architecture()
- if root_arch != host_arch:
- raise morphlib.Error(
- 'Are you trying to cross-build? '
- 'Host architecture is %s but target is %s'
- % (host_arch, root_arch))
+
+ if root_arch == host_arch:
+ return
+
+ # Since the armv8 instruction set is nearly entirely armv7 compatible,
+ # and since the incompatibilities are appropriately trapped in the
+ # kernel, we can safely run any armv7 toolchain natively on armv8.
+ if host_arch == 'armv8l' and root_arch in ('armv7l', 'armv7lhf'):
+ return
+ if host_arch == 'armv8b' and root_arch in ('armv7b', 'armv7bhf'):
+ return
+
+ raise morphlib.Error(
+ 'Are you trying to cross-build? Host architecture is %s but '
+ 'target is %s' % (host_arch, root_arch))
@staticmethod
def _validate_has_non_bootstrap_chunks(srcpool):
diff --git a/morphlib/exts/sysroot.check b/morphlib/exts/sysroot.check
new file mode 100755
index 00000000..bfacd3fc
--- /dev/null
+++ b/morphlib/exts/sysroot.check
@@ -0,0 +1,30 @@
+#!/bin/sh
+# Copyright (C) 2015 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Preparatory checks for Morph 'sysroot' write extension
+
+set -eu
+
+location="$1"
+if [ -d "$location" ]; then
+ echo >&2 "ERROR: Deployment directory already exists: $location"
+ exit 1
+fi
+
+if [ "$UPGRADE" == "yes" ]; then
+ echo >&2 "ERROR: Cannot upgrade a sysroot deployment"
+ exit 1
+fi
diff --git a/morphlib/exts/sysroot.write b/morphlib/exts/sysroot.write
index 1ae4864f..be315365 100755
--- a/morphlib/exts/sysroot.write
+++ b/morphlib/exts/sysroot.write
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2014 Codethink Limited
+# Copyright (C) 2014,2015 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
@@ -18,9 +18,7 @@
set -eu
-# Ensure the target is an empty directory
mkdir -p "$2"
-find "$2" -mindepth 1 -delete
# Move the contents of our source directory to our target
# Previously we would (cd "$1" && find -print0 | cpio -0pumd "$absolute_path")
diff --git a/morphlib/stagingarea.py b/morphlib/stagingarea.py
index e7783890..fd3f6881 100644
--- a/morphlib/stagingarea.py
+++ b/morphlib/stagingarea.py
@@ -190,9 +190,10 @@ class StagingArea(object):
shutil.rmtree(self.dirname)
- to_mount = (
+ to_mount_in_staging = (
('dev/shm', 'tmpfs', 'none'),
)
+ to_mount_in_bootstrap = ()
def ccache_dir(self, source): #pragma: no cover
ccache_dir = self._app.settings['compiler-cache-dir']
@@ -266,7 +267,13 @@ class StagingArea(object):
do_not_mount_dirs += [temp_dir]
logging.debug("Not mounting dirs %r" % do_not_mount_dirs)
+ if self.use_chroot:
+ mounts = self.to_mount_in_staging
+ else:
+ mounts = [(os.path.join(self.dirname, target), type, source)
+ for target, type, source in self.to_mount_in_bootstrap]
mount_proc = self.use_chroot
+
if ccache_dir and not self._app.settings['no-ccache']:
ccache_target = os.path.join(
self.dirname, kwargs['env']['CCACHE_DIR'].lstrip('/'))
@@ -277,9 +284,9 @@ class StagingArea(object):
container_config=dict(
cwd=kwargs.pop('cwd', '/'),
root=chroot_dir,
- mounts=self.to_mount,
- binds=binds,
+ mounts=mounts,
mount_proc=mount_proc,
+ binds=binds,
writable_paths=do_not_mount_dirs)
cmdline = morphlib.util.containerised_cmdline(
diff --git a/morphlib/util.py b/morphlib/util.py
index e7a8a50e..63e85b6c 100644
--- a/morphlib/util.py
+++ b/morphlib/util.py
@@ -465,6 +465,10 @@ def get_host_architecture(): # pragma: no cover
'i686': 'x86_32',
'armv7l': 'armv7l',
'armv7b': 'armv7b',
+ 'armv8l': 'armv8l',
+ 'armv8b': 'armv8b',
+ 'aarch64': 'aarch64',
+ 'aarch64b': 'aarch64b',
'ppc64': 'ppc64'
}