summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh2
-rw-r--r--etc/README.md20
-rw-r--r--etc/build.usage14
-rw-r--r--midipix.env102
-rw-r--r--subr.rtl/rtl_complex.subr8
-rw-r--r--subr.rtl/rtl_list.subr42
-rw-r--r--subr.rtl/rtl_state.subr26
-rw-r--r--subr/build_init.subr171
-rw-r--r--subr/ex_pkg_exec.subr2
-rw-r--r--subr/ex_pkg_restart.subr286
-rw-r--r--subr/pkg_build_clean.subr33
-rw-r--r--subr/pkg_configure_clean.subr20
-rw-r--r--subr/pkg_fetch_clean.subr21
-rw-r--r--subr/pkg_install_clean.subr12
14 files changed, 528 insertions, 231 deletions
diff --git a/build.sh b/build.sh
index aa4b4b59..a9db0909 100755
--- a/build.sh
+++ b/build.sh
@@ -39,7 +39,7 @@ buildp_dispatch_fail_pkg() {
rtl_log_msg fatal "${BUILD_WORKDIR}/${_pkg_name}_stderrout.log:";
cat "${BUILD_WORKDIR}/${_pkg_name}_stderrout.log";
if [ -n "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}" ]; then
- printf "%s" "${_pkg_name}" > "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}";
+ printf "%s\n" "${_pkg_name}" > "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}";
fi;
rtl_log_msg fatal "Build failed in \`%s', check \`%s' for details." "${_pkg_name}" "${BUILD_WORKDIR}/${_pkg_name}_stderrout.log";
else rtl_log_msg warning "Build failed in \`%s', check \`%s' for details." "${_pkg_name}" "${BUILD_WORKDIR}/${_pkg_name}_stderrout.log";
diff --git a/etc/README.md b/etc/README.md
index 582a5da6..be8c54f6 100644
--- a/etc/README.md
+++ b/etc/README.md
@@ -248,7 +248,7 @@ Rebuild entire build groups including or excluding group dependencies, respectiv
```
usage: ./build.sh [-a nt32|nt64] [-b debug|release] [-C dir[,..]] [-D kind[,..]]
- [-F ipv4|ipv6|offline] [-h] [-p jobs] [-P] [-r ALL|LAST]
+ [-F ipv4|ipv6|offline] [-h|--help| [-p jobs] [-P] [-r ALL|LAST]
[-r [*[*[*]]]name[,..][:[^|<|<=|>|>=]step,..]] [-R] [-v[v[v[v]]]]
[--as-needed] [--debug-minipix] [--dump-on-abort] [--reset-state]
[--roar] [[=]<group>|<variable name>=<variable override>[ ..]]
@@ -265,7 +265,7 @@ usage: ./build.sh [-a nt32|nt64] [-b debug|release] [-C dir[,..]] [-D kind[,
Force IPv4 (ipv4) or IPv6 (ipv6) when downloading package
archives and/or Git repositories or don't download either at all
(offline.)
- -h Show this screen.
+ -h|--help Show short/full help screen, respectively.
-p jobs Enables parallelisation at group-level, whenever applicable.
-P The maximum count of jobs defaults to the number of logical
processors on the host system divided by two (2.)
@@ -292,14 +292,14 @@ usage: ./build.sh [-a nt32|nt64] [-b debug|release] [-C dir[,..]] [-D kind[,
with, resp.
Currently defined build steps are:
- fetch_download, fetch_extract, configure_patch_pre,
- configure_autotools, configure_patch, configure, build,
- install_subdirs, install_make, install_files, install_libs,
- install, install_rpm, and clean.
-
- Additionally, the following shorthand aliases and pseudo-steps are provided:
- @fetch, @configure, @build, @install, and @clean, and
- start and finish.
+ fetch_clean, fetch_download, fetch_extract, configure_clean,
+ configure_patch_pre, configure_autotools, configure_patch,
+ configure, build_clean, build, install_clean, install_subdirs,
+ install_make, install_files, install_libs, install, install_rpm,
+ and clean.
+
+ Additionally, the following virtual steps are provided:
+ @fetch, @configure, @build, @install, @clean, and finish.
-R Ignore build failures, skip printing package logs, and continue
building (relaxed mode.)
diff --git a/etc/build.usage b/etc/build.usage
index aeb775b3..8ba2445c 100644
--- a/etc/build.usage
+++ b/etc/build.usage
@@ -43,14 +43,14 @@ usage: ./build.sh [-a nt32|nt64] [-b debug|release] [-C dir[,..]] [-D kind[,
with, resp.
Currently defined build steps are:
- fetch_download, fetch_extract, configure_patch_pre,
- configure_autotools, configure_patch, configure, build,
- install_subdirs, install_make, install_files, install_libs,
- install, install_rpm, and clean.
+ fetch_clean, fetch_download, fetch_extract, configure_clean,
+ configure_patch_pre, configure_autotools, configure_patch,
+ configure, build_clean, build, install_clean, install_subdirs,
+ install_make, install_files, install_libs, install, install_rpm,
+ and clean.
- Additionally, the following shorthand aliases and pseudo-steps are provided:
- @fetch, @configure, @build, @install, and @clean, and
- start and finish.
+ Additionally, the following virtual steps are provided:
+ @fetch, @configure, @build, @install, @clean, and finish.
-R Ignore build failures, skip printing package logs, and continue
building (relaxed mode.)
diff --git a/midipix.env b/midipix.env
index f0233986..51f3d40c 100644
--- a/midipix.env
+++ b/midipix.env
@@ -9,34 +9,42 @@
#
# Build {step,variable}s
-DEFAULT_BUILD_STEPS=" \
- start \
- fetch_download fetch_extract \
- configure_patch_pre configure_autotools configure_patch configure \
- build \
- install_subdirs install_make install_files install_libs install install_rpm \
- clean \
+DEFAULT_BUILD_STEPS=" \
+ fetch_clean fetch_download fetch_extract \
+ configure_clean configure_patch_pre configure_autotools configure_patch configure \
+ build_clean build \
+ install_clean install_subdirs install_make install_files install_libs install install_rpm \
+ clean \
finish";
-DEFAULT_BUILD_VARS=" \
- AR BASE_DIR BUILD_DIR BUILD_STEPS_DISABLE BUILD_TYPE \
- CC CFLAGS_BUILD CFLAGS_BUILD_EXTRA CFLAGS_CONFIGURE \
- CFLAGS_CONFIGURE_EXTRA CONFIG_CACHE CONFIG_CACHE_EXTRA \
- CONFIG_CACHE_LOCAL CONFIGURE CONFIGURE_ARGS CONFIGURE_ARGS_EXTRA \
- CXX CXXFLAGS_CONFIGURE CXXFLAGS_CONFIGURE_EXTRA \
- DEPENDS DESTDIR DESTDIR_HOST DISABLED ENV_VARS_EXTRA \
- FNAME FORCE_AUTORECONF GITROOT INHERIT_FROM INSTALL_FILES \
- INSTALL_FILES_DESTDIR INSTALL_FILES_DESTDIR_EXTRA INSTALL_TARGET \
- INSTALL_TARGET_EXTRA IN_TREE LDFLAGS_BUILD_EXTRA LDFLAGS_CONFIGURE \
- LDFLAGS_CONFIGURE_EXTRA LIBTOOL MAKE MAKE_INSTALL_VNAME \
- MAKE_SUBDIRS MAKEFLAGS_BUILD MAKEFLAGS_BUILD_EXTRA \
- MAKEFLAGS_INSTALL MAKEFLAGS_INSTALL_EXTRA MAKEFLAGS_VERBOSITY \
- MIRRORS MIRRORS_GIT SOFORT_FORCE SOFORT_NATIVE_CC SOFORT_NATIVE_CFLAGS \
- SOFORT_NATIVE_CFLAGS_EXTRA SOFORT_NATIVE_CXX SOFORT_NATIVE_CXXFLAGS \
- SOFORT_NATIVE_CXXFLAGS_EXTRA SOFORT_NATIVE_LD SOFORT_NATIVE_LDFLAGS \
- SOFORT_NATIVE_LDFLAGS_EXTRA NO_CLEAN NO_CLEAN_BASE_DIR NO_LOG_VARS \
- PYTHON PATCHES_EXTRA PKG_CONFIG PKG_CONFIG_LIBDIR PKGLIST_DISABLE PREFIX \
+DEFAULT_BUILD_VARS=" \
+ AR BASE_DIR BUILD_DIR BUILD_STEPS_DISABLE BUILD_TYPE \
+ CC CFLAGS_BUILD CFLAGS_BUILD_EXTRA CFLAGS_CONFIGURE \
+ CFLAGS_CONFIGURE_EXTRA CONFIG_CACHE CONFIG_CACHE_EXTRA \
+ CONFIG_CACHE_LOCAL CONFIGURE CONFIGURE_ARGS CONFIGURE_ARGS_EXTRA \
+ CXX CXXFLAGS_CONFIGURE CXXFLAGS_CONFIGURE_EXTRA \
+ DEPENDS DESTDIR DESTDIR_HOST DISABLED ENV_VARS_EXTRA \
+ FNAME FORCE_AUTORECONF GITROOT INHERIT_FROM INSTALL_FILES \
+ INSTALL_FILES_DESTDIR INSTALL_FILES_DESTDIR_EXTRA INSTALL_TARGET \
+ INSTALL_TARGET_EXTRA IN_TREE LDFLAGS_BUILD_EXTRA LDFLAGS_CONFIGURE \
+ LDFLAGS_CONFIGURE_EXTRA LIBTOOL MAKE MAKE_INSTALL_VNAME \
+ MAKE_SUBDIRS MAKEFLAGS_BUILD MAKEFLAGS_BUILD_EXTRA \
+ MAKEFLAGS_INSTALL MAKEFLAGS_INSTALL_EXTRA MAKEFLAGS_VERBOSITY \
+ MIRRORS MIRRORS_GIT SOFORT_FORCE SOFORT_NATIVE_CC SOFORT_NATIVE_CFLAGS \
+ SOFORT_NATIVE_CFLAGS_EXTRA SOFORT_NATIVE_CXX SOFORT_NATIVE_CXXFLAGS \
+ SOFORT_NATIVE_CXXFLAGS_EXTRA SOFORT_NATIVE_LD SOFORT_NATIVE_LDFLAGS \
+ SOFORT_NATIVE_LDFLAGS_EXTRA NO_CLEAN NO_CLEAN_BASE_DIR NO_LOG_VARS \
+ PYTHON PATCHES_EXTRA PKG_CONFIG PKG_CONFIG_LIBDIR PKGLIST_DISABLE PREFIX \
RANLIB RPM_DISABLE SHA256SUM SUBDIR TARGET URL URLS_GIT VERSION";
+#
+# Prerequisite commands
+DEFAULT_PREREQS=" \
+ awk bunzip2 bzip2 cat chmod cmake cp date find flock \
+ g++ gcc git grep gunzip gzip hostname id install kill \
+ ln lzip make mkdir mkfifo mktemp mv paste patch perl \
+ pgrep pkill printf readlink rm sed sha256sum sort \
+ stat tail tar test touch tr uniq wget xz zip";
+
# Path names
: ${PREFIX_ROOT:="${HOME}/midipix"};
: ${PREFIX:="${PREFIX_ROOT}/${ARCH}/${BUILD_KIND}"};
@@ -48,36 +56,36 @@ DEFAULT_BUILD_VARS=" \
: ${BUILD_DLCACHEDIR:="${PREFIX_ROOT}/dlcache"};
: ${BUILD_WORKDIR:="${PREFIX}/tmp"};
: ${DEFAULT_CHECK_PATH_VARS:="PREFIX PREFIX_NATIVE PREFIX_CROSS BUILD_DLCACHEDIR BUILD_WORKDIR"};
-: ${DEFAULT_CLEAR_ENV_VARS_EXCEPT:=" \
- HOME PATH TERM USER \
- ARCH BUILD_KIND \
- BUILD_DLCACHEDIR BUILD_HNAME BUILD_WORKDIR \
+: ${DEFAULT_CLEAR_ENV_VARS_EXCEPT:=" \
+ HOME PATH TERM USER \
+ ARCH BUILD_KIND \
+ BUILD_DLCACHEDIR BUILD_HNAME BUILD_WORKDIR \
PREFIX PREFIX_CROSS PREFIX_MINGW32 PREFIX_MINIPIX PREFIX_NATIVE PREFIX_ROOT PREFIX_RPM"};
: ${DEFAULT_CLEAR_PREFIX_PATHS:="
bin i686-nt32-midipix doc include info lib lib64 libexec man minipix minipix_dist native
rpm sbin share tmp usr x86_64-nt64-midipix x86_64-w64-mingw32 pkglist.cross pkglist.host
pkglist.native SHA256SUMS SHA256SUMS.last"};
-: ${DEFAULT_INSTALL_FILES_DESTDIR:=" \
- /=bin /=include /=lib /=lib/pkgconfig /=sbin \
- /=share /=share/doc /=share/info /=share/man \
- /=share/man/man1 /=share/man/man2 /=share/man/man3 /=share/man/man4 /=share/man/man5 \
- /=share/man/man6 /=share/man/man7 /=share/man/man8 /=share/man/man9 \
- @share/doc=doc \
- @share/info=info \
- @lib=lib64 \
- @share/man=man \
- @../lib/pkgconfig=share/pkgconfig \
+: ${DEFAULT_INSTALL_FILES_DESTDIR:=" \
+ /=bin /=include /=lib /=lib/pkgconfig /=sbin \
+ /=share /=share/doc /=share/info /=share/man \
+ /=share/man/man1 /=share/man/man2 /=share/man/man3 /=share/man/man4 /=share/man/man5 \
+ /=share/man/man6 /=share/man/man7 /=share/man/man8 /=share/man/man9 \
+ @share/doc=doc \
+ @share/info=info \
+ @lib=lib64 \
+ @share/man=man \
+ @../lib/pkgconfig=share/pkgconfig \
@.=usr"};
-: ${DEFAULT_LOG_ENV_VARS:=" \
- ARCH BUILD_KIND BUILD_DLCACHEDIR BUILD_WORKDIR DEFAULT_GITROOT \
- HOME PATH PREFIX PREFIX_CROSS PREFIX_MINGW32 PREFIX_MINIPIX \
+: ${DEFAULT_LOG_ENV_VARS:=" \
+ ARCH BUILD_KIND BUILD_DLCACHEDIR BUILD_WORKDIR DEFAULT_GITROOT \
+ HOME PATH PREFIX PREFIX_CROSS PREFIX_MINGW32 PREFIX_MINIPIX \
PREFIX_NATIVE PREFIX_RPM USER"};
-: ${DEFAULT_MIRRORS:=" \
-https://midipix.org/mirror/ \
-https://midipix.lucioillanes.de/archives/ \
+: ${DEFAULT_MIRRORS:=" \
+https://midipix.org/mirror/ \
+https://midipix.lucioillanes.de/archives/ \
"};
-: ${DEFAULT_MIRRORS_GIT:=" \
-https://midipix.lucioillanes.de/repos_git/ \
+: ${DEFAULT_MIRRORS_GIT:=" \
+https://midipix.lucioillanes.de/repos_git/ \
"};
# Default flags & variables
diff --git a/subr.rtl/rtl_complex.subr b/subr.rtl/rtl_complex.subr
index 8866484f..61637f69 100644
--- a/subr.rtl/rtl_complex.subr
+++ b/subr.rtl/rtl_complex.subr
@@ -72,4 +72,12 @@ rtl_percentage() {
printf "%d\n" "${_perc}";
};
+rtl_sunset() {
+ local _rs_rset="${1#\$}" _rs_kname="" IFS=" ";
+ eval set -- '${'"${_rs_rset}"'}';
+ while [ "${#}" -gt 0 ]; do
+ unset "${_rs_rset}${_rs_kname}"; shift;
+ done; unset "${_rs_rset}";
+};
+
# vim:filetype=sh
diff --git a/subr.rtl/rtl_list.subr b/subr.rtl/rtl_list.subr
index 29abef2e..e24973e9 100644
--- a/subr.rtl/rtl_list.subr
+++ b/subr.rtl/rtl_list.subr
@@ -46,6 +46,31 @@ rtl_lfilter() {
printf "%s" "${_lnew}";
};
+rtl_lfilter2() {
+ local _rlist="${1#\$}" _rlist_new="${2#\$}" _filter="${3}" _sep="${4:- }" IFS="${4:-${IFS:- }}"\
+ _filterfl="" _litem="" _litem_filter="" _lnew="";
+
+ if [ "${_filter:+1}" != 1 ]; then
+ eval ${_rlist_new}=; return 0;
+ else eval set -- '${'"${_rlist}"'}'\; ${_rlist_new}=;
+ while [ "${#}" -gt 0 ]; do
+ _litem="${1}"; shift; _filterfl=0;
+ for _litem_filter in ${_filter}; do
+ if [ "${_litem_filter}" = "${_litem}" ]; then
+ _filterfl=1; break;
+ fi;
+ done;
+ if [ "${_filterfl:-0}" -eq 0 ]; then
+ eval ${_rlist_new}='${'"${_rlist_new}"':+${'"${_rlist_new}"'}${_sep}}${_litem}';
+ fi;
+ done;
+ fi;
+};
+
+rtl_lfilter3() {
+ rtl_lfilter2 "${1}" "${1}" "${2}" "${3:-}";
+};
+
rtl_lfirst() {
local _list="${1}" _sep="${2}" IFS; IFS="${_sep}";
set -- ${_list}; RTL_LFIRST_HEAD="${1}";
@@ -64,12 +89,29 @@ rtl_llength() {
printf "%s" "${_llength}";
};
+rtl_llength2() {
+ local _rlist="${1#\$}" _rlen="${2#\$}" _sep="${3:- }" IFS="${3:-${IFS:- }}";
+ eval set -- '${'"${_rlist}"'}'\; ${_rlen}='${#}';
+};
+
rtl_llift() {
local _list="${1}" _sep="${2}" _sep_new="${3}" IFS; IFS="${_sep}";
set -- ${_list}; IFS="${_sep_new}";
printf "%s" "${*}";
};
+rtl_llift2() {
+ local _rlist="${1#\$}" _rlist_new="${2#\$}" _sep="${3}" \
+ _sep_new="${4}" IFS; IFS="${_sep}";
+
+ eval set -- '${'"${_rlist}"'}'; IFS="${_sep_new}";
+ eval ${_rlist_new}='"${*}"';
+};
+
+rtl_llift3() {
+ rtl_llift2 "${1}" "${1}" "${2}" "${3}";
+};
+
rtl_lmatch() {
local _list="${1}" _item="${2}" _sep="${3:- }";
[ -n "$(rtl_lsearch "${_list}" "${_item}" "${_sep}")" ];
diff --git a/subr.rtl/rtl_state.subr b/subr.rtl/rtl_state.subr
index 203ec520..da091e9c 100644
--- a/subr.rtl/rtl_state.subr
+++ b/subr.rtl/rtl_state.subr
@@ -23,16 +23,22 @@ rtl_state_set() {
};
rtl_state_test() {
- local _workdir="${1}" _pkg_name="${2}" _build_step="${3}" _restart_at="${4:-}" _done_fname="";
- _done_fname="${_workdir}/.${_pkg_name}.${_build_step}";
- if [ -z "${_restart_at}" ]\
- || [ "${_restart_at}" = "LAST" ]; then
- rtl_fileop test "${_done_fname}";
- elif [ "${_restart_at}" = "ALL" ]; then
- return 1;
- else
- ! rtl_lmatch "${_restart_at}" "${_build_step}" ",";
- fi;
+ local _workdir="${1}" _pkg_name="${2}" _build_steps="${3}" \
+ _restart_at="${4:-}" _build_step="" _done_fname="" \
+ IFS="," _rc=0;
+
+ for _build_step in ${_build_steps}; do
+ _done_fname="${_workdir}/.${_pkg_name}.${_build_step}";
+ if [ "${_restart_at:+1}" != 1 ]\
+ || [ "${_restart_at}" = "LAST" ]; then
+ rtl_fileop test "${_done_fname}"; _rc="${?}";
+ elif [ "${_restart_at}" = "ALL" ]; then
+ _rc=1;
+ else
+ rtl_lmatch "${_restart_at}" "${_build_step}" ",";
+ _rc=$((${?} ? 0 : 1));
+ fi; [ "${_rc}" -eq 0 ] && break;
+ done; return "${_rc}";
};
# vim:filetype=sh
diff --git a/subr/build_init.subr b/subr/build_init.subr
index f5894e69..2d78da91 100644
--- a/subr/build_init.subr
+++ b/subr/build_init.subr
@@ -2,145 +2,8 @@
# set +o errexit -o noglob -o nounset is assumed.
#
-buildp_expand_restart_at() {
- local _restart_at_spec="${1}" _restart_at="" _restart_at_spec_new="";
-
- for _restart_at in $(rtl_llift "${_restart_at_spec}" "," " "); do
- case "${_restart_at}" in
- @fetch) _restart_at="fetch_download,fetch_extract"; ;;
- @configure)
- _restart_at="configure_patch_pre,configure_autotools,configure_patch,configure"; ;;
- @build) _restart_at="build"; ;;
- @install)
- _restart_at="install_subdirs,install_make,install_files,install_libs,install,install_rpm"; ;;
- @clean)
- _restart_at="clean"; ;;
- *) ;;
- esac;
- _restart_at_spec_new="$(rtl_lconcat "${_restart_at_spec_new}" "${_restart_at}" ",")"
- done;
- printf "%s" "${_restart_at_spec_new}";
-};
-
-buildp_expand_restart_recursive() {
- local _restart_spec="${1}" _last_pkg="" _restart_spec_at="" _restart_spec_recursive=0;
-
- case "${_restart_spec}" in
- \*\*\*[a-zA-Z]*)
- _restart_spec="${_restart_spec#\*\*\*}"; _restart_spec_recursive=3; ;;
- \*\*[a-zA-Z]*) _restart_spec="${_restart_spec#\*\*}"; _restart_spec_recursive=2; ;;
- \*[a-zA-Z]*) _restart_spec="${_restart_spec#\*}"; _restart_spec_recursive=1; ;;
- ALL) _restart_spec_at=ALL; _restart_spec_recursive=2; ;;
- LAST) _restart_spec_at=ALL; _restart_spec_recursive=0;
- if [ -n "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}" ]\
- && [ -e "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}" ]; then
- _last_pkg="$(cat "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}")";
- rtl_fileop rm "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}";
- rtl_state_clear "${BUILD_WORKDIR}" "${_last_pkg}";
- _restart_spec="${_last_pkg}";
- else
- _status="cannot rebuild last failed package"; return 1;
- fi; ;;
- esac;
- ARG_RESTART="${_restart_spec}";
- ARG_RESTART_AT="${_restart_spec_at}";
- ARG_RESTART_RECURSIVE="${_restart_spec_recursive}";
- return 0;
-};
-
-buildp_process_restart_spec() {
- local _restart_spec="${1}" _eqfl=0 _ltfl=0 _restart_spec_at0="" _restart_spec_at="" _step="" _step1=""; _status="";
-
- buildp_expand_restart_recursive "${_restart_spec}" || return "${?}";
- _restart_spec="${ARG_RESTART}"; _restart_spec_at="${ARG_RESTART_AT}";
-
- case "${_restart_spec}" in
- "") return 0; ;;
- *:*)
- _restart_spec_at="${_restart_spec#*:}"; _restart_spec="${_restart_spec%%:*}";
- _restart_spec_at0="${_restart_spec_at}"; _restart_spec_at="";
- case "${_restart_spec_at0}" in
- ALL|LAST)
- _restart_spec_at="${_restart_spec_at0}"; ;;
-
- ^*) _restart_spec_at0="${_restart_spec_at0#^}";
- _restart_spec_at0="$(buildp_expand_restart_at "${_restart_spec_at0}")";
- _restart_spec_at="$(rtl_llift "${DEFAULT_BUILD_STEPS}" " " ",")";
- for _restart_at in $(rtl_llift "${_restart_spec_at0}" "," " "); do
- _restart_spec_at="$(rtl_lfilter "${_restart_spec_at}" "${_restart_at}" ",")";
- done; _restart_spec_at="$(rtl_lfilter "${_restart_spec_at}" "finish" ",")"; ;;
-
- \<=*|\<*|\>=*|\>*)
- [ "${_restart_spec_at0#<}" != "${_restart_spec_at0}" ] && _ltfl=1;
- if [ "${_restart_spec_at0#[<>]=}" != "${_restart_spec_at0}" ]; then
- _restart_spec_at0="${_restart_spec_at0#[<>]=}"; _eqfl=1;
- else
- _restart_spec_at0="${_restart_spec_at0#[<>]}"; _eqfl=0;
- fi; _restart_spec_at="";
- _restart_spec_at0="$(buildp_expand_restart_at "${_restart_spec_at0%%,*}")";
- if [ \( "${_eqfl}" -eq 1 \) -a \( "${_ltfl}" -eq 1 \) ]\
- || [ \( "${_eqfl}" -eq 0 \) -a \( "${_ltfl}" -eq 0 \) ]; then
- _restart_spec_at0="${_restart_spec_at0##*,}";
- elif [ \( "${_eqfl}" -eq 1 \) -a \( "${_ltfl}" -eq 0 \) ]\
- || [ \( "${_eqfl}" -eq 0 \) -a \( "${_ltfl}" -eq 1 \) ]; then
- _restart_spec_at0="${_restart_spec_at0%%,*}";
- fi;
- for _restart_at in ${DEFAULT_BUILD_STEPS}; do
- if [ "${_ltfl}" -eq 1 ]; then
- if [ "${_restart_at}" = "${_restart_spec_at0%%,*}" ]; then
- if [ "${_eqfl}" -eq 1 ]; then
- _restart_spec_at="$(rtl_lconcat "${_restart_spec_at}" "${_restart_at}" ",")";
- fi; break;
- fi;
- else
- if [ "${_restart_at}" = "${_restart_spec_at0%%,*}" ]; then
- _foundfl=1; [ "${_eqfl}" -eq 0 ] && continue;
- fi; [ "${_foundfl}" -eq 0 ] && continue;
- fi;
- _restart_spec_at="$(rtl_lconcat "${_restart_spec_at}" "${_restart_at}" ",")";
- done; ;;
-
- *) _restart_spec_at="$(buildp_expand_restart_at "${_restart_spec_at0}")"; ;;
- esac; ;;
-
- *) _restart_spec_at=ALL; ;;
- esac;
-
- ARG_RESTART="$(rtl_llift "${_restart_spec}" "," " ")";
- ARG_RESTART_AT="${_restart_spec_at}";
- if [ "${#ARG_RESTART_AT}" -eq 0 ]; then
- _status="zero-length build step list"; return 1;
- elif [ "${ARG_RESTART_AT}" != "ALL" ]\
- && [ "${ARG_RESTART_AT}" != "LAST" ]; then
- for _restart_at in $(rtl_lfilter "$(rtl_llift "${ARG_RESTART_AT}" "," " ")" "${DEFAULT_BUILD_STEPS}"); do
- case "${_restart_at}" in
- start) ;;
- *) _status="unknown build step \`${_restart_at}'"; return 1; ;;
- esac;
- done;
- fi;
- if [ "${#ARG_RESTART_AT}" -gt 0 ]\
- && [ "${ARG_RESTART_AT}" != "ALL" ]\
- && [ "${ARG_RESTART_AT}" != "LAST" ]; then
- _restart_spec_at="${ARG_RESTART_AT}"; ARG_RESTART_AT="";
- for _restart_at in ${DEFAULT_BUILD_STEPS}; do
- if rtl_lmatch "${_restart_spec_at}" "${_restart_at}" ","; then
- ARG_RESTART_AT="$(rtl_lconcat "${ARG_RESTART_AT}" "${_restart_at}" ",")";
- fi;
- done;
- if [ "${ARG_RESTART_AT##*,}" != "finish" ]; then
- _step="$(rtl_lfilter "${ARG_RESTART_AT}" "clean,finish" ",")"; _step="${_step##*,}";
- _step1="$(rtl_lfilter "${DEFAULT_BUILD_STEPS}" "clean finish")"; _step1="${_step1##* }";
- if [ "${_step}" = "${_step1}" ]; then
- ARG_RESTART_AT="$(rtl_lconcat "${ARG_RESTART_AT}" "finish" ",")";
- fi;
- fi;
- fi;
- return 0;
-};
-
buildp_init_args() {
- local _eqfl=0 _foundfl=0 _group="" _pkg_names_unknown="" _rc=0 \
+ local _foundfl=0 _group="" _pkg_names_unknown="" _rc=0 \
EX_PKG_BUILD_GROUPS EX_PKG_BUILD_GROUPS_NOAUTO; _status="";
case "${ARG_FETCH_FORCE}" in
@@ -149,26 +12,26 @@ buildp_init_args() {
ipv6) DEFAULT_GIT_ARGS="$(rtl_lconcat "-6" "${DEFAULT_GIT_ARGS}")";
DEFAULT_WGET_ARGS="$(rtl_lconcat "-6" "${DEFAULT_WGET_ARGS}")"; ;;
esac;
- if [ -z "${BUILD_HNAME:-}" ]\
+ if [ "${BUILD_HNAME:+1}" != 1 ]\
&& ! BUILD_HNAME="$(hostname)"; then
_rc=1; _status="Error: failed to obtain hostname.";
elif [ "${ARG_DUMP_ON_ABORT:-0}" -eq 1 ]\
- && [ "${ARG_RELAXED:-0}" -eq 1 ]; then
+ && [ "${ARG_RELAXED:-0}" -eq 1 ]; then
_rc=1; _status="Error: --dump-on-abort excludes -R.";
elif [ "${ARG_AS_NEEDED:-0}" -eq 1 ]\
- && [ -e "${PREFIX}/build.gitref" ]\
- && [ "$(git rev-parse HEAD)" = "$(cat "${PREFIX}/build.gitref")" ]; then
+ && [ -e "${PREFIX}/build.gitref" ]\
+ && [ "$(git rev-parse HEAD)" = "$(cat "${PREFIX}/build.gitref")" ]; then
_rc=0; _status="Git repository has not changed since last build and --as-needed was specified.";
- elif ! buildp_process_restart_spec "${ARG_RESTART:-}"; then
+ elif ! ex_pkg_process_restart_spec \$ARG_RESTART \$ARG_RESTART_AT \$ARG_RESTART_RECURSIVE; then
_rc=1; _status="Error: failed to process -r specification: ${_status}.";
elif ! ex_pkg_load_groups; then
_rc=1; _status="Error: failed to load build groups.";
else if ! rtl_lmatch "${ARG_DIST:-}" "rpm" ","\
- && [ -z "${ARG_DUMP_IN:-}" ]\
+ && [ "${ARG_DUMP_IN:+1}" != 1 ]\
&& [ "${ARG_DUMP_ON_ABORT:-0}" -eq 0 ]; then
EX_PKG_BUILD_GROUPS="$(rtl_lfilter "${EX_PKG_BUILD_GROUPS}" "host_deps_rpm")";
fi;
- if [ -z "${BUILD_GROUPS}" ]; then
+ if [ "${BUILD_GROUPS:+1}" != 1 ]; then
BUILD_GROUPS="${EX_PKG_BUILD_GROUPS}";
else _foundfl=0; for _group in ${BUILD_GROUPS}; do
if rtl_lmatch "${EX_PKG_BUILD_GROUPS}" "${_group}"; then
@@ -184,10 +47,11 @@ buildp_init_args() {
fi;
fi;
if [ "${_rc:-0}" -eq 0 ]; then
- if [ -n "${ARG_DIST}" ]; then
+ if [ "${ARG_DIST:+1}" = 1 ]; then
BUILD_GROUPS="$(rtl_lconcat "$(rtl_lfilter "${BUILD_GROUPS}" "dist")" "dist")";
fi;
- if [ -n "${ARG_RESTART}" ] && ! rtl_lmatch "${ARG_RESTART}" "ALL LAST"; then
+ if [ "${ARG_RESTART:+1}" = 1 ]\
+ && ! rtl_lmatch "${ARG_RESTART}" "ALL LAST"; then
for _pkg_name in ${ARG_RESTART}; do
if ! ex_pkg_find_package "${BUILD_GROUPS}" "${_pkg_name}" >/dev/null; then
_pkg_names_unknown="$(rtl_lconcat "${_pkg_names_unknown}" "${_pkg_name}")";
@@ -205,6 +69,7 @@ buildp_init_args() {
buildp_init_env() {
local _fname="" _rc=0; _status="";
+
if ! cd "${0%/*}"; then
printf "Error: failed to change working directory to \`${0%/*}'." >&2; exit 1;
elif ! umask 022; then
@@ -221,6 +86,7 @@ buildp_init_env() {
buildp_init_files() {
local _log_last_fname="" _log_last_num=1 _rc=0; _status=""
+
if ! rtl_fileop mkdir "${BUILD_DLCACHEDIR}" "${BUILD_WORKDIR}"\
|| rtl_lmatch "${ARG_DIST}" "rpm" ","\
&& ! rtl_fileop mkdir "${PREFIX_RPM}"; then
@@ -359,16 +225,11 @@ buildp_init_getopts() {
};
buildp_init_prereqs() {
- if ! rtl_check_prereqs \
- awk bunzip2 bzip2 cat chmod cmake cp date find flock \
- g++ gcc git grep gunzip gzip hostname id install kill \
- ln lzip make mkdir mkfifo mktemp mv paste patch perl \
- pgrep pkill printf readlink rm sed sha256sum sort \
- stat tail tar test touch tr uniq wget xz zip; then
+ if ! rtl_check_prereqs ${DEFAULT_PREREQS}; then
printf "%s\n" "${_status}" >&2; exit 1;
elif ! awk -V 2>/dev/null | grep -q "^GNU Awk "; then
printf "Error: awk(1) in \$PATH must be GNU Awk." >&2; exit 1;
- elif ! (FNAME="$(mktemp)" && { trap "rm -f \"\${FNAME}\"" EXIT; \
+ elif ! (FNAME="$(mktemp)" && { trap "rm -f \"\${FNAME}\"" EXIT; \
sed -i'' -e '' "${FNAME}" >/dev/null 2>&1; }); then
printf "Error: sed(1) in \${PATH} does not support the \`-i' option.\n" >&2; exit 1;
fi;
@@ -378,8 +239,8 @@ build_init() {
local _rc=0; _status="";
if ! buildp_init_env \
|| ! buildp_init_getopts "${@}" \
- || ! buildp_init_prereqs \
|| ! ex_pkg_load_vars \
+ || ! buildp_init_prereqs \
|| ! buildp_init_args \
|| ! buildp_init_files; then
_rc=1; _status="${_status}";
diff --git a/subr/ex_pkg_exec.subr b/subr/ex_pkg_exec.subr
index ee49b87d..f20c5c38 100644
--- a/subr/ex_pkg_exec.subr
+++ b/subr/ex_pkg_exec.subr
@@ -94,7 +94,7 @@ ex_pkg_exec() {
_rc=1;
elif rtl_test_cmd "pkg_${_pkg_name}_all"; then
"pkg_${_pkg_name}_all" "${_restart_at}"; _rc="${?}";
- else set -- $(rtl_lfilter "${PKG_BUILD_STEPS}" "start");
+ else set -- ${PKG_BUILD_STEPS};
while [ ${#} -gt 0 ]; do
_step="${1}"; shift;
if [ "${#_restart_at}" -gt 0 ]\
diff --git a/subr/ex_pkg_restart.subr b/subr/ex_pkg_restart.subr
new file mode 100644
index 00000000..20e35b63
--- /dev/null
+++ b/subr/ex_pkg_restart.subr
@@ -0,0 +1,286 @@
+#
+# set +o errexit -o noglob -o nounset is assumed.
+#
+
+#
+# exp_pkg_check_restart_at() - XXX
+# @_rspec_at: in reference to restart build step list
+#
+# Calling convention: in ref. @_rspec_at
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+exp_pkg_check_restart_at() {
+ local _epcra_rspec_at="${1#\$}" _epcra_len="" _epcra_rc=0 _epcra_spec_at=""; _status=""
+
+ if ! rtl_llift2 "${_epcra_rspec_at}" \$_epcra_spec_at "," " "\
+ || ! rtl_lfilter3 \$_epcra_spec_at "${DEFAULT_BUILD_STEPS} ALL LAST"\
+ || ! rtl_llength2 \$_epcra_spec_at \$_epcra_len; then
+ _epcra_rc=1;
+ elif [ "${_epcra_len}" -gt 0 ]; then
+ _status="unknown build step(s) \`${_epcra_spec_at}'"; _epcra_rc=1;
+ fi; return "${_epcra_rc}";
+};
+
+#
+# exp_pkg_expand_restart_at_spec() - XXX
+# @_rset: in reference to restart virtual build step set
+# @_rspec_at: inout reference to restart build step list
+#
+# Calling convention: in ref. @_rset, inout ref. @_rspec_at
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+exp_pkg_expand_restart_at_spec() {
+ local _eperas_rset="${1#\$}" _eperas_rspec_at="${2#\$}" _eperas_at="" \
+ _eperas_rc=0 _eperas_spec_at="" _eperas_spec_at_=""; _status="";
+ eval _eperas_spec_at='${'"${_eperas_rspec_at}"'}';
+
+ case "${_eperas_spec_at}" in
+ ALL|LAST|"")
+ ;;
+
+ ^*)
+ _eperas_spec_at="${_eperas_spec_at#^}";
+ if exp_pkg_expand_restart_at_virtual \
+ "${_eperas_spec_at}" \$_eperas_spec_at \
+ "${_eperas_rset}" \
+ && exp_pkg_check_restart_at \$_eperas_spec_at; then
+ rtl_llift2 \$DEFAULT_BUILD_STEPS "${_eperas_rspec_at}" " " ",";
+ rtl_llift2 \$_eperas_spec_at \$_eperas_spec_at_ "," " ";
+ for _eperas_at in ${_eperas_spec_at_}; do
+ rtl_lfilter3 "${_eperas_rspec_at}" "${_eperas_at}" ",";
+ done; rtl_lfilter3 "${_eperas_rspec_at}" "finish" ",";
+ else
+ _eperas_rc=1;
+ fi; ;;
+
+ \<=*|\<*|\>=*|\>*)
+ exp_pkg_expand_restart_at_spec_cmp \
+ "${_eperas_rset}" "${_eperas_rspec_at}"; _eperas_rc="${?}"; ;;
+
+ *)
+ if ! exp_pkg_expand_restart_at_virtual \
+ "${_eperas_spec_at}" "${_eperas_rspec_at}" \
+ "${_eperas_rset}"; then
+ _eperas_rc=1;
+ fi; ;;
+ esac;
+
+ if [ "${_eperas_rc}" -eq 0 ]; then
+ if ! exp_pkg_check_restart_at "${_eperas_rspec_at}"; then
+ _epprs_rc=1;
+ elif eval [ '"${'"${_eperas_rspec_at}"':+1}"' != 1 ]; then
+ _status="zero-length build step list"; _epprs_rc=1;
+ fi;
+ fi;
+ return "${_eperas_rc}";
+};
+
+#
+# exp_pkg_expand_restart_at_spec_cmp() - XXX
+# @_rset: in reference to restart virtual build step set
+# @_rspec_at: inout reference to restart build step list
+#
+# Calling convention: in ref. @_rset, inout ref. @_rspec_at
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+exp_pkg_expand_restart_at_spec_cmp() {
+ local _eperasc_rset="${1#\$}" _eperasc_rspec_at="${2#\$}" _eperasc_at="" \
+ _eperasc_eqfl="" _eperasc_foundfl="" _eperasc_ltfl="" _eperasc_rc=0 \
+ _eperasc_spec_at="" _eperasc_spec_at0="";
+ eval _eperasc_spec_at0='${'"${_eperasc_rspec_at}"'}';
+
+ [ "${_eperasc_spec_at0#<}" = "${_eperasc_spec_at0}" ]; _eperasc_ltfl="${?}";
+ if [ "${_eperasc_spec_at0#[<>]=}" != "${_eperasc_spec_at0}" ]; then
+ _eperasc_spec_at0="${_eperasc_spec_at0#[<>]=}"; _eperasc_eqfl=1;
+ else
+ _eperasc_spec_at0="${_eperasc_spec_at0#[<>]}"; _eperasc_eqfl=0;
+ fi; _eperasc_spec_at="";
+
+ if exp_pkg_expand_restart_at_virtual \
+ "${_eperasc_spec_at0%%,*}" \$_eperasc_spec_at0 \
+ "${_eperasc_rset}" \
+ && exp_pkg_check_restart_at \$_eperasc_spec_at0; then
+ if [ \( "${_eperasc_eqfl}" -eq 1 \) -a \( "${_eperasc_ltfl}" -eq 1 \) ]\
+ || [ \( "${_eperasc_eqfl}" -eq 0 \) -a \( "${_eperasc_ltfl}" -eq 0 \) ]; then
+ _eperasc_spec_at0="${_eperasc_spec_at0##*,}";
+ elif [ \( "${_eperasc_eqfl}" -eq 1 \) -a \( "${_eperasc_ltfl}" -eq 0 \) ]\
+ || [ \( "${_eperasc_eqfl}" -eq 0 \) -a \( "${_eperasc_ltfl}" -eq 1 \) ]; then
+ _eperasc_spec_at0="${_eperasc_spec_at0%%,*}";
+ fi;
+
+ _eperasc_foundfl=0; for _eperasc_at in ${DEFAULT_BUILD_STEPS}; do
+ if [ "${_eperasc_ltfl}" -eq 1 ]; then
+ if [ "${_eperasc_at}" = "${_eperasc_spec_at0%%,*}" ]; then
+ if [ "${_eperasc_eqfl}" -eq 1 ]; then
+ _eperasc_spec_at="${_eperasc_spec_at:+${_eperasc_spec_at},}${_eperasc_at}";
+ fi; break;
+ fi;
+ else
+ if [ "${_eperasc_at}" = "${_eperasc_spec_at0%%,*}" ]; then
+ _eperasc_foundfl=1; [ "${_eperasc_eqfl}" -eq 0 ] && continue;
+ fi; [ "${_eperasc_foundfl}" -eq 0 ] && continue;
+ fi;
+ _eperasc_spec_at="${_eperasc_spec_at:+${_eperasc_spec_at},}${_eperasc_at}";
+ done;
+ else
+ _eperasc_rc=1;
+ fi;
+
+ eval ${_eperasc_rspec_at}='${_eperasc_spec_at}';
+ return "${_eperasc_rc}";
+};
+
+#
+# exp_pkg_expand_restart_at_virtual() - XXX
+# @_spec_at: restart build step list
+# @_rspec_at_new: out reference to new restart build step list
+# @_rset: inout reference to restart virtual build step set
+#
+# Calling convention: inout ref. @_rspec_recursive
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+exp_pkg_expand_restart_at_virtual() {
+ local _epera_spec_at="${1}" _epera_rspec_at_new="${2#\$}" _epera_rset="${3#\$}" \
+ _epera_at="" _epera_IFS0="${IFS:- }" _epera_rc=0 _epera_spec_at_new="" \
+ IFS; _status="";
+
+ eval ${_epera_rspec_at_new}=;
+ IFS=","; set -- ${_epera_spec_at}; IFS="${_epera_IFS0}";
+ while [ "${#}" -gt 0 ]; do
+ _epera_at="${1}"; shift;
+ if [ "${_epera_at#@}" != "${_epera_at}" ]; then
+ _epera_at="${_epera_at#@}";
+ if [ "${_epera_at%[^0-9a-zA-Z_]*}" != "${_epera_at}" ]; then
+ _status="invalid virtual build step \`${_epera_at}'"; _epera_rc=1;
+ elif eval [ '"${'"${_epera_rset}${_epera_at}"':+1}"' = 1 ]; then
+ eval _epera_at='${'"${_epera_rset}${_epera_at}"'}';
+ else
+ _status="unknown virtual build step \`${_epera_at}'"; _epera_rc=1;
+ fi;
+ fi;
+ eval ${_epera_rspec_at_new}='${'"${_epera_rspec_at_new}"':+${'"${_epera_rspec_at_new}"'},}${_epera_at}';
+ done;
+ return "${_epera_rc}";
+};
+
+#
+# exp_pkg_expand_restart_recursive() - XXX
+# @_rspec: inout reference to restart {specification,package name list}
+# @_rrecursive: out reference to recursion flag
+#
+# Calling convention: inout ref. @_rspec, out ref. @_rrecursive
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+exp_pkg_expand_restart_recursive() {
+ local _eperr_rspec="${1#\$}" _eperr_rrecursive="${2#\$}" _eperr_spec=""; _status=""
+ eval _eperr_spec='${'"${_eperr_rspec}"'}';
+
+ case "${_eperr_spec}" in
+ \*\*\*[a-zA-Z]*)
+ eval ${_eperr_rspec}='${_eperr_spec#\*\*\*}' ${_eperr_rrecursive}=3; ;;
+ \*\*[a-zA-Z]*) eval ${_eperr_rspec}='${_eperr_spec#\*\*}' ${_eperr_rrecursive}=2; ;;
+ \*[a-zA-Z]*) eval ${_eperr_rspec}='${_eperr_spec#\*}' ${_eperr_rrecursive}=1; ;;
+ ALL) eval ${_eperr_rrecursive}=2; ;;
+ LAST) eval ${_eperr_rrecursive}=0; ;;
+ esac;
+ return 0;
+};
+
+#
+# exp_pkg_expand_restart_spec() - XXX
+# @_rspec: inout reference to restart {specification,package name list}
+# @_rspec_at: out reference to restart build step list
+#
+# Calling convention: inout ref. @_rspec, out ref. @_rspec_at, out ref. @_rrecursive
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+exp_pkg_expand_restart_spec() {
+ local _epers_rspec="${1#\$}" _epers_rspec_at="${2#\$}" _epers_last_pkg="" \
+ _epers_rc=0 _epers_spec="" _epers_spec_at="" _epers_spec_at0="";
+ eval _epers_spec='${'"${_epers_rspec}"'}';
+
+ case "${_epers_spec}" in
+ "") eval ${_eppras_rspec_at}=; ;;
+ ALL) eval ${_epers_rspec_at}=ALL; ;;
+ LAST|LAST:*)
+ case "${_epers_spec}" in
+ LAST) eval ${_epers_rspec_at}=LAST; ;;
+ LAST:*) eval ${_epers_rspec_at}='${_epers_spec#LAST:}'; ;;
+ esac;
+ if [ "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME:+1}" = 1 ]\
+ && [ -e "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}" ]; then
+ if read -r _epers_last_pkg <"${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}"\
+ && rtl_fileop rm "${DEFAULT_BUILD_LAST_FAILED_PKG_FNAME}"; then
+ eval ${_epers_rspec}='${_epers_last_pkg}';
+ else
+ _status="failed to read or clear status of last failed package \`${_epers_last_pkg}'"; _epers_rc=1;
+ fi;
+ else
+ _status="cannot rebuild last failed package"; _epers_rc=1;
+ fi; ;;
+
+ *:*) eval ${_epers_rspec}='${_epers_spec%:*}' ${_epers_rspec_at}='${_epers_spec#*:}'; ;;
+ *) eval ${_epers_rspec_at}= ${_epers_rspec_at}=ALL; ;;
+ esac;
+ return "${_epers_rc}";
+};
+
+#
+# exp_pkg_init_restart_at_virtual() - XXX
+# @_rset: out reference to restart virtual build step set
+#
+# Calling convention: out ref. @_rset
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+exp_pkg_init_restart_at_virtual() {
+ local _eperav_rset="${1#\$}" _eperav_step="" _eperav_step_virtual="" _epera_steps="";
+
+ rtl_lfilter2 \$DEFAULT_BUILD_STEPS \$_epera_steps "finish";
+ for _eperav_step in ${_epera_steps}; do
+ _eperav_step_virtual="${_eperav_step%%_*}";
+ if eval [ '"${'"${_eperav_rset}${_eperav_step_virtual}"':+1}"' != 1 ]; then
+ eval ${_eperav_rset}='"${'"${_eperav_rset}"':+${'"${_eperav_rset}"'},}${_eperav_step_virtual}"';
+ fi;
+ eval ${_eperav_rset}${_eperav_step_virtual}='"${'"${_eperav_rset}${_eperav_step_virtual}"':+${'"${_eperav_rset}${_eperav_step_virtual}"'},}${_eperav_step}"';
+ done; return 0;
+};
+
+#
+# ex_pkg_process_restart_spec() - XXX
+# @_rspec: inout reference to restart {specification,package name list}
+# @_rspec_at: out reference to restart build step list
+# @_rrecursive: out reference to restart recursion flag
+#
+# Calling convention: inout ref. @_rspec, out ref. @_rspec_at
+# Returns: zero (0) on success, non-zero (>0) on failure
+#
+ex_pkg_process_restart_spec() {
+ local _epprs_rspec="${1#\$}" _epprs_rspec_at="${2#\$}" _epprs_rrecursive="${3#\$}" \
+ _epprs_at="" _epprs_rc=0 _epprs_spec_at_new="" _epprs_step="" _epprs_step1="" \
+ _epprs_virtual_set=""; _status="";
+
+ if exp_pkg_init_restart_at_virtual \$_epprs_virtual_set \
+ && exp_pkg_expand_restart_spec "${_epprs_rspec}" \$_epprs_spec_at_new \
+ && exp_pkg_expand_restart_recursive "${_epprs_rspec}" "${_epprs_rrecursive}" \
+ && exp_pkg_expand_restart_at_spec \$_epprs_virtual_set \$_epprs_spec_at_new; then
+ eval ${_epprs_rspec_at}=;
+ for _epprs_at in ${DEFAULT_BUILD_STEPS}; do
+ if rtl_lmatch "${_epprs_at}" "${_epprs_spec_at_new}" ","; then
+ eval ${_epprs_rspec_at}='${'"${_epprs_rspec_at}"':+${'"${_epprs_rspec_at}"'},}${_epprs_at}';
+ fi;
+ done;
+ if eval [ '"${'"${_epprs_rspec_at}"'##*,}"' != "finish" ]; then
+ rtl_lfilter2 "${_epprs_rspec_at}" \$_epprs_step "clean,finish" ","; _epprs_step="${_epprs_step##*,}";
+ rtl_lfilter2 \$DEFAULT_BUILD_STEPS \$_epprs_step1 "clean finish"; _epprs_step1="${_epprs_step1##* }";
+ if [ "${_epprs_step}" = "${_epprs_step1}" ]; then
+ eval ${_epprs_rspec_at}='${'"${_epprs_rspec_at}"':+${'"${_epprs_rspec_at}"'},}finish';
+ fi;
+ fi;
+ else
+ _epprs_rc=1;
+ fi;
+ rtl_sunset \$_epprs_virtual_set;
+ return "${_epprs_rc}";
+};
+
+# vim:filetype=sh
diff --git a/subr/pkg_build_clean.subr b/subr/pkg_build_clean.subr
new file mode 100644
index 00000000..55dc19c5
--- /dev/null
+++ b/subr/pkg_build_clean.subr
@@ -0,0 +1,33 @@
+#
+# set +o errexit -o noglob -o nounset is assumed.
+#
+
+pkg_build_clean() {
+ local _libtool="" _makeflags_verbosity="${PKG_MAKEFLAGS_VERBOSITY:-}" \
+ _no_autoconf="" _rc=0 _subdir="";
+
+ if ex_pkg_state_test "${_pkg_name}" "build" "${_restart_at}"; then
+ case "${PKG_LIBTOOL:-}" in
+ "") _libtool=""; ;;
+ none) _libtool=""; ;;
+ *) _libtool="${PKG_LIBTOOL}"; ;;
+ esac;
+ [ ! -x "${PKG_CONFIGURE:-}" ] && _no_autoconf=1;
+
+ for _subdir in ${PKG_MAKE_SUBDIRS:-:}; do
+ [ "${_subdir}" = ":" ] && _subdir="";
+ [ "${#_libtool}" -gt 0 ] && export MAKE="make LIBTOOL=${_libtool}";
+ rtl_run_cmd_unsplit "${PKG_MAKE}" \
+ ${PKG_MAKEFLAGS_BUILD:-} \
+ ${PKG_MAKEFLAGS_BUILD_EXTRA:-} \
+ ${_libtool:+"LIBTOOL=${_libtool}"} \
+ ${_makeflags_verbosity} \
+ ${_subdir:+-C "${_subdir}"} \
+ clean; _rc="${?}";
+ [ "${#_libtool}" -gt 0 ] && unset MAKE;
+ [ "${_rc}" -ne 0 ] && return 1;
+ done; return 0;
+ fi;
+};
+
+# vim:filetype=sh
diff --git a/subr/pkg_configure_clean.subr b/subr/pkg_configure_clean.subr
new file mode 100644
index 00000000..48549a90
--- /dev/null
+++ b/subr/pkg_configure_clean.subr
@@ -0,0 +1,20 @@
+#
+# set +o errexit -o noglob -o nounset is assumed.
+#
+
+pkg_configure_clean() {
+ local _group_name="${1}" _pkg_name="${2}" _restart_at="${3}";
+
+ if ex_pkg_state_test \
+ "${_pkg_name}" \
+ "configure_patch_pre,configure_autotools,configure_patch,configure" \
+ "${_restart_at}"; then
+ if [ "${PKG_BUILD_DIR:-}" != "${PKG_SUBDIR:-}" ]; then
+ rtl_fileop rm "${PKG_BUILD_DIR}" || return 1;
+ rtl_fileop mkdir "${PKG_BUILD_DIR}" || return 1;
+ rtl_fileop cd "${PKG_BUILD_DIR}" || return 1;
+ fi;
+ fi;
+};
+
+# vim:filetype=sh
diff --git a/subr/pkg_fetch_clean.subr b/subr/pkg_fetch_clean.subr
new file mode 100644
index 00000000..a56196cb
--- /dev/null
+++ b/subr/pkg_fetch_clean.subr
@@ -0,0 +1,21 @@
+#
+# set +o errexit -o noglob -o nounset is assumed.
+#
+
+pkg_fetch_clean() {
+ local _dname="";
+
+ if [ -n "${PKG_URLS_GIT:-}" ]; then
+ if [ -n "${PKG_SUBDIR:-}" ]\
+ && [ "${PKG_SUBDIR}" != "${PKG_URLS_GIT%%=*}" ]; then
+ rtl_fileopm rm "${PKG_SUBDIR}";
+ fi;
+ for _dname in ${PKG_URLS_GIT}; do
+ _dname="${_dname%%=*}"; rtl_fileop rm "${_dname}";
+ done;
+ elif [ -n "${PKG_SUBDIR}" ]; then
+ rtl_fileop rm "${PKG_SUBDIR}";
+ fi; return 0;
+};
+
+# vim:filetype=sh
diff --git a/subr/pkg_install_clean.subr b/subr/pkg_install_clean.subr
new file mode 100644
index 00000000..3d99f321
--- /dev/null
+++ b/subr/pkg_install_clean.subr
@@ -0,0 +1,12 @@
+#
+# set +o errexit -o noglob -o nounset is assumed.
+#
+
+pkg_install_clean() {
+ if [ -n "${PKG_DESTDIR:-}" ]; then
+ rtl_fileop rm "${PKG_DESTDIR}" || return 1;
+ rtl_fileop mkdir "${PKG_DESTDIR}" || return 1;
+ fi; return 0;
+};
+
+# vim:filetype=sh