From abb4547eff36dc1891a8037a181aaf2edde113ce Mon Sep 17 00:00:00 2001 From: InsanePrawn Date: Sun, 6 Feb 2022 19:20:24 +0100 Subject: [PATCH] WIP: meson crosscompile support --- chroot.py | 10 +++++++++- constants.py | 3 ++- generator.py | 32 +++++++++++++++++++++++++++++++- packages.py | 31 ++++++++++++++++++++++++++----- 4 files changed, 68 insertions(+), 8 deletions(-) diff --git a/chroot.py b/chroot.py index 9404d7f..3171485 100644 --- a/chroot.py +++ b/chroot.py @@ -12,7 +12,7 @@ from shlex import quote as shell_quote from utils import mount, umount, check_findmnt, log_or_exception from wrapper import enforce_wrap from constants import Arch, GCC_HOSTSPECS, CROSSDIRECT_PKGS, BASE_PACKAGES, CHROOT_PATHS -from generator import generate_makepkg_conf +from generator import generate_makepkg_conf, generate_meson_cross_conf BIND_BUILD_DIRS = 'BINDBUILDDIRS' BASE_CHROOT_PREFIX = 'base_' @@ -545,6 +545,14 @@ class Chroot: with open(self.get_path('etc/pacman.conf'), 'w') as file: file.write(conf_text) + def write_meson_cross_conf(self, target_arch: Arch): + dir_path = self.get_path('/usr/lib/meson/cross') + file_path = os.path.join(dir_path, f'cross_{target_arch}.txt') + os.makedirs(dir_path, exist_ok=True) + conf_text = generate_meson_cross_conf(target_arch) + with open(file_path, 'w') as file: + file.write(conf_text) + @click.command('chroot') @click.argument('type', required=False, default='build') diff --git a/constants.py b/constants.py index fb53e72..88333b2 100644 --- a/constants.py +++ b/constants.py @@ -130,7 +130,8 @@ CFLAGS_ARCHES: dict[Arch, list[str]] = { } QEMU_BINFMT_PKGS = ['qemu-user-static-bin', 'binfmt-qemu-static'] -CROSSDIRECT_PKGS = ['crossdirect'] + QEMU_BINFMT_PKGS +# TODO: split crossdirect and crosscompile +CROSSDIRECT_PKGS = ['crossdirect'] + QEMU_BINFMT_PKGS + ['meson-cross-wrapper'] SSH_DEFAULT_HOST = '172.16.42.1' SSH_DEFAULT_PORT = 22 diff --git a/generator.py b/generator.py index 3de7538..79d912a 100644 --- a/generator.py +++ b/generator.py @@ -176,7 +176,7 @@ SRCEXT='.src.tar.gz' includes = f'-I/usr/{hostspec}/usr/include -I/{chroot}/usr/include' libs = f'-L/usr/{hostspec}/lib -L/{chroot}/usr/lib' conf += f''' - +export CARGO_BUILD_TARGET="{GCC_HOSTSPECS[arch][arch]}" export ARCH="{COMPILE_ARCHES[arch]}" export CROSS_COMPILE="{hostspec}-" export CC="{hostspec}-gcc {includes} {libs}" @@ -187,3 +187,33 @@ export LDFLAGS="$LDFLAGS,-L/usr/{hostspec}/lib,-L/{chroot}/usr/lib,-rpath-link,/ ''' return conf + + +def generate_meson_cross_conf(arch: Arch): + compile_arch = COMPILE_ARCHES[arch] + hostspec = GCC_HOSTSPECS[config.runtime['arch']][arch] + rust_hostspec = GCC_HOSTSPECS[arch][arch] + return f""" +[binaries] +c = '/usr/bin/{hostspec}-gcc' +cpp = '/usr/bin/{hostspec}-g++' +ar = '/usr/bin/{hostspec}-ar' +strip = '/usr/bin/{hostspec}-strip' +objcopy = '/usr/bin/{hostspec}-objcopy' +ld= '/usr/bin/{hostspec}-ld' +rust = ['rustc', '--target', '{rust_hostspec}'] +pkgconfig = ['/usr/bin/pkg-config', '--personality', '{hostspec}'] + +[properties] +#pkg_config_libdir = '/chroot/build_{arch}/lib/pkgconfig' +sys_root = '/chroot/build_{arch}' + +[built-in options] +pkg_config_path = '/chroot/build_{arch}/lib/pkgconfig' + +[host_machine] +system = 'linux' +cpu_family = '{arch}' +cpu = '{compile_arch}' +endian = 'little' +""" diff --git a/packages.py b/packages.py index 7a3a64e..80363b2 100644 --- a/packages.py +++ b/packages.py @@ -42,8 +42,11 @@ def get_makepkg_env(): } -def get_makepkg_cross_env(): - return get_makepkg_env() | {'PACMAN': os.path.join(config.runtime['script_source_dir'], 'local/bin/pacman_aarch64')} +def get_makepkg_cross_env(arch: Arch): + return get_makepkg_env() | { + 'CARGO_BUILD_TARGET': GCC_HOSTSPECS[arch][arch], + #'PACMAN': os.path.join(config.runtime['script_source_dir'], 'local/bin/pacman_aarch64'), + } class Package: @@ -479,19 +482,37 @@ def build_package( logging.info(f'Cross-compiling {package.path}') build_root = native_chroot makepkg_compile_opts += ['--nodeps'] - #env = get_makepkg_cross_env() - env = deepcopy(get_makepkg_env()) + env = deepcopy(get_makepkg_cross_env(arch)) + env |= { + 'KUPFER_CROSS_TARGET': arch, + 'PATH': f"/usr/lib/meson/cross/bin:{env['PATH']}", + } if enable_ccache: env['PATH'] = f"/usr/lib/ccache:{env['PATH']}" logging.info('Setting up dependencies for cross-compilation') + + dependencies = package.depends + if 'rust' in dependencies: + rust_target = GCC_HOSTSPECS[arch][arch] + logging.info(f'installing rustup and {rust_target} target') + native_chroot.run_cmd("\ + (yes | pacman -S rustup) && \ + rustup default stable && \ + rustup target add aarch64-unknown-linux-gnu \ + ") + dependencies.remove('rust') # include crossdirect for ccache symlinks and qemu-user - results = native_chroot.try_install_packages(package.depends + CROSSDIRECT_PKGS + [f"{GCC_HOSTSPECS[native_chroot.arch][arch]}-gcc"]) + crosstoolchain = [(GCC_HOSTSPECS[config.runtime['arch']][arch] + f'-{bin}') for bin in [ + 'gcc', + ]] + results = native_chroot.try_install_packages(dependencies + CROSSDIRECT_PKGS + crosstoolchain) if results['crossdirect'].returncode != 0: raise Exception('Unable to install crossdirect') # mount foreign arch chroot inside native chroot chroot_relative = os.path.join(CHROOT_PATHS['chroots'], target_chroot.name) makepkg_path_absolute = native_chroot.write_makepkg_conf(target_arch=arch, cross_chroot_relative=chroot_relative, cross=True) makepkg_conf_path = os.path.join('etc', os.path.basename(makepkg_path_absolute)) + native_chroot.write_meson_cross_conf(arch) native_chroot.mount_crosscompile(target_chroot) else: logging.info(f'Host-compiling {package.path}')