# $NetBSD: replace.mk,v 1.9 2024/01/26 12:42:01 riastradh Exp $ # # _pkgformat-destdir-replace: # Updates a package in-place on the system. # # See also: # replace # # XXX: The whole replacement, from deinstalling the old package up # to installing the new package, should be one transaction. # _pkgformat-replace: \ replace-tarup \ replace-preserve-installed-info \ replace-preserve-required-by \ deinstall \ install-clean \ install \ replace-fixup-required-by \ replace-fixup-installed-info \ .PHONY # tarup is omitted for DESTDIR, because the benefits are very small _pkgformat-destdir-replace: \ replace-destdir \ .PHONY # _pkgformat-undo-replace: # Undoes the actions from a previous _pkgformat-replace. # # See also: # undo-replace # _pkgformat-undo-replace: \ undo-replace-check \ replace-preserve-installed-info \ replace-preserve-required-by \ deinstall \ undo-replace-install \ replace-fixup-required-by \ replace-clean \ .PHONY _pkgformat-destdir-undo-replace: \ undo-replace-check \ undo-destdir-replace-install \ replace-clean \ .PHONY _INSTALLED_INFO_FILE= ${WRKDIR}/.replace-+INSTALLED_INFO _REQUIRED_BY_FILE= ${WRKDIR}/.replace-+REQUIRED_BY _COOKIE.replace= ${WRKDIR}/.replace_done _REPLACE_OLDNAME_FILE= ${WRKDIR}/.replace_oldname _REPLACE_NEWNAME_FILE= ${WRKDIR}/.replace_newname _REPLACE_OLDNAME_CMD= \ [ -f ${_REPLACE_OLDNAME_FILE} ] \ || ${FAIL_MSG} "[${.TARGET}] ${_REPLACE_OLDNAME_FILE}: File not found"; \ oldname=`${CAT} ${_REPLACE_OLDNAME_FILE}` _REPLACE_NEWNAME_CMD= \ [ -f ${_REPLACE_NEWNAME_FILE} ] \ || ${FAIL_MSG} "[${.TARGET}] ${_REPLACE_NEWNAME_FILE}: File not found"; \ newname=`${CAT} ${_REPLACE_NEWNAME_FILE}` # Verifies that there was a previous "replace" action performed that can be undone. # undo-replace-check: .PHONY ${RUN} [ -f ${_COOKIE.replace} ] \ || ${FAIL_MSG} "No replacement to undo!" # Generates a binary package for the (older) installed package using pkg_tarup. # replace-tarup: .PHONY ${RUN} [ -x ${_PKG_TARUP_CMD:Q} ] \ || ${FAIL_MSG} ${_PKG_TARUP_CMD:Q}" was not found."; \ ${_REPLACE_OLDNAME_CMD}; \ ${PKGSRC_SETENV} PKG_DBDIR=${_PKG_DBDIR} PKG_SUFX=${PKG_SUFX} \ PKGREPOSITORY=${WRKDIR} \ ${_PKG_TARUP_CMD} $${oldname} || \ ${FAIL_MSG} "Could not pkg_tarup $${oldname}". # Re-installs the old package that has been saved by replace-tarup. # undo-replace-install: .PHONY @${PHASE_MSG} "Re-adding ${PKGNAME} from saved tar-up package." ${RUN} ${_REPLACE_OLDNAME_CMD}; \ ${ECHO} "Installing saved package ${WRKDIR}/$${oldname}${PKG_SUFX}"; \ ${SETENV} ${PKGTOOLS_ENV} ${PKG_ADD} ${WRKDIR}/$${oldname}${PKG_SUFX} undo-destdir-replace-install: .PHONY @${PHASE_MSG} "Re-adding ${PKGNAME} from saved tar-up package." ${RUN} ${_REPLACE_OLDNAME_CMD}; \ ${ECHO} "Installing saved package ${WRKDIR}/$${oldname}${PKG_SUFX}"; \ ${SETENV} ${PKGTOOLS_ENV} ${PKG_ADD} -U -D ${WRKDIR}/$${oldname}${PKG_SUFX} # Computes and saves the full names of the installed package to be replaced # (oldname) and the package that will be installed (newname), so that these # names are available later. # replace-names: .PHONY ${RUN} if [ x"${OLDNAME}" = x ]; then \ wildcard=${PKGWILDCARD:Q}; \ else \ wildcard="${OLDNAME}-[0-9]*"; \ fi; \ ${_PKG_BEST_EXISTS} "$${wildcard}" > ${_REPLACE_OLDNAME_FILE} ${RUN} ${ECHO} ${PKGNAME} > ${_REPLACE_NEWNAME_FILE} ${RUN} ${CP} -f ${_REPLACE_NEWNAME_FILE} ${_COOKIE.replace} # Saves and removes the +INSTALLED_INFO file from the installed package. # replace-preserve-installed-info: .PHONY @${STEP_MSG} "Preserving existing +INSTALLED_INFO file." ${RUN} ${_REPLACE_OLDNAME_CMD}; \ installed_info="${_PKG_DBDIR}/$$oldname/+INSTALLED_INFO"; \ ${TEST} ! -f "$$installed_info" || \ ${MV} $$installed_info ${_INSTALLED_INFO_FILE} # Saves and removes the +REQUIRED_BY file from the installed package. # replace-preserve-required-by: .PHONY @${STEP_MSG} "Preserving existing +REQUIRED_BY file." ${RUN} ${_REPLACE_OLDNAME_CMD}; \ required_by="${_PKG_DBDIR}/$$oldname/+REQUIRED_BY"; \ ${TEST} ! -f "$$required_by" || \ ${MV} $$required_by ${_REQUIRED_BY_FILE} # Fixes the +CONTENTS files of dependent packages to refer to the # replacement package, and puts the +REQUIRED_BY file back into place. # It also sets the unsafe_depends_strict tag on each dependent package, # and sets the unsafe_depends tag if the replaced package has a different # version. # # XXX Only set unsafe_depends if there is an ABI change. # replace-fixup-required-by: .PHONY @${STEP_MSG} "Fixing @pkgdep entries in dependent packages." ${RUN} ${_REPLACE_OLDNAME_CMD}; \ ${_REPLACE_NEWNAME_CMD}; \ ${TEST} -f ${_REQUIRED_BY_FILE} || exit 0; \ ${CAT} ${_REQUIRED_BY_FILE} | \ while read pkg; do \ case $$pkg in \ "") continue ;; \ /*) pkgdir="$$pkg" ;; \ *) pkgdir="${_PKG_DBDIR}/$$pkg" ;; \ esac; \ contents="$$pkgdir/+CONTENTS"; \ newcontents="$$contents.$$$$"; \ ${PKGSRC_SETENV} OLDNAME="$$oldname" NEWNAME="$$newname" \ ${AWK} '($$0 ~ "^@pkgdep " ENVIRON["OLDNAME"]) \ { print "@pkgdep " ENVIRON["NEWNAME"]; next } \ { print }' \ $$contents > $$newcontents; \ ${MV} -f $$newcontents $$contents; \ ${PKG_ADMIN} set unsafe_depends_strict=YES $$pkg; \ if ${TEST} "$$oldname" != "$$newname"; then \ ${PKG_ADMIN} set unsafe_depends=YES $$pkg; \ fi; \ done; \ ${MV} ${_REQUIRED_BY_FILE} ${_PKG_DBDIR}/$$newname/+REQUIRED_BY # Removes unsafe_depends*, rebuild and mismatch tags from this package. # replace-fixup-installed-info: .PHONY @${STEP_MSG} "Removing unsafe_depends and rebuild tags." ${RUN} ${_REPLACE_NEWNAME_CMD}; \ [ ! -f ${_INSTALLED_INFO_FILE} ] || \ ${MV} ${_INSTALLED_INFO_FILE} ${_PKG_DBDIR}/$$newname/+INSTALLED_INFO; \ for var in unsafe_depends unsafe_depends_strict rebuild mismatch; do \ ${PKG_ADMIN} unset $$var $$newname; \ done # Removes the state files for the "replace" target, so that it may be re-invoked. # replace-clean: .PHONY ${RUN} ${_REPLACE_OLDNAME_CMD}; \ ${_REPLACE_NEWNAME_CMD}; \ ${RM} -f ${WRKDIR}/$$oldname${PKG_SUFX}; \ ${RM} -f ${WRKDIR}/$$newname${PKG_SUFX}; \ ${RM} -f ${_REPLACE_OLDNAME_FILE} ${_REPLACE_NEWNAME_FILE} \ ${_COOKIE.replace} # Logically we would like to do a "pkg_add -U". However, that fails # if there is a depending package that exactly depends on the package # being replaced, so we override that check with -D. Historically, # 'make replace' would replace a package regardless of whether that # broke depending packages (typically due to shlib ABI changes, # especially major version bumps). Therefore, make replace in DESTDIR # mode should behave the same way. unsafe_depends will be set on # depending packages, and then those may be rebuilt via a manual # process or by pkg_rolling-replace. replace-destdir: .PHONY @${PHASE_MSG} "Updating using binary package of "${PKGNAME:Q} .if !empty(USE_CROSS_COMPILE:M[yY][eE][sS]) @${MKDIR} ${_CROSS_DESTDIR}${PREFIX} ${SETENV} ${PKGTOOLS_ENV} ${PKG_ADD} -U -D -m ${OPSYS:Q}/${MACHINE_ARCH:Q}\ ${OS_VERSION:Q} -I -p ${_CROSS_DESTDIR}${PREFIX} ${STAGE_PKGFILE} @${ECHO} "Fixing recorded cwd..." @${SED} -e 's|@cwd ${_CROSS_DESTDIR}|@cwd |' ${_PKG_DBDIR}/${PKGNAME:Q}/+CONTENTS > ${_PKG_DBDIR}/${PKGNAME:Q}/+CONTENTS.tmp @${MV} ${_PKG_DBDIR}/${PKGNAME:Q}/+CONTENTS.tmp ${_PKG_DBDIR}/${PKGNAME:Q}/+CONTENTS .else ${SETENV} ${PKGTOOLS_ENV} ${PKG_ADD} -U -D ${STAGE_PKGFILE} .endif ${RUN}${_REPLACE_OLDNAME_CMD}; \ ${PKG_INFO} -qR ${PKGNAME:Q} | while read pkg; do \ [ -n "$$pkg" ] || continue; \ ${PKG_ADMIN} set unsafe_depends_strict=YES "$$pkg"; \ if [ "$$oldname" != ${PKGNAME:Q} ]; then \ ${PKG_ADMIN} set unsafe_depends=YES "$$pkg"; \ fi; \ done ${RUN}for var in unsafe_depends unsafe_depends_strict rebuild mismatch; do \ ${PKG_ADMIN} unset $$var ${PKGNAME:Q}; \ done