#
# Copyright (c) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 LucĂa Andrea Illanes Albornoz <lucia@luciaillanes.de>
# set +o errexit -o noglob -o nounset is assumed.
#
#
# ex_pkg_check_depends() - check single named package for unsatisfied dependencies
# @_checkfl: enable (1) or inhibit (0) dependency expansion
# @_rpkg_disabled: in reference to variable of list of disabled packages
# @_rpkg_finished: in reference to variable of list of finished packages
# @_pkg_name: single package name
# @_rpkg_names: in reference to variable of list of package names
# @_workdir: pathname to build-specific temporary directory
#
# Returns: zero (0) given no outstanding dependencies, non-zero (>0) otherwise
# Side effects: ${PKG_${_PKG_NAME}_DEPENDS_FULL} may be mutated
#
ex_pkg_check_depends() {
local _epcd_checkfl="${1}" _epcd_rpkg_disabled="${2}" _epcd_rpkg_finished="${3#\$}" \
_epcd_pkg_name="${4}" _epcd_rpkg_names="${5#\$}" _epcd_workdir="${6}" \
_epcd_dependfl=0 _epcd_depends="" _epcd_pkg_name_depend="";
if [ "${_epcd_checkfl}" -eq 1 ]; then
if ! rtl_get_var_unsafe \$_epcd_depends -u "PKG_"${_epcd_pkg_name}"_DEPENDS_FULL"\
|| [ "${_epcd_depends:+1}" != 1 ];
then
if rtl_get_var_unsafe \$_epcd_depends -u "PKG_"${_epcd_pkg_name}"_DEPENDS";
then
eval PKG_"${_epcd_pkg_name}"_DEPENDS_FULL='$(rtl_uniq ${_epcd_depends})';
else
return 0;
fi;
fi;
for _epcd_pkg_name_depend in ${_epcd_depends}; do
if ! rtl_lmatch "${_epcd_rpkg_disabled}" "${_epcd_pkg_name_depend}"\
&& ! ex_pkg_state_test2 "${_epcd_workdir}" "${_epcd_pkg_name_depend}" finish;
then
if ! rtl_lmatch "${_epcd_rpkg_names}" "${_epcd_pkg_name_depend}"; then
rtl_log_msgV "fatalexit" "${MSG_build_unknown_dep}" "${_epcd_pkg_name_depend}" "${_epcd_pkg_name}";
else
_epcd_dependfl=1; break;
fi;
fi;
done;
fi;
return "${_epcd_dependfl}";
};
#
# ex_pkg_find_package() - find build group a single named package belongs to
# @_rgroup_name: out reference to variable of build group name
# @_group_names: build group names
# @_pkg_name: single named package
#
# Returns: zero (0) on success, non-zero (>0) if package not found, group name on stdout if package was found.
#
ex_pkg_find_package() {
local _epfp_rgroup_name="${1#\$}" _epfp_group_names="${2}" _epfp_pkg_name="${3}" \
_epfp_foundfl=0 _epfp_group_name="" _epfp_pkg_names="";
for _epfp_group_name in ${_epfp_group_names}; do
if rtl_get_var_unsafe \$_epfp_pkg_names -u "${_epfp_group_name}_PACKAGES"\
&& [ "${_epfp_pkg_names:+1}" = 1 ]\
&& rtl_lmatch \$_epfp_pkg_names "${_epfp_pkg_name}"; then
_epfp_foundfl=1; break;
fi;
done;
case "${_epfp_foundfl:-0}" in
0) eval ${_epfp_rgroup_name}=;
return 1; ;;
1) eval ${_epfp_rgroup_name}='${_epfp_group_name}';
return 0; ;;
esac;
};
#
# ex_pkg_get_default() - get single package default value
# @_rdefault: out reference to variable of default value or "" on end of list
# @_default_idx: one-based single default value index
# @_pkg_name: single package name
# @_pkg_version: single package version
# @_ldefault: SP-separated list of default value names (any of: patches, patches_pre, vars_files)
#
# Returns: zero (0) on success, non-zero (>0) on invalid default value name or unknown package.
#
ex_pkg_get_default() {
local _epgd_rdefault="${1#\$}" _epgd_default_idx="${2}" _epgd_pkg_name="${3}" \
_epgd_pkg_version="${4}" _epgd_ldefault="${5}" \
_epgd_default="" _epgd_group_name="" _epgd_patch_fname="" \
_epgd_pkg_name_full="" _epgd_pkg_patches_extra="" _epgd_rc=0;
set --;
_epgd_pkg_name_full="${_epgd_pkg_name}${_epgd_pkg_version:+-${_epgd_pkg_version}}";
_epgd_rc=0;
for _epgd_default in ${_epgd_ldefault}; do
case "${_epgd_default}" in
patches)
rtl_get_var_unsafe \$_epgd_pkg_patches_extra -u "PKG_${_epgd_pkg_name}_PATCHES_EXTRA";
set +o noglob;
set -- \
"${@}" \
"${MIDIPIX_BUILD_PWD}/patches/${_epgd_pkg_name}/"*.patch \
"${MIDIPIX_BUILD_PWD}/patches/${_epgd_pkg_name_full}.local.patch" \
"${MIDIPIX_BUILD_PWD}/patches/${_epgd_pkg_name_full}.local@${BUILD_HNAME}.patch" \
${_epgd_pkg_patches_extra};
set -o noglob;
;;
patches_pre)
set -- \
"${@}" \
"${MIDIPIX_BUILD_PWD}/patches/${_epgd_pkg_name_full}_pre.local.patch" \
"${MIDIPIX_BUILD_PWD}/patches/${_epgd_pkg_name_full}_pre.local@${BUILD_HNAME}.patch";
;;
vars_files)
rtl_get_var_unsafe \$_epgd_group_name -u "PKG_${_epgd_pkg_name}_GROUP";
set -- \
"vars/${_epgd_pkg_name}.vars" \
"vars.${_epgd_group_name}/${_epgd_pkg_name}.vars";
;;
*)
_epgd_rc=1; break;
;;
esac;
done;
if [ "${_epgd_rc}" = 0 ]; then
eval ${_epgd_rdefault}="\${${_epgd_default_idx}:-}";
fi;
return "${_epgd_rc}";
};
#
# ex_pkg_get_packages() - get list of packages belonging to single named build group
# @_rpkg_names: out reference to variable of package names
# @_group_name: build group name
#
# Returns: zero (0) on success, non-zero (>0) on failure, list of package names on stdout on success.
#
ex_pkg_get_packages() {
local _epgp_rpkg_names="${1#\$}" _epgp_group_name="${2}" \
_epgp_pkg_names="";
if rtl_get_var_unsafe \$_epgp_pkg_names -u "${_epgp_group_name}_PACKAGES"\
&& [ "${_epgp_pkg_names:+1}" = 1 ]; then
eval ${_epgp_rpkg_names}='${_epgp_pkg_names}';
return 0;
else
eval ${_epgp_rpkg_names}=;
return 1;
fi;
};
#
# ex_pkg_get_package_vars() - get package variable names
# @_rpkg_vnames: out reference to package variable names variable
# @_build_vars_default: list of default build variables
# @_pkg_name: single package name
#
# Returns: zero (0) on success, non-zero (>0) on failure, list of package names on stdout on success.
#
ex_pkg_get_package_vars() {
local _epgpv_rpkg_vnames="${1#\$}" _epgpv_build_vars_default="${2}" _epgpv_pkg_name="${3}" \
_epgpv_pkg_name_uc="" _epgpv_vname="" _epgpv_vnames="";
rtl_toupper2 \$_epgpv_pkg_name \$_epgpv_pkg_name_uc;
for _epgpv_vname in ${_epgpv_build_vars_default}; do
if eval [ \"\${PKG_${_epgpv_pkg_name_uc}_${_epgpv_vname}:+1}\" = 1 ]; then
rtl_lconcat \$_epgpv_vnames "PKG_${_epgpv_pkg_name_uc}_${_epgpv_vname}";
fi;
done;
eval ${_epgpv_rpkg_vnames}='${_epgpv_vnames}';
return 0;
}
#
# ex_pkg_load_vars() - load build variables
# @_rstatus: out reference to status string
# @_rbuild_arch: in reference to build architecture
# @_rbuild_kind: in reference to build kind
#
# Returns: zero (0) on success, non-zero (>0) on failure, build variables post-return on success.
#
ex_pkg_load_vars() {
local _eplv_rstatus="${1#\$}" _eplv_rbuild_arch="${2#\$}" _eplv_rbuild_kind="${3#\$}" \
_eplv_build_arch="" _eplv_rc=0 _eplv_fname="";
if ! rtl_lmatch "${_eplv_rbuild_arch}" "nt32 nt64"; then
_eplv_rc=1;
rtl_setrstatus "${_eplv_rstatus}" 'invalid architecture \`${'"${_eplv_rbuild_arch}"'}'\''.';
elif ! rtl_lmatch "${_eplv_rbuild_kind}" "debug release"; then
_eplv_rc=1;
rtl_setrstatus "${_eplv_rstatus}" 'unknown build type \`${'"${_eplv_rbuild_kind}"'}'\''.';
else
eval _eplv_build_arch="\${${_eplv_rbuild_arch}}";
case "${_eplv_build_arch}" in
nt32) DEFAULT_TARGET="i686-nt32-midipix"; ;;
nt64) DEFAULT_TARGET="x86_64-nt64-midipix"; ;;
esac;
if [ "${PREFIX_ROOT:+1}" ]\
&& [ "${PREFIX_ROOT#/}" = "${PREFIX_ROOT}" ]; then
PREFIX_ROOT="${PWD%/}/${PREFIX_ROOT}";
fi;
if [ "${PREFIX:+1}" ]\
&& [ "${PREFIX#/}" = "${PREFIX}" ]; then
PREFIX="${PWD%/}/${PREFIX}";
fi;
for _eplv_fname in \
"${HOME}/midipix_build.vars" \
"${HOME}/.midipix_build.vars" \
../midipix_build.vars;
do
if [ -r "${_eplv_fname}" ]; then
rtl_fileop source "${_eplv_fname}";
fi;
done;
set +o noglob;
for _eplv_fname in \
./vars.env.d/*.env;
do
set -o noglob;
if [ -r "${_eplv_fname}" ]; then
rtl_fileop source "${_eplv_fname}";
fi;
done;
set -o noglob;
fi;
return "${_eplv_rc}";
};
#
# ex_pkg_load_groups() - load all available build groups
# @_rgroups: out reference to variable of build groups
# @_rgroups_noauoto: optional out reference to variable of build groups not built automatically
#
# Returns: zero (0) on success, non-zero (>0) on failure.
#
ex_pkg_load_groups() {
local _eplg_rgroups="${1#\$}" _eplg_rgroups_noauto="${2#\$}" \
_eplg_build_groups="" _eplg_build_groups_noauto="" \
_eplg_fname="" _eplg_group="" _eplg_group_noautofl=0 \
_eplg_group_target="" _eplg_group_target_uc="" \
_eplg_group_target_appendfl=0 _eplg_groups="" _eplg_pkg_name="" \
_eplg_pkg_names="";
for _eplg_fname in $(find ./groups.d -name *.group | sort); do
rtl_fileop source "${_eplg_fname}";
_eplg_group="${_eplg_fname##*/}";
_eplg_group="${_eplg_group%.group}";
_eplg_group="${_eplg_group#*.}";
if [ "${GROUP_TARGET_APPEND:+1}" = 1 ]; then
_eplg_group_target="${GROUP_TARGET_APPEND}";
_eplg_group_target_appendfl=1;
unset GROUP_TARGET_APPEND;
else
_eplg_group_target="${_eplg_group}";
_eplg_group_target_appendfl=0;
fi;
_eplg_group_noautofl=0;
if ! rtl_lmatch \$_eplg_groups "${_eplg_group_target}"; then
rtl_lconcat \$_eplg_groups "${_eplg_group_target}";
if eval [ \"\${GROUP_AUTO:+1}\" = 1 ]; then
if eval [ \"\${GROUP_AUTO:-0}\" -ne 0 ]; then
_eplg_group_noautofl=0;
rtl_lconcat \$_eplg_build_groups "${_eplg_group_target}";
else
_eplg_group_noautofl=1;
rtl_lconcat \$_eplg_build_groups_noauto "${_eplg_group_target}";
fi;
unset GROUP_AUTO;
else
rtl_lconcat \$_eplg_build_groups "${_eplg_group_target}";
fi;
fi;
if rtl_get_var_unsafe \$_eplg_pkg_names -u "${_eplg_group}_PACKAGES"\
&& [ "${_eplg_pkg_names:+1}" = 1 ]; then
if [ "${_eplg_group_target_appendfl}" -eq 1 ]; then
rtl_toupper2 \$_eplg_group_target \$_eplg_group_target_uc;
rtl_lconcat "\$${_eplg_group_target_uc}_PACKAGES" "${_eplg_pkg_names}";
fi;
if [ "${_eplg_group_noautofl}" -eq 0 ]; then
for _eplg_pkg_name in ${_eplg_pkg_names}; do
rtl_set_var_unsafe -u "PKG_${_eplg_pkg_name}_GROUP" "${_eplg_group}";
rtl_set_var_unsafe -u "PKG_${_eplg_pkg_name}_GROUP_FNAME" "${_eplg_fname}";
done;
fi;
fi;
done;
for _eplg_fname in $(find ./groups.d -mindepth 2 -name *.package | sort); do
rtl_fileop source_with_fnamevar "${_eplg_fname}";
done;
_eplg_build_groups="$(rtl_uniq "${_eplg_build_groups}")";
eval ${_eplg_rgroups}=\"${_eplg_build_groups}\";
if [ "${_eplg_rgroups_noauto:+1}" = 1 ]; then
_eplg_build_groups_noauto="$(rtl_uniq "${_eplg_build_groups_noauto}")";
eval ${_eplg_rgroups_noauto}=\"${_eplg_build_groups_noauto}\";
fi;
return 0;
};
#
# ex_pkg_register() - register single package
# @_pkg_name: single package name
# @_fname: pathname to file package is defined in, relative to midipix_build root
# @[_group_name]: optional build group name; inferred from @_fname if not specified
#
# Returns: zero (0) on success, non-zero (>0) on failure.
#
ex_pkg_register() {
local _epr_pkg_name="${1}" _epr_fname="${2}" _epr_group_name="${3:-}" \
_epr_group_name_uc="" _epr_group_noautofl=0;
if [ "${_epr_group_name:+1}" != 1 ]; then
_epr_group_name="${_epr_fname#./*/}";
_epr_group_name="${_epr_group_name%%/*}";
_epr_group_name="${_epr_group_name%.d}";
_epr_group_name="${_epr_group_name#*.}";
fi;
rtl_toupper2 \$_epr_group_name \$_epr_group_name_uc;
rtl_lconcat "\$${_epr_group_name_uc}_PACKAGES" "${_epr_pkg_name}";
rtl_set_var_unsafe -u "PKG_${_epr_pkg_name}_GROUP" "${_epr_group_name}";
rtl_set_var_unsafe -u "PKG_${_epr_pkg_name}_GROUP_FNAME" "${_epr_fname}";
return 0;
};
#
# ex_pkg_unfold_depends() - unfold list of package names into dependency-expanded set of complete, disabled, finished, and outstanding package names
# @_rdisabled: in reference toout variable of disabled packages
# @_rfinished: in reference toout variable of finished packages
# @_rnames: out reference to variable of package names
# @_checkfl: enable (1) or inhibit (0) dependency expansion
# @_forcefl: enable (1) or inhibit (0) forcibly rebuilding finished packages
# @_group_name: build group name
# @_pkg_names: list of package names
# @_restart: optional whitespace-separated list of package names to rebuild
# @_test_finished: only exclude disabled packages (0,) split finished packages
# @_workdir: pathname to build-specific temporary directory
#
# Returns: zero (0) on success, non-zero (>0) on failure.
#
ex_pkg_unfold_depends() {
local _epud_rdisabled="${1#\$}" _epud_rfinished="${2#\$}" _epud_rnames="${3#\$}" \
_epud_checkfl="${4}" _epud_forcefl="${5}" _epud_group_name="${6}" \
_epud_pkg_names="${7}" _epud_restart="${8}" _epud_test_finished="${9}" \
_epud_workdir="${10}" \
_epud_pkg_disabled="" _epud_pkg_force="" _epud_pkg_name="" \
_epud_pkg_names_new="" _epud_restartfl=0;
if [ "${_epud_restart:+1}" = 1 ]\
&& ! rtl_lmatch \$_epud_restart "ALL LAST"; then
rtl_lsearch \$_epud_pkg_names "${_epud_restart}";
fi;
if [ "${_epud_restart:+1}" = 1 ]\
&& [ "${_epud_checkfl:-0}" -eq 1 ]; then
rtl_lunfold_dependsV 'PKG_${_rld_name}_DEPENDS' \$_epud_pkg_names ${_epud_pkg_names};
_epud_pkg_names="$(rtl_uniq ${_epud_pkg_names})";
fi;
for _epud_pkg_name in ${_epud_pkg_names}; do
if [ "${_epud_restart}" = "ALL" ]\
|| rtl_lmatch \$_epud_restart "${_epud_pkg_name}"; then
_epud_restartfl=1;
else
_epud_restartfl=0;
fi;
if rtl_get_var_unsafe \$_epud_pkg_disabled -u "PKG_${_epud_pkg_name}_DISABLED"\
&& [ "${_epud_pkg_disabled}" = 1 ];
then
rtl_lconcat "${_epud_rdisabled}" "${_epud_pkg_name}";
elif [ "${_epud_test_finished:-1}" -eq 1 ]\
&& ex_pkg_state_test2 "${_epud_workdir}" "${_epud_pkg_name}" finish\
&& [ "${_epud_restartfl:-0}" -eq 0 ]\
&& [ "${_epud_forcefl:-0}" -ne 1 ]\
&& rtl_get_var_unsafe \$_epud_pkg_force -u "${_epud_group_name}_FORCE"\
&& [ "${_epud_pkg_force}" != 1 ];
then
rtl_lconcat "${_epud_rfinished}" "${_epud_pkg_name}";
else
rtl_lconcat \$_epud_pkg_names_new "${_epud_pkg_name}";
fi;
done;
eval ${_epud_rdisabled}='$(rtl_uniq2 "${_epud_rdisabled}")';
eval ${_epud_rfinished}='$(rtl_uniq2 "${_epud_rfinished}")';
eval ${_epud_rnames}='$(rtl_uniq "${_epud_pkg_names_new}")';
return 0;
};
#
# ex_pkg_unfold_rdepends() - unfold list of package names into reverse dependency-expanded set of complete, disabled, finished, and outstanding package names
# @_rdisabled: in reference toout variable of disabled packages
# @_rfinished: in reference toout variable of finished packages
# @_rnames: out reference to variable of package names
# @_group_name: build group name
# @_pkg_names: list of package names
# @_restart: optional whitespace-separated list of package names to rebuild
# @_test_finished: only exclude disabled packages (0,) split finished packages
# @_workdir: pathname to build-specific temporary directory
#
# Returns: zero (0) on success, non-zero (>0) on failure.
#
ex_pkg_unfold_rdepends() {
local _epur_rdisabled="${1#\$}" _epur_rfinished="${2#\$}" _epur_rnames="${3#\$}" \
_epur_group_name="${4}" _epur_pkg_names="${5}" _epur_restart="${6}" \
_epur_test_finished="${7}" _epur_workdir="${8}" \
_epur_depends="" _epur_disabled=0 _epur_force=0 _epur_pkg_depends="" \
_epur_pkg_name="" _epur_pkg_names_new="" _epur_pkg_name_depend="" \
_epur_pkg_rdepends="";
for _epur_pkg_name_depend in ${_epur_restart}; do
for _epur_pkg_name in ${_epur_pkg_names}; do
if [ "${_epur_pkg_name}" = "${_epur_pkg_name_depend}" ]; then
continue;
elif rtl_get_var_unsafe \$_epur_depends -u "PKG_"${_epur_pkg_name}"_DEPENDS"\
&& rtl_lunfold_dependsV 'PKG_${_rld_name}_DEPENDS' \$_epur_pkg_depends ${_epur_depends}\
&& [ "${_epur_pkg_depends:+1}" = 1 ]\
&& rtl_lmatch \$_epur_pkg_depends "${_epur_pkg_name_depend}";
then
if rtl_get_var_unsafe \$_epur_disabled -u "PKG_${_epur_pkg_name}_DISABLED"\
&& [ "${_epur_disabled}" = 1 ];
then
rtl_lconcat "${_epur_rdisabled}" "${_epur_pkg_name}";
elif [ "${_epur_test_finished}" -eq 1 ]\
&& ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name}" finish\
&& rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
&& [ "${_epur_force}" != 1 ];
then
rtl_lconcat "${_epur_rfinished}" "${_epur_pkg_name}";
elif [ "${_epur_test_finished:-1}" -eq 0 ]\
|| ! ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name}" finish\
|| ( rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
&& [ "${_epur_force}" = 1 ] );
then
rtl_lconcat \$_epur_pkg_names_new "${_epur_pkg_name}";
fi;
fi;
done;
done;
eval ${_epur_rdisabled}='$(rtl_uniq2 "${_epur_rdisabled}")';
eval ${_epur_rfinished}='$(rtl_uniq2 "${_epur_rfinished}")';
eval ${_epur_rnames}='$(rtl_uniq "${_epur_pkg_names_new}")';
return 0;
};
# vim:filetype=sh textwidth=0