summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--etc/README.md62
-rw-r--r--etc/pkgtool.usage17
-rwxr-xr-xpkgtool.sh114
-rw-r--r--subr/ex_pkg.subr210
-rw-r--r--subr/ex_pkg_dispatch.subr80
-rw-r--r--subr/ex_pkg_env.subr25
-rw-r--r--subr/pkgtool_init.subr125
-rw-r--r--subr/rtl_list.subr5
8 files changed, 459 insertions, 179 deletions
diff --git a/etc/README.md b/etc/README.md
index 92786105..290a6dd3 100644
--- a/etc/README.md
+++ b/etc/README.md
@@ -17,6 +17,7 @@ internal repositories required in order to build Midipix.
3.3. [Addressing build failure](#33-addressing-build-failure)
3.4. [Patches and ``vars`` files](#34-patches-and-vars-files)
3.5. [``pkgtool.sh``](#35-pkgtoolsh)
+ 3.5.1. [``-s``: package build shell environment](#351-s-package-build-shell-environment)
4. [Build variables](#4-build-variables)
4.1. [Build steps](#41-build-steps)
4.2. [Package variables](#42-package-variables)
@@ -84,19 +85,18 @@ amount of logical processors on the build host divided by two (2).
[//]: # "{{{ 2.1. Build-time dependencies"
### 2.1. Build-time dependencies
-* **Alpine Linux**: binutils bzip2 cmake coreutils curl findutils g++ gawk gcc
+* **Alpine Linux**: awk binutils bzip2 cmake coreutils curl findutils g++ gcc
git grep gzip libc-dev linux-headers lzip make musl-dev
net-tools patch perl perl-xml-parser procps sed tar
util-linux wget xz zip
-* **Debian/-derived Linux**: binutils bzip2 clzip cmake coreutils curl findutils
- g++ gawk gcc git grep gzip hostname libc6-dev
- libxml-parser-perl lzma make patch perl procps sed
- tar util-linux wget xz-utils zip
+* **Debian/-derived Linux**: awk binutils bzip2 clzip cmake coreutils curl findutils
+ g++ gcc git grep gzip hostname libc6-dev libxml-parser-perl
+ lzma make patch perl procps sed tar util-linux wget xz-utils zip
* **OpenSUSE Linux**: binutils bzip2 cmake coreutils curl findutils gawk gcc
gcc-c++ git grep gzip hostname linux-glibc-devel lzip make
patch perl perl-XML-Parser procps sed tar util-linux wget
xz zip
-
+
> N.B. Busybox is not supported.
[Back to top](#table-of-contents)
@@ -117,12 +117,16 @@ defective.
On successful completion of the build, a ZIP archive containing the Midipix
distribution will be created inside ``${PREFIX}`` (see section [4](#4-build-variables).)
-Extract its contents on the target machine, run ``bash.bat``, and then
-``/install.sh`` inside the resulting self-contained Midipix installation shell
-window.
+Create a directory on the target machine and extract the contents of the distribution
+ZIP archive into it, run ``bash.bat``, and then ``/install.sh`` inside the resulting
+self-contained Midipix installation shell window.
> N.B. The pathname of the target directory containing ``bash.bat`` and all other
-distribution files must not contain whitespaces.
+distribution files must not contain whitespaces.
+
+> N.B. The Midipix installer defaults to ``/dev/fs/c/midipix (C:\midipix)``. If left
+unchanged, the distribution ZIP archive must not be extracted into a directory of the
+same pathname.
[Back to top](#table-of-contents)
@@ -287,7 +291,7 @@ in, most usually, ``${PKG_BUILD_DIR}/config.log``.
If ``--dump-on-abort`` was specified, a subset of the variables set and environment
variables exported will be written to ``${BUILD_WORKDIR}/${PKG_NAME}.dump``, which may
subsequently be used in order to obtain a package build shell environment with the
-``pkgtool.sh`` script (see section [3.5](#35-pkgtoolsh).)
+``pkgtool.sh`` script (see sections [3.5](#35-pkgtoolsh)[3.5.1](#351-s-package-build-shell-environment).)
[Back to top](#table-of-contents)
@@ -322,13 +326,43 @@ for a list of package build steps and how they are overriden.
[//]: # "{{{ 3.5. ``pkgtool.sh``"
## 3.5. ``pkgtool.sh``
+```
+usage: ./pkgtool.sh [-a nt32|nt64] [-b debug|release] [-i|-r|-s|-t]
+ [<variable name>=<variable override>[ ..]] name
+
+ -a nt32|nt64 Selects 32-bit or 64-bit architecture; defaults to nt64.
+ -b debug|release Selects debug or release build; defaults to debug.
+ -i List package variables and dependencies of single named package.
+ -r List reverse dependencies of single named package.
+ -s Enter interactive package build shell environment for single
+ named package; requires a package dump file. If the package
+ has not been built yet or built successfully, it will be rebuilt
+ at build steps up until, by default, the `build' build step and
+ forcibly aborted and dumped prior to enterting the shell.
+ -t Produce tarball of package build root directory and build log
+ file for the purpose of distribution given build failure.
+
+ <variable name>=<variable override>[ ..]
+ Override build variable.
+```
+
+> N.B. When using ``pkgtool.sh`` on a build w/ build variables (see section [4](#4-build-variables))
+overriden on the command line or via the environment, ensure that they are included in the
+``pkgtool.sh`` command line, preceding the package name, or exported, respectively.
+
+[Back to top](#table-of-contents)
+
+[//]: # "}}}"
+[//]: # "{{{ 3.5.1. -s: package build shell environment"
+### 3.5.1. -s: package build shell environment
+
When ``build.sh`` is executed with the ``--dump-on-abort`` option, a subset of the
variables set and environment variables exported will be written to ``${BUILD_WORKDIR}/${PKG_NAME}.dump``
on build failure, which may subsequently be used in order to obtain a package build shell
environment with the ``pkgtool.sh`` script, e.g.:
```
-midipix_build@sandbox:(src/midipix_build)> $ ./pkgtool.sh -a nt64 -b debug mc
+midipix_build@sandbox:(src/midipix_build)> $ ./pkgtool.sh -a nt64 -b debug -s mc
==> 2020/03/11 15:46:28 Launching shell `/usr/bin/zsh' within package environment and `/home/midipix_build/midipix/nt64/debug/tmp'.
==> 2020/03/11 15:46:28 Run $R to rebuild `mc'.
==> 2020/03/11 15:46:28 Run $RS <step> to restart the specified build step of `mc'
@@ -345,10 +379,6 @@ Consult sections [3.2](#32-adding-a-package), [3.4](#34-patches-and-vars-files),
[4.1](#41-build-steps), and [4.2](#42-package-variables) for further information
concerning the package build process.
-> N.B. When using ``pkgtool.sh`` on a build w/ build variables (see section [4](#4-build-variables))
-overriden on the command line or via the environment, ensure that they are included in the
-``pkgtool.sh`` command line, preceding the package name, or exported, respectively.
-
[Back to top](#table-of-contents)
[//]: # "}}}"
diff --git a/etc/pkgtool.usage b/etc/pkgtool.usage
new file mode 100644
index 00000000..aeed47b4
--- /dev/null
+++ b/etc/pkgtool.usage
@@ -0,0 +1,17 @@
+usage: ./pkgtool.sh [-a nt32|nt64] [-b debug|release] [-i|-r|-s|-t]
+ [<variable name>=<variable override>[ ..]] name
+
+ -a nt32|nt64 Selects 32-bit or 64-bit architecture; defaults to nt64.
+ -b debug|release Selects debug or release build; defaults to debug.
+ -i List package variables and dependencies of single named package.
+ -r List reverse dependencies of single named package.
+ -s Enter interactive package build shell environment for single
+ named package; requires a package dump file. If the package
+ has not been built yet or built successfully, it will be rebuilt
+ at build steps up until, by default, the `build' build step and
+ forcibly aborted and dumped prior to enterting the shell.
+ -t Produce tarball of package build root directory and build log
+ file for the purpose of distribution given build failure.
+
+ <variable name>=<variable override>[ ..]
+ Override build variable.
diff --git a/pkgtool.sh b/pkgtool.sh
index 2241f4af..e6768e85 100755
--- a/pkgtool.sh
+++ b/pkgtool.sh
@@ -1,7 +1,35 @@
#!/bin/sh
-# Copyright (c) 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
+# Copyright (c) 2020 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
#
+pkgtoolp_info() {
+ local _group_name="" _pkg_name_uc="$(rtl_toupper "${PKG_NAME}")" _pkg_names="" \
+ EX_PKG_DISABLED=""; EX_PKG_FINISHED=""; EX_PKG_NAMES="";
+ if ! _group_name="$(ex_pkg_find_package "${BUILD_GROUPS}" "${PKG_NAME}")"; then
+ rtl_log_msg failexit "Error: unknown package \`${PKG_NAME}'.";
+ elif ! _pkg_names="$(ex_pkg_get_packages "${_group_name}")"; then
+ rtl_log_msg failexit "Error: failed to expand package list of build group \`${_group_name}'.";
+ elif ! ex_pkg_env "${DEFAULT_BUILD_STEPS}" "${DEFAULT_BUILD_VARS}" \
+ "${_group_name}" 1 "${PKG_NAME}" "" "${BUILD_WORKDIR}"; then
+ rtl_log_msg failexit "Error: failed to set package environment for \`${PKG_NAME}'.";
+ else rtl_log_env_vars "package" $(set | awk -F= '/^PKG_'"${_pkg_name_uc}"'_/{print $1}' | sort);
+ if [ -z "${PKG_DEPENDS}" ]; then
+ rtl_log_msg info "Package \`${PKG_NAME}' has no dependencies.";
+ else rtl_log_msg info "Direct dependencies of \`${PKG_NAME}': ${PKG_DEPENDS}";
+ if ! ex_pkg_unfold_depends "${_group_name}" "${_pkg_names}" "${PKG_NAME}" 2 0; then
+ rtl_log_msg warn "Warning: failed to unfold dependency-expanded package name list for \`${PKG_NAME}'.";
+ else EX_PKG_NAMES="$(rtl_lfilter "${EX_PKG_NAMES}" "${PKG_NAME}")";
+ if [ -n "${EX_PKG_NAMES}" ]; then
+ rtl_log_msg info "Full dependencies of \`${PKG_NAME}': $(rtl_lsort "${EX_PKG_NAMES}")";
+ fi;
+ if [ -n "${EX_PKG_DISABLED}" ]; then
+ rtl_log_msg info "Full dependencies of \`${PKG_NAME}' (disabled packages:) $(rtl_lsort "${EX_PKG_DISABLED}")";
+ fi;
+ fi;
+ fi;
+ fi;
+};
+
pkgtoolp_restart_at() {
case "${ARG_RESTART_AT}" in
ALL) "${MIDIPIX_BUILD_PWD}/build.sh" -P -r "${PKG_NAME}" -v; ;;
@@ -9,7 +37,27 @@ pkgtoolp_restart_at() {
esac;
};
+pkgtoolp_rdepends() {
+ local _group_name="" _pkg_names="" EX_PKG_DISABLED=""; EX_PKG_FINISHED=""; EX_PKG_NAMES="";
+ if ! _group_name="$(ex_pkg_find_package "${BUILD_GROUPS}" "${PKG_NAME}")"; then
+ rtl_log_msg failexit "Error: unknown package \`${PKG_NAME}'.";
+ elif ! _pkg_names="$(ex_pkg_get_packages "${_group_name}")"; then
+ rtl_log_msg failexit "Error: failed to expand package list of build group \`${_group_name}'.";
+ elif ! ex_pkg_unfold_rdepends "${_group_name}" "${_pkg_names}" "${PKG_NAME}" 0; then
+ rtl_log_msg failexit "Error: failed to unfold reverse dependency-expanded package name list for \`${PKG_NAME}'.";
+ elif [ -z "${EX_PKG_NAMES}" ] && [ -z "${EX_PKG_DISABLED}" ]; then
+ rtl_log_msg info "Package \`${PKG_NAME}' has no reverse dependencies.";
+ else if [ -n "${EX_PKG_NAMES}" ]; then
+ rtl_log_msg info "Reverse dependencies of \`${PKG_NAME}': $(rtl_lsort "${EX_PKG_NAMES}")";
+ fi;
+ if [ -n "${EX_PKG_DISABLED}" ]; then
+ rtl_log_msg info "Reverse dependencies of \`${PKG_NAME}' (disabled packages:) $(rtl_lsort "${EX_PKG_DISABLED}")";
+ fi;
+ fi;
+};
+
pkgtoolp_shell() {
+ rtl_log_env_vars "build" $(set | awk -F= '/^PKG_/{print $1}' | sort);
rtl_log_msg info "Launching shell \`${SHELL}' within package environment and \`${PKG_BUILD_DIR}'.";
rtl_log_msg info "Run \$R to rebuild \`${PKG_NAME}'.";
rtl_log_msg info "Run \$RS <step> to restart the specified build step of \`${PKG_NAME}'";
@@ -27,6 +75,35 @@ pkgtoolp_shell() {
"${SHELL}";
};
+pkgtoolp_tarball() {
+ local _date="" _group_name="" _hname="" _pkg_name_full="" _pkg_version="" _tarball_fname="";
+ if ! _group_name="$(ex_pkg_find_package "${BUILD_GROUPS}" "${PKG_NAME}")"; then
+ rtl_log_msg failexit "Error: unknown package \`${PKG_NAME}'.";
+ elif ! ex_pkg_env "${DEFAULT_BUILD_STEPS}" "${DEFAULT_BUILD_VARS}" \
+ "${_group_name}" "${PKG_NAME}" "" "${BUILD_WORKDIR}"; then
+ rtl_log_msg failexit "Error: failed to set package environment for \`${PKG_NAME}'.";
+ elif ! _date="$(date +%Y%m%d_%H%M%S)"; then
+ rtl_log_msg failexit "Error: failed to call date(1).";
+ elif ! _hname="$(hostname -f)"; then
+ rtl_log_msg failexit "Error: failed to call hostname(1).";
+ else if [ -n "${PKG_VERSION}" ]; then
+ _pkg_name_full="${PKG_NAME}-${PKG_VERSION}";
+ else
+ _pkg_name_full="${PKG_NAME}";
+ fi;
+ _tarball_fname="${_pkg_name_full}@${_hname}-${_date}.tbz2";
+ rtl_log_msg info "Creating compressed tarball of \`${PKG_BASE_DIR}' and \`${PKG_NAME}_stderrout.log'...";
+ if ! tar -C "${BUILD_WORKDIR}" -cpf - \
+ "${PKG_BASE_DIR#${BUILD_WORKDIR%/}/}" \
+ "${PKG_NAME}_stderrout.log" |\
+ bzip2 -c -9 - > "${_tarball_fname}"; then
+ rtl_log_msg failexit "Error: failed to create compressed tarball of \`${PKG_BASE_DIR}' and \`${PKG_NAME}_stderrout.log'.";
+ else
+ rtl_log_msg info "Created compressed tarball of \`${PKG_BASE_DIR}' and \`${PKG_NAME}_stderrout.log'.";
+ fi;
+ fi;
+};
+
pkgtoolp_update_diff() {
local _diff_fname_dst="" _diff_fname_src="" _fname="" _fname_base="";
if [ -n "${PKG_VERSION}" ]; then
@@ -56,43 +133,24 @@ pkgtoolp_update_diff() {
fi;
};
-pkgtoolp_env() {
- local _rc=0; _status="";
- if [ ! -e "${BUILD_WORKDIR}/${PKG_NAME}.dump" ]; then
- rtl_log_msg fail "Warning: failed to locate environment dump for package \`${PKG_NAME}' in \`${BUILD_WORKDIR}'.";
- rtl_log_msg info "Rebuilding package \`${PKG_NAME}' w/ --dump-in build...";
- (export ARCH BUILD \
- BUILD_DLCACHEDIR BUILD_WORKDIR \
- PREFIX PREFIX_CROSS PREFIX_MINGW32 PREFIX_MINIPIX \
- PREFIX_NATIVE PREFIX_ROOT PREFIX_RPM;
- ./build.sh -a "${ARCH}" -b "${BUILD}" --dump-in build -P -r "${PKG_NAME}" -v);
- if [ ! -e "${BUILD_WORKDIR}/${PKG_NAME}.dump" ]; then
- _rc=1; _status="Error: failed to locate environment dump for package \`${PKG_NAME}' in \`${BUILD_WORKDIR}'.";
- fi;
- else
- _rc=0;
- fi;
- if [ "${_rc:-0}" -eq 0 ]\
- && ! . "${BUILD_WORKDIR}/${PKG_NAME}.dump"; then
- _rc=1; _status="Error: failed to source environment dump for package \`${PKG_NAME}' from \`${BUILD_WORKDIR}'.";
- fi; return "${_rc}";
-};
-
pkgtool() {
local _status="";
if ! cd "$(dirname "${0}")"\
|| ! . ./subr/pkgtool_init.subr\
|| ! pkgtool_init "${@}"; then
printf "Error: failed to setup environment.\n"; exit 1;
- elif ! pkgtoolp_env; then
- rtl_log_msg failexit "${_status}";
- elif ! rtl_fileop cd "${PKG_BUILD_DIR}"; then
- rtl_log_msg failexit "Error: failed to change working directory to \`${PKG_BUILD_DIR}'.";
elif [ -n "${ARG_RESTART_AT}" ]; then
pkgtoolp_restart_at;
elif [ "${ARG_UPDATE_DIFF:-0}" -eq 1 ]; then
pkgtoolp_update_diff;
- else pkgtoolp_shell;
+ elif [ "${ARG_INFO:-0}" -eq 1 ]; then
+ pkgtoolp_info;
+ elif [ "${ARG_RDEPENDS:-0}" -eq 1 ]; then
+ pkgtoolp_rdepends;
+ elif [ "${ARG_SHELL:-0}" -eq 1 ]; then
+ pkgtoolp_shell;
+ elif [ "${ARG_TARBALL:-0}" -eq 1 ]; then
+ pkgtoolp_tarball;
fi;
};
diff --git a/subr/ex_pkg.subr b/subr/ex_pkg.subr
index 68587dd4..497e89ce 100644
--- a/subr/ex_pkg.subr
+++ b/subr/ex_pkg.subr
@@ -4,7 +4,8 @@
#
# ex_pkg_check_depends() - check single named package for unsatisfied dependencies
-# @_pkg_complete: list of completed packages
+# @_pkg_disabled: list of disabled packages
+# @_pkg_finished: list of finished packages
# @_pkg_name: single package name
# @_pkg_wait: list of in-progress packages
# @_restart_recursive: optional flag specifiying either no dependency expansion (0,) dependency expansion (1,) dependency expansion and forcibly rebuild (2,) forcibly rebuild reverse dependencies (3.)
@@ -12,15 +13,18 @@
# Return: zero (0) given no outstanding dependencies, non-zero (>0) otherwise
#
ex_pkg_check_depends() {
- local _pkg_complete="${1}" _pkg_name="${2}" _pkg_wait="${3}" _restart_recursive="${4}" \
+ local _pkg_disabled="${1}" _pkg_finished="${2}" _pkg_name="${3}" \
+ _pkg_wait="${4}" _restart_recursive="${5}" \
_pkg_depends="" _pkg_name_depend="" _dependfl=0;
- if _pkg_depends="$(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' $(rtl_get_var_unsafe -u "PKG_"${_pkg_name}"_DEPENDS"))"\
+ if _pkg_depends="$(rtl_uniq $(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' $(rtl_get_var_unsafe -u "PKG_"${_pkg_name}"_DEPENDS")))"\
&& [ -n "${_pkg_depends}" ]; then
if [ -z "${_restart}" ]\
|| [ "${_restart_recursive:-0}" -ge 1 ]; then
for _pkg_name_depend in $(rtl_uniq ${_pkg_depends}); do
- if ! rtl_lmatch "${_pkg_complete}" "${_pkg_name_depend}"\
- || rtl_lmatch "${_pkg_wait}" "${_pkg_name_depend}"; then
+ if ! rtl_lmatch "${_pkg_disabled}" "${_pkg_name_depend}"\
+ && ! rtl_lmatch "${_pkg_finished}" "${_pkg_name_depend}"; then
+ _dependfl=1; break;
+ elif rtl_lmatch "${_pkg_wait}" "${_pkg_name_depend}"; then
_dependfl=1; break;
fi;
done;
@@ -30,89 +34,137 @@ ex_pkg_check_depends() {
};
#
-# ex_pkg_expand_packages() - expand build group name to list of packages ordered and filtered according to dependency and restart constraints
+# ex_pkg_find_package() - find build group a single named package belongs to
+# @_group_names: build group names
+# @_pkg_name: single named package
+#
+# Return: zero (0) on success, non-zero (>0) if package not found, group name on stdout if package was found.
+#
+ex_pkg_find_package() {
+ local _group_names="${1}" _pkg_name="${2}" _group_name="" _pkg_names="";
+ for _group_name in ${_group_names}; do
+ if _pkg_names="$(rtl_get_var_unsafe -u "${_group_name}_PACKAGES")"\
+ && [ -n "${_pkg_names}" ]\
+ && rtl_lmatch "${_pkg_names}" "${_pkg_name}"; then
+ _foundfl=1; break;
+ fi;
+ done;
+ case "${_foundfl:-0}" in
+ 0) return 1; ;;
+ 1) echo "${_group_name}"; return 0; ;;
+ esac;
+};
+
+#
+# ex_pkg_get_packages() - get list of packages belonging to single named build group
+# @_group_name: build group name
+#
+# Return: zero (0) on success, non-zero (>0) on failure, list of package names on stdout on success.
+#
+ex_pkg_get_packages() {
+ local _group_name="${1}" _pkg_names="";
+ if _pkg_names="$(rtl_get_var_unsafe -u "${_group_name}_PACKAGES")"\
+ && [ -n "${_pkg_names}" ]; then
+ echo "${_pkg_names}"; return 0;
+ else
+ return 1;
+ fi;
+};
+
+#
+# ex_pkg_unfold_depends() - unfold list of package names into dependency-expanded set of complete, disabled, finished, and outstanding package names
# @_group_name: build group name
+# @_pkg_names: list of package names
# @_restart: optional whitespace-separated list of package names to rebuild
# @_restart_recursive: optional flag specifiying either no dependency expansion (0,) dependency expansion (1,) dependency expansion and forcibly rebuild (2,) forcibly rebuild reverse dependencies (3.)
+# @_test_finished: only exclude disabled packages from ${EX_PKG_NAMES} (0,) split finished packages into ${EX_PKG_FINISHED}
#
-# Return: zero (0) on success, non-zero (>0) on failure, ${EXP_PKG_COMPLETE}, ${EXP_PKG_DISABLED}, ${EXP_PKG_FINISHED}, and ${EXP_PKG_NAMES} set post-return.
+# Return: zero (0) on success, non-zero (>0) on failure, ${EX_PKG_DISABLED}, ${EX_PKG_FINISHED}, and ${EX_PKG_NAMES} set post-return.
#
-ex_pkg_expand_packages() {
- local _group_name="${1}" _restart="${2}" _restart_recursive="${3}" \
- _pkg_depends="" _pkg_name="" _pkg_name_depend="" _pkg_names="" \
- _pkg_rdepends="" _restartfl=0;
- EXP_PKG_COMPLETE=""; EXP_PKG_DISABLED=""; EXP_PKG_FINISHED=""; EXP_PKG_NAMES="";
- if _pkg_names="$(rtl_get_var_unsafe -u "${_group_name}_PACKAGES")"\
- && [ -n "${_pkg_names}" ]; then
- if [ "${_restart_recursive:-0}" -ne 3 ]; then
- if [ -n "${_restart}" ] && ! rtl_lmatch "${_restart}" "ALL LAST"; then
- _pkg_names="$(rtl_lsearch "${_pkg_names}" "${_restart}")";
- fi;
- if [ -n "${_restart}" ]\
- && [ "${_restart_recursive:-0}" -ge 1 ]\
- && [ "${_restart_recursive:-0}" -le 2 ]; then
- _pkg_names="$(rtl_uniq $(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' ${_pkg_names}))";
+ex_pkg_unfold_depends() {
+ local _group_name="${1}" _pkg_names="${2}" _restart="${3}" \
+ _restart_recursive="${4}" _test_finished="${5}" \
+ _pkg_name="" _restartfl=0;
+ if [ -n "${_restart}" ] && ! rtl_lmatch "${_restart}" "ALL LAST"; then
+ _pkg_names="$(rtl_lsearch "${_pkg_names}" "${_restart}")";
+ fi;
+ if [ -n "${_restart}" ]\
+ && [ "${_restart_recursive:-0}" -ge 1 ]\
+ && [ "${_restart_recursive:-0}" -le 2 ]; then
+ _pkg_names="$(rtl_uniq $(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' ${_pkg_names}))";
+ fi;
+ for _pkg_name in ${_pkg_names}; do
+ if [ "${_restart}" = "ALL" ]\
+ || rtl_lmatch "${_restart}" "${_pkg_name}"; then
+ _restartfl=1;
+ else
+ _restartfl=0;
+ fi;
+ if [ "x$(rtl_get_var_unsafe -u "PKG_${_pkg_name}_DISABLED")" = "x1" ]; then
+ EX_PKG_DISABLED="$(rtl_lconcat "${EX_PKG_DISABLED}" "${_pkg_name}")";
+ _pkg_names="$(rtl_lfilter "${_pkg_names}" "${_pkg_name}")";
+ elif [ "${_test_finished:-1}" -eq 1 ]\
+ && ex_pkg_state_test "${_pkg_name}" finish\
+ && [ "${_restartfl:-0}" -eq 0 ]\
+ && [ "${_restart_recursive:-0}" -ne 2 ]\
+ && [ "x$(rtl_get_var_unsafe -u "${_group_name}_FORCE")" != "x1" ]; then
+ EX_PKG_FINISHED="$(rtl_lconcat "${EX_PKG_FINISHED}" "${_pkg_name}")";
+ _pkg_names="$(rtl_lfilter "${_pkg_names}" "${_pkg_name}")";
+ fi;
+ done;
+ EX_PKG_DISABLED="$(rtl_uniq ${EX_PKG_DISABLED})";
+ EX_PKG_FINISHED="$(rtl_uniq ${EX_PKG_FINISHED})";
+ EX_PKG_NAMES="$(rtl_uniq ${_pkg_names})";
+};
+
+#
+# ex_pkg_unfold_rdepends() - unfold list of package names into reverse dependency-expanded set of complete, disabled, finished, and outstanding package names
+# @_group_name: build group name
+# @_pkg_names: list of package names
+# @_restart: optional whitespace-separated list of package names to rebuild
+# @_restart_recursive: optional flag specifiying either no dependency expansion (0,) dependency expansion (1,) dependency expansion and forcibly rebuild (2,) forcibly rebuild reverse dependencies (3.)
+# @_test_finished: only exclude disabled packages from ${EX_PKG_NAMES} (0,) split finished packages into ${EX_PKG_FINISHED}
+#
+# Return: zero (0) on success, non-zero (>0) on failure, ${EX_PKG_DISABLED}, ${EX_PKG_FINISHED}, and ${EX_PKG_NAMES} set post-return.
+#
+ex_pkg_unfold_rdepends() {
+ local _group_name="${1}" _pkg_names="${2}" _restart="${3}" _test_finished="${4}" \
+ _pkg_depends="" _pkg_name="" _pkg_name_depend="" _pkg_rdepends="" _restartfl=0;
+ for _pkg_name_depend in ${_restart}; do
+ for _pkg_name in ${_pkg_names}; do
+ if [ "${_pkg_name}" != "${_pkg_name_depend}" ]\
+ && [ "x$(rtl_get_var_unsafe -u "PKG_${_pkg_name}_DISABLED")" != "x1" ]\
+ && _pkg_depends="$(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' $(rtl_get_var_unsafe -u "PKG_"${_pkg_name}"_DEPENDS"))"\
+ && [ -n "${_pkg_depends}" ]\
+ && rtl_lmatch "${_pkg_depends}" "${_pkg_name_depend}"; then
+ _pkg_rdepends="$(rtl_lconcat "${_pkg_rdepends}" "${_pkg_name}")";
fi;
- for _pkg_name in ${_pkg_names}; do
- if [ "${_restart}" = "ALL" ]\
- || rtl_lmatch "${_restart}" "${_pkg_name}"; then
- _restartfl=1;
- else
- _restartfl=0;
- fi;
- if [ "x$(rtl_get_var_unsafe -u "PKG_${_pkg_name}_DISABLED")" = "x1" ]; then
- EXP_PKG_COMPLETE="$(rtl_lconcat "${EXP_PKG_COMPLETE}" "${_pkg_name}")";
- EXP_PKG_DISABLED="$(rtl_lconcat "${EXP_PKG_DISABLED}" "${_pkg_name}")";
- _pkg_names="$(rtl_lfilter "${_pkg_names}" "${_pkg_name}")";
- elif ex_pkg_state_test "${_pkg_name}" finish\
- && [ "${_restartfl:-0}" -eq 0 ]\
- && [ "${_restart_recursive:-0}" -ne 2 ]\
- && [ "x$(rtl_get_var_unsafe -u "${_group_name}_FORCE")" != "x1" ]; then
- EXP_PKG_COMPLETE="$(rtl_lconcat "${EXP_PKG_COMPLETE}" "${_pkg_name}")";
- EXP_PKG_FINISHED="$(rtl_lconcat "${EXP_PKG_FINISHED}" "${_pkg_name}")";
- _pkg_names="$(rtl_lfilter "${_pkg_names}" "${_pkg_name}")";
+ done;
+ done;
+ _pkg_names="";
+ for _pkg_name in ${_pkg_rdepends}; do
+ if _pkg_depends="$(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' $(rtl_get_var_unsafe -u "PKG_"${_pkg_name}"_DEPENDS"))"\
+ && [ -n "${_pkg_depends}" ]; then
+ for _pkg_name_depend in ${_pkg_depends}; do
+ if [ "x$(rtl_get_var_unsafe -u "PKG_${_pkg_name_depend}_DISABLED")" = "x1" ]; then
+ EX_PKG_DISABLED="$(rtl_lconcat "${EX_PKG_DISABLED}" "${_pkg_name_depend}")";
+ elif [ "${_test_finished:-1}" -eq 1 ]\
+ && ex_pkg_state_test "${_pkg_name_depend}" finish\
+ && [ "x$(rtl_get_var_unsafe -u "${_group_name}_FORCE")" != "x1" ]\
+ && ! rtl_lmatch "${_pkg_rdepends}" "${_pkg_name_depend}"; then
+ EX_PKG_FINISHED="$(rtl_lconcat "${EX_PKG_FINISHED}" "${_pkg_name_depend}")";
+ elif [ "${_test_finished:-1}" -eq 0 ]\
+ || ! ex_pkg_state_test "${_pkg_name_depend}" finish\
+ || [ "x$(rtl_get_var_unsafe -u "${_group_name}_FORCE")" = "x1" ]; then
+ _pkg_names="$(rtl_lconcat "${_pkg_names}" "${_pkg_name_depend}")";
fi;
done;
- else for _pkg_name_depend in ${_restart}; do
- for _pkg_name in ${_pkg_names}; do
- if [ "${_pkg_name}" != "${_pkg_name_depend}" ]\
- && [ "x$(rtl_get_var_unsafe -u "PKG_${_pkg_name}_DISABLED")" != "x1" ]\
- && _pkg_depends="$(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' $(rtl_get_var_unsafe -u "PKG_"${_pkg_name}"_DEPENDS"))"\
- && [ -n "${_pkg_depends}" ]\
- && rtl_lmatch "${_pkg_depends}" "${_pkg_name_depend}"; then
- _pkg_rdepends="$(rtl_lconcat "${_pkg_rdepends}" "${_pkg_name}")";
- fi;
- done;
- done;
- _pkg_names="";
- for _pkg_name in ${_pkg_rdepends}; do
- if _pkg_depends="$(rtl_lunfold_depends 'PKG_${_name}_DEPENDS' $(rtl_get_var_unsafe -u "PKG_"${_pkg_name}"_DEPENDS"))"\
- && [ -n "${_pkg_depends}" ]; then
- for _pkg_name_depend in ${_pkg_depends}; do
- if [ "x$(rtl_get_var_unsafe -u "PKG_${_pkg_name_depend}_DISABLED")" = "x1" ]; then
- EXP_PKG_COMPLETE="$(rtl_lconcat "${EXP_PKG_COMPLETE}" "${_pkg_name_depend}")";
- EXP_PKG_DISABLED="$(rtl_lconcat "${EXP_PKG_DISABLED}" "${_pkg_name_depend}")";
- elif ex_pkg_state_test "${_pkg_name_depend}" finish\
- && [ "x$(rtl_get_var_unsafe -u "${_group_name}_FORCE")" != "x1" ]\
- && ! rtl_lmatch "${_pkg_rdepends}" "${_pkg_name_depend}"; then
- EXP_PKG_COMPLETE="$(rtl_lconcat "${EXP_PKG_COMPLETE}" "${_pkg_name_depend}")";
- EXP_PKG_FINISHED="$(rtl_lconcat "${EXP_PKG_FINISHED}" "${_pkg_name_depend}")";
- elif ! ex_pkg_state_test "${_pkg_name_depend}" finish\
- || [ "x$(rtl_get_var_unsafe -u "${_group_name}_FORCE")" = "x1" ]; then
- _pkg_names="$(rtl_lconcat "${_pkg_names}" "${_pkg_name_depend}")";
- fi;
- done;
- fi;
- _pkg_names="$(rtl_lconcat "${_pkg_names}" "${_pkg_name}")";
- done;
- EXP_PKG_COMPLETE="$(rtl_uniq ${EXP_PKG_COMPLETE})";
- EXP_PKG_DISABLED="$(rtl_uniq ${EXP_PKG_DISABLED})";
- EXP_PKG_FINISHED="$(rtl_uniq ${EXP_PKG_FINISHED})";
- _pkg_names="$(rtl_uniq ${_pkg_names})";
fi;
- EXP_PKG_NAMES="${_pkg_names}";
- fi;
- return 0;
+ _pkg_names="$(rtl_lconcat "${_pkg_names}" "${_pkg_name}")";
+ done;
+ EX_PKG_DISABLED="$(rtl_uniq ${EX_PKG_DISABLED})";
+ EX_PKG_FINISHED="$(rtl_uniq ${EX_PKG_FINISHED})";
+ EX_PKG_NAMES="$(rtl_uniq ${_pkg_names})";
};
# vim:filetype=sh textwidth=0
diff --git a/subr/ex_pkg_dispatch.subr b/subr/ex_pkg_dispatch.subr
index 5274d3f3..5426b8d7 100644
--- a/subr/ex_pkg_dispatch.subr
+++ b/subr/ex_pkg_dispatch.subr
@@ -22,6 +22,27 @@ exp_pkg_dispatch_complete() {
};
#
+# exp_pkg_dispatch_expand_packages() - expand build group name to list of packages ordered and filtered according to dependency and restart constraints
+# @_group_name: build group name
+# @_restart: optional whitespace-separated list of package names to rebuild
+# @_restart_recursive: optional flag specifiying either no dependency expansion (0,) dependency expansion (1,) dependency expansion and forcibly rebuild (2,) forcibly rebuild reverse dependencies (3.)
+#
+# Return: zero (0) on success, non-zero (>0) on failure, ${EX_PKG_DISABLED}, ${EX_PKG_FINISHED}, and ${EX_PKG_NAMES} set post-return.
+#
+exp_pkg_dispatch_expand_packages() {
+ local _group_name="${1}" _restart="${2}" _restart_recursive="${3}" _pkg_names="";
+ EX_PKG_DISABLED=""; EX_PKG_FINISHED=""; EX_PKG_NAMES="";
+ if _pkg_names="$(rtl_get_var_unsafe -u "${_group_name}_PACKAGES")"\
+ && [ -n "${_pkg_names}" ]; then
+ if [ "${_restart_recursive:-0}" -ne 3 ]; then
+ ex_pkg_unfold_depends "${_group_name}" "${_pkg_names}" "${_restart}" "${_restart_recursive}" 1;
+ else ex_pkg_unfold_rdepends "${_group_name}" "${_pkg_names}" "${_restart}" 1;
+ fi;
+ fi;
+ return 0;
+};
+
+#
# exp_pkg_dispatch_group() - dispatch a single build group
# @_build_steps_default: list of default build steps
# @_build_vars_default: list of default build variables
@@ -43,18 +64,19 @@ exp_pkg_dispatch_group() {
while true; do
while [ "${EXP_PKG_DISPATCH_NJOBS:-0}" -gt 0 ] && read _pipe_msg; do
case "${_pipe_msg%% *}" in
- done) : $((EXP_PKG_DISPATCH_NJOBS-=1)); _pkg_name="${_pipe_msg#done * }";
+ done) _pkg_name="${_pipe_msg#done * }"; : $((EXP_PKG_DISPATCH_NJOBS-=1));
+ EX_PKG_FINISHED="$(rtl_lconcat "${EX_PKG_FINISHED}" "${_pkg_name}")";
"${_dispatch_fn}" finish_pkg ${_pipe_msg#done };
- EXP_PKG_COMPLETE="$(rtl_lconcat "${EXP_PKG_COMPLETE}" "${_pkg_name}")";
- EXP_PKG_NAMES="$(rtl_lfilter "${EXP_PKG_NAMES}" "${_pkg_name}")";
+ EX_PKG_NAMES="$(rtl_lfilter "${EX_PKG_NAMES}" "${_pkg_name}")";
EX_PKG_DISPATCH_WAIT="$(rtl_lfilter "${EX_PKG_DISPATCH_WAIT}" "${_pkg_name}")";
- if [ -n "${EXP_PKG_NAMES}" ] && [ "${_rc}" -eq 0 ]; then
+ if [ -n "${EX_PKG_NAMES}" ] && [ "${_rc}" -eq 0 ]; then
if [ "${EXP_PKG_DISPATCH_NJOBS}" -ne "${_njobs_max}" ]; then
exp_pkg_dispatch_packages "${_build_steps_default}" \
"${_build_vars_default}" "${_dispatch_fn}" \
"${_group_name}" "${_njobs_max}" \
- "${_pipe_path}" "${EXP_PKG_COMPLETE}" \
- "${_restart_at}" "${_restart_recursive}" "${_workdir}";
+ "${_pipe_path}" "${EX_PKG_DISABLED}" \
+ "${EX_PKG_FINISHED}" "${_restart_at}" \
+ "${_restart_recursive}" "${_workdir}";
fi;
elif [ "${EXP_PKG_DISPATCH_NJOBS:-0}" -eq 0 ]; then
break;
@@ -65,13 +87,14 @@ exp_pkg_dispatch_group() {
"${_dispatch_fn}" msg_pkg ${_pipe_msg#msg_pkg }; ;;
step) "${_dispatch_fn}" step_pkg ${_pipe_msg#step }; ;;
esac; done <>"${_pipe_path}";
- if [ -n "${EXP_PKG_NAMES}" ] && [ "${_rc}" -eq 0 ]; then
+ if [ -n "${EX_PKG_NAMES}" ] && [ "${_rc}" -eq 0 ]; then
if [ "${EXP_PKG_DISPATCH_NJOBS}" -ne "${_njobs_max}" ]; then
exp_pkg_dispatch_packages "${_build_steps_default}" \
"${_build_vars_default}" "${_dispatch_fn}" \
"${_group_name}" "${_njobs_max}" "${_pipe_path}" \
- "${EXP_PKG_COMPLETE}" "${_restart_at}" \
- "${_restart_recursive}" "${_workdir}";
+ "${EX_PKG_DISABLED}" "${EX_PKG_FINISHED}" \
+ "${_restart_at}" "${_restart_recursive}" \
+ "${_workdir}";
fi;
elif [ "${EXP_PKG_DISPATCH_NJOBS:-0}" -eq 0 ]; then
break;
@@ -91,7 +114,7 @@ exp_pkg_dispatch_group() {
# @_restart_at: optional comma-separated list of build steps at which to rebuild or ALL
# @_workdir: pathname to build-specific temporary directory
#
-# Return: zero (0) on success, non-zero (>0) on failure, ${EXP_PKG_DISPATCH_NJOBS}, ${EXP_PKG_DISPATCH_COUNT}, ${EXP_PKG_NAMES}, and ${EX_PKG_DISPATCH_WAIT} may be mutated post-return.
+# Return: zero (0) on success, non-zero (>0) on failure, ${EXP_PKG_DISPATCH_NJOBS}, ${EXP_PKG_DISPATCH_COUNT}, ${EX_PKG_NAMES}, and ${EX_PKG_DISPATCH_WAIT} may be mutated post-return.
#
exp_pkg_dispatch_package() {
local _build_steps_default="${1}" _build_vars_default="${2}" _dispatch_fn="${3}" \
@@ -100,7 +123,7 @@ exp_pkg_dispatch_package() {
: $((EXP_PKG_DISPATCH_NJOBS+=1)); : $((EXP_PKG_DISPATCH_COUNT+=1)); EX_PKG_DISPATCH_WAIT="$(rtl_lconcat "${EX_PKG_DISPATCH_WAIT}" "${_pkg_name}")";
(set +o errexit -o noglob; BUILD_IS_PARENT=0;
if ex_pkg_env "${_build_steps_default}" "${_build_vars_default}" \
- "${_group_name}" "${_pkg_name}" "${_restart_at}" "${_workdir}"; then
+ "${_group_name}" 0 "${_pkg_name}" "${_restart_at}" "${_workdir}"; then
ex_pkg_exec "${_dispatch_fn}" "${_group_name}" "${_pkg_name}" "${_restart_at}";
else
return 1;
@@ -118,24 +141,27 @@ exp_pkg_dispatch_package() {
# @_group_name: build group name
# @_njobs_max: maximum count of simultaneous jobs
# @_pipe_path: pathname to parent-child process FIFO
-# @_pkg_complete: list of completed packages
+# @_pkg_disabled: list of disabled packages
+# @_pkg_finished: list of finished packages
# @_restart_at: optional comma-separated list of build steps at which to rebuild or ALL
# @_restart_recursive: optional flag specifiying either no dependency expansion (0,) dependency expansion (1,) dependency expansion and forcibly rebuild (2,) forcibly rebuild reverse dependencies (3.)
# @_workdir: pathname to build-specific temporary directory
#
-# Return: zero (0) on success, non-zero (>0) on failure, ${EXP_PKG_DISPATCH_NJOBS}, ${EXP_PKG_DISPATCH_COUNT}, ${EXP_PKG_NAMES}, and ${EX_PKG_DISPATCH_WAIT} may be mutated post-return.
+# Return: zero (0) on success, non-zero (>0) on failure, ${EXP_PKG_DISPATCH_NJOBS}, ${EXP_PKG_DISPATCH_COUNT}, ${EX_PKG_NAMES}, and ${EX_PKG_DISPATCH_WAIT} may be mutated post-return.
#
exp_pkg_dispatch_packages() {
local _build_steps_default="${1}" _build_vars_default="${2}" _dispatch_fn="${3}" \
- _group_name="${4}" _njobs_max="${5}" _pipe_path="${6}" _pkg_complete="${7}" \
- _restart_at="${8}" _restart_recursive="${9}" _workdir="${10}" \
+ _group_name="${4}" _njobs_max="${5}" _pipe_path="${6}" _pkg_disabled="${7}" \
+ _pkg_finished="${8}" _restart_at="${9}" _restart_recursive="${10}" _workdir="${11}" \
_foundfl=0 _njob=0 _pkg_depends="" _pkg_name="";
while [ "${EXP_PKG_DISPATCH_NJOBS:-0}" -lt "${_njobs_max}" ]; do
_foundfl=0;
- for _pkg_name in ${EXP_PKG_NAMES}; do
- if ! rtl_lmatch "${_pkg_complete}" "${_pkg_name}"\
+ for _pkg_name in ${EX_PKG_NAMES}; do
+ if ! rtl_lmatch "${_pkg_disabled}" "${_pkg_name}"\
+ && ! rtl_lmatch "${_pkg_finished}" "${_pkg_name}"\
&& ! rtl_lmatch "${EX_PKG_DISPATCH_WAIT}" "${_pkg_name}"\
- && ex_pkg_check_depends "${_pkg_complete}" "${_pkg_name}" "${EX_PKG_DISPATCH_WAIT}" "${_restart_recursive}"; then
+ && ex_pkg_check_depends "${_pkg_disabled}" "${_pkg_finished}" "${_pkg_name}" \
+ "${EX_PKG_DISPATCH_WAIT}" "${_restart_recursive}"; then
exp_pkg_dispatch_package "${_build_steps_default}" \
"${_build_vars_default}" "${_dispatch_fn}" \
"${_group_name}" "${_pkg_name}" "${_restart_at}" \
@@ -169,25 +195,23 @@ ex_pkg_dispatch() {
_group_names="${4}" _groups_inhibit_deps="${5}" _njobs_max="${6}" _pipe_path="${7}" \
_restart="${8}" _restart_at="${9}" _restart_recursive="${10}" _workdir="${11}" \
_pkg_name="" _pkg_names="" _rc=0 \
- EXP_PKG_COMPLETE EXP_PKG_DISABLED EXP_PKG_FINISHED EXP_PKG_DISPATCH_COUNT \
- EXP_PKG_DISPATCH_COUNT_MAX EXP_PKG_DISPATCH_NJOBS EXP_PKG_NAMES;
- EX_PKG_DISPATCH_WAIT="";
+ EX_PKG_DISABLED EX_PKG_FINISHED EX_PKG_NAMES EXP_PKG_DISPATCH_COUNT \
+ EXP_PKG_DISPATCH_COUNT_MAX EXP_PKG_DISPATCH_NJOBS; EX_PKG_DISPATCH_WAIT="";
if [ "${_groups_inhibit_deps:-0}" -eq 0 ]; then
_group_names="$(rtl_uniq $(rtl_lunfold_depends '${_name}_GROUP_DEPENDS' ${_group_names}))";
fi;
for _group_name in ${_group_names}; do
- EXP_PKG_COMPLETE="" EXP_PKG_DISABLED="" EXP_PKG_FINISHED="";
- EXP_PKG_DISPATCH_COUNT=0 EXP_PKG_DISPATCH_COUNT_MAX=0 EXP_PKG_DISPATCH_NJOBS=0;
- EXP_PKG_NAMES="" EX_PKG_DISPATCH_WAIT="";
+ EX_PKG_DISABLED=""; EX_PKG_DISPATCH_WAIT=""; EX_PKG_FINISHED=""; EX_PKG_NAMES="";
+ EXP_PKG_DISPATCH_COUNT=0; EXP_PKG_DISPATCH_COUNT_MAX=0; EXP_PKG_DISPATCH_NJOBS=0;
if "${_dispatch_fn}" start_group "${_group_name}" ""; then
if rtl_fileop mkdir "${_workdir}"\
&& rtl_log_msg vnfo "Resolving \`${_group_name}' dependencies..."\
- && ex_pkg_expand_packages "${_group_name}" "${_restart}" "${_restart_recursive}"\
- && exp_pkg_dispatch_complete "${_dispatch_fn}" "${_group_name}" "${EXP_PKG_DISABLED}" "${EXP_PKG_FINISHED}"\
+ && exp_pkg_dispatch_expand_packages "${_group_name}" "${_restart}" "${_restart_recursive}"\
+ && exp_pkg_dispatch_complete "${_dispatch_fn}" "${_group_name}" "${EX_PKG_DISABLED}" "${EX_PKG_FINISHED}"\
&& rtl_log_msg vnfo "Resolved \`${_group_name}' dependencies."\
- && EXP_PKG_DISPATCH_COUNT_MAX="$(rtl_llength "${EXP_PKG_NAMES}")"\
+ && EXP_PKG_DISPATCH_COUNT_MAX="$(rtl_llength "${EX_PKG_NAMES}")"\
&& [ "${EXP_PKG_DISPATCH_COUNT_MAX}" -gt 0 ]; then
- _pkg_names="$(rtl_lconcat "${_pkg_names}" "${EXP_PKG_NAMES}")";
+ _pkg_names="$(rtl_lconcat "${_pkg_names}" "${EX_PKG_NAMES}")";
exp_pkg_dispatch_group "${_build_steps_default}" \
"${_build_vars_default}" "${_dispatch_fn}" "${_group_name}" \
"${_njobs_max}" "${_pipe_path}" "${_restart_at}" \
diff --git a/subr/ex_pkg_env.subr b/subr/ex_pkg_env.subr
index b4e1810f..edb5e8d1 100644
--- a/subr/ex_pkg_env.subr
+++ b/subr/ex_pkg_env.subr
@@ -40,6 +40,7 @@ exp_pkg_env_defaults() {
# exp_pkg_env_set() - set package variables for single named package
# @_build_vars_default: list of default build variables
# @_group_name: build group name
+# @_nounset: don't clear package variable namespace
# @_pkg_name: single package name
#
# Sets package variables from either defaults, defaults specific to build type,
@@ -50,27 +51,30 @@ exp_pkg_env_defaults() {
# Return: zero (0) on success, non-zero (>0) on failure
#
exp_pkg_env_set() {
- local _build_vars_default="${1}" _group_name="${2}" _pkg_name="${3}" _var_prefixes="" _vars_set="" _vname="";
+ local _build_vars_default="${1}" _group_name="${2}" _nounset="${3}" \
+ _pkg_name="${4}" _var_prefixes="" _vars_set="" _vname="";
rtl_set_vars _vars_set BUILD_TYPE "DEFAULT ${_group_name} PKG_${_pkg_name}";
rtl_set_vars _vars_set INHERIT_FROM "PKG_${_pkg_name}";
_var_prefixes="$(rtl_toupper "DEFAULT DEFAULT_${PKG_BUILD_TYPE} ${_group_name}")";
for _vname in $(rtl_lfilter "${_build_vars_default}" BUILD_TYPE); do
if [ -n "${PKG_INHERIT_FROM}" ]; then
- rtl_set_vars _vars_set "${_vname}" \
- "$(rtl_lconcat "${_var_prefixes}" \
+ rtl_set_vars _vars_set "${_vname}" \
+ "$(rtl_lconcat "${_var_prefixes}" \
"$(rtl_toupper "PKG_${PKG_INHERIT_FROM} PKG_${_pkg_name}")")"
else
- rtl_set_vars _vars_set "${_vname}" \
- "$(rtl_lconcat "${_var_prefixes}" \
+ rtl_set_vars _vars_set "${_vname}" \
+ "$(rtl_lconcat "${_var_prefixes}" \
"$(rtl_toupper "PKG_${_pkg_name}")")";
fi;
done;
rtl_push_IFS :; for _vname in ${PKG_ENV_VARS_EXTRA}; do
export "${_vname}";
done; rtl_pop_IFS;
- rtl_unset_vars $(rtl_lfilter \
- "$(set | sed -ne '/^PKG_[^=]*=/s/=.*$//p')" \
- "${_vars_set}");
+ if [ "${_nounset:-0}" -eq 0 ]; then
+ rtl_unset_vars $(rtl_lfilter \
+ "$(set | sed -ne '/^PKG_[^=]*=/s/=.*$//p')" \
+ "${_vars_set}");
+ fi;
};
#
@@ -78,6 +82,7 @@ exp_pkg_env_set() {
# @_build_steps_default: list of default build steps
# @_build_vars_default: list of default build variables
# @_group_name: build group name
+# @_nounset: don't clear package variable namespace
# @_pkg_name: single package name
# @_restart_at: optional comma-separated list of build steps at which to rebuild or ALL
# @_workdir: pathname to build-specific temporary directory
@@ -86,9 +91,9 @@ exp_pkg_env_set() {
#
ex_pkg_env() {
local _build_steps_default="${1}" _build_vars_default="${2}" _group_name="${3}" \
- _pkg_name="${4}" _restart_at="${5}" _workdir="${6}" _vname="";
+ _nounset="${4}" _pkg_name="${5}" _restart_at="${6}" _workdir="${7}" _vname="";
rtl_fileop source_opt "vars/${_pkg_name}.vars" "${_group_name}/${_pkg_name}.${_group_name}";
- if ! exp_pkg_env_set "${_build_vars_default}" "${_group_name}" "${_pkg_name}"\
+ if ! exp_pkg_env_set "${_build_vars_default}" "${_group_name}" "${_nounset}" "${_pkg_name}"\
|| ! exp_pkg_env_defaults "${_build_steps_default}" "${_pkg_name}" "${_workdir}"; then
return 1;
fi;
diff --git a/subr/pkgtool_init.subr b/subr/pkgtool_init.subr
index da6a6640..c0e26ace 100644
--- a/subr/pkgtool_init.subr
+++ b/subr/pkgtool_init.subr
@@ -5,7 +5,38 @@
pkgtoolp_init_defaults() {
: ${ARCH:="nt64"}; : ${BUILD:="debug"}; : ${PKG_NAME:=""};
: ${BUILD_WORKDIR:=""}; : ${PREFIX=""};
- ARG_RESTART_AT=""; ARG_UPDATE_DIFF=0;
+ ARG_INFO=0; ARG_RESTART_AT=""; ARG_RDEPENDS=0;
+ ARG_UPDATE_DIFF=0; ARG_SHELL=0; ARG_TARBALL=0;
+ BUILD_GROUPS="";
+};
+
+pkgtoolp_init_dump() {
+ local _rc=0; _status="";
+ if [ -n "${ARG_RESTART_AT}" ]\
+ || [ "${ARG_UPDATE_DIFF:-0}" -eq 1 ]\
+ || [ "${ARG_SHELL:-0}" -eq 1 ]; then
+ if [ ! -e "${BUILD_WORKDIR}/${PKG_NAME}.dump" ]; then
+ rtl_log_msg warn "Warning: failed to locate environment dump for package \`${PKG_NAME}' in \`${BUILD_WORKDIR}'.";
+ rtl_log_msg info "Rebuilding package \`${PKG_NAME}' w/ --dump-in build...";
+ (export ARCH BUILD \
+ BUILD_DLCACHEDIR BUILD_WORKDIR \
+ PREFIX PREFIX_CROSS PREFIX_MINGW32 PREFIX_MINIPIX \
+ PREFIX_NATIVE PREFIX_ROOT PREFIX_RPM;
+ ./build.sh -a "${ARCH}" -b "${BUILD}" --dump-in build -P -r "${PKG_NAME}" -v);
+ if [ ! -e "${BUILD_WORKDIR}/${PKG_NAME}.dump" ]; then
+ _rc=1; _status="Error: failed to locate environment dump for package \`${PKG_NAME}' in \`${BUILD_WORKDIR}'.";
+ fi;
+ else
+ _rc=0;
+ fi;
+ if [ "${_rc:-0}" -eq 0 ]\
+ && ! . "${BUILD_WORKDIR}/${PKG_NAME}.dump"; then
+ _rc=1; _status="Error: failed to source environment dump for package \`${PKG_NAME}' from \`${BUILD_WORKDIR}'.";
+ elif [ "${_rc:-0}" -eq 0 ]\
+ && ! rtl_fileop cd "${PKG_BUILD_DIR}"; then
+ _rc=1; _status="Error: failed to change working directory to \`${PKG_BUILD_DIR}'.";
+ fi;
+ fi; return "${_rc}";
};
pkgtoolp_init_env() {
@@ -39,18 +70,30 @@ pkgtoolp_init_getopts() {
break;
elif [ "${_shiftfl:-0}" -gt 0 ]; then
shift "${_shiftfl}"; continue;
- elif getopts a:b:C:D:Fhp:Pr:R _opt; then
+ elif getopts a:b:hirst _opt; then
case "${_opt}" in
a) ARCH="${OPTARG}"; ;;
b) BUILD="${OPTARG}"; ;;
- h) pkgtoolp_usage; exit 0; ;;
- *) pkgtoolp_usage; exit 1; ;;
+ h) cat etc/pkgtool.usage; exit 0; ;;
+ i) ARG_INFO=1; ;;
+ r) ARG_RDEPENDS=1; ;;
+ s) ARG_SHELL=1; ;;
+ t) ARG_TARBALL=1; ;;
+ *) cat etc/pkgtool.usage; exit 1; ;;
esac; shift $((${OPTIND}-1)); OPTIND=1;
else
break;
fi;
done;
if [ "${_rc}" -eq 0 ]; then
+ if [ "$((${ARG_INFO:-0} + ${ARG_RDEPENDS:-0} + ${ARG_SHELL:-0} + ${ARG_TARBALL:-0}))" -gt 1 ]; then
+ cat etc/pkgtool.usage; rtl_log_msg failexit "Error: only one of -i, -r, -s, or -t must be specified.";
+ elif [ "$((${ARG_INFO:-0} + ${ARG_RDEPENDS:-0} + ${ARG_SHELL:-0} + ${ARG_TARBALL:-0}))" -eq 0 ]; then
+ if [ -z "${ARG_RESTART_AT}" ]\
+ && [ "${ARG_UPDATE_DIFF:-0}" -eq 0 ]; then
+ cat etc/pkgtool.usage; rtl_log_msg failexit "Error: one of -i, -r, -s, or -t must be specified.";
+ fi;
+ fi;
while [ "${#}" -gt 0 ]; do
case "${1}" in
*=*) rtl_set_var_unsafe "${1%%=*}" "${1#*=}"; ;;
@@ -70,24 +113,71 @@ pkgtoolp_init_getopts() {
return "${_rc}";
};
+pkgtoolp_init_groups() {
+ local _default_build_groups="" _fname="" _group="" _groups="" _rc=0; _status="";
+ if [ "${ARG_INFO:-0}" -eq 1 ]\
+ || [ "${ARG_RDEPENDS:-0}" -eq 1 ]\
+ || [ "${ARG_TARBALL:-0}" -eq 1 ]; then
+ for _fname in $(find ./groups -name *.group | sort); do
+ rtl_fileop source_opt "${_fname}";
+ if [ -n "${GROUP_TARGET}" ]; then
+ _group="${GROUP_TARGET}"; unset GROUP_TARGET;
+ else
+ _group="${_fname##*/}"; _group="${_group%.group}"; _group="${_group#*.}";
+ fi;
+ if ! rtl_lmatch "${_groups}" "${_group}"; then
+ _groups="$(rtl_lconcat "${_groups}" "${_group}")";
+ if [ -n "${GROUP_AUTO}" ]; then
+ if [ "${GROUP_AUTO:-0}" -ne 0 ]; then
+ _default_build_groups="$(rtl_lconcat "${_default_build_groups}" "${_group}")";
+ fi;
+ unset GROUP_AUTO;
+ else
+ _default_build_groups="$(rtl_lconcat "${_default_build_groups}" "${_group}")";
+ fi;
+ fi;
+ done;
+ _default_build_groups="$(rtl_uniq "${_default_build_groups}")";
+ BUILD_GROUPS="${_default_build_groups}";
+ fi; return "${_rc}";
+};
+
+pkgtoolp_init_package() {
+ local _foundfl=0 _group_name="" _pkg_names="" _rc=0; _status="";
+ if [ "${ARG_INFO:-0}" -eq 1 ]\
+ || [ "${ARG_RDEPENDS:-0}" -eq 1 ]\
+ || [ "${ARG_TARBALL:-0}" -eq 1 ]; then
+ for _group_name in ${BUILD_GROUPS}; do
+ if ! _pkg_names="$(rtl_get_var_unsafe -u "${_group_name}_PACKAGES")"\
+ || [ -z "${_pkg_names}" ]; then
+ rtl_log_msg warn "Warning: ignoring non-existent or invalid build group \`${_build_group}'.";
+ elif rtl_lmatch "${_pkg_names}" "${PKG_NAME}"; then
+ _foundfl=1;
+ fi;
+ done;
+ if [ "${_foundfl:-0}" -eq 0 ]; then
+ _rc=1; _status="Error: package \`${PKG_NAME}' unknown.";
+ fi;
+ fi; return "${_rc}";
+};
+
pkgtoolp_init_prereqs() {
local _cmd="" _cmds_missing="" _rc=0; _status="";
for _cmd in \
- awk bunzip2 cat chmod cmake cp date find flock g++ \
- gcc git grep gunzip gzip hostname install kill \
- ln lzip make mkdir mkfifo mv paste patch perl \
- pgrep pkill printf readlink rm sed seq sha256sum \
- sort stat tail tar test touch tr wget xz zip; do
+ awk bunzip2 bzip2 cat chmod cmake cp date find flock \
+ g++ gcc git grep gunzip gzip hostname install kill \
+ ln lzip make mkdir mkfifo mktemp mv paste patch perl \
+ pgrep pkill printf readlink rm sed sha256sum sort \
+ tail tar test touch tr uniq wget xz zip; do
if ! which "${_cmd}" >/dev/null 2>&1; then
_cmds_missing="${_cmds_missing:+${_cmds_missing} }${_cmd}";
fi;
done;
if [ -n "${_cmds_missing}" ]; then
_rc=1; _status="Error: missing prerequisite package(s): ${_cmds_missing}";
- elif ! awk -V 2>/dev/null | grep -q "^GNU Awk "; then
- _rc=1; _status="Error: awk(1) in \$PATH must be GNU Awk.";
- elif ! sed --version 2>/dev/null | grep -q "^GNU sed "; then
- _rc=1; _status="Error: sed(1) in \$PATH must be GNU sed.";
+ elif ! (FNAME="$(mktemp)" && { trap "rm -f \"\${FNAME}\"" EXIT; \
+ sed -i'' -e '' "${FNAME}" >/dev/null 2>&1; }); then
+ _rc=1; _status="Error: sed(1) in \${PATH} does not support the \`-i' option.";
fi;
return "${_rc}";
};
@@ -111,17 +201,16 @@ pkgtoolp_init_vars() {
return "${_rc}";
};
-pkgtoolp_usage() {
- echo "usage: ./pkgtool.sh [-a nt32|nt64] [-b debug|release] name" >&2;
-};
-
pkgtool_init() {
local _fname="" _rc=0 _status="";
if ! pkgtoolp_init_env \
|| ! pkgtoolp_init_defaults \
|| ! pkgtoolp_init_getopts "${@}" \
|| ! pkgtoolp_init_prereqs \
- || ! pkgtoolp_init_vars; then
+ || ! pkgtoolp_init_vars \
+ || ! pkgtoolp_init_dump \
+ || ! pkgtoolp_init_groups \
+ || ! pkgtoolp_init_package; then
_rc="${?}"; rtl_log_msg fail "${_status}"; exit "${_rc}";
elif [ -n "${_status}" ]; then
rtl_log_msg info "${_status}"; exit 0;
diff --git a/subr/rtl_list.subr b/subr/rtl_list.subr
index 479b0fd4..f57a3ee9 100644
--- a/subr/rtl_list.subr
+++ b/subr/rtl_list.subr
@@ -65,6 +65,11 @@ rtl_lsearch() {
echo "${_lnew}";
};
+rtl_lsort() {
+ local _list="${1}" _sep="${2:- }";
+ printf "%s" "${_list}" | tr "${_sep}" "\n" | sort | paste -s -d "${_sep}";
+};
+
rtl_lunfold_depends() {
local _vname_template="${1}" _depends="" _name="" _names=""; shift;
for _name in "${@}"; do