1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972 |
- #! /bin/sh
- # Copyright (C) 2022-2024 mintsuki
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are met:
- # 1. Redistributions of source code must retain the above copyright notice,
- # this list of conditions and the following disclaimer.
- # 2. Redistributions in binary form must reproduce the above copyright notice,
- # this list of conditions and the following disclaimer in the documentation
- # and/or other materials provided with the distribution.
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- # POSSIBILITY OF SUCH DAMAGE.
- set -e
- IFS=" "" "'
- '
- LC_COLLATE=C
- export LC_COLLATE
- umask 0022
- jinx_major_ver="0.4"
- jinx_minor_ver="7"
- jinx_version="${jinx_major_ver}.${jinx_minor_ver}"
- die() {
- echo "$1"
- exit 1
- }
- case "$1" in
- version|--version)
- echo "Jinx version $jinx_version"
- exit 0
- ;;
- esac
- if ! [ "$(uname -s)" = "Linux" ]; then
- die "$0: Jinx only supports running on Linux hosts."
- fi
- if [ "$(id -u)" = "0" ]; then
- die "$0: Jinx does not support running as root."
- fi
- debian_snapshot="20241203T084120Z"
- case "$(uname -m)" in
- x86_64)
- debian_architecture=amd64
- debian_rootfs_b2sum=9e5ca2b7d987c3ac1d463a20fc57fe3bca0189663118d0dd97869dff9e4eb94935f55ede26cba3df89be16cce17a7bc1dbe78f3f0ad646833a323bfc7ca29e82
- ;;
- aarch64)
- debian_architecture=arm64
- debian_rootfs_b2sum=196ed3de6038b3b0d71d2edff1949a0fc21ee63f9e302453f3b8df13971fb7e544d728f3b6fd033495669b8a23a9f5141e31d2b74a9e919b3f2d840998cae4c2
- ;;
- arm*)
- debian_architecture=armhf
- debian_rootfs_b2sum=14248e197538f3c26ef08d48c0827dcd5dfe0ddb6964fd2766095302ef8f3742f9bd280ec775bc9ffeb985085ba1691275e84c482e26a8c4119dc03acd3b9504
- ;;
- i?86)
- debian_architecture=i386
- debian_rootfs_b2sum=c55b07876f97530a9315f18b62632b89e5839bcb2eb5d4b75b047ce5a392c6a5aec9b24e38e06b994a6a45c8476dad48b8fedbe6576534c1816eb8f329d46cb9
- ;;
- mips64el)
- debian_architecture=mips64el
- debian_rootfs_b2sum=2bf08471d53eeec532cdbe2b0dc0f8d6fc020f8b12a2fe8b0c4f26733525ec1b47be605e8d9e906aa91e22be7cfe68285877130fd51c207efce81833977d74df
- ;;
- ppc64le)
- debian_architecture=ppc64el
- debian_rootfs_b2sum=57028eedb1edaa27497ed4e607ac814256569c31472fb32c37bdc8fc09100471ebda6abbd6d7b3d670ab1d4f23a3dd67c9a9bf0c8f3a5b841920d871699406f4
- ;;
- riscv64)
- debian_architecture=riscv64
- debian_rootfs_b2sum=5efb44776a3fae5f14cfdb711b0408b4b0842172dc67ce524a77545467bf163dea07c2017c0a823f3585f36a0ee28b52ec7f4490ed620017ee6e8c33cea722d0
- ;;
- s390x)
- debian_architecture=s390x
- debian_rootfs_b2sum=776f818f15ca2c506d8a553eb036d7bfea33fe6c74f9134198e0b37e38b3a0eefdf9b8a9862d41dd0baddde610ebd7b626e2019c9359b8c4b43326339382fcf0
- ;;
- *)
- die "$0: Unsupported architecture: $(uname -m)"
- ;;
- esac
- XSTOW_VERSION=1.1.1
- make_dir() {
- for d in "$@"; do
- mkdir -p "$d"
- dn="$(cd "$d" && pwd -P)"
- while true; do
- if [ "$dn" = "$base_dir" ] || [ "$dn" = "$build_dir" ] || [ "$dn" = "/" ]; then
- break
- fi
- chmod 755 "$dn"
- dn="$(dirname "$dn")"
- done
- done
- }
- if [ -z "$JINX_PARALLELISM" ]; then
- max_threads_by_mem="$(( ((($(free | awk '/^Mem:/{print $2}') + 1048575) / 1048576) + 1) / 2 ))"
- parallelism="$(nproc 2>/dev/null || echo 1)"
- parallelism="$(( $parallelism < $max_threads_by_mem ? $parallelism : $max_threads_by_mem ))"
- else
- parallelism="$JINX_PARALLELISM"
- fi
- build_dir="$(pwd -P)"
- if [ -z "$JINX_SOURCE_DIR" ]; then
- base_dir="$build_dir"
- else
- base_dir="$(cd "$JINX_SOURCE_DIR" && pwd -P)"
- fi
- script_name="$(basename "$0")"
- script_dir="$(dirname "$0")"
- if [ "$script_dir" = "." ] || [ -z "$script_dir" ]; then
- if echo "$0" | grep "/" >/dev/null 2>&1; then
- script_dir=.
- else
- script_dir="$(dirname $(which "${script_name}"))"
- fi
- fi
- script_dir="$(cd "${script_dir}" && pwd -P)"
- script="${script_dir}/${script_name}"
- if [ -z "$JINX_CONFIG_FILE" ]; then
- JINX_CONFIG_FILE="${base_dir}/jinx-config"
- fi
- if ! [ -d "$(dirname "$JINX_CONFIG_FILE")" ]; then
- die "$0: cannot access config file directory"
- fi
- JINX_CONFIG_FILE="$(cd "$(dirname "$JINX_CONFIG_FILE")" && pwd -P)"/"$(basename "$JINX_CONFIG_FILE")"
- if [ -z "$JINX_CACHE_DIR" ]; then
- JINX_CACHE_DIR="${build_dir}/.jinx-cache"
- fi
- if ! [ -d "$(dirname "$JINX_CACHE_DIR")" ]; then
- die "$0: cannot access cache directory parent"
- fi
- make_dir "$JINX_CACHE_DIR"
- JINX_CACHE_DIR="$(cd "$JINX_CACHE_DIR" && pwd -P)"
- in_container=false
- if [ "$script" = "//jinx" ]; then
- in_container=true
- fi
- if [ "$in_container" = "false" ]; then
- make_dir "${base_dir}/sources" "${build_dir}/host-builds" "${build_dir}/host-pkgs" "${build_dir}/builds" "${build_dir}/pkgs"
- fi
- apt_cache="$JINX_CACHE_DIR/apt-cache"
- temp_collect=""
- trap 'eval rm -rf "$temp_collect"' EXIT
- make_temp() {
- tmp="$(mktemp "$JINX_CACHE_DIR/tmp.XXXXXXXX")"
- temp_collect="${temp_collect} \"${tmp}\""
- if [ "$1" = "-d" ]; then
- rm -f "${tmp}"
- make_dir "${tmp}"
- fi
- }
- build_hostdeps() {
- for hostdep in ${hostdeps} ${hostrundeps}; do
- [ -f "${base_dir}"/host-recipes/${hostdep} ] || die "missing host dependency '${hostdep}' for recipe '${name}'"
- [ -d "${build_dir}"/host-pkgs/${hostdep} ] && continue
- "${script}" host-build ${hostdep}
- done
- }
- build_deps() {
- for dep in ${deps} ${builddeps}; do
- [ -f "${base_dir}"/recipes/${dep} ] || die "missing dependency '${dep}' for recipe '${name}'"
- [ -d "${build_dir}"/pkgs/${dep} ] && continue
- "${script}" build ${dep}
- done
- }
- get_hostdeps_file_run() {
- deps_to_do=""
- for hostdep in ${hostrundeps}; do
- grep " ${hostdep} " "${hostdeps_file}" >/dev/null 2>&1 || deps_to_do="${deps_to_do} ${hostdep}"
- grep " ${hostdep} " "${hostdeps_file}" >/dev/null 2>&1 || printf " ${hostdep} " >> "${hostdeps_file}"
- done
- for hostdep in ${deps_to_do}; do
- "${script}" internal-get-hostdeps-file-run ${hostdep} "${hostdeps_file}"
- done
- }
- get_hostdeps_file() {
- deps_to_do=""
- for hostdep in ${hostdeps} ${hostrundeps}; do
- grep " ${hostdep} " "${hostdeps_file}" >/dev/null 2>&1 || deps_to_do="${deps_to_do} ${hostdep}"
- grep " ${hostdep} " "${hostdeps_file}" >/dev/null 2>&1 || printf " ${hostdep} " >> "${hostdeps_file}"
- done
- for hostdep in ${deps_to_do}; do
- "${script}" internal-get-hostdeps-file-run ${hostdep} "${hostdeps_file}"
- done
- }
- get_builddeps_file() {
- deps_to_do=""
- for dep in ${deps} ${builddeps}; do
- grep " ${dep} " "${deps_file}" >/dev/null 2>&1 || deps_to_do="${deps_to_do} ${dep}"
- grep " ${dep} " "${deps_file}" >/dev/null 2>&1 || printf " ${dep} " >> "${deps_file}"
- done
- for dep in ${deps_to_do}; do
- "${script}" internal-get-deps-file ${dep} "${deps_file}"
- done
- }
- get_deps_file() {
- deps_to_do=""
- for dep in ${deps}; do
- grep " ${dep} " "${deps_file}" >/dev/null 2>&1 || deps_to_do="${deps_to_do} ${dep}"
- grep " ${dep} " "${deps_file}" >/dev/null 2>&1 || printf " ${dep} " >> "${deps_file}"
- done
- for dep in ${deps_to_do}; do
- "${script}" internal-get-deps-file ${dep} "${deps_file}"
- done
- }
- run_in_container1() {
- if ! [ -z "$TERM" ]; then
- run_in_cont1_term="--env TERM=\"$TERM\""
- fi
- if ! [ -z "$COLORTERM" ]; then
- run_in_cont1_colorterm="--env COLORTERM=\"$COLORTERM\""
- fi
- run_in_cont1_root="$1"
- shift 1
- "$JINX_CACHE_DIR/rbrt" \
- --root "$run_in_cont1_root" rw \
- --uid 0 \
- --gid 0 \
- --env HOME=/root \
- --env LANG=en_US.UTF-8 \
- --env LC_COLLATE=C \
- --env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \
- --env LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib64:/usr/lib \
- ${run_in_cont1_term} \
- ${run_in_cont1_colorterm} \
- -m"${apt_cache}":/var/cache/apt/archives \
- -- \
- "$@"
- }
- check_duplicates() {
- for elem in $(cd "$1" && find .); do
- if [ -f "$2"/${elem} ] || [ -L "$2"/${elem} ]; then
- return 1
- fi
- done
- }
- prepare_container() {
- cd "${build_dir}"
- make_temp
- hostdeps_file="${tmp}"
- make_temp
- deps_file="${tmp}"
- build_hostdeps
- build_deps
- get_hostdeps_file
- get_builddeps_file
- make_temp -d
- container_pkgs="${tmp}"
- make_temp -d
- sysroot_dir="${tmp}"
- rm -rf "$JINX_CACHE_DIR"/saved-info-dir
- for dep in $(cat "${deps_file}"); do
- if [ -f "${build_dir}"/pkgs/${dep}/usr/share/info/dir ]; then
- mv "${build_dir}"/pkgs/${dep}/usr/share/info/dir "$JINX_CACHE_DIR"/saved-info-dir
- fi
- copy_failed=0
- check_duplicates "${build_dir}"/pkgs/${dep} "${sysroot_dir}" || copy_failed=1
- cp -Pplr "${build_dir}"/pkgs/${dep}/. "${sysroot_dir}"/
- if [ -f "$JINX_CACHE_DIR"/saved-info-dir ]; then
- mv "$JINX_CACHE_DIR"/saved-info-dir "${build_dir}"/pkgs/${dep}/usr/share/info/dir
- fi
- if [ "$copy_failed" = 1 ]; then
- die "jinx: error: Dependency '${dep}' contains file confilcts"
- fi
- done
- if [ "$JINX_NATIVE_MODE" = "yes" ] && [ -z "$cross_compile" ]; then
- imgroot="${sysroot_dir}"
- else
- for hostdep in $(cat "${hostdeps_file}"); do
- if [ -f "${build_dir}"/host-pkgs/${hostdep}/usr/local/share/info/dir ]; then
- mv "${build_dir}"/host-pkgs/${hostdep}/usr/local/share/info/dir "$JINX_CACHE_DIR"/saved-info-dir
- fi
- copy_failed=0
- check_duplicates "${build_dir}"/host-pkgs/${hostdep}/usr/local "${container_pkgs}" || copy_failed=1
- cp -Pplr "${build_dir}"/host-pkgs/${hostdep}/usr/local/. "${container_pkgs}"/
- if [ -f "$JINX_CACHE_DIR"/saved-info-dir ]; then
- mv "$JINX_CACHE_DIR"/saved-info-dir "${build_dir}"/host-pkgs/${hostdep}/usr/local/share/info/dir
- fi
- if [ "$copy_failed" = 1 ]; then
- die "jinx: error: Dependency '${hostdep}' contains file confilcts"
- fi
- done
- imagedeps="$(echo "${imagedeps}" | xargs -n1 | sort -u | xargs)"
- pkgset=""
- for pkg in ${imagedeps}; do
- pkgset="${pkgset}${pkg}/"
- if [ -f "$JINX_CACHE_DIR/sets/${pkgset}.image/.jinx-set-valid" ]; then
- continue
- fi
- make_dir "$JINX_CACHE_DIR/sets/${pkgset}"
- cp -Pplrf "$JINX_CACHE_DIR/sets/${pkgset}../.image" "$JINX_CACHE_DIR/sets/${pkgset}.image"
- rm -f "$JINX_CACHE_DIR/sets/${pkgset}.image/.jinx-set-valid"
- if ! run_in_container1 "$JINX_CACHE_DIR/sets/${pkgset}.image" apt-get install -y "${pkg}"; then
- die 'Jinx error: Installing an imagedep failed.'
- fi
- # Fix permissions of files
- for f in $(find "$JINX_CACHE_DIR/sets/${pkgset}.image" -perm 000 2>/dev/null); do
- chmod 755 "$f"
- done
- touch "$JINX_CACHE_DIR/sets/${pkgset}.image/.jinx-set-valid"
- done
- imgroot="$JINX_CACHE_DIR/sets/${pkgset}.image"
- fi
- }
- run_in_container() {
- if [ "${allow_network}" = "yes" ]; then
- unshare_net_flag=""
- else
- unshare_net_flag="-n"
- fi
- if [ ! -z "$TERM" ]; then
- run_in_cont_term="--env TERM=\"$TERM\""
- fi
- if ! [ -z "$COLORTERM" ]; then
- run_in_cont_colorterm="--env COLORTERM=\"$COLORTERM\""
- fi
- touch "${imgroot}/jinx"
- chmod +x "${imgroot}/jinx"
- touch "${imgroot}/jinx-config"
- make_dir "${imgroot}/base_dir" "${imgroot}/sources" "${imgroot}/build_dir"
- native_mode_mounts=""
- if ( [ "$JINX_NATIVE_MODE" = "yes" ] && [ "$cross_compile" = "yes" ] ) || ( ! [ "$JINX_NATIVE_MODE" = "yes" ] ); then
- make_dir "${imgroot}/sysroot"
- container_pkgs_native_mount="-m${container_pkgs}:/usr/local:ro"
- sysroot_native_mount="-m${sysroot_dir}:/sysroot:ro"
- run_in_cont_lang=en_US.UTF-8
- else
- if ! [ -z "$JINX_NATIVE_LANG" ]; then
- run_in_cont_lang="$JINX_NATIVE_LANG"
- else
- run_in_cont_lang=C
- fi
- fi
- run_in_cont_argvar=""
- for arg in "$@"; do
- run_in_cont_argvar="$run_in_cont_argvar \"$arg\""
- done
- shadow_git_dir_build=""
- if [ -d "${build_dir}"/.git ]; then
- make_temp -d
- shadow_git_dir_build="-m${tmp}:/build_dir/.git"
- fi
- shadow_git_dir_base=""
- if [ -d "${base_dir}"/.git ]; then
- make_temp -d
- shadow_git_dir_base="-m${tmp}:/base_dir/.git"
- fi
- "$JINX_CACHE_DIR/rbrt" \
- --root "${imgroot}" \
- --uid $(id -u) \
- --gid $(id -g) \
- --env HOME=/root \
- --env LANG=${run_in_cont_lang} \
- --env LC_COLLATE=C \
- --env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \
- --env LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib64:/usr/lib \
- ${run_in_cont_term} \
- ${run_in_cont_colorterm} \
- --env JINX_PARALLELISM="$parallelism" \
- --env JINX_CONFIG_FILE=/jinx-config \
- --env JINX_SOURCE_DIR=/base_dir \
- ${container_pkgs_native_mount:+"${container_pkgs_native_mount}"} \
- ${sysroot_native_mount:+"${sysroot_native_mount}"} \
- -m"${script}":/jinx:ro \
- -m"${JINX_CONFIG_FILE}":/jinx-config:ro \
- -m"${base_dir}":/base_dir${container_base_dir_ro} \
- ${shadow_git_dir_base:+"${shadow_git_dir_base}"} \
- -m"${base_dir}"/sources:/base_dir/sources${container_sources_ro} \
- -m"${build_dir}":/build_dir \
- ${shadow_git_dir_build:+"${shadow_git_dir_build}"} \
- ${unshare_net_flag} \
- --workdir / \
- -- \
- /bin/bash -c "cd /build_dir && /bin/bash /jinx $run_in_cont_argvar"
- rm -rf "${imgroot}/sysroot" "${imgroot}/jinx" "${imgroot}/jinx-config" "${imgroot}/base_dir" "${imgroot}/sources" "${imgroot}/build_dir"
- }
- destroy_container() {
- rm -rf "${container_pkgs}" "${sysroot_dir}"
- }
- do_hg_fetch() {
- [ -d "${source_dir}" ] && return
- hg clone "${hg_url}" "${base_dir}"/sources/${name}
- ( cd "${base_dir}"/sources/${name} && hg up "${tag}" )
- }
- do_git_fetch() {
- [ -d "${source_dir}" ] && return
- if ! [ -z "${commit}" ]; then
- git clone "${git_url}" "${base_dir}"/sources/${name}
- ( cd "${base_dir}"/sources/${name} && git checkout ${commit} )
- elif [ "${shallow}" = "no" ]; then
- git clone "${git_url}" --branch="${branch}" "${base_dir}"/sources/${name}
- else
- git clone "${git_url}" --branch="${branch}" --depth=1 "${base_dir}"/sources/${name}
- fi
- }
- do_tarball_fetch() {
- [ -d "${source_dir}" ] && return
- tarball_path="${base_dir}"/sources/"$(basename "${tarball_url}")"
- if ! [ -f "$tarball_path" ]; then
- make_temp
- download_path="${tmp}"
- curl -L -o "${download_path}" "${tarball_url}"
- mv "${download_path}" "${tarball_path}"
- fi
- checksum_verified=no
- if ! [ -z "${tarball_sha256}" ]; then
- actual_sha256="$(sha256sum "${tarball_path}" | awk '{print $1;}')"
- if ! [ ${actual_sha256} = ${tarball_sha256} ]; then
- die "* error: Failed to verify SHA256 for ${name}.
- Expected '${tarball_sha256}';
- got '${actual_sha256}'."
- fi
- checksum_verified=yes
- fi
- if ! [ -z "${tarball_sha512}" ]; then
- actual_sha512="$(sha512sum "${tarball_path}" | awk '{print $1;}')"
- if ! [ ${actual_sha512} = ${tarball_sha512} ]; then
- die "* error: Failed to verify SHA512 for ${name}.
- Expected '${tarball_sha512}';
- got '${actual_sha512}'."
- fi
- checksum_verified=yes
- fi
- if ! [ -z "${tarball_blake2b}" ]; then
- actual_blake2b="$("$JINX_CACHE_DIR/b2sum" "${tarball_path}" | awk '{print $1;}')"
- if ! [ ${actual_blake2b} = ${tarball_blake2b} ]; then
- die "* error: Failed to verify BLAKE2B for ${name}.
- Expected '${tarball_blake2b}';
- got '${actual_blake2b}'."
- fi
- checksum_verified=yes
- fi
- if [ "${checksum_verified}" = "no" ]; then
- die "* error: No checksum method specified for ${name}"
- fi
- make_temp -d
- extract_dir="${tmp}"
- ( cd "${extract_dir}" && tar -xf "${tarball_path}" )
- mv "${extract_dir}"/* "${base_dir}"/sources/${name} >/dev/null 2>&1 || (
- make_dir "${base_dir}"/sources/${name}
- mv "${extract_dir}"/* "${base_dir}"/sources/${name}/
- )
- rm -rf "${extract_dir}" "${tarball_path}"
- }
- get_real_source_dir() {
- if [ -z "${source_dir}" ]; then
- source_dir="${base_dir}"/sources/${name}
- else
- source_dir="${base_dir}"/"${source_dir}"
- is_local_package=true
- fi
- }
- do_fetch() {
- make_dir "${base_dir}"/sources
- if ! [ -z "${git_url}" ]; then
- do_git_fetch
- elif ! [ -z "${hg_url}" ]; then
- do_hg_fetch
- elif ! [ -z "${tarball_url}" ]; then
- do_tarball_fetch
- fi
- }
- default_recipe_steps() {
- prepare() {
- true
- }
- configure() {
- true
- }
- build() {
- true
- }
- package() {
- true
- }
- }
- source_source_recipe() {
- if [ -f "${base_dir}"/source-recipes/$1 ]; then
- . "${base_dir}"/source-recipes/$1
- elif [ -f "${base_dir}"/recipes/$1 ]; then
- . "${base_dir}"/recipes/$1
- unset deps
- unset builddeps
- unset hostrundeps
- imagedeps="${source_imagedeps}"
- hostdeps="${source_hostdeps}"
- deps="${source_deps}"
- allow_network="${source_allow_network}"
- else
- die "* could not find source recipe '$1'"
- fi
- }
- cont_patch() {
- source_source_recipe $1
- get_real_source_dir
- make_temp
- patch_trash="${tmp}"
- cd "${source_dir}"
- if [ -d "${base_dir}"/patches/${name} ]; then
- for patch in "${base_dir}"/patches/${name}/*; do
- [ "${patch}" = "${base_dir}/patches/${name}/*" ] && break
- [ "${patch}" = "${base_dir}"/patches/${name}/jinx-working-patch.patch ] && continue
- patch --no-backup-if-mismatch -p1 -r "${patch_trash}" < "${patch}"
- done
- fi
- cp -rp "${source_dir}" "${base_dir}"/sources/${name}-clean
- if [ -f "${base_dir}"/patches/${name}/jinx-working-patch.patch ]; then
- patch --no-backup-if-mismatch -p1 -r "${patch_trash}" < "${base_dir}"/patches/${name}/jinx-working-patch.patch
- fi
- cp -rp "${source_dir}" "${base_dir}"/sources/${name}-workdir
- cd "${base_dir}"
- touch "${base_dir}"/sources/${name}.patched
- }
- do_prepare() {
- default_recipe_steps
- source_source_recipe $1
- get_real_source_dir
- [ -f "${base_dir}"/sources/${name}.prepared ] && return
- sysroot_dir="/sysroot"
- cd "${source_dir}"
- [ "${is_local_package}" = true ] || container_base_dir_ro=":ro"
- prepare
- container_base_dir_ro=""
- cd "${base_dir}"
- touch "${base_dir}"/sources/${name}.prepared
- }
- do_configure_host() {
- default_recipe_steps
- unset from_source
- . "${base_dir}"/host-recipes/$1
- make_dir "${build_dir}"/host-builds/${name}
- if ! [ -z "${from_source}" ]; then
- version=$(unset version && source_source_recipe ${from_source} && echo "$version")
- source_dir="$(unset source_dir && source_source_recipe ${from_source} && echo "$source_dir")"
- if [ -z "${source_dir}" ]; then
- source_dir="${base_dir}"/sources/${from_source}
- else
- source_dir="${base_dir}"/"${source_dir}"
- fi
- fi
- prefix="/usr/local"
- sysroot_dir="/sysroot"
- cd "${build_dir}"/host-builds/${name}
- configure
- cd "${base_dir}"
- }
- do_build_host() {
- default_recipe_steps
- unset from_source
- . "${base_dir}"/host-recipes/$1
- make_dir "${build_dir}"/host-builds/${name}
- if ! [ -z "${from_source}" ]; then
- version=$(unset version && source_source_recipe ${from_source} && echo "$version")
- source_dir="$(unset source_dir && source_source_recipe ${from_source} && echo "$source_dir")"
- if [ -z "${source_dir}" ]; then
- source_dir="${base_dir}"/sources/${from_source}
- else
- source_dir="${base_dir}"/"${source_dir}"
- fi
- fi
- prefix="/usr/local"
- sysroot_dir="/sysroot"
- cd "${build_dir}"/host-builds/${name}
- build
- cd "${base_dir}"
- }
- do_package_host() {
- default_recipe_steps
- unset from_source
- . "${base_dir}"/host-recipes/$1
- dest_dir="${build_dir}"/host-pkgs/${name}
- rm -rf "${dest_dir}"
- make_dir "${dest_dir}"
- if ! [ -z "${from_source}" ]; then
- version=$(unset version && source_source_recipe ${from_source} && echo "$version")
- source_dir="$(unset source_dir && source_source_recipe ${from_source} && echo "$source_dir")"
- if [ -z "${source_dir}" ]; then
- source_dir="${base_dir}"/sources/${from_source}
- else
- source_dir="${base_dir}"/"${source_dir}"
- fi
- fi
- prefix="/usr/local"
- sysroot_dir="/sysroot"
- make_dir "${dest_dir}${prefix}"
- cd "${build_dir}"/host-builds/${name}
- package
- cd "${base_dir}"
- # Remove libtool files
- for i in $(find "${dest_dir}${prefix}" -name "*.la"); do
- rm -rvf $i
- done
- }
- do_configure() {
- default_recipe_steps
- unset from_source
- . "${base_dir}"/recipes/$1
- make_dir "${build_dir}"/builds/${name}
- if ! [ -z "${from_source}" ] || ! [ -z "${tarball_url}" ] || ! [ -z "${git_url}" ] || ! [ -z "${hg_url}" ] || ! [ -z "${source_dir}" ]; then
- if ! [ -z "${from_source}" ]; then
- version=$(unset version && source_source_recipe ${from_source} && echo "$version")
- source_dir="$(unset source_dir && source_source_recipe ${from_source} && echo "$source_dir")"
- else
- from_source=${name}
- fi
- if [ -z "${source_dir}" ]; then
- source_dir="${base_dir}"/sources/${from_source}
- else
- source_dir="${base_dir}"/"${source_dir}"
- fi
- fi
- prefix="/usr"
- sysroot_dir="/sysroot"
- cd "${build_dir}"/builds/${name}
- configure
- cd "${base_dir}"
- }
- do_build() {
- default_recipe_steps
- unset from_source
- . "${base_dir}"/recipes/$1
- make_dir "${build_dir}"/builds/${name}
- if ! [ -z "${from_source}" ] || ! [ -z "${tarball_url}" ] || ! [ -z "${git_url}" ] || ! [ -z "${hg_url}" ] || ! [ -z "${source_dir}" ]; then
- if ! [ -z "${from_source}" ]; then
- version=$(unset version && source_source_recipe ${from_source} && echo "$version")
- source_dir="$(unset source_dir && source_source_recipe ${from_source} && echo "$source_dir")"
- else
- from_source=${name}
- fi
- if [ -z "${source_dir}" ]; then
- source_dir="${base_dir}"/sources/${from_source}
- else
- source_dir="${base_dir}"/"${source_dir}"
- fi
- fi
- prefix="/usr"
- sysroot_dir="/sysroot"
- cd "${build_dir}"/builds/${name}
- build
- cd "${base_dir}"
- }
- do_package() {
- default_recipe_steps
- unset from_source
- . "${base_dir}"/recipes/$1
- dest_dir="${build_dir}"/pkgs/${name}
- rm -rf "${dest_dir}"
- make_dir "${dest_dir}"
- if ! [ -z "${from_source}" ] || ! [ -z "${tarball_url}" ] || ! [ -z "${git_url}" ] || ! [ -z "${hg_url}" ] || ! [ -z "${source_dir}" ]; then
- if ! [ -z "${from_source}" ]; then
- version=$(unset version && source_source_recipe ${from_source} && echo "$version")
- source_dir="$(unset source_dir && source_source_recipe ${from_source} && echo "$source_dir")"
- else
- from_source=${name}
- fi
- if [ -z "${source_dir}" ]; then
- source_dir="${base_dir}"/sources/${from_source}
- else
- source_dir="${base_dir}"/"${source_dir}"
- fi
- fi
- prefix="/usr"
- sysroot_dir="/sysroot"
- make_dir "${dest_dir}${prefix}"
- cd "${build_dir}"/builds/${name}
- package
- cd "${base_dir}"
- # Remove libtool files
- for i in $(find "${dest_dir}${prefix}" -name "*.la"); do
- rm -rvf $i
- done
- }
- precont_patch() {
- [ -f "${base_dir}"/sources/$1.patched ] && return
- cross_compile=yes
- prepare_container
- run_in_container internal-cont-patch $1
- destroy_container
- }
- do_source() {
- source_source_recipe $1
- get_real_source_dir
- do_fetch
- "${script}" internal-precont-patch $1
- [ -f "${base_dir}"/sources/$1.prepared ] && return
- cross_compile=yes
- prepare_container
- run_in_container internal-prepare $1
- destroy_container
- }
- do_cmd_rebuild() {
- rm -rf "${build_dir}"/builds/"$1"
- do_pkg "$1"
- }
- do_cmd_host_rebuild() {
- rm -rf "${build_dir}"/host-builds/"$1"
- do_host_pkg "$1"
- }
- do_cmd_prepare() {
- source_source_recipe $1
- [ -f "${base_dir}"/sources/$1.patched ] || die "cannot regenerate non-built package"
- get_real_source_dir
- make_temp
- patch_file="${tmp}"
- if ! [ "${is_local_package}" = true ]; then
- cd "${base_dir}"/sources
- # exclude version control dirs
- make_temp -d
- vc_dir_clean="${tmp}"
- rm -rf "${vc_dir_clean}"
- make_temp -d
- vc_dir_workdir="${tmp}"
- rm -rf "${vc_dir_workdir}"
- if ! [ -z "${git_url}" ]; then
- mv $1-clean/.git "${vc_dir_clean}"
- mv $1-workdir/.git "${vc_dir_workdir}"
- elif ! [ -z "${hg_url}" ]; then
- mv $1-clean/.hg "${vc_dir_clean}"
- mv $1-workdir/.hg "${vc_dir_workdir}"
- fi
- git diff --no-index --no-prefix $1-clean $1-workdir >"${patch_file}" || true
- if ! [ -z "${git_url}" ]; then
- mv "${vc_dir_clean}" $1-clean/.git
- mv "${vc_dir_workdir}" $1-workdir/.git
- elif ! [ -z "${hg_url}" ]; then
- mv "${vc_dir_clean}" $1-clean/.hg
- mv "${vc_dir_workdir}" $1-workdir/.hg
- fi
- if [ -s "${patch_file}" ]; then
- make_dir "${base_dir}"/patches/$1
- mv "${patch_file}" "${base_dir}"/patches/$1/jinx-working-patch.patch
- fi
- cd "${base_dir}"
- rm -rf "${source_dir}"
- cp -rp "${base_dir}"/sources/$1-workdir "${source_dir}"
- fi
- rm -rf "${base_dir}"/sources/$1.prepared
- cross_compile=yes
- prepare_container
- run_in_container internal-prepare $1
- destroy_container
- }
- do_host_pkg() {
- unset from_source
- . "${base_dir}"/host-recipes/$1
- echo "* building host package: $name"
- if ! [ -z "${from_source}" ]; then
- from_source="$(. "${base_dir}"/host-recipes/$1 && echo "$from_source")"
- [ -f "${base_dir}"/sources/${from_source}.prepared ] || \
- "${script}" internal-source "${from_source}"
- fi
- cross_compile=yes
- prepare_container
- container_sources_ro=":ro"
- if ! [ -d "${base_dir}"/host-builds/$1 ]; then
- run_in_container internal-configure-host $1
- fi
- run_in_container internal-build-host $1
- rm -rf "${base_dir}"/host-pkgs/$1
- if ! run_in_container internal-package-host $1; then
- rm -rf "${base_dir}"/host-pkgs/$1
- return 1
- fi
- unset container_sources_ro
- destroy_container
- }
- do_pkg() {
- unset from_source
- . "${base_dir}"/recipes/$1
- echo "* building package: $name"
- if ! [ -z "${from_source}" ]; then
- from_source="$(. "${base_dir}"/recipes/$1 && echo "$from_source")"
- [ -f "${base_dir}"/sources/${from_source}.prepared ] || \
- "${script}" internal-source "${from_source}"
- fi
- if ! [ -z "${tarball_url}" ] || ! [ -z "${git_url}" ] || ! [ -z "${hg_url}" ] || ! [ -z "${source_dir}" ]; then
- "${script}" internal-source "${name}"
- fi
- prepare_container
- container_sources_ro=":ro"
- if ! [ -d "${base_dir}"/builds/$1 ]; then
- run_in_container internal-configure $1
- fi
- run_in_container internal-build $1
- rm -rf "${base_dir}"/pkgs/$1
- if ! run_in_container internal-package $1; then
- rm -rf "${base_dir}"/pkgs/$1
- return 1
- fi
- unset container_sources_ro
- destroy_container
- }
- cmd_host_build() {
- for ppkg in "$@"; do
- for pkg in $(eval '(' cd "'${base_dir}'"/host-recipes '&&' echo "${ppkg}" ')' ); do
- "${script}" internal-do-host-pkg "${pkg}"
- done
- done
- }
- cmd_build() {
- for ppkg in "$@"; do
- for pkg in $(eval '(' cd "'${base_dir}'"/recipes '&&' echo "${ppkg}" ')' ); do
- "${script}" internal-do-pkg "${pkg}"
- done
- done
- }
- cmd_prepare() {
- for i in "$@"; do
- "${script}" internal-do-prepare "$i"
- done
- }
- cmd_host_rebuild() {
- for ppkg in "$@"; do
- for pkg in $(eval '(' cd "'${base_dir}'"/host-recipes '&&' echo "${ppkg}" ')' ); do
- "${script}" internal-do-host-rebuild "${pkg}"
- done
- done
- }
- cmd_rebuild() {
- for ppkg in "$@"; do
- for pkg in $(eval '(' cd "'${base_dir}'"/recipes '&&' echo "${ppkg}" ')' ); do
- "${script}" internal-do-rebuild "${pkg}"
- done
- done
- }
- cmd_install() {
- sysroot="$1"
- shift 1
- mkdir -m 755 -p "${sysroot}"
- pkgs_to_install=""
- if [ "$1" = '*' ]; then
- for pkg in "${base_dir}"/recipes/*; do
- pkgs_to_install="${pkgs_to_install} $(basename "${pkg}")"
- done
- else
- for ppkg in "$@"; do
- for pkg in $(eval '(' cd "'${base_dir}'"/recipes '&&' echo "${ppkg}" ')' ); do
- deps="${deps} ${pkg}"
- done
- done
- make_temp
- deps_file="${tmp}"
- echo "* resolving dependencies..."
- get_deps_file
- pkgs_to_install="$(cat "${deps_file}")"
- fi
- make_temp
- all_files="${tmp}"
- pkg_dirs_to_install=""
- for pkg in ${pkgs_to_install}; do
- echo "* installing ${pkg}..."
- if ! [ -d "${build_dir}"/pkgs/${pkg} ]; then
- "${script}" internal-do-pkg "${pkg}"
- fi
- ( cd "${build_dir}"/pkgs/${pkg} && find . >>"${all_files}" )
- pkg_dirs_to_install="${pkg_dirs_to_install} ${pkg}/."
- done
- echo "* checking for conflicts..."
- make_temp
- all_files_sorted="${tmp}"
- make_temp
- all_files_uniq="${tmp}"
- sort <"${all_files}" >"${all_files_sorted}"
- uniq <"${all_files_sorted}" >"${all_files_uniq}"
- dup_elements="$(comm -23 "${all_files_sorted}" "${all_files_uniq}" | uniq)"
- rm -f "$JINX_CACHE_DIR/merged-info-dir"
- for pkg in ${pkgs_to_install}; do
- for elem in ${dup_elements}; do
- if [ -f "${build_dir}"/pkgs/${pkg}/${elem} ] || [ -L "${build_dir}"/pkgs/${pkg}/${elem} ]; then
- if [ "${elem}" = "./usr/share/info/dir" ]; then
- # Coalesce info directory
- if ! [ -f "$JINX_CACHE_DIR/merged-info-dir" ]; then
- cp "${build_dir}"/pkgs/${pkg}/${elem} "$JINX_CACHE_DIR/merged-info-dir"
- else
- "$JINX_CACHE_DIR/merge-info" -o "$JINX_CACHE_DIR/merged-info-dir" "${build_dir}"/pkgs/${pkg}/${elem} "$JINX_CACHE_DIR/merged-info-dir"
- fi
- continue
- fi
- die "* error: duplicate files were found in package '${pkg}': ${elem}"
- fi
- done
- done
- echo "* synchronising package files to sysroot '${sysroot}'..."
- sysroot_abs="$(cd "${sysroot}" && pwd -P)"
- ( cd "${build_dir}/pkgs" && rsync -urlptD ${pkg_dirs_to_install} "${sysroot_abs}"/ )
- # inject the merged info dir into sysroot
- if [ -f "${sysroot}"/usr/share/info/dir ] && [ -f "$JINX_CACHE_DIR/merged-info-dir" ]; then
- "$JINX_CACHE_DIR/merge-info" -o "${sysroot}"/usr/share/info/dir "$JINX_CACHE_DIR/merged-info-dir" "${sysroot}"/usr/share/info/dir
- else
- if [ -f "$JINX_CACHE_DIR/merged-info-dir" ]; then
- cp "$JINX_CACHE_DIR/merged-info-dir" "${sysroot}"/usr/share/info/dir
- fi
- fi
- }
- rebuild_b2sum() {
- cat <<'EOF' >"$JINX_CACHE_DIR/b2sum.c"
- // This blake2b implementation comes from the GNU coreutils project.
- // https://github.com/coreutils/coreutils/blob/master/src/blake2/blake2b-ref.c
- #include <stdbool.h>
- #include <stdint.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define BLAKE2B_OUT_BYTES 64
- #define BLAKE2B_BLOCK_BYTES 128
- #define BLAKE2B_KEY_BYTES 64
- #define BLAKE2B_SALT_BYTES 16
- #define BLAKE2B_PERSONAL_BYTES 16
- static const uint64_t blake2b_iv[8] = {
- 0x6a09e667f3bcc908,
- 0xbb67ae8584caa73b,
- 0x3c6ef372fe94f82b,
- 0xa54ff53a5f1d36f1,
- 0x510e527fade682d1,
- 0x9b05688c2b3e6c1f,
- 0x1f83d9abfb41bd6b,
- 0x5be0cd19137e2179,
- };
- static const uint8_t blake2b_sigma[12][16] = {
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
- { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
- { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
- { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
- { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
- { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
- { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
- { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
- { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
- { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
- };
- struct blake2b_state {
- uint64_t h[8];
- uint64_t t[2];
- uint64_t f[2];
- uint8_t buf[BLAKE2B_BLOCK_BYTES];
- size_t buf_len;
- uint8_t last_node;
- };
- struct blake2b_param {
- uint8_t digest_length;
- uint8_t key_length;
- uint8_t fan_out;
- uint8_t depth;
- uint32_t leaf_length;
- uint32_t node_offset;
- uint32_t xof_length;
- uint8_t node_depth;
- uint8_t inner_length;
- uint8_t reserved[14];
- uint8_t salt[BLAKE2B_SALT_BYTES];
- uint8_t personal[BLAKE2B_PERSONAL_BYTES];
- } __attribute__((packed));
- static void blake2b_increment_counter(struct blake2b_state *state, uint64_t inc) {
- state->t[0] += inc;
- state->t[1] += state->t[0] < inc;
- }
- static inline uint64_t rotr64(uint64_t w, unsigned c) {
- return (w >> c) | (w << (64 - c));
- }
- #define G(r, i, a, b, c, d) do { \
- a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
- d = rotr64(d ^ a, 32); \
- c = c + d; \
- b = rotr64(b ^ c, 24); \
- a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
- d = rotr64(d ^ a, 16); \
- c = c + d; \
- b = rotr64(b ^ c, 63); \
- } while (0)
- #define ROUND(r) do { \
- G(r, 0, v[0], v[4], v[8], v[12]); \
- G(r, 1, v[1], v[5], v[9], v[13]); \
- G(r, 2, v[2], v[6], v[10], v[14]); \
- G(r, 3, v[3], v[7], v[11], v[15]); \
- G(r, 4, v[0], v[5], v[10], v[15]); \
- G(r, 5, v[1], v[6], v[11], v[12]); \
- G(r, 6, v[2], v[7], v[8], v[13]); \
- G(r, 7, v[3], v[4], v[9], v[14]); \
- } while (0)
- static void blake2b_compress(struct blake2b_state *state, const uint8_t block[static BLAKE2B_BLOCK_BYTES]) {
- uint64_t m[16];
- uint64_t v[16];
- for (int i = 0; i < 16; i++) {
- m[i] = *(uint64_t *)(block + i * sizeof(m[i]));
- }
- for (int i = 0; i < 8; i++) {
- v[i] = state->h[i];
- }
- v[8] = blake2b_iv[0];
- v[9] = blake2b_iv[1];
- v[10] = blake2b_iv[2];
- v[11] = blake2b_iv[3];
- v[12] = blake2b_iv[4] ^ state->t[0];
- v[13] = blake2b_iv[5] ^ state->t[1];
- v[14] = blake2b_iv[6] ^ state->f[0];
- v[15] = blake2b_iv[7] ^ state->f[1];
- ROUND(0);
- ROUND(1);
- ROUND(2);
- ROUND(3);
- ROUND(4);
- ROUND(5);
- ROUND(6);
- ROUND(7);
- ROUND(8);
- ROUND(9);
- ROUND(10);
- ROUND(11);
- for (int i = 0; i < 8; i++) {
- state->h[i] = state->h[i] ^ v[i] ^ v[i + 8];
- }
- }
- #undef G
- #undef ROUND
- static void blake2b_init(struct blake2b_state *state) {
- struct blake2b_param param;
- memset(¶m, 0, sizeof(struct blake2b_param));
- param.digest_length = BLAKE2B_OUT_BYTES;
- param.fan_out = 1;
- param.depth = 1;
- memset(state, 0, sizeof(struct blake2b_state));
- for (int i = 0; i < 8; i++) {
- state->h[i] = blake2b_iv[i];
- }
- for (int i = 0; i < 8; i++) {
- state->h[i] ^= *(uint64_t *)((void *)¶m + sizeof(state->h[i]) * i);
- }
- }
- static void blake2b_update(struct blake2b_state *state, const void *in, size_t in_len) {
- if (in_len == 0) {
- return;
- }
- size_t left = state->buf_len;
- size_t fill = BLAKE2B_BLOCK_BYTES - left;
- if (in_len > fill) {
- state->buf_len = 0;
- memcpy(state->buf + left, in, fill);
- blake2b_increment_counter(state, BLAKE2B_BLOCK_BYTES);
- blake2b_compress(state, state->buf);
- in += fill;
- in_len -= fill;
- while (in_len > BLAKE2B_BLOCK_BYTES) {
- blake2b_increment_counter(state, BLAKE2B_BLOCK_BYTES);
- blake2b_compress(state, in);
- in += fill;
- in_len -= fill;
- }
- }
- memcpy(state->buf + state->buf_len, in, in_len);
- state->buf_len += in_len;
- }
- static void blake2b_final(struct blake2b_state *state, void *out) {
- uint8_t buffer[BLAKE2B_OUT_BYTES] = {0};
- blake2b_increment_counter(state, state->buf_len);
- state->f[0] = (uint64_t)-1;
- memset(state->buf + state->buf_len, 0, BLAKE2B_BLOCK_BYTES - state->buf_len);
- blake2b_compress(state, state->buf);
- for (int i = 0; i < 8; i++) {
- *(uint64_t *)(buffer + sizeof(state->h[i]) * i) = state->h[i];
- }
- memcpy(out, buffer, BLAKE2B_OUT_BYTES);
- memset(buffer, 0, sizeof(buffer));
- }
- static void blake2b(void *out, const void *in, size_t in_len) {
- struct blake2b_state state = {0};
- blake2b_init(&state);
- blake2b_update(&state, in, in_len);
- blake2b_final(&state, out);
- }
- int main(int argc, char *argv[]) {
- if (argc < 2) {
- return EXIT_FAILURE;
- }
- FILE *f = fopen(argv[1], "r");
- if (f == NULL) {
- return EXIT_FAILURE;
- }
- fseek(f, 0, SEEK_END);
- size_t f_size = ftell(f);
- rewind(f);
- void *mem = malloc(f_size);
- if (mem == NULL) {
- return EXIT_FAILURE;
- }
- if (fread(mem, f_size, 1, f) != 1) {
- return EXIT_FAILURE;
- }
- uint8_t out_buf[BLAKE2B_OUT_BYTES];
- blake2b(out_buf, mem, f_size);
- for (size_t i = 0; i < BLAKE2B_OUT_BYTES; i++) {
- printf("%02x", out_buf[i]);
- }
- printf(" %s\n", argv[1]);
- }
- EOF
- cc -O2 -pipe -fno-strict-aliasing -Wall -Wextra "$JINX_CACHE_DIR/b2sum.c" -o "$JINX_CACHE_DIR/b2sum"
- }
- rebuild_rbrt() {
- cat <<'EOF' >"$JINX_CACHE_DIR/rbrt.c"
- // Written by 48cf (iretq@riseup.net)
- // Inspired heavily by https://github.com/managarm/cbuildrt/
- #define _GNU_SOURCE
- #include <stddef.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include <errno.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sched.h>
- #include <sys/mount.h>
- #include <sys/wait.h>
- #define STRINGIFY(x) #x
- #define TOSTRING(x) STRINGIFY(x)
- int main(int argc, char *argv[]) {
- int ok = 1;
- const char *err_msg = "";
- char *rootfs = NULL;
- char **mounts = NULL;
- char **envs = NULL;
- char **process_args = NULL;
- int mount_count = 0;
- int mounts_size = 0;
- int env_count = 0;
- int envs_size = 0;
- bool rw_root = false;
- bool unshare_net = false;
- int uid = -1, gid = -1;
- int euid = geteuid();
- int egid = getegid();
- int setgroups_fd = -1;
- int uid_map_fd = -1;
- int gid_map_fd = -1;
- char *workdir = "/";
- for (int i = 1; i < argc; ) {
- if (strcmp(argv[i], "--workdir") == 0) {
- workdir = argv[i + 1];
- i += 2;
- } else if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--root") == 0) {
- if (i == argc - 1) {
- fprintf(stderr, "%s: '%s' requires a value\n", argv[0], argv[i]);
- goto cleanup;
- }
- rootfs = argv[i + 1];
- i += 2;
- if (i < argc - 1 && strcmp(argv[i], "rw") == 0) {
- rw_root = true;
- i++;
- }
- } else if (strcmp(argv[i], "-u") == 0 || strcmp(argv[i], "--uid") == 0) {
- if (i == argc - 1) {
- fprintf(stderr, "%s: '%s' requires a value\n", argv[0], argv[i]);
- goto cleanup;
- }
- if (sscanf(argv[i + 1], "%d", &uid) != 1) {
- fprintf(stderr, "%s: '%s' is not a valid user ID\n", argv[0], argv[i + 1]);
- goto cleanup;
- }
- i += 2;
- } else if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "--gid") == 0) {
- if (i == argc - 1) {
- fprintf(stderr, "%s: '%s' requires a value\n", argv[0], argv[i]);
- goto cleanup;
- }
- if (sscanf(argv[i + 1], "%d", &gid) != 1) {
- fprintf(stderr, "%s: '%s' is not a valid group ID\n", argv[0], argv[i + 1]);
- goto cleanup;
- }
- i += 2;
- } else if (strncmp(argv[i], "-m", 2) == 0) {
- if (mount_count == mounts_size) {
- mounts_size = mounts_size == 0 ? 16 : mounts_size * 2;
- char **tmp_mounts = realloc(mounts, sizeof(char *) * mounts_size);
- if (tmp_mounts == NULL) {
- fprintf(stderr, "%s: failed to allocate mounts array\n", argv[0]);
- goto cleanup;
- }
- mounts = tmp_mounts;
- }
- char *target = argv[i] + 2;
- while (*target && *target != ':') {
- target++;
- }
- if (!*target) {
- fprintf(stderr, "%s: mount points need to be provided in the 'source:target' format\n", argv[0]);
- goto cleanup;
- }
- mounts[mount_count++] = argv[i] + 2;
- i += 1;
- } else if (strcmp(argv[i], "-e") == 0 || strcmp(argv[i], "--env") == 0) {
- if (i == argc - 1) {
- fprintf(stderr, "%s: '%s' requires a value\n", argv[0], argv[i]);
- goto cleanup;
- }
- if (env_count == envs_size) {
- envs_size = envs_size == 0 ? 16 : envs_size * 2;
- char **tmp_envs = realloc(envs, sizeof(char *) * envs_size);
- if (tmp_envs == NULL) {
- fprintf(stderr, "%s: failed to allocate environment variables array\n", argv[0]);
- goto cleanup;
- }
- envs = tmp_envs;
- }
- char *value = argv[i + 1];
- while (*value && *value != '=') {
- value++;
- }
- if (!*value) {
- fprintf(stderr, "%s: environment variables need to be provided in the 'key=value' format\n", argv[0]);
- goto cleanup;
- }
- envs[env_count++] = argv[i + 1];
- i += 2;
- } else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--net") == 0) {
- unshare_net = true;
- i += 1;
- } else if (strcmp(argv[i], "--") == 0) {
- if (i == argc - 1) {
- fprintf(stderr, "%s: at least one trailing argument is required\n", argv[0]);
- goto cleanup;
- }
- process_args = &argv[i + 1];
- break;
- } else {
- fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[i]);
- goto cleanup;
- }
- }
- if (rootfs == NULL) {
- fprintf(stderr, "%s: root file system path is required\n", argv[0]);
- goto cleanup;
- }
- if (process_args == NULL) {
- fprintf(stderr, "%s: process arguments are requires\n", argv[0]);
- goto cleanup;
- }
- if (uid == -1 || gid == -1) {
- fprintf(stderr, "%s: user and group IDs are both required\n", argv[0]);
- goto cleanup;
- }
- if (unshare(CLONE_NEWUSER | CLONE_NEWPID) < 0) {
- err_msg = "unshare() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- char uid_map[64], gid_map[64];
- int uid_map_len = snprintf(uid_map, 64, "%d %d 1", uid, euid);
- int gid_map_len = snprintf(gid_map, 64, "%d %d 1", gid, egid);
- setgroups_fd = open("/proc/self/setgroups", O_RDWR);
- if (setgroups_fd < 0 || write(setgroups_fd, "deny", 4) < 0) {
- err_msg = "failed to open or write to /proc/self/setgroups at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- close(setgroups_fd);
- setgroups_fd = -1;
- uid_map_fd = open("/proc/self/uid_map", O_RDWR);
- if (uid_map_fd < 0 || write(uid_map_fd, uid_map, uid_map_len) < 0) {
- err_msg = "failed to open or write to /proc/self/uid_map at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- close(uid_map_fd);
- uid_map_fd = -1;
- gid_map_fd = open("/proc/self/gid_map", O_RDWR);
- if (gid_map_fd < 0 || write(gid_map_fd, gid_map, gid_map_len) < 0) {
- err_msg = "failed to open or write to /proc/self/gid_map at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- close(gid_map_fd);
- gid_map_fd = -1;
- if (setuid(uid) < 0 || setgid(gid) < 0) {
- err_msg = "setuid()/setgid() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- int child_pid = fork();
- if (child_pid == 0) {
- if (unshare(CLONE_NEWNS) < 0) {
- err_msg = "unshare() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- if (mount(rootfs, rootfs, NULL, MS_BIND, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- int root_flags = MS_REMOUNT | MS_BIND | MS_NOSUID | MS_NODEV;
- if (!rw_root) {
- root_flags |= MS_RDONLY;
- }
- if (mount(rootfs, rootfs, NULL, root_flags, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- char target_path[PATH_MAX];
- snprintf(target_path, PATH_MAX, "%s/etc/resolv.conf", rootfs);
- if (mount("/etc/resolv.conf", target_path, NULL, MS_BIND, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- snprintf(target_path, PATH_MAX, "%s/dev", rootfs);
- if (mount("/dev", target_path, NULL, MS_REC | MS_BIND | MS_SLAVE, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- snprintf(target_path, PATH_MAX, "%s/sys", rootfs);
- if (mount("/sys", target_path, NULL, MS_REC | MS_BIND | MS_SLAVE, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- snprintf(target_path, PATH_MAX, "%s/run", rootfs);
- if (mount(NULL, target_path, "tmpfs", 0, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- snprintf(target_path, PATH_MAX, "%s/tmp", rootfs);
- if (mount(NULL, target_path, "tmpfs", 0, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- snprintf(target_path, PATH_MAX, "%s/var/tmp", rootfs);
- if (mount(NULL, target_path, "tmpfs", 0, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- snprintf(target_path, PATH_MAX, "%s/proc", rootfs);
- if (mount(NULL, target_path, "proc", 0, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- for (int i = 0; i < mount_count; i++) {
- char *source = mounts[i];
- char *target = source;
- while (*target && *target != ':') {
- target++;
- }
- *target++ = 0;
- char *read_only = target;
- while (*read_only && *read_only != ':') {
- read_only++;
- }
- bool ro = false;
- if (*read_only == ':') {
- *read_only++ = 0;
- ro = strcmp(read_only, "ro") == 0;
- }
- snprintf(target_path, PATH_MAX, "%s%s", rootfs, target);
- if (mount(source, target_path, NULL, MS_BIND | (ro ? MS_RDONLY : 0), NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- if (ro) {
- if (mount(source, target_path, NULL, MS_REMOUNT | MS_BIND | MS_RDONLY, NULL) < 0) {
- err_msg = "mount() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- }
- }
- if (unshare_net && unshare(CLONE_NEWNET) < 0) {
- err_msg = "unshare() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- if (chroot(rootfs) < 0) {
- err_msg = "chroot() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- if (chdir(workdir) < 0) {
- err_msg = "chdir() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- int child = fork();
- if (child == 0) {
- clearenv();
- setenv("HOME", "/root", 1);
- setenv("LANG", "C", 1);
- setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 1);
- for (int i = 0; i < env_count; i++) {
- char *key = envs[i];
- char *value = key;
- while (*value && *value != '=') {
- value++;
- }
- *value++ = 0;
- setenv(key, value, 1);
- }
- if (execvp(process_args[0], process_args) < 0) {
- err_msg = "execvp() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- __builtin_unreachable();
- } else {
- int exit_code = -1;
- if (waitpid(child, &exit_code, 0) < 0) {
- err_msg = "waitpid() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- ok = WEXITSTATUS(exit_code);
- goto cleanup;
- }
- __builtin_unreachable();
- } else {
- int exit_code = -1;
- if (waitpid(child_pid, &exit_code, 0) < 0) {
- err_msg = "waitpid() failure at line " TOSTRING(__LINE__);
- goto errno_error;
- }
- ok = WEXITSTATUS(exit_code);
- goto cleanup;
- }
- errno_error:
- fprintf(stderr, "%s: %s: %s\n", argv[0], err_msg, strerror(errno));
- cleanup:
- if (mounts != NULL) {
- free(mounts);
- }
- if (envs != NULL) {
- free(envs);
- }
- if (setgroups_fd >= 0) {
- close(setgroups_fd);
- }
- if (uid_map_fd >= 0) {
- close(uid_map_fd);
- }
- if (gid_map_fd >= 0) {
- close(gid_map_fd);
- }
- return ok;
- }
- EOF
- cc -O2 -pipe -Wall -Wextra "$JINX_CACHE_DIR/rbrt.c" -o "$JINX_CACHE_DIR/rbrt"
- }
- reinit_container() {
- chmod -R 777 "$JINX_CACHE_DIR/sets" 2>/dev/null || true
- chmod -R 777 "$JINX_CACHE_DIR/apt-cache" 2>/dev/null || true
- rm -rf "$JINX_CACHE_DIR/debian-rootfs.tar.xz" "$JINX_CACHE_DIR/sets" "$JINX_CACHE_DIR/apt-cache"
- make_dir "${apt_cache}"
- curl -Lo "$JINX_CACHE_DIR/debian-rootfs.tar.xz" https://github.com/mintsuki/debian-rootfs/releases/download/${debian_snapshot}/debian-rootfs-${debian_architecture}.tar.xz
- if ! "$JINX_CACHE_DIR/b2sum" "$JINX_CACHE_DIR/debian-rootfs.tar.xz" | grep "${debian_rootfs_b2sum}" >/dev/null 2>&1; then
- die "Jinx: Failed to verify Debian rootfs tarball"
- fi
- ( cd "$JINX_CACHE_DIR" && xzcat debian-rootfs.tar.xz | tar -xf - )
- rm "$JINX_CACHE_DIR/debian-rootfs.tar.xz"
- make_dir "$JINX_CACHE_DIR/sets"
- mv "$JINX_CACHE_DIR/debian-rootfs-${debian_architecture}" "$JINX_CACHE_DIR/sets/.image"
- echo 'en_US.UTF-8 UTF-8' > "$JINX_CACHE_DIR/sets/.image/etc/locale.gen"
- echo 'APT::Install-Suggests "0";
- APT::Install-Recommends "0";
- APT::Sandbox::User "root";
- Acquire::Check-Valid-Until "0";' >> "$JINX_CACHE_DIR/sets/.image/etc/apt/apt.conf"
- run_in_container1 "$JINX_CACHE_DIR/sets/.image" apt-get update
- run_in_container1 "$JINX_CACHE_DIR/sets/.image" apt-get install -y locales
- run_in_container1 "$JINX_CACHE_DIR/sets/.image" locale-gen
- # Fix permissions of files
- for f in $(find "$JINX_CACHE_DIR/sets/.image" -perm 000 2>/dev/null); do
- chmod 755 "$f"
- done
- run_in_container1 "$JINX_CACHE_DIR/sets/.image" apt-get install -y autopoint bash bison bzip2 curl diffutils docbook-xsl doxygen file findutils flex gawk gettext grep gzip xsltproc m4 make patch perl python3 sed tar texinfo w3m which xmlto xz-utils
- # Build xstow
- XSTOW_BUILDENV="$JINX_CACHE_DIR/xstow_buildenv"
- cp -Pprf "$JINX_CACHE_DIR/sets/.image/." "${XSTOW_BUILDENV}/"
- curl -Lo "${XSTOW_BUILDENV}/xstow-${XSTOW_VERSION}.tar.gz" https://github.com/majorkingleo/xstow/releases/download/${XSTOW_VERSION}/xstow-${XSTOW_VERSION}.tar.gz
- ( cd "${XSTOW_BUILDENV}" && gunzip < xstow-${XSTOW_VERSION}.tar.gz | tar -xf - )
- run_in_container1 "${XSTOW_BUILDENV}" apt-get install -y build-essential
- run_in_container1 "${XSTOW_BUILDENV}" sh -c "cd /xstow-${XSTOW_VERSION} && ./configure LDFLAGS='-static' --enable-static --enable-merge-info --without-curses && make -j${parallelism}"
- mv "${XSTOW_BUILDENV}/xstow-${XSTOW_VERSION}/src/merge-info" "$JINX_CACHE_DIR/"
- chmod -R 777 "$XSTOW_BUILDENV"
- rm -rf "$XSTOW_BUILDENV"
- }
- first_use() {
- echo "* preparing Jinx cache..."
- make_dir "$JINX_CACHE_DIR"
- rebuild_b2sum
- rebuild_rbrt
- reinit_container
- echo "$jinx_version" > "$JINX_CACHE_DIR/version"
- echo "* done"
- }
- redo_first_use() {
- echo "* purging old Jinx cache..."
- chmod -R 777 "$JINX_CACHE_DIR" || true
- rm -rf "$JINX_CACHE_DIR"
- first_use
- }
- if ! [ -f "$JINX_CONFIG_FILE" ]; then
- die "$0: missing Jinx config file '$JINX_CONFIG_FILE'"
- fi
- . "${JINX_CONFIG_FILE}"
- if [ -z "$JINX_MAJOR_VER" ]; then
- die "$0: required config variable \$JINX_MAJOR_VER missing"
- fi
- if ! [ "$JINX_MAJOR_VER" = "$jinx_major_ver" ]; then
- die "$0: needed major version ($JINX_MAJOR_VER) differs from Jinx-provided major version ($jinx_major_ver)"
- fi
- if ! [ -d "$JINX_CACHE_DIR" ]; then
- first_use
- fi
- if ! [ -f "$JINX_CACHE_DIR/version" ] || ! [ "$(cat "$JINX_CACHE_DIR/version")" = "$jinx_version" ]; then
- redo_first_use
- fi
- case "$1" in
- internal-prepare)
- do_prepare "$2"
- ;;
- internal-precont-patch)
- precont_patch "$2"
- ;;
- internal-cont-patch)
- cont_patch "$2"
- ;;
- internal-configure-host)
- do_configure_host "$2"
- ;;
- internal-build-host)
- do_build_host "$2"
- ;;
- internal-package-host)
- do_package_host "$2"
- ;;
- internal-configure)
- do_configure "$2"
- ;;
- internal-build)
- do_build "$2"
- ;;
- internal-package)
- do_package "$2"
- ;;
- internal-get-deps-file)
- . "${base_dir}"/recipes/$2
- deps_file="$3"
- get_deps_file
- ;;
- internal-get-hostdeps-file-run)
- . "${base_dir}"/host-recipes/$2
- hostdeps_file="$3"
- get_hostdeps_file_run
- ;;
- internal-source)
- do_source "$2"
- ;;
- internal-do-host-pkg)
- do_host_pkg "$2"
- ;;
- internal-do-pkg)
- do_pkg "$2"
- ;;
- internal-do-prepare)
- do_cmd_prepare "$2"
- ;;
- internal-do-host-rebuild)
- do_cmd_host_rebuild "$2"
- ;;
- internal-do-rebuild)
- do_cmd_rebuild "$2"
- ;;
- host-build)
- shift 1
- cmd_host_build "$@"
- ;;
- build)
- shift 1
- cmd_build "$@"
- ;;
- regenerate)
- shift 1
- cmd_prepare "$@"
- ;;
- host-rebuild)
- shift 1
- cmd_host_rebuild "$@"
- ;;
- rebuild)
- shift 1
- cmd_rebuild "$@"
- ;;
- install)
- shift 1
- cmd_install "$@"
- ;;
- rbrt)
- rebuild_rbrt
- ;;
- rebuild-cache)
- redo_first_use
- ;;
- *)
- if [ -z "$1" ]; then
- die "$0: no command specified."
- else
- die "$0: unknown command: $1"
- fi
- ;;
- esac
|