Add another stage 'check' between 'build' and 'install'. It is be enabled using the variable XBPS_CHECK_PKGS=yes and disabled if unset, set to "0" or "no" in your local etc/conf. A new xbps-src option `-q` for `quick` will disable XBPS_CHECK_PKGS by overriding it to 0. If enabled, `common/xbps-src/shutils/xbps-src-docheck.sh` checks for an existing `do_check()` function in the package's template and, if it exists, calls it. A new template variable `checkdepends` may be present and list packages required to run the `do_check()` function. Example: `checkdepends="bc unittest-cpp"`.
439 lines
14 KiB
Bash
439 lines
14 KiB
Bash
# vim: set ts=4 sw=4 et:
|
|
#
|
|
setup_pkg_depends() {
|
|
local pkg="$1" j _pkgdepname _pkgdep _rpkgname _depname _depver _replacement
|
|
|
|
if [ -n "$pkg" ]; then
|
|
# subpkg
|
|
if declare -f ${pkg}_package >/dev/null; then
|
|
${pkg}_package
|
|
fi
|
|
fi
|
|
|
|
for j in ${depends}; do
|
|
_rpkgname="${j%\?*}"
|
|
_depname="${j#*\?}"
|
|
_pkgdepname="$($XBPS_UHELPER_CMD getpkgdepname ${_depname} 2>/dev/null)"
|
|
if [ -z "${_pkgdepname}" ]; then
|
|
_pkgdepname="$($XBPS_UHELPER_CMD getpkgname ${_depname} 2>/dev/null)"
|
|
fi
|
|
if [ -s ${XBPS_DISTDIR}/etc/virtual ]; then
|
|
_replacement=$(egrep "^${_pkgdepname:-${_depname}}[[:blank:]]" ${XBPS_DISTDIR}/etc/virtual|cut -d ' ' -f2)
|
|
elif [ -s ${XBPS_DISTDIR}/etc/defaults.virtual ]; then
|
|
_replacement=$(egrep "^${_pkgdepname:-${_depname}}[[:blank:]]" ${XBPS_DISTDIR}/etc/defaults.virtual|cut -d ' ' -f2)
|
|
fi
|
|
if [ "${_rpkgname}" = "virtual" ]; then
|
|
if [ -z "${_replacement}" ]; then
|
|
msg_error "$pkgver: failed to resolve virtual dependency for '$j' (missing from etc/virtual)\n"
|
|
fi
|
|
_pkgdepname="$($XBPS_UHELPER_CMD getpkgdepname ${_replacement} 2>/dev/null)"
|
|
if [ -z "${_pkgdepname}" ]; then
|
|
_pkgdepname="$($XBPS_UHELPER_CMD getpkgname ${_replacement} 2>/dev/null)"
|
|
fi
|
|
if [ -z "${_pkgdepname}" ]; then
|
|
_pkgdepname="${_replacement}>=0"
|
|
fi
|
|
run_depends+=" ${_depname}?${_pkgdepname}"
|
|
#echo "Adding dependency virtual: ${_depname}?${_pkgdepname}"
|
|
else
|
|
if [ -z "${_pkgdepname}" ]; then
|
|
_pkgdep="${_depname}>=0"
|
|
else
|
|
_pkgdep="${_depname}"
|
|
fi
|
|
run_depends+=" ${_pkgdep}"
|
|
fi
|
|
done
|
|
for j in ${hostmakedepends}; do
|
|
_depname="${j%\?*}"
|
|
_depver=$(srcpkg_get_version ${_depname}) || exit $?
|
|
host_build_depends+=" ${_depname}-${_depver}"
|
|
done
|
|
if ! [ -z "$XBPS_CHECK_PKGS" -o "$XBPS_CHECK_PKGS" = "0" -o "$XBPS_CHECK_PKGS" = "no" ]; then
|
|
for j in ${checkdepends}; do
|
|
_depname="${j%\?*}"
|
|
_depver=$(srcpkg_get_version ${_depname}) || exit $?
|
|
host_check_depends+=" ${_depname}-${_depver}"
|
|
done
|
|
fi
|
|
for j in ${makedepends}; do
|
|
_depname="${j%\?*}"
|
|
_depver=$(srcpkg_get_version ${_depname}) || exit $?
|
|
build_depends+=" ${_depname}-${_depver}"
|
|
done
|
|
}
|
|
|
|
# Install a required package dependency, like:
|
|
#
|
|
# xbps-install -Ay <pkgname>
|
|
#
|
|
# Returns 0 if package already installed or installed successfully.
|
|
# Any other error number otherwise.
|
|
#
|
|
install_pkg_from_repos() {
|
|
local pkg="$1" cross="$2" rval= tmplogf=
|
|
|
|
mkdir -p $XBPS_STATEDIR
|
|
tmplogf=${XBPS_STATEDIR}/xbps_${XBPS_TARGET_MACHINE}_bdep_${pkg}.log
|
|
|
|
if [ -n "$cross" ]; then
|
|
$XBPS_INSTALL_XCMD -Ayd "$pkg" >$tmplogf 2>&1
|
|
else
|
|
$XBPS_INSTALL_CMD -Ayd "$pkg" >$tmplogf 2>&1
|
|
fi
|
|
rval=$?
|
|
if [ $rval -ne 0 -a $rval -ne 17 ]; then
|
|
# xbps-install can return:
|
|
#
|
|
# SUCCESS (0): package installed successfully.
|
|
# ENOENT (2): package missing in repositories.
|
|
# ENXIO (6): package depends on invalid dependencies.
|
|
# EAGAIN (11): package conflicts.
|
|
# EEXIST (17): package already installed.
|
|
# ENODEV (19): package depends on missing dependencies.
|
|
# ENOTSUP (95): no repositories registered.
|
|
#
|
|
[ -z "$XBPS_KEEP_ALL" ] && remove_pkg_autodeps
|
|
msg_red "$pkgver: failed to install '$1' dependency! (error $rval)\n"
|
|
cat $tmplogf
|
|
msg_error "Please see above for the real error, exiting...\n"
|
|
fi
|
|
[ $rval -eq 17 ] && rval=0
|
|
return $rval
|
|
}
|
|
|
|
#
|
|
# Returns 0 if pkgpattern in $1 is matched against current installed
|
|
# package, 1 if no match and 2 if not installed.
|
|
#
|
|
check_pkgdep_matched() {
|
|
local pkg="$1" checkver="$2" cross="$3" uhelper= pkgn= iver=
|
|
|
|
[ "$build_style" = "meta" ] && return 2
|
|
[ -z "$pkg" ] && return 255
|
|
|
|
pkgn="$($XBPS_UHELPER_CMD getpkgdepname ${pkg} 2>/dev/null)"
|
|
if [ -z "$pkgn" ]; then
|
|
pkgn="$($XBPS_UHELPER_CMD getpkgname ${pkg} 2>/dev/null)"
|
|
fi
|
|
[ -z "$pkgn" ] && return 255
|
|
|
|
if [ -n "$cross" ]; then
|
|
uhelper="$XBPS_UHELPER_XCMD"
|
|
else
|
|
uhelper="$XBPS_UHELPER_CMD"
|
|
fi
|
|
|
|
iver="$($uhelper $checkver $pkgn)"
|
|
if [ $? -eq 0 -a -n "$iver" ]; then
|
|
$XBPS_UHELPER_CMD pkgmatch "${pkgn}-${iver}" "${pkg}"
|
|
[ $? -eq 1 ] && return 0
|
|
else
|
|
return 2
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
#
|
|
# Returns 0 if pkgpattern in $1 is installed and greater than current
|
|
# installed package, otherwise 1.
|
|
#
|
|
check_installed_pkg() {
|
|
local pkg="$1" cross="$2" uhelper= pkgn= iver=
|
|
|
|
[ -z "$pkg" ] && return 2
|
|
|
|
pkgn="$($XBPS_UHELPER_CMD getpkgname ${pkg})"
|
|
[ -z "$pkgn" ] && return 2
|
|
|
|
if [ -n "$cross" ]; then
|
|
uhelper="$XBPS_UHELPER_XCMD"
|
|
else
|
|
uhelper="$XBPS_UHELPER_CMD"
|
|
fi
|
|
|
|
iver="$($uhelper version $pkgn)"
|
|
if [ $? -eq 0 -a -n "$iver" ]; then
|
|
$XBPS_CMPVER_CMD "${pkgn}-${iver}" "${pkg}"
|
|
[ $? -eq 0 -o $? -eq 1 ] && return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
srcpkg_get_version() {
|
|
local pkg="$1"
|
|
# Run this in a sub-shell to avoid polluting our env.
|
|
(
|
|
unset XBPS_BINPKG_EXISTS
|
|
setup_pkg $pkg || exit $?
|
|
echo "${version}_${revision}"
|
|
) || msg_error "$pkgver: failed to transform dependency $pkg\n"
|
|
}
|
|
|
|
srcpkg_get_pkgver() {
|
|
local pkg="$1"
|
|
# Run this in a sub-shell to avoid polluting our env.
|
|
(
|
|
unset XBPS_BINPKG_EXISTS
|
|
setup_pkg $pkg || exit $?
|
|
echo "${sourcepkg}-${version}_${revision}"
|
|
) || msg_error "$pkgver: failed to transform dependency $pkg\n"
|
|
}
|
|
|
|
#
|
|
# Installs all dependencies required by a package.
|
|
#
|
|
install_pkg_deps() {
|
|
local pkg="$1" targetpkg="$2" target="$3" cross="$4" cross_prepare="$5"
|
|
local rval _realpkg _vpkg _curpkg curpkgdepname pkgn iver
|
|
local i j found rundep repo
|
|
|
|
local -a host_binpkg_deps check_binpkg_deps binpkg_deps
|
|
local -a host_missing_deps check_missing_deps missing_deps missing_rdeps
|
|
|
|
[ -z "$pkgname" ] && return 2
|
|
|
|
setup_pkg_depends
|
|
|
|
if [ "$pkg" != "$targetpkg" ]; then
|
|
msg_normal "$pkgver: building (dependency of $targetpkg) ...\n"
|
|
else
|
|
msg_normal "$pkgver: building ...\n"
|
|
fi
|
|
|
|
if [ -z "$build_depends" -a -z "$host_build_depends" -a -z "$host_check_depends" -a -z "$run_depends" ]; then
|
|
return 0
|
|
fi
|
|
|
|
#
|
|
# Host build dependencies.
|
|
#
|
|
for i in ${host_build_depends}; do
|
|
check_pkgdep_matched "$i" version
|
|
local rval=$?
|
|
if [ $rval -eq 0 ]; then
|
|
echo " [host] ${i}: installed."
|
|
continue
|
|
elif [ $rval -eq 1 ]; then
|
|
_realpkg="$($XBPS_UHELPER_CMD getpkgname $i 2>/dev/null)"
|
|
iver=$($XBPS_UHELPER_CMD version ${_realpkg})
|
|
if [ $? -eq 0 -a -n "$iver" ]; then
|
|
echo " [host] ${i}: installed $iver (virtualpkg)."
|
|
continue
|
|
else
|
|
echo " [host] ${i}: unresolved build dependency!"
|
|
return 1
|
|
fi
|
|
else
|
|
repo=$($XBPS_QUERY_CMD -R -prepository ${i} 2>/dev/null)
|
|
if [ -n "${repo}" ]; then
|
|
echo " [host] ${i}: found ($repo)"
|
|
host_binpkg_deps+=("${i}")
|
|
continue
|
|
else
|
|
echo " [host] ${i}: not found."
|
|
fi
|
|
fi
|
|
host_missing_deps+=("${i}")
|
|
done
|
|
|
|
#
|
|
# Host check dependencies.
|
|
#
|
|
for i in ${host_check_depends}; do
|
|
check_pkgdep_matched "$i" version
|
|
local rval=$?
|
|
if [ $rval -eq 0 ]; then
|
|
echo " [check] ${i}: installed."
|
|
continue
|
|
elif [ $rval -eq 1 ]; then
|
|
_realpkg="$($XBPS_UHELPER_CMD getpkgname $i 2>/dev/null)"
|
|
iver=$($XBPS_UHELPER_CMD version ${_realpkg})
|
|
if [ $? -eq 0 -a -n "$iver" ]; then
|
|
echo " [check] ${i}: installed $iver (virtualpkg)."
|
|
continue
|
|
else
|
|
echo " [check] ${i}: unresolved check dependency!"
|
|
return 1
|
|
fi
|
|
else
|
|
repo=$($XBPS_QUERY_CMD -R -prepository ${i} 2>/dev/null)
|
|
if [ -n "${repo}" ]; then
|
|
echo " [check] ${i}: found ($repo)"
|
|
check_binpkg_deps+=("${i}")
|
|
continue
|
|
else
|
|
echo " [check] ${i}: not found."
|
|
fi
|
|
fi
|
|
check_missing_deps+=("${i}")
|
|
done
|
|
|
|
|
|
#
|
|
# Target build dependencies.
|
|
#
|
|
for i in ${build_depends}; do
|
|
_realpkg="$($XBPS_UHELPER_CMD getpkgname $i 2>/dev/null)"
|
|
# Check if dependency is a subpkg, if it is, ignore it.
|
|
unset found
|
|
for j in ${subpackages}; do
|
|
[ "$j" = "${_realpkg}" ] && found=1 && break
|
|
done
|
|
[ -n "$found" ] && continue
|
|
check_pkgdep_matched "${i}" version $cross
|
|
local rval=$?
|
|
if [ $rval -eq 0 ]; then
|
|
echo " [target] ${i}: installed."
|
|
continue
|
|
elif [ $rval -eq 1 ]; then
|
|
iver=$($XBPS_UHELPER_XCMD version ${_realpkg})
|
|
if [ $? -eq 0 -a -n "$iver" ]; then
|
|
echo " [target] ${i}: installed $iver (virtualpkg)."
|
|
continue
|
|
else
|
|
echo " [target] ${i}: unresolved build dependency!"
|
|
return 1
|
|
fi
|
|
else
|
|
repo=$($XBPS_QUERY_XCMD -R -prepository ${i} 2>/dev/null)
|
|
if [ -n "${repo}" ]; then
|
|
echo " [target] ${i}: found ($repo)"
|
|
binpkg_deps+=("${i}")
|
|
continue
|
|
else
|
|
echo " [target] ${i}: not found."
|
|
fi
|
|
fi
|
|
missing_deps+=("${i}")
|
|
done
|
|
|
|
#
|
|
# Target run time dependencies
|
|
#
|
|
for i in ${run_depends}; do
|
|
_realpkg="${i%\?*}"
|
|
_curpkg="${_realpkg}"
|
|
_vpkg="${i#*\?}"
|
|
if [ "${_realpkg}" != "${_vpkg}" ]; then
|
|
_realpkg="${_vpkg}"
|
|
else
|
|
unset _curpkg
|
|
fi
|
|
pkgn=$($XBPS_UHELPER_CMD getpkgdepname "${_realpkg}")
|
|
if [ -z "$pkgn" ]; then
|
|
pkgn=$($XBPS_UHELPER_CMD getpkgname "${_realpkg}")
|
|
if [ -z "$pkgn" ]; then
|
|
msg_error "$pkgver: invalid runtime dependency: ${_realpkg}\n"
|
|
fi
|
|
fi
|
|
# Check if dependency is a subpkg, if it is, ignore it.
|
|
unset found
|
|
for j in ${subpackages}; do
|
|
[ "$j" = "${pkgn}" ] && found=1 && break
|
|
done
|
|
[ -n "$found" ] && continue
|
|
_props=$($XBPS_QUERY_XCMD -R -ppkgver,repository ${_realpkg} 2>/dev/null)
|
|
if [ -n "${_props}" ]; then
|
|
set -- ${_props}
|
|
$XBPS_UHELPER_CMD pkgmatch ${1} "${_realpkg}"
|
|
if [ $? -eq 1 ]; then
|
|
if [ -n "${_curpkg}" ]; then
|
|
echo " [runtime] ${_curpkg}:${_realpkg} (virtual dependency): found $1 ($2)"
|
|
else
|
|
echo " [runtime] ${_realpkg}: found $1 ($2)"
|
|
fi
|
|
shift 2
|
|
continue
|
|
else
|
|
if [ -n "${_curpkg}" ]; then
|
|
echo " [runtime] ${_curpkg}:${_realpkg} (virtual dependency): not found."
|
|
else
|
|
echo " [runtime] ${_realpkg}: not found."
|
|
fi
|
|
fi
|
|
shift 2
|
|
else
|
|
if [ -n "${_curpkg}" ]; then
|
|
echo " [runtime] ${_curpkg}:${_realpkg} (virtual dependency): not found."
|
|
else
|
|
echo " [runtime] ${_realpkg}: not found."
|
|
fi
|
|
fi
|
|
missing_rdeps+=("${_realpkg}")
|
|
done
|
|
|
|
# Missing host dependencies, build from srcpkgs.
|
|
for i in ${host_missing_deps[@]}; do
|
|
# packages not found in repos, install from source.
|
|
(
|
|
curpkgdepname=$($XBPS_UHELPER_CMD getpkgname "$i" 2>/dev/null)
|
|
setup_pkg $curpkgdepname
|
|
exec env XBPS_DEPENDENCY=1 XBPS_BINPKG_EXISTS=1 \
|
|
$XBPS_LIBEXECDIR/build.sh $sourcepkg $pkg $target || exit $?
|
|
) || exit $?
|
|
host_binpkg_deps+=("$i")
|
|
done
|
|
|
|
# Missing check dependencies, build from srcpkgs.
|
|
for i in ${check_missing_deps[@]}; do
|
|
# packages not found in repos, install from source.
|
|
(
|
|
curpkgdepname=$($XBPS_UHELPER_CMD getpkgname "$i" 2>/dev/null)
|
|
setup_pkg $curpkgdepname
|
|
exec env XBPS_DEPENDENCY=1 XBPS_BINPKG_EXISTS=1 \
|
|
$XBPS_LIBEXECDIR/build.sh $sourcepkg $pkg $target || exit $?
|
|
) || exit $?
|
|
check_binpkg_deps+=("$i")
|
|
done
|
|
|
|
# Missing target dependencies, build from srcpkgs.
|
|
for i in ${missing_deps[@]}; do
|
|
# packages not found in repos, install from source.
|
|
(
|
|
curpkgdepname=$($XBPS_UHELPER_CMD getpkgname "$i" 2>/dev/null)
|
|
setup_pkg $curpkgdepname $cross
|
|
exec env XBPS_DEPENDENCY=1 XBPS_BINPKG_EXISTS=1 \
|
|
$XBPS_LIBEXECDIR/build.sh $sourcepkg $pkg $target $cross $cross_prepare || exit $?
|
|
) || exit $?
|
|
binpkg_deps+=("$i")
|
|
done
|
|
|
|
# Target runtime missing dependencies, build from srcpkgs.
|
|
for i in ${missing_rdeps[@]}; do
|
|
# packages not found in repos, install from source.
|
|
(
|
|
curpkgdepname=$($XBPS_UHELPER_CMD getpkgdepname "$i" 2>/dev/null)
|
|
if [ -z "$curpkgdepname" ]; then
|
|
curpkgdepname=$($XBPS_UHELPER_CMD getpkgname "$i" 2>/dev/null)
|
|
if [ -z "$curpkgdepname" ]; then
|
|
curpkgdepname="$i"
|
|
fi
|
|
fi
|
|
setup_pkg $curpkgdepname $cross
|
|
exec env XBPS_DEPENDENCY=1 XBPS_BINPKG_EXISTS=1 \
|
|
$XBPS_LIBEXECDIR/build.sh $sourcepkg $pkg $target $cross $cross_prepare || exit $?
|
|
) || exit $?
|
|
done
|
|
|
|
if [ "$pkg" != "$targetpkg" ]; then
|
|
msg_normal "$pkg: building (dependency of $targetpkg) ...\n"
|
|
fi
|
|
|
|
for i in ${host_binpkg_deps[@]}; do
|
|
msg_normal "$pkgver: installing host dependency '$i' ...\n"
|
|
install_pkg_from_repos "${i}"
|
|
done
|
|
|
|
for i in ${check_binpkg_deps[@]}; do
|
|
msg_normal "$pkgver: installing check dependency '$i' ...\n"
|
|
install_pkg_from_repos "${i}"
|
|
done
|
|
|
|
for i in ${binpkg_deps[@]}; do
|
|
msg_normal "$pkgver: installing target dependency '$i' ...\n"
|
|
install_pkg_from_repos "$i" $cross
|
|
done
|
|
}
|