#!/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 "openssl" "true" pkg "bison" "true" pkg "cmake" "true" pkg "ninja" "true" } function msg_err { msg=$1 echo -e "$msg" exit 1 } function env_run { command="$1" sudo mount --bind /dev "${MASTERDIR}/dev" sudo mount --make-rslave "${MASTERDIR}/dev" sudo mount --bind /dev/pts "${MASTERDIR}/dev/pts" sudo mount --bind /proc "${MASTERDIR}/proc" sudo mount --bind /sys "${MASTERDIR}/sys" sudo mount --bind /tmp "${MASTERDIR}/tmp" sudo mount --bind "$(pwd)/compiled" "${MASTERDIR}/compiled" unshare --pid -r --fork --user --mount chroot ${MASTERDIR} /bin/bash -c "${command}" sudo umount "${MASTERDIR}/compiled" sudo umount "${MASTERDIR}/tmp" sudo umount "${MASTERDIR}/sys" sudo umount "${MASTERDIR}/proc" sudo umount "${MASTERDIR}/dev/pts" sudo umount "${MASTERDIR}/dev" } function chroot { sudo mount --bind /dev "${MASTERDIR}/dev" sudo mount --make-rslave "${MASTERDIR}/dev" sudo mount --bind /dev/pts "${MASTERDIR}/dev/pts" sudo mount --bind /proc "${MASTERDIR}/proc" sudo mount --bind /sys "${MASTERDIR}/sys" sudo mount --bind /tmp "${MASTERDIR}/tmp" sudo mount --bind "$(pwd)/compiled" "${MASTERDIR}/compiled" unshare --pid -r --fork --user --mount chroot ${MASTERDIR} /bin/bash sudo umount "${MASTERDIR}/compiled" sudo umount "${MASTERDIR}/tmp" sudo umount "${MASTERDIR}/sys" sudo umount "${MASTERDIR}/proc" sudo umount "${MASTERDIR}/dev/pts" sudo 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 cp "stubs/configure" "${MASTERDIR}/build/" env_run "DISTRO_TC=${DISTRO_TC} ./build/configure" cp "stubs/build" "${MASTERDIR}/build/buildstub" env_run "DISTRO_TC=${DISTRO_TC} ./build/buildstub" cp "stubs/install" "${MASTERDIR}/build/install" 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