diff options
author | Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de> | 2020-03-13 15:33:05 +0000 |
---|---|---|
committer | Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de> | 2020-03-13 15:33:05 +0000 |
commit | 60fba634600d0e20726c02d88735cc3d71ff0103 (patch) | |
tree | d42d7e13716ccae6e326d3bec8b30fbd3d38b612 /subr | |
parent | 4e5750f7ba7c84d09f0e8a60d92a7fc3e7ca410f (diff) | |
download | midipix_build-60fba634600d0e20726c02d88735cc3d71ff0103.tar.bz2 midipix_build-60fba634600d0e20726c02d88735cc3d71ff0103.tar.xz |
Implements ./pkgtool.sh -[irt] options.
etc/{README.md,pkgtool.usage}: updated.
subr/ex_pkg.subr:ex_pkg_{find_package,get_packages}(): initial implementation.
subr/ex_pkg.subr:ex_pkg_unfold_{,r}depends(): split from ex_pkg_expand_packages().
subr/ex_pkg{,_dispatch}.subr: removes ${EX_PKG_COMPLETE} scoped global.
subr/ex_pkg_dispatch.subr:exp_pkg_dispatch_expand_packages(): split from subr/ex_pkg.subr.
subr/rtl_list.subr:rtl_lsort(): initial implementation.
Diffstat (limited to 'subr')
-rw-r--r-- | subr/ex_pkg.subr | 210 | ||||
-rw-r--r-- | subr/ex_pkg_dispatch.subr | 80 | ||||
-rw-r--r-- | subr/ex_pkg_env.subr | 25 | ||||
-rw-r--r-- | subr/pkgtool_init.subr | 125 | ||||
-rw-r--r-- | subr/rtl_list.subr | 5 |
5 files changed, 310 insertions, 135 deletions
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 |