From 7e4024be9740c68021297d6feb2de33b31d0acf8 Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Wed, 26 Jul 2017 19:01:44 +0000 Subject: [PATCH] Fix #260, fix #87: Don't cross-compile when not necessary (#265) --- pmb/build/autodetect.py | 3 ++- pmb/chroot/init.py | 10 ++++++---- pmb/chroot/shutdown.py | 9 ++++++--- pmb/parse/arch.py | 18 ++++++++++++++++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/pmb/build/autodetect.py b/pmb/build/autodetect.py index 89fc8c98..51e6d1e2 100644 --- a/pmb/build/autodetect.py +++ b/pmb/build/autodetect.py @@ -19,6 +19,7 @@ along with pmbootstrap. If not, see . import fnmatch import pmb.config import pmb.chroot.apk +import pmb.parse.arch def carch(args, apkbuild, carch): @@ -63,7 +64,7 @@ def crosscompile(args, apkbuild, carch, suffix): return None if apkbuild["pkgname"].endswith("-repack"): return None - if carch == args.arch_native: + if not pmb.parse.arch.cpu_emulation_required(args, carch): return None if suffix == "native": return "native" diff --git a/pmb/chroot/init.py b/pmb/chroot/init.py index 20b2f135..a4f8008a 100644 --- a/pmb/chroot/init.py +++ b/pmb/chroot/init.py @@ -45,9 +45,11 @@ def init(args, suffix="native"): # When already initialized: just prepare the chroot chroot = args.work + "/chroot_" + suffix arch = pmb.parse.arch.from_chroot_suffix(args, suffix) + emulate = pmb.parse.arch.cpu_emulation_required(args, arch) + pmb.chroot.mount(args, suffix) if os.path.islink(chroot + "/bin/sh"): - if suffix != "native": + if emulate: pmb.chroot.binfmt.register(args, arch) copy_resolv_conf(args, suffix) pmb.chroot.apk.update_repository_list(args, suffix) @@ -57,7 +59,7 @@ def init(args, suffix="native"): pmb.chroot.apk_static.init(args) # Non-native chroot: require qemu-user-static - if suffix != "native": + if emulate: pmb.chroot.apk.install(args, ["qemu-user-static-repack", "qemu-user-static-repack-binfmt"]) pmb.chroot.binfmt.register(args, arch) @@ -80,7 +82,7 @@ def init(args, suffix="native"): # Install alpine-base (no clean exit for non-native chroot!) pmb.chroot.apk_static.run(args, ["-U", "--root", chroot, "--cache-dir", apk_cache, "--initdb", "--arch", arch, - "add", "alpine-base"], check=(suffix == "native")) + "add", "alpine-base"], check=(not emulate)) # Create device nodes for dev in pmb.config.chroot_device_nodes: @@ -99,7 +101,7 @@ def init(args, suffix="native"): " to an eCryptfs folder.)") # Non-native chroot: install qemu-user-binary, run apk fix - if suffix != "native": + if emulate: arch_debian = pmb.parse.arch.alpine_to_debian(arch) pmb.helpers.run.root(args, ["cp", args.work + "/chroot_native/usr/bin/qemu-" + arch_debian + "-static", diff --git a/pmb/chroot/shutdown.py b/pmb/chroot/shutdown.py index f4a685a5..ad4b8ee0 100644 --- a/pmb/chroot/shutdown.py +++ b/pmb/chroot/shutdown.py @@ -20,10 +20,11 @@ import logging import glob import os -import pmb.install.losetup -import pmb.helpers.mount import pmb.chroot import pmb.chroot.distccd +import pmb.helpers.mount +import pmb.install.losetup +import pmb.parse.arch def shutdown_cryptsetup_device(args, name): @@ -73,5 +74,7 @@ def shutdown(args, only_install_related=False): # Clean up the rest pmb.helpers.mount.umount_all(args, args.work) pmb.helpers.mount.umount_all(args, args.work) - pmb.chroot.binfmt.unregister(args, args.deviceinfo["arch"]) + arch = args.deviceinfo["arch"] + if pmb.parse.arch.cpu_emulation_required(args, arch): + pmb.chroot.binfmt.unregister(args, arch) logging.info("Shutdown complete") diff --git a/pmb/parse/arch.py b/pmb/parse/arch.py index f5bc81fd..be83947e 100644 --- a/pmb/parse/arch.py +++ b/pmb/parse/arch.py @@ -102,3 +102,21 @@ def alpine_to_hostspec(arch): raise ValueError("Can not map Alpine architecture " + arch + " to the right hostspec value") + + +def cpu_emulation_required(args, arch): + # Obvious case: host arch is target arch + if args.arch_native == arch: + return False + + # Other cases: host arch on the left, target archs on the right + not_required = { + "x86_64": ["x86"], + "aarch64": ["armel", "armhf", "armv7"], + } + if args.arch_native in not_required: + if arch in not_required[args.arch_native]: + return False + + # No match: then it's required + return True