commit f9ba5a3cfdc55dd7b0a9d0527b34a21e964177b9 Author: jld3103 Date: Wed Aug 4 18:36:37 2021 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93526df --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +venv/ +__pycache__/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8900047 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM archlinux:base-devel + +RUN pacman -Syu --noconfirm \ + python python-pip \ + devtools rsync \ + aarch64-linux-gnu-gcc aarch64-linux-gnu-binutils aarch64-linux-gnu-glibc aarch64-linux-gnu-linux-api-headers \ + git + +RUN sed -i "s/EUID == 0/EUID == -1/g" $(which makepkg) + +RUN cd /tmp && \ + git clone https://aur.archlinux.org/aarch64-linux-gnu-pkg-config.git && \ + cd aarch64-linux-gnu-pkg-config && \ + makepkg -s --skippgpcheck && \ + pacman -U --noconfirm *.pkg* + +RUN yes | pacman -Scc + +RUN sed -i "s/SigLevel.*/SigLevel = Never/g" /etc/pacman.conf +RUN sed -i "s|run_pacman |run_pacman --root \"/chroot/copy\" --arch aarch64 --config \"/app/src/pacman_copy.conf\" |g" $(which makepkg) +RUN echo "Server = http://mirror.archlinuxarm.org/\$arch/\$repo" > /etc/pacman.d/aarch64_mirrorlist +RUN mkdir -p /app/bin +RUN ln -sf $(which aarch64-linux-gnu-strip) /app/bin/strip + +RUN systemd-machine-id-setup + +ENV KUPFERBOOTSTRAP_DOCKER=1 +WORKDIR /app +ENV PATH=/app/bin:$PATH + +COPY requirements.txt . +RUN pip install -r requirements.txt + +COPY . . + +WORKDIR /src diff --git a/README.md b/README.md new file mode 100644 index 0000000..11f1cc8 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# kupferbootstrap + +## Install +Install Docker and Python 3 and put `bin/` into your `PATH`. +Then use `kupferbootstrap`. + +## Develop +Put `dev` into `version.txt` to always rebuild kupferboostrap from this directory and use `kupferbootstrap` as normal. diff --git a/bin/kupferbootstrap b/bin/kupferbootstrap new file mode 100755 index 0000000..7185350 --- /dev/null +++ b/bin/kupferbootstrap @@ -0,0 +1,4 @@ +#!/bin/bash + +# shellcheck disable=SC2068 +python3 "$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")/wrapper.py" $@ diff --git a/cache.py b/cache.py new file mode 100644 index 0000000..48603fb --- /dev/null +++ b/cache.py @@ -0,0 +1,26 @@ +import shutil +from logger import * +import click +import os + + +@click.group(name='cache') +def cmd_cache(): + pass + + +@click.command(name='clean') +@verbose_option +def cmd_clean(verbose): + setup_logging(verbose) + + for dir in ['/chroot', '/var/cache/pacman/pkg']: + for file in os.listdir(dir): + path = os.path.join(dir, file) + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.unlink(path) + + +cmd_cache.add_command(cmd_clean) diff --git a/logger.py b/logger.py new file mode 100644 index 0000000..fd91f9f --- /dev/null +++ b/logger.py @@ -0,0 +1,23 @@ +import click +import logging +import sys + + +def setup_logging(verbose: bool): + level = logging.INFO + if verbose: + level = logging.DEBUG + logging.basicConfig( + stream=sys.stdout, + format='%(asctime)s %(levelname)s: %(message)s', + datefmt='%m/%d/%Y %H:%M:%S', + level=level + ) + + +verbose_option = click.option( + '-v', + '--verbose', + is_flag=True, + help='Enables verbose logging' +) diff --git a/main.py b/main.py new file mode 100644 index 0000000..62c738b --- /dev/null +++ b/main.py @@ -0,0 +1,12 @@ +from packages import cmd_packages +from cache import cmd_cache +import click + + +@click.group() +def cli(): + pass + + +cli.add_command(cmd_cache) +cli.add_command(cmd_packages) diff --git a/packages.py b/packages.py new file mode 100644 index 0000000..0788d9d --- /dev/null +++ b/packages.py @@ -0,0 +1,431 @@ +from logger import * +import atexit +import click +import logging +import multiprocessing +import os +import shutil +import subprocess + +makepkg_env = os.environ.copy() | { + 'LANG': 'C', + 'MAKEFLAGS': f'-j{multiprocessing.cpu_count()}', +} + +makepkg_cmd = ['makepkg', + '--config', '/app/src/makepkg.conf', + '--noconfirm', + '--ignorearch', + '--needed'] + +pacman_cmd = ['pacman', + '--noconfirm', + '--overwrite=*', + '--needed', ] + + +class Package: + names = [] + depends = [] + local_depends = None + repo = '' + mode = '' + has_pkgver = False + + def __init__(self, path: str) -> None: + self.path = path + self._loadinfo() + + def _loadinfo(self): + result = subprocess.run(makepkg_cmd+['--printsrcinfo'], + cwd=self.path, + stdout=subprocess.PIPE) + lines = result.stdout.decode('utf-8').split('\n') + names = [] + depends = [] + for line in lines: + if line.startswith('pkgbase') or line.startswith('\tpkgname') or line.startswith('\tprovides'): + names.append(line.split(' = ')[1]) + if line.startswith('\tdepends') or line.startswith('\tmakedepends') or line.startswith('\tcheckdepends') or line.startswith('\toptdepends'): + depends.append(line.split(' = ')[1].split('=')[0]) + self.names = list(set(names)) + self.depends = list(set(depends)) + + self.repo = self.path.split('/')[0] + + mode = '' + with open(os.path.join(self.path, 'PKGBUILD'), 'r') as file: + for line in file.read().split('\n'): + if line.startswith('_mode='): + mode = line.split('=')[1] + break + if mode not in ['host', 'cross']: + logging.fatal( + f'Package {self.path} has an invalid mode configured: \'{mode}\'') + exit(1) + self.mode = mode + + has_pkgver = False + with open(os.path.join(self.path, 'PKGBUILD'), 'r') as file: + for line in file.read().split('\n'): + if line.startswith('pkgver()'): + has_pkgver = True + break + self.has_pkgver = has_pkgver + + +def check_prebuilts(): + if not os.path.exists('prebuilts'): + os.makedirs('prebuilts') + for repo in ['main', 'device']: + if not os.path.exists(os.path.join('prebuilts', repo)): + os.makedirs(os.path.join('prebuilts', repo)) + for ext1 in ['db', 'files']: + for ext2 in ['', '.tar.xz']: + if not os.path.exists(os.path.join('prebuilts', repo, f'{repo}.{ext1}{ext2}')): + result = subprocess.run(['tar', + '-czf', + f'{repo}.{ext1}{ext2}', + '-T', '/dev/null'], + cwd=os.path.join('prebuilts', repo)) + if result.returncode != 0: + logging.fatal('Failed create prebuilt repos') + exit(1) + + +def setup_chroot(): + if not os.path.exists('/chroot/root'): + logging.info('Initializing root chroot') + result = subprocess.run(['mkarchroot', + '-s', + '-C', '/app/src/pacman.conf', + '-f', '/etc/locale.gen', + '/chroot/root', + 'base-devel']) + if result.returncode != 0: + logging.fatal('Failed to initialize root chroot') + shutil.rmtree('/chroot/root') + exit(1) + else: + logging.info('Updating root chroot') + result = subprocess.run(pacman_cmd + + ['-Syuu', + '--root', '/chroot/root', + '--arch', 'aarch64', + '--config', '/app/src/pacman.conf']) + if result.returncode != 0: + logging.fatal('Failed to update root chroot') + exit(1) + + shutil.copyfile('/app/src/pacman.conf', '/app/src/pacman_copy.conf') + with open('/app/src/pacman_copy.conf', 'a') as file: + file.write('\n\n[main]\nServer = file:///src/prebuilts/main') + file.write('\n\n[device]\nServer = file:///src/prebuilts/device') + shutil.copyfile('/app/src/pacman_copy.conf', + '/chroot/root/etc/pacman.conf') + shutil.copyfile('/etc/pacman.d/aarch64_mirrorlist', + '/chroot/root/etc/pacman.d/aarch64_mirrorlist') + result = subprocess.run(pacman_cmd + + ['-Sy', + '--root', '/chroot/root', + '--arch', 'aarch64', + '--config', '/chroot/root/etc/pacman.conf']) + if result.returncode != 0: + logging.fatal('Failed to update root chroot') + exit(1) + + with open('/chroot/root/usr/bin/makepkg', 'r') as file: + data = file.read() + data = data.replace('EUID == 0', 'EUID == -1') + with open('/chroot/root/usr/bin/makepkg', 'w') as file: + file.write(data) + + with open('/chroot/root/etc/makepkg.conf', 'r') as file: + data = file.read() + data = data.replace('xz -c', 'xz -T0 -c') + data = data.replace(' check ', ' !check ') + with open('/chroot/root/etc/makepkg.conf', 'w') as file: + file.write(data) + + logging.info('Syncing chroot copy') + result = subprocess.run( + ['rsync', '-a', '--delete', '-q', '-W', '-x', '/chroot/root/', '/chroot/copy']) + if result.returncode != 0: + logging.fatal('Failed to sync chroot copy') + exit(1) + + +def discover_packages() -> list[Package]: + packages = [] + paths = [] + + for dir in os.listdir('main'): + paths.append(os.path.join('main', dir)) + for dir1 in os.listdir('device'): + for dir2 in os.listdir(os.path.join('device', dir1)): + paths.append(os.path.join('device', dir1, dir2)) + + for path in paths: + logging.debug(f'Discovered {path}') + packages.append(Package(path)) + + # This filters the deps to only include the ones that are provided in this repo + for package in packages: + package.local_depends = package.depends.copy() + for dep in package.depends.copy(): + found = False + for p in packages: + for name in p.names: + if dep == name: + found = True + break + if found: + break + if not found: + package.local_depends.remove(dep) + + return packages + + +def generate_package_order(packages: list[Package]) -> list[Package]: + unsorted = packages.copy() + sorted = [] + + """ + It goes through all unsorted packages and checks if the dependencies have already been sorted. + If that is true, the package itself is added to the sorted packages + """ + while len(unsorted) > 0: + for package in unsorted.copy(): + if len(package.local_depends) == 0: + sorted.append(package) + unsorted.remove(package) + for package in sorted: + for name in package.names: + for p in unsorted: + for dep in p.local_depends.copy(): + if name == dep: + p.local_depends.remove(name) + + return sorted + + +def update_package_version_and_sources(package: Package): + """ + This updates the package version and the sources. + It is done here already, because doing it while host-compiling takes longer. + We decided to even pin the commit of every -git package so this won't update any version, but it would if possible. + """ + cmd = makepkg_cmd+['--nobuild', '--noprepare', '--nodeps', '--skipinteg'] + if not package.has_pkgver: + cmd.append('--noextract') + logging.info(f'Updating package version for {package.path}') + result = subprocess.run(cmd, + env=makepkg_env, + cwd=package.path) + if result.returncode != 0: + logging.fatal(f'Failed to update package version for {package.path}') + exit(1) + + +def check_package_version_built(package: Package) -> bool: + built = True + + result = subprocess.run(makepkg_cmd + + ['--nobuild', + '--noprepare', + '--packagelist'], + env=makepkg_env, + cwd=package.path, + capture_output=True) + if result.returncode != 0: + logging.fatal(f'Failed to get package list for {package.path}') + exit(1) + + for line in result.stdout.decode('utf-8').split('\n'): + if line != "": + file = os.path.basename(line) + if not os.path.exists(os.path.join('prebuilts', package.repo, file)): + built = False + + return built + + +def setup_dependencies_and_sources(package: Package): + logging.info(f'Setting up dependencies and sources for {package.path}') + + """ + To make cross-compilation work for almost every package, the host needs to have the dependencies installed + so that the build tools can be used + """ + if package.mode == 'cross': + for p in package.depends: + subprocess.run(pacman_cmd + ['-Sw', p], + stderr=subprocess.DEVNULL) + + result = subprocess.run(makepkg_cmd + + ['--nobuild', + '--skipinteg', + '--holdver', + '--syncdeps'], + env=makepkg_env, + cwd=package.path) + if result.returncode != 0: + logging.fatal( + f'Failed to setup dependencies and sources for {package.path}') + exit(1) + + +def build_package(package: Package): + makepkg_compile_opts = ['--noextract', + '--skipinteg', + '--holdver', + '--nodeps'] + + if package.mode == 'cross': + logging.info(f'Cross-compiling {package.path}') + result = subprocess.run(makepkg_cmd+makepkg_compile_opts, + env=makepkg_env | { + 'QEMU_LD_PREFIX': '/usr/aarch64-linux-gnu'}, + cwd=package.path) + if result.returncode != 0: + logging.fatal( + f'Failed to cross-compile package {package.path}') + exit(1) + else: + logging.info(f'Host-compiling {package.path}') + + def umount(): + subprocess.run(['umount', '-lc', '/chroot/copy'], + stderr=subprocess.DEVNULL) + atexit.register(umount) + + result = subprocess.run( + ['mount', '-o', 'bind', '/chroot/copy', '/chroot/copy']) + if result.returncode != 0: + logging.fatal('Failed to bind mount chroot to itself') + exit(1) + + os.makedirs('/chroot/copy/src') + result = subprocess.run( + ['mount', '-o', 'bind', '.', '/chroot/copy/src']) + if result.returncode != 0: + logging.fatal( + f'Failed to bind mount folder to chroot') + exit(1) + + env = [] + for key in makepkg_env: + env.append(f'{key}={makepkg_env[key]}') + result = subprocess.run( + ['arch-chroot', '/chroot/copy', '/bin/bash', '-c', f'cd /src/{package.path} && {" ".join(env)} makepkg --noconfirm --ignorearch {" ".join(makepkg_compile_opts)}']) + if result.returncode != 0: + logging.fatal(f'Failed to host-compile package {package.path}') + exit(1) + + umount() + + +def add_package_to_repo(package: Package): + logging.info(f'Adding {package.path} to repo') + dir = os.path.join('prebuilts', package.repo) + if not os.path.exists(dir): + os.mkdir(dir) + + for file in os.listdir(package.path): + # Forced extension by makepkg.conf + if file.endswith('.pkg.tar.xz'): + shutil.move( + os.path.join(package.path, file), + os.path.join(dir, file), + ) + result = subprocess.run(['repo-add', + '--remove', + '--new', + '--prevent-downgrade', + os.path.join( + 'prebuilts', + package.repo, + f'{package.repo}.db.tar.xz', + ), + os.path.join(dir, file), + ]) + if result.returncode != 0: + logging.fatal(f'Failed add package {package.path} to repo') + exit(1) + for repo in ['main', 'device']: + for ext in ['db', 'files']: + if os.path.exists(os.path.join('prebuilts', repo, f'{repo}.{ext}.tar.xz')): + os.unlink(os.path.join('prebuilts', repo, f'{repo}.{ext}')) + shutil.copyfile( + os.path.join('prebuilts', repo, f'{repo}.{ext}.tar.xz'), + os.path.join('prebuilts', repo, f'{repo}.{ext}') + ) + if os.path.exists(os.path.join('prebuilts', repo, f'{repo}.{ext}.tar.xz.old')): + os.unlink(os.path.join('prebuilts', repo, + f'{repo}.{ext}.tar.xz.old')) + + +@click.group(name='packages') +def cmd_packages(): + pass + + +@click.command(name='build') +@verbose_option +@click.argument('path') +def cmd_build(verbose, path): + setup_logging(verbose) + + check_prebuilts() + + if path == 'all': + packages = generate_package_order(discover_packages()) + need_build = [] + + for package in packages: + update_package_version_and_sources(package) + if not check_package_version_built(package): + need_build.append(package) + + if len(need_build) == 0: + logging.info('Everything built already') + return + logging.info('Building %s', ', '.join( + map(lambda x: x.path, need_build))) + with open('.last_built', 'w') as file: + file.write('\n'.join( + map(lambda x: x.path, need_build))) + + for package in need_build: + setup_chroot() + setup_dependencies_and_sources(package) + build_package(package) + add_package_to_repo(package) + else: + package = Package(path) + update_package_version_and_sources(package) + if not check_package_version_built(package): + with open('.last_built', 'w') as file: + file.write(package.path) + setup_chroot() + setup_dependencies_and_sources(package) + build_package(package) + add_package_to_repo(package) + + +@click.command(name='clean') +@verbose_option +def cmd_clean(verbose): + setup_logging(verbose) + result = subprocess.run(['git', + 'clean', + '-dffX', + 'main', 'device']) + if result.returncode != 0: + logging.fatal(f'Failed to git clean') + exit(1) + + +cmd_packages.add_command(cmd_build) +cmd_packages.add_command(cmd_clean) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..70f45e4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +click==8.0.1 +appdirs==1.4.4 diff --git a/src/makepkg.conf b/src/makepkg.conf new file mode 100644 index 0000000..81d4f47 --- /dev/null +++ b/src/makepkg.conf @@ -0,0 +1,169 @@ +#!/hint/bash +# +# /etc/makepkg.conf +# + +######################################################################### +# SOURCE ACQUISITION +######################################################################### +# +#-- The download utilities that makepkg should use to acquire sources +# Format: 'protocol::agent' +DLAGENTS=('file::/usr/bin/curl -gqC - -o %o %u' + 'ftp::/usr/bin/curl -gqfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u' + 'http::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' + 'https::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' + 'rsync::/usr/bin/rsync --no-motd -z %u %o' + 'scp::/usr/bin/scp -C %u %o') + +# Other common tools: +# /usr/bin/snarf +# /usr/bin/lftpget -c +# /usr/bin/wget + +#-- The package required by makepkg to download VCS sources +# Format: 'protocol::package' +VCSCLIENTS=('bzr::bzr' + 'fossil::fossil' + 'git::git' + 'hg::mercurial' + 'svn::subversion') + +######################################################################### +# ARCHITECTURE, COMPILE FLAGS +######################################################################### +# +CARCH="aarch64" +CHOST="aarch64-unknown-linux-gnu" + +#-- Compiler and Linker Flags +# -march (or -mcpu) builds exclusively for an architecture +# -mtune optimizes for an architecture, but builds for whole processor family +CPPFLAGS="" +CFLAGS="-march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -fexceptions \ + -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \ + -fstack-clash-protection" +CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS" +LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now" +#RUSTFLAGS="-C opt-level=2" +#-- Make Flags: change this for DistCC/SMP systems +#MAKEFLAGS="-j2" +#-- Debugging flags +DEBUG_CFLAGS="-g -fvar-tracking-assignments" +DEBUG_CXXFLAGS="-g -fvar-tracking-assignments" +#DEBUG_RUSTFLAGS="-C debuginfo=2" + +######################################################################### +# BUILD ENVIRONMENT +######################################################################### +# +# Makepkg defaults: BUILDENV=(!distcc !color !ccache !check !sign) +# A negated environment option will do the opposite of the comments below. +# +#-- distcc: Use the Distributed C/C++/ObjC compiler +#-- color: Colorize output messages +#-- ccache: Use ccache to cache compilation +#-- check: Run the check() function if present in the PKGBUILD +#-- sign: Generate PGP signature file +# +BUILDENV=(!distcc color !ccache !check !sign) +# +#-- If using DistCC, your MAKEFLAGS will also need modification. In addition, +#-- specify a space-delimited list of hosts running in the DistCC cluster. +#DISTCC_HOSTS="" +# +#-- Specify a directory for package building. +#BUILDDIR=/tmp/makepkg + +######################################################################### +# GLOBAL PACKAGE OPTIONS +# These are default values for the options=() settings +######################################################################### +# +# Makepkg defaults: OPTIONS=(!strip docs libtool staticlibs emptydirs !zipman !purge !debug !lto) +# A negated option will do the opposite of the comments below. +# +#-- strip: Strip symbols from binaries/libraries +#-- docs: Save doc directories specified by DOC_DIRS +#-- libtool: Leave libtool (.la) files in packages +#-- staticlibs: Leave static library (.a) files in packages +#-- emptydirs: Leave empty directories in packages +#-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip +#-- purge: Remove files specified by PURGE_TARGETS +#-- debug: Add debugging flags as specified in DEBUG_* variables +#-- lto: Add compile flags for building with link time optimization +# +OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !debug !lto) + +#-- File integrity checks to use. Valid: md5, sha1, sha224, sha256, sha384, sha512, b2 +INTEGRITY_CHECK=(sha256) +#-- Options to be used when stripping binaries. See `man strip' for details. +STRIP_BINARIES="--strip-all" +#-- Options to be used when stripping shared libraries. See `man strip' for details. +STRIP_SHARED="--strip-unneeded" +#-- Options to be used when stripping static libraries. See `man strip' for details. +STRIP_STATIC="--strip-debug" +#-- Manual (man and info) directories to compress (if zipman is specified) +MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info}) +#-- Doc directories to remove (if !docs is specified) +DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc}) +#-- Files to be removed from all packages (if purge is specified) +PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod) +#-- Directory to store source code in for debug packages +DBGSRCDIR="/usr/src/debug" + +######################################################################### +# PACKAGE OUTPUT +######################################################################### +# +# Default: put built package and cached source in build directory +# +#-- Destination: specify a fixed directory where all packages will be placed +#PKGDEST=/home/packages +#-- Source cache: specify a fixed directory where source files will be cached +#SRCDEST=/home/sources +#-- Source packages: specify a fixed directory where all src packages will be placed +#SRCPKGDEST=/home/srcpackages +#-- Log files: specify a fixed directory where all log files will be placed +#LOGDEST=/home/makepkglogs +#-- Packager: name/email of the person or organization building packages +#PACKAGER="John Doe " +#-- Specify a key to use for package signing +#GPGKEY="" + +######################################################################### +# COMPRESSION DEFAULTS +######################################################################### +# +COMPRESSGZ=(gzip -c -f -n) +COMPRESSBZ2=(bzip2 -c -f) +COMPRESSXZ=(xz -T0 -c -z -) +COMPRESSZST=(zstd -c -z -q -) +COMPRESSLRZ=(lrzip -q) +COMPRESSLZO=(lzop -q) +COMPRESSZ=(compress -c -f) +COMPRESSLZ4=(lz4 -q) +COMPRESSLZ=(lzip -c -f) + +######################################################################### +# EXTENSION DEFAULTS +######################################################################### +# +PKGEXT='.pkg.tar.xz' +SRCEXT='.src.tar.gz' + +######################################################################### +# OTHER +######################################################################### +# +#-- Command used to run pacman as root, instead of trying sudo and su +#PACMAN_AUTH=() + +export CROOT="/usr/aarch64-linux-gnu" +export ARCH="arm64" +export CROSS_COMPILE="aarch64-linux-gnu-" +export CC="aarch64-linux-gnu-gcc -I${CROOT}/usr/include -I/chroot/copy/usr/include -L${CROOT}/lib -L/chroot/copy/usr/lib" +export CXX="aarch64-linux-gnu-g++ -I${CROOT}/usr/include -I/chroot/copy/usr/include -L${CROOT}/lib -L/chroot/copy/usr/lib" +export CFLAGS="$CFLAGS -I${CROOT}/usr/include -I/chroot/copy/usr/include" +export CXXFLAGS="$CXXFLAGS -I${CROOT}/usr/include -I/chroot/copy/usr/include" +export LDFLAGS="$LDFLAGS,-L${CROOT}/lib,-L/chroot/copy/usr/lib,-rpath-link,${CROOT}/lib,-rpath-link,/chroot/copy/usr/lib" diff --git a/src/pacman.conf b/src/pacman.conf new file mode 100644 index 0000000..b9843aa --- /dev/null +++ b/src/pacman.conf @@ -0,0 +1,91 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = aarch64 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#NoProgressBar +#CheckSpace +#VerbosePkgLists +ParallelDownloads = 8 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Never +LocalFileSigLevel = Never +#RemoteFileSigLevel = Never + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux ARM +# packagers with `pacman-key --populate archlinuxarm`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core] +Include = /etc/pacman.d/aarch64_mirrorlist + +[extra] +Include = /etc/pacman.d/aarch64_mirrorlist + +[community] +Include = /etc/pacman.d/aarch64_mirrorlist + +[alarm] +Include = /etc/pacman.d/aarch64_mirrorlist + +[aur] +Include = /etc/pacman.d/aarch64_mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Never +#Server = file:///home/custompkgs diff --git a/src/update-pacman-files.sh b/src/update-pacman-files.sh new file mode 100755 index 0000000..c499ce3 --- /dev/null +++ b/src/update-pacman-files.sh @@ -0,0 +1,31 @@ +#!/bin/sh +set -e + +wget https://raw.githubusercontent.com/archlinuxarm/PKGBUILDs/master/core/pacman/makepkg.conf -O makepkg.conf +sed -i "s/@CARCH@/aarch64/g" makepkg.conf +sed -i "s/@CHOST@/aarch64-unknown-linux-gnu/g" makepkg.conf +sed -i "s/@CARCHFLAGS@/-march=armv8-a /g" makepkg.conf +sed -i "s/xz /xz -T0 /g" makepkg.conf +sed -i "s/ check / !check /g" makepkg.conf +chroot="/chroot/copy" +include="-I\${CROOT}/usr/include -I$chroot/usr/include" +lib_croot="\${CROOT}/lib" +lib_chroot="$chroot/usr/lib" +cat >>makepkg.conf <