#!/bin/bash ## This project is heavily influenced by xbps, which I just really like as ## a package manager. So if you are seeing similar patterns, they are very ## similar. #set -e MIRROR_GNU_FTP="https://ftp.gnu.org/gnu" if [ -z "${CACHE}" ] then CACHE="$(pwd)/cache/" fi mkdir -p "${CACHE}" if [ -z "${MASTERDIR}" ] then MASTERDIR="$(pwd)/env" fi if [ -z "${DISTRO_TC}" ] then DISTRO_TC="x86_64-x221e-linux-gnu" fi PY_ROOT="/usr/lib/python3.14/site-packages/" COMPILED_DIR="$(pwd)/compiled" function usage { echo -e "You must supply a valid argument!" echo -e "Available arguments: " echo -e " pkg - installs and provides the specified package." } if [ $# -eq 0 ] then usage exit 1 fi ## Commands ## --------- ## ibps-src bootstrap-rootfs ## ibps-src pkg ## function bootstrap-rootfs { pkg "perl" "true" pkg "libxcrypt" "true" pkg "openssl3" "true" pkg "python" "true" pkg "pip" "true" pkg "bison" "true" pkg "libidn2" "true" pkg "cmake" "true" pkg "ninja" "true" pkg "meson" "true" pkg "gmp" "true" pkg "mpc" "true" pkg "mpfr" "true" pkg "gcc" "true" } function msg_err { msg=$1 echo -e "$msg" exit 1 } function env_run { command="$1" doas mount --bind /dev "${MASTERDIR}/dev" doas mount --make-rslave "${MASTERDIR}/dev" doas mount --bind /dev/pts "${MASTERDIR}/dev/pts" doas mount --bind /proc "${MASTERDIR}/proc" doas mount --bind /sys "${MASTERDIR}/sys" doas mount --bind /tmp "${MASTERDIR}/tmp" doas mount --bind "$(pwd)/compiled" "${MASTERDIR}/compiled" unshare --pid -r --fork --user --mount chroot ${MASTERDIR} /bin/bash -c "${command}" doas umount "${MASTERDIR}/compiled" doas umount "${MASTERDIR}/tmp" doas umount "${MASTERDIR}/sys" doas umount "${MASTERDIR}/proc" doas umount "${MASTERDIR}/dev/pts" doas umount "${MASTERDIR}/dev" } function chroot { doas mount --bind /dev "${MASTERDIR}/dev" doas mount --make-rslave "${MASTERDIR}/dev" doas mount --bind /dev/pts "${MASTERDIR}/dev/pts" doas mount --bind /proc "${MASTERDIR}/proc" doas mount --bind /sys "${MASTERDIR}/sys" doas mount --bind /tmp "${MASTERDIR}/tmp" doas mount --bind "$(pwd)/compiled" "${MASTERDIR}/compiled" unshare --pid -r --fork --user --mount chroot ${MASTERDIR} /bin/bash doas umount "${MASTERDIR}/compiled" doas umount "${MASTERDIR}/tmp" doas umount "${MASTERDIR}/sys" doas umount "${MASTERDIR}/proc" doas umount "${MASTERDIR}/dev/pts" doas umount "${MASTERDIR}/dev" } function download_if_uncached { pkgname="$1" version="$2" upstream="$3" if [[ ! -e "${CACHE}/upstream/${pkgname}-${version}.tar" || ! -f "${CACHE}/upstream/${pkgname}-${version}.tar" ]] then mkdir -p "${CACHE}/upstream" curl --output-dir="${CACHE}/upstream" -L -o "${pkgname}-${version}.tar" $upstream fi } function extract_archive { currdir=$(pwd) cd "${MASTERDIR}/build/" tar -xf "${MASTERDIR}/build/${pkgname}-${version}.tar" cd "${currdir}" } function package_app { pkgname="$1" version="$2" build_no="$3" pkgdir="${pkgname}-${version}-${build_no}" if [ ! -e "${COMPILED_DIR}/${pkgdir}" ] then echo -e "error: cannot package '${pkgdir}', is not located under "${COMPILED_DIR}". Build problem?" exit 1 fi for i in $(find "${COMPILED_DIR}/${pkgdir}" -type f); do echo $(ldd "$i" 2>/dev/null) done echo "name=${pkgname}" > "${COMPILED_DIR}/${pkgdir}/.desc" echo "description=${description}" >> "${COMPILED_DIR}/${pkgdir}/.desc" echo "version=${version}" >> "${COMPILED_DIR}/${pkgdir}/.desc" echo "build_no=${build_no}" >> "${COMPILED_DIR}/${pkgdir}/.desc" echo "depends=${depends[@]}" >> "${COMPILED_DIR}/${pkgdir}/.desc" if [ -e "./templates/${pkgname}/hooks" ] && [ -f "./templates/${pkgname}/hooks" ]; then echo $(cat "./templates/${pkgname}/hooks") >> "${COMPILED_DIR}/${pkgdir}/.desc" fi currdir="$(pwd)" cd "${COMPILED_DIR}" tar --zstd -cf "${pkgdir}.ibps" "${pkgdir}" cd "${currdir}" mv "$(pwd)/compiled/${pkgdir}.ibps" "$(pwd)/ready/" } function apply_patches { cp -r "./templates/${pkgname}/patches" "${MASTERDIR}/build/" if [[ -e "./templates/${pkgname}/patches" && -d "./templates/${pkgname}/patches" ]] then currdir="$(pwd)" if [ -n "${cddir}" ] then cd "${cddir}" else cd "${MASTERDIR}/build/${pkgname}-${version}" fi for i in $(ls ../patches); do patch -p1 < "../patches/$i" done cd "${currdir}" fi } function pkg { local pkg="$1" local install_sys="$2" if [ -z "$pkg" ] then msg_err "You must specify a package name!" fi echo -e "Searching for '$pkg' in local repository." template_loc="./templates/$pkg/template" if [ ! -e "$template_loc" ] then msg_err "Template does not exist!" fi local makedepends pkgname version build_no cddir upstream extract depends extras source "${template_loc}" echo -e "Found '$pkgname' with version '$version'." if [[ bootstrap_only == "true" && install_sys == "false" ]]; then echo -e "This package is only meant to be bootstrapped!" exit 1 fi if [ ${#makedepends[@]} -gt 0 ] then for i in "${makedepends[@]}"; do pkg_exists=$(grep "^${i}=" "${MASTERDIR}/packages") if [ -z "${pkg_exists}" ] then echo -e "Error on: ${i}" echo "Please first install the dependencies of '${pkgname}': ${makedepends[@]}" exit 1 fi done echo "All requirements appear satisfied" fi download_if_uncached "${pkgname}" "${version}" "${upstream}" mkdir -p "${MASTERDIR}/build/" for extra in ${extras[@]}; do curl -OL "$extra" --output-dir="${MASTERDIR}/build/" echo -e "Downloaded ${extra}" done cp "${CACHE}/upstream/${pkgname}-${version}.tar" "${MASTERDIR}/build/" if [[ -z "${extract}" || "${extract}" == "true" ]] then extract_archive else mkdir -p "${MASTERDIR}/build/${pkgname}-${version}" fi cp "${template_loc}" "${MASTERDIR}/build/template" apply_patches if [[ "$(type -t 'do_configure')" == "function" ]]; then cp "stubs/configure" "${MASTERDIR}/build/" env_run "DISTRO_TC=${DISTRO_TC} ./build/configure" fi if [[ "$(type -t 'do_build')" == "function" ]]; then cp "stubs/build" "${MASTERDIR}/build/buildstub" env_run "DISTRO_TC=${DISTRO_TC} ./build/buildstub" fi if [[ "$(type -t 'do_install')" == "function" ]]; then cp "stubs/install" "${MASTERDIR}/build/install" fi if [[ "${install_sys}" == "true" ]] then env_run "DISTRO_TC=${DISTRO_TC} DESTDIR=/ PY_SITE_PACKAGES=${PY_ROOT} ./build/install" echo "${pkgname}=${version}" >> "${MASTERDIR}/packages" else env_run "DISTRO_TC=${DISTRO_TC} PY_SITE_PACKAGES=${PY_ROOT} ./build/install" package_app "${pkgname}" "${version}" "${build_no}" fi rm -rf "${MASTERDIR}/build" } function pkg_all { all_templates=$(ls templates/) for tmpl in $all_templates[@]; do pkg "${tmpl}" done } case "$1" in "bootstrap-rootfs" ) bootstrap-rootfs ;; "pkg" ) pkg "$2" ;; "chroot") chroot ;; "install" ) pkg "$2" "true" ;; "pkg-all" ) pkg_all ;; * ) echo -e "Command '$1' not found!" && usage && exit 1 ;; esac