mirror of
https://gitlab.com/kupfer/kupferbootstrap.git
synced 2025-06-25 18:08:22 -04:00
chroot: break up into subclasses
This commit is contained in:
parent
13e0de7f03
commit
d13392b2b8
6 changed files with 643 additions and 583 deletions
138
chroot/build.py
Normal file
138
chroot/build.py
Normal file
|
@ -0,0 +1,138 @@
|
|||
import glob
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from config import config
|
||||
from constants import Arch, GCC_HOSTSPECS, CROSSDIRECT_PKGS, CHROOT_PATHS
|
||||
from distro.distro import get_kupfer_local
|
||||
|
||||
from .abstract import Chroot, get_chroot
|
||||
from .helpers import build_chroot_name
|
||||
from .base import get_base_chroot
|
||||
|
||||
|
||||
class BuildChroot(Chroot):
|
||||
|
||||
copy_base: bool = True
|
||||
|
||||
def create_rootfs(self, reset: bool, pacman_conf_target: str, active_previously: bool):
|
||||
if reset or not os.path.exists(self.get_path('usr/bin')):
|
||||
base_chroot = get_base_chroot(self.arch)
|
||||
if base_chroot == self:
|
||||
raise Exception('base_chroot == self, bailing out. this is a bug')
|
||||
base_chroot.initialize()
|
||||
logging.info(f'Copying {base_chroot.name} chroot to {self.name}')
|
||||
result = subprocess.run([
|
||||
'rsync',
|
||||
'-a',
|
||||
'--delete',
|
||||
'-q',
|
||||
'-W',
|
||||
'-x',
|
||||
'--exclude',
|
||||
CHROOT_PATHS['pkgbuilds'].strip('/'),
|
||||
'--exclude',
|
||||
CHROOT_PATHS['packages'].strip('/'),
|
||||
f'{base_chroot.path}/',
|
||||
f'{self.path}/',
|
||||
])
|
||||
if result.returncode != 0:
|
||||
raise Exception(f'Failed to copy {base_chroot.name} to {self.name}')
|
||||
|
||||
else:
|
||||
logging.debug(f'{self.name}: Reusing existing installation')
|
||||
|
||||
if set(get_kupfer_local(self.arch).repos).intersection(set(self.extra_repos)):
|
||||
self.mount_packages()
|
||||
|
||||
self.mount_pacman_cache()
|
||||
self.write_pacman_conf()
|
||||
self.initialized = True
|
||||
self.activate()
|
||||
self.try_install_packages(self.base_packages, refresh=True, allow_fail=False)
|
||||
self.deactivate_core()
|
||||
|
||||
# patch makepkg
|
||||
with open(self.get_path('/usr/bin/makepkg'), 'r') as file:
|
||||
data = file.read()
|
||||
data = data.replace('EUID == 0', 'EUID == -1')
|
||||
with open(self.get_path('/usr/bin/makepkg'), 'w') as file:
|
||||
file.write(data)
|
||||
|
||||
# configure makepkg
|
||||
self.write_makepkg_conf(self.arch, cross_chroot_relative=None, cross=False)
|
||||
|
||||
if active_previously:
|
||||
self.activate()
|
||||
|
||||
def mount_crossdirect(self, native_chroot: Chroot = None, fail_if_mounted: bool = False):
|
||||
"""
|
||||
mount `native_chroot` at `target_chroot`/native
|
||||
returns the absolute path that `native_chroot` has been mounted at.
|
||||
"""
|
||||
target_arch = self.arch
|
||||
if not native_chroot:
|
||||
native_chroot = get_build_chroot(config.runtime['arch'])
|
||||
host_arch = native_chroot.arch
|
||||
hostspec = GCC_HOSTSPECS[host_arch][target_arch]
|
||||
cc = f'{hostspec}-cc'
|
||||
gcc = f'{hostspec}-gcc'
|
||||
|
||||
native_mount = os.path.join(self.path, 'native')
|
||||
logging.debug(f'Activating crossdirect in {native_mount}')
|
||||
native_chroot.initialize()
|
||||
native_chroot.mount_pacman_cache()
|
||||
native_chroot.mount_packages()
|
||||
native_chroot.activate()
|
||||
results = native_chroot.try_install_packages(CROSSDIRECT_PKGS + [gcc], refresh=True, allow_fail=False)
|
||||
if results[gcc].returncode != 0:
|
||||
logging.debug('Failed to install cross-compiler package {gcc}')
|
||||
if results['crossdirect'].returncode != 0:
|
||||
raise Exception('Failed to install crossdirect')
|
||||
|
||||
cc_path = os.path.join(native_chroot.path, 'usr', 'bin', cc)
|
||||
target_lib_dir = os.path.join(self.path, 'lib64')
|
||||
# TODO: crosscompiler weirdness, find proper fix for /include instead of /usr/include
|
||||
target_include_dir = os.path.join(self.path, 'include')
|
||||
|
||||
for target, source in {cc_path: gcc, target_lib_dir: 'lib', target_include_dir: 'usr/include'}.items():
|
||||
if not os.path.exists(target):
|
||||
logging.debug(f'Symlinking {source} at {target}')
|
||||
os.symlink(source, target)
|
||||
ld_so = os.path.basename(glob(f"{os.path.join(native_chroot.path, 'usr', 'lib', 'ld-linux-')}*")[0])
|
||||
ld_so_target = os.path.join(target_lib_dir, ld_so)
|
||||
if not os.path.islink(ld_so_target):
|
||||
os.symlink(os.path.join('/native', 'usr', 'lib', ld_so), ld_so_target)
|
||||
else:
|
||||
logging.debug(f'ld-linux.so symlink already exists, skipping for {self.name}')
|
||||
|
||||
# TODO: find proper fix
|
||||
rustc = os.path.join(native_chroot.path, 'usr/lib/crossdirect', target_arch, 'rustc')
|
||||
if os.path.exists(rustc):
|
||||
logging.debug('Disabling crossdirect rustc')
|
||||
os.unlink(rustc)
|
||||
|
||||
os.makedirs(native_mount, exist_ok=True)
|
||||
logging.debug(f'Mounting {native_chroot.name} to {native_mount}')
|
||||
self.mount(native_chroot.path, 'native', fail_if_mounted=fail_if_mounted)
|
||||
return native_mount
|
||||
|
||||
def mount_crosscompile(self, foreign_chroot: Chroot, fail_if_mounted: bool = False):
|
||||
mount_dest = os.path.join(CHROOT_PATHS['chroots'].lstrip('/'), os.path.basename(foreign_chroot.path))
|
||||
return self.mount(
|
||||
absolute_source=foreign_chroot.path,
|
||||
relative_destination=mount_dest,
|
||||
fail_if_mounted=fail_if_mounted,
|
||||
)
|
||||
|
||||
|
||||
def get_build_chroot(arch: Arch, add_kupfer_repos: bool = True, **kwargs) -> BuildChroot:
|
||||
name = build_chroot_name(arch)
|
||||
if 'extra_repos' in kwargs:
|
||||
raise Exception('extra_repos!')
|
||||
repos = get_kupfer_local(arch).repos if add_kupfer_repos else {}
|
||||
default = BuildChroot(name, arch, initialize=False, copy_base=True, extra_repos=repos)
|
||||
chroot = get_chroot(name, **kwargs, default=default)
|
||||
chroot.extra_repos = repos
|
||||
return chroot
|
Loading…
Add table
Add a link
Reference in a new issue