diff options
Diffstat (limited to 'mk/pkgformat')
-rw-r--r-- | mk/pkgformat/README | 69 | ||||
-rw-r--r-- | mk/pkgformat/bsd.pkgformat-vars.mk | 11 | ||||
-rw-r--r-- | mk/pkgformat/bsd.pkgformat.mk | 7 | ||||
-rw-r--r-- | mk/pkgformat/pkg/check.mk | 25 | ||||
-rw-r--r-- | mk/pkgformat/pkg/deinstall.mk | 57 | ||||
-rw-r--r-- | mk/pkgformat/pkg/depends.mk | 181 | ||||
-rw-r--r-- | mk/pkgformat/pkg/install.mk | 75 | ||||
-rwxr-xr-x | mk/pkgformat/pkg/list-dependencies | 67 | ||||
-rw-r--r-- | mk/pkgformat/pkg/metadata.mk | 415 | ||||
-rw-r--r-- | mk/pkgformat/pkg/package.mk | 159 | ||||
-rw-r--r-- | mk/pkgformat/pkg/pkgformat-vars.mk | 92 | ||||
-rw-r--r-- | mk/pkgformat/pkg/pkgformat.mk | 27 | ||||
-rwxr-xr-x | mk/pkgformat/pkg/reduce-depends.awk | 158 | ||||
-rwxr-xr-x | mk/pkgformat/pkg/register-dependencies | 51 | ||||
-rw-r--r-- | mk/pkgformat/pkg/replace.mk | 227 | ||||
-rwxr-xr-x | mk/pkgformat/pkg/resolve-dependencies | 49 | ||||
-rw-r--r-- | mk/pkgformat/pkg/utility.mk | 99 | ||||
-rw-r--r-- | mk/pkgformat/pkg/views.mk | 90 |
18 files changed, 1859 insertions, 0 deletions
diff --git a/mk/pkgformat/README b/mk/pkgformat/README new file mode 100644 index 00000000000..8de3f480767 --- /dev/null +++ b/mk/pkgformat/README @@ -0,0 +1,69 @@ +$NetBSD: README,v 1.1 2011/10/15 00:23:09 reed Exp $ + += Introduction = + +A package format is a packaging system that is supported by pkgsrc. +Currently, there is only one (the native pkgsrc tools), but maybe we can +support RPM, dpkg or the Solaris native packages someday. It can also be +used to test new variants of the packaging tools. + +NOTE: The Google Summer of Code 2011 project includes rpm and debian +http://addpackageforma.sourceforge.net/ + +The PKG_FORMAT variable is used to select the format. The default +format is ``pkg''. + += Interface = + +== Variables usable at load-time == + +A package system format must define the following variables so that they +can be used when loading Makefiles. (That is, no references to undefined +variables.) + +=== Legacy === + +* PKG_DBDIR (TODO: Make the other parts of pkgsrc independent of that + variable; this should go away.) + +=== Packaging commands === + +The following variables all refer to shell commands, which must accept +some command line options that are detailed in the respective man pages. +(TODO: Find out which command line options are really used and which +ones are useful. Document them.) + +* PKG_ADD +* PKG_ADMIN +* PKG_CREATE +* PKG_DELETE +* PKG_INFO +* PKG_VIEW +* LINKFARM +* PKG_BEST_EXISTS + +The following variables must be defined so that they can be used in +shell commands. They may contain references to all other variables. + +* PKG_FILELIST_CMD + +XXX: Why isn't this variable in the previous list? + +== Make targets == + +The following make targets must be implemented: + +* _pkgformat-check-vulnerable +* _pkgformat-deinstall +* _pkgformat-show-depends +* _pkgformat-install-dependencies +* bootstrap-depends +* _pkgformat-register +* tarup (XXX: This doesn't sound like a target that should be defined + here.) +* tarup-pkg +* package-install +* _pkgformat-replace +* _pkgformat-destdir-replace +* _pkgformat-undo-replace + diff --git a/mk/pkgformat/bsd.pkgformat-vars.mk b/mk/pkgformat/bsd.pkgformat-vars.mk new file mode 100644 index 00000000000..ad9052c5186 --- /dev/null +++ b/mk/pkgformat/bsd.pkgformat-vars.mk @@ -0,0 +1,11 @@ +# $NetBSD: bsd.pkgformat-vars.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# +# This Makefile fragment is included by bsd.prefs.mk and defines some +# variables which must be defined earlier than where bsd.pkgformat.mk +# is included. +# + +# Default to the pkgsrc package format. +PKG_FORMAT?= pkg + +.sinclude "${PKG_FORMAT}/pkgformat-vars.mk" diff --git a/mk/pkgformat/bsd.pkgformat.mk b/mk/pkgformat/bsd.pkgformat.mk new file mode 100644 index 00000000000..9ec830e4fe5 --- /dev/null +++ b/mk/pkgformat/bsd.pkgformat.mk @@ -0,0 +1,7 @@ +# $NetBSD: bsd.pkgformat.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# +# This Makefile fragment is included by bsd.pkg.mk and pulls in the correct +# target and variable overrides for the selected package system format. +# + +.include "${PKG_FORMAT}/pkgformat.mk" diff --git a/mk/pkgformat/pkg/check.mk b/mk/pkgformat/pkg/check.mk new file mode 100644 index 00000000000..e53d00c9d09 --- /dev/null +++ b/mk/pkgformat/pkg/check.mk @@ -0,0 +1,25 @@ +# $NetBSD: check.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# + +# _pkgformat-check-vulnerable: +# Checks for known vulnerabilities in the package if a vulnerability +# file exists. +# +.if defined(NO_PKGTOOLS_REQD_CHECK) +_pkgformat-check-vulnerable: .PHONY + ${RUN}${DO_NADA} +.else +_pkgformat-check-vulnerable: .PHONY + ${RUN}\ + _PKGVULNDIR=`${_EXTRACT_PKGVULNDIR}`; \ + vulnfile=$$_PKGVULNDIR/pkg-vulnerabilities; \ + if ${TEST} ! -f "$$vulnfile"; then \ + ${PHASE_MSG} "Skipping vulnerability checks."; \ + ${WARNING_MSG} "No $$vulnfile file found."; \ + ${WARNING_MSG} "To fix run: \`${DOWNLOAD_VULN_LIST}'."; \ + exit 0; \ + fi; \ + ${PHASE_MSG} "Checking for vulnerabilities in ${PKGNAME}"; \ + ${AUDIT_PACKAGES} ${_AUDIT_PACKAGES_CMD} ${AUDIT_PACKAGES_FLAGS} ${PKGNAME} \ + || ${FAIL_MSG} "Define ALLOW_VULNERABLE_PACKAGES in mk.conf or ${_AUDIT_CONFIG_OPTION} in ${_AUDIT_CONFIG_FILE}(5) if this package is absolutely essential." +.endif diff --git a/mk/pkgformat/pkg/deinstall.mk b/mk/pkgformat/pkg/deinstall.mk new file mode 100644 index 00000000000..5928a41ac5b --- /dev/null +++ b/mk/pkgformat/pkg/deinstall.mk @@ -0,0 +1,57 @@ +# $NetBSD: deinstall.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ + +# Set the appropriate flags to pass to pkg_delete(1) based on the value +# of DEINSTALLDEPENDS (see pkgsrc/mk/install/deinstall.mk). +# +.if defined(DEINSTALLDEPENDS) +. if empty(DEINSTALLDEPENDS:M[nN][oO]) +. if !empty(DEINSTALLDEPENDS:M[aA][lL][lL]) +_PKG_ARGS_DEINSTALL+= -r # for "update" target +. else +_PKG_ARGS_DEINSTALL+= -r -R # for removing stuff in bulk builds +. endif +. endif +.endif + +.if defined(PKG_VERBOSE) +_PKG_ARGS_DEINSTALL+= -v +.endif + +.if defined(PKG_PRESERVE) +. if defined(_UPDATE_RUNNING) && !empty(_UPDATE_RUNNING:M[yY][eE][sS]) +_PKG_ARGS_DEINSTALL+= -N -f -f # update w/o removing any files + +MAKEFLAGS.su-deinstall+= _UPDATE_RUNNING=YES +. endif +.endif + +# _pkgformat-deinstall: +# Removes a package from the system. +# +# See also: +# deinstall +# +_pkgformat-deinstall: .PHONY + ${RUN} \ + if [ x"${OLDNAME}" = x ]; then \ + found=`${PKG_INFO} -e "${PKGNAME}" || ${TRUE}`; \ + else \ + found=${OLDNAME}; \ + fi; \ + case "$$found" in \ + "") found=`${_PKG_BEST_EXISTS} ${PKGWILDCARD:Q} || ${TRUE}`;; \ + esac; \ + if ${TEST} -n "$$found"; then \ + ${ECHO} "Running ${PKG_DELETE} ${_PKG_ARGS_DEINSTALL} $$found"; \ + ${PKG_DELETE} ${_PKG_ARGS_DEINSTALL} "$$found" || ${TRUE} ; \ + fi +.if defined(DEINSTALLDEPENDS) && !empty(DEINSTALLDEPENDS:M[yY][eE][sS]) +. for _pkg_ in ${BUILD_DEPENDS:C/:.*$//} + ${RUN} \ + found=`${_PKG_BEST_EXISTS} ${_pkg_:Q} || ${TRUE}`; \ + if ${TEST} -n "$$found"; then \ + ${ECHO} "Running ${PKG_DELETE} ${_PKG_ARGS_DEINSTALL} $$found"; \ + ${PKG_DELETE} ${_PKG_ARGS_DEINSTALL} "$$found" || ${TRUE}; \ + fi +. endfor +.endif diff --git a/mk/pkgformat/pkg/depends.mk b/mk/pkgformat/pkg/depends.mk new file mode 100644 index 00000000000..9893c5ccf27 --- /dev/null +++ b/mk/pkgformat/pkg/depends.mk @@ -0,0 +1,181 @@ +# $NetBSD: depends.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ + +# This command prints out the dependency patterns for all full (run-time) +# dependencies of the package. +# +# This is used in install.mk and metadata.mk. +# + +# ${_DEPENDS_FILE} contains all the dependency information +# for the package. The format of each line of the file is: +# +# <depends_type> <pattern> <directory> +# +# Valid dependency types are "bootstrap", "build" and "full". +# +# ${_RDEPENDS_FILE} contains the resolved dependency information +# for the package. For each line in ${_DEPENDS_FILE} +# a corresponding line of the following form exists: +# +# <depends_type> <pattern> <pkg> +# +# "pkg" is the match for "pattern" used to fulfill the dependency. +# +_DEPENDS_FILE= ${WRKDIR}/.depends +_RDEPENDS_FILE= ${WRKDIR}/.rdepends + +_FULL_DEPENDS_CMD= \ + ${AWK} '$$1 == "full" { print $$3; }' < ${_RDEPENDS_FILE} + +_REDUCE_DEPENDS_CMD= ${PKGSRC_SETENV} CAT=${CAT:Q} \ + PKG_ADMIN=${PKG_ADMIN_CMD:Q} \ + PWD_CMD=${PWD_CMD:Q} TEST=${TEST:Q} \ + ${AWK} -f ${PKGSRCDIR}/mk/pkgformat/pkg/reduce-depends.awk + +_pkgformat-show-depends: .PHONY + @case ${VARNAME:Q}"" in \ + BUILD_DEPENDS) ${_REDUCE_DEPENDS_CMD} ${BUILD_DEPENDS:Q} ;; \ + DEPENDS|*) ${_REDUCE_DEPENDS_CMD} ${DEPENDS:Q} ;; \ + esac + +_LIST_DEPENDS_CMD= \ + ${PKGSRC_SETENV} AWK=${AWK:Q} PKG_ADMIN=${PKG_ADMIN:Q} \ + PKGSRCDIR=${PKGSRCDIR:Q} PWD_CMD=${PWD_CMD:Q} SED=${SED:Q} \ + ${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/list-dependencies \ + " "${BOOTSTRAP_DEPENDS:Q} \ + " "${BUILD_DEPENDS:Q} \ + " "${DEPENDS:Q} + +_LIST_DEPENDS_CMD.bootstrap= \ + ${PKGSRC_SETENV} AWK=${AWK:Q} PKG_ADMIN=${PKG_ADMIN:Q} \ + PKGSRCDIR=${PKGSRCDIR:Q} PWD_CMD=${PWD_CMD:Q} SED=${SED:Q} \ + ${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/list-dependencies \ + " "${BOOTSTRAP_DEPENDS:Q} " " " " + +_RESOLVE_DEPENDS_CMD= \ + ${PKGSRC_SETENV} _PKG_DBDIR=${_PKG_DBDIR:Q} PKG_INFO=${PKG_INFO:Q} \ + _DEPENDS_FILE=${_DEPENDS_FILE:Q} \ + ${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/resolve-dependencies \ + " "${BOOTSTRAP_DEPENDS:Q} \ + " "${BUILD_DEPENDS:Q} \ + " "${DEPENDS:Q} + +# _DEPENDS_INSTALL_CMD checks whether the package $pattern is installed, +# and installs it if necessary. +# +# @param $pattern The pattern of the package to be installed. +# @param $dir The pkgsrc directory from which the package can be +# built. +# @param $type The dependency type. Can be one of bootstrap, +# build, full. +# +_DEPENDS_INSTALL_CMD= \ + pkg=`${_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`; \ + case $$type in bootstrap) Type=Bootstrap;; build) Type=Build;; full) Type=Full;; esac; \ + case "$$pkg" in \ + "") \ + ${STEP_MSG} "$$Type dependency $$pattern: NOT found"; \ + target=${DEPENDS_TARGET:Q}; \ + ${STEP_MSG} "Verifying $$target for $$dir"; \ + [ -d "$$dir" ] || ${FAIL_MSG} "[depends.mk] The directory \`\`$$dir'' does not exist."; \ + cd $$dir; \ + ${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV} _PKGSRC_DEPS=" ${PKGNAME}${_PKGSRC_DEPS}" PKGNAME_REQD="$$pattern" ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes $$target; \ + pkg=`${_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`; \ + case "$$pkg" in \ + "") ${ERROR_MSG} "[depends.mk] A package matching \`\`$$pattern'' should"; \ + ${ERROR_MSG} " be installed, but one cannot be found. Perhaps there is a"; \ + ${ERROR_MSG} " stale work directory for $$dir?"; \ + exit 1; \ + esac; \ + ${STEP_MSG} "Returning to build of ${PKGNAME}"; \ + ;; \ + *) \ + objfmt=`${PKG_INFO} -Q OBJECT_FMT "$$pkg"`; \ + case "$$objfmt" in \ + "") ${WARNING_MSG} "[depends.mk] Unknown object format for installed package $$pkg" ;; \ + ${OBJECT_FMT}) ;; \ + *) ${ERROR_MSG} "[depends.mk] Installed package $$pkg has an"; \ + ${ERROR_MSG} " object format \`\`$$objfmt'' which differs from \`\`${OBJECT_FMT}''. Please"; \ + ${ERROR_MSG} " update the $$pkg package to ${OBJECT_FMT}."; \ + exit 1; \ + ;; \ + esac; \ + silent=${_BOOTSTRAP_VERBOSE:Dyes}; \ + if ${TEST} -z "$${silent}"; then \ + ${STEP_MSG} "$$Type dependency $$pattern: found $$pkg"; \ + fi; \ + ;; \ + esac + +${_DEPENDS_FILE}: + ${RUN} ${MKDIR} ${.TARGET:H} + ${RUN} ${_LIST_DEPENDS_CMD} > ${.TARGET} + +${_RDEPENDS_FILE}: ${_DEPENDS_FILE} + ${RUN} ${_RESOLVE_DEPENDS_CMD} > ${.TARGET} + +# _pkgformat-install-dependencies: +# Installs any missing dependencies. +# +_pkgformat-install-dependencies: .PHONY ${_DEPENDS_FILE} + ${RUN} \ + exec 3<&0; \ + ${CAT} ${_DEPENDS_FILE} | \ + while read type pattern dir; do \ + ${TEST} "$$type" != "bootstrap" || continue; \ + ${_DEPENDS_INSTALL_CMD} 0<&3; \ + done + +# _pkgformat-post-install-dependencies: +# Targets after installing all dependencies. +# +_pkgformat-post-install-dependencies: .PHONY ${_RDEPENDS_FILE} + +###################################################################### +### pkg_install-depends (PUBLIC, pkgsrc/mk/depends/depends.mk) +###################################################################### +### pkg_install-depends is a public target to install or update +### pkg_install itself. +### +.PHONY: pkg_install-depends +pkg_install-depends: + ${RUN}if [ `${PKG_INFO_CMD} -V 2>/dev/null || echo 20010302` -lt ${PKGTOOLS_REQD} ]; then \ + ${PHASE_MSG} "Trying to handle out-dated pkg_install..."; \ + cd ../../pkgtools/pkg_install && ${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV} \ + _PKGSRC_DEPS=" ${PKGNAME}${_PKGSRC_DEPS}" \ + ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes clean && \ + cd ../../pkgtools/pkg_install && ${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV} \ + _PKGSRC_DEPS=" ${PKGNAME}${_PKGSRC_DEPS}" \ + ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes ${DEPENDS_TARGET:Q}; \ + fi + +###################################################################### +### bootstrap-depends (PUBLIC, pkgsrc/mk/depends/depends.mk) +###################################################################### +### bootstrap-depends is a public target to install any missing +### dependencies needed during stages before the normal "depends" +### stage. These dependencies are listed in BOOTSTRAP_DEPENDS. +### +.PHONY: bootstrap-depends +_BOOTSTRAP_DEPENDS_TARGETS+= acquire-bootstrap-depends-lock +_BOOTSTRAP_DEPENDS_TARGETS+= _pkgformat-bootstrap-depends +_BOOTSTRAP_DEPENDS_TARGETS+= release-bootstrap-depends-lock + +bootstrap-depends: ${_BOOTSTRAP_DEPENDS_TARGETS} + +.PHONY: _pkgformat-bootstrap-depends +.if empty(PKG_FAIL_REASON) +_pkgformat-bootstrap-depends: + ${RUN}${_LIST_DEPENDS_CMD.bootstrap} | \ + while read type pattern dir; do \ + ${TEST} "$$type" = "bootstrap" || continue; \ + ${_DEPENDS_INSTALL_CMD}; \ + done +.else +_pkgformat-bootstrap-depends: + ${RUN}${DO_NADA} +.endif + +.PHONY: +acquire-bootstrap-depends-lock: acquire-lock +release-bootstrap-depends-lock: release-lock diff --git a/mk/pkgformat/pkg/install.mk b/mk/pkgformat/pkg/install.mk new file mode 100644 index 00000000000..7fcbc274ffb --- /dev/null +++ b/mk/pkgformat/pkg/install.mk @@ -0,0 +1,75 @@ +# $NetBSD: install.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# +# _pkgformat-check-conflicts: +# Checks for conflicts between the package and installed packages. +# +# XXX: Needs WRKDIR. +# +# _pkgformat-check-installed: +# Checks if the package (or an older version of it) is already +# installed on the system. +# +# XXX: Needs WRKDIR. +# +# _pkgformat-register: +# Populates the package database with the appropriate entries to +# register the package as being installed on the system. +# +# _pkgformat-install-clean: +# Removes the state files from the run of an ``install'' target. +# + +_pkgformat-check-conflicts: .PHONY error-check + ${RUN}${RM} -f ${WRKDIR}/.CONFLICTS +.for _conflict_ in ${CONFLICTS} + ${RUN} \ + found="`${_PKG_BEST_EXISTS} ${_conflict_:Q} || ${TRUE}`"; \ + case "$$found" in \ + "") ;; \ + *) ${ECHO} "$$found" >> ${WRKDIR}/.CONFLICTS ;; \ + esac +.endfor + ${RUN} \ + ${TEST} -f ${WRKDIR}/.CONFLICTS || exit 0; \ + exec 1>${ERROR_DIR}/${.TARGET}; \ + ${ECHO} "${PKGNAME} conflicts with installed package(s):"; \ + ${CAT} ${WRKDIR}/.CONFLICTS | ${SED} -e "s|^| |"; \ + ${ECHO} "They install the same files into the same place."; \ + ${ECHO} "Please remove conflicts first with pkg_delete(1)."; \ + ${RM} -f ${WRKDIR}/.CONFLICTS + +_pkgformat-check-installed: .PHONY error-check + ${RUN} \ + found="`${_PKG_BEST_EXISTS} ${PKGWILDCARD:Q} || ${TRUE}`"; \ + ${TEST} -n "$$found" || exit 0; \ + exec 1>${ERROR_DIR}/${.TARGET}; \ + ${ECHO} "$$found is already installed - perhaps an older version?"; \ + ${ECHO} "If so, you may use either of:"; \ + ${ECHO} " - \"pkg_delete $$found\" and \"${MAKE} reinstall\""; \ + ${ECHO} " to upgrade properly"; \ + ${ECHO} " - \"${MAKE} update\" to rebuild the package and all"; \ + ${ECHO} " of its dependencies"; \ + ${ECHO} " - \"${MAKE} replace\" to replace only the package without"; \ + ${ECHO} " re-linking dependencies, risking various problems." + +_REGISTER_DEPENDENCIES= \ + ${PKGSRC_SETENV} PKG_DBDIR=${_PKG_DBDIR:Q} \ + AWK=${TOOLS_AWK:Q} \ + ${SH} ${PKGSRCDIR}/mk/pkgformat/pkg/register-dependencies + +_pkgformat-register: .PHONY _pkgformat-generate-metadata ${_RDEPENDS_FILE} + @${STEP_MSG} "Registering installation for ${PKGNAME}" + ${RUN}${RM} -fr ${_PKG_DBDIR}/${PKGNAME} + ${RUN}${MKDIR} ${_PKG_DBDIR}/${PKGNAME} + ${RUN}${CP} ${PKG_DB_TMPDIR}/* ${_PKG_DBDIR}/${PKGNAME} + ${RUN}${PKG_ADMIN} add ${PKGNAME} + ${RUN} \ + case ${_AUTOMATIC:Q}"" in \ + [yY][eE][sS]) ${PKG_ADMIN} set automatic=yes ${PKGNAME} ;; \ + esac + ${RUN}${_FULL_DEPENDS_CMD} | \ + ${SORT} -u | ${_REGISTER_DEPENDENCIES} ${PKGNAME} + ${RUN}${GREP} '^@pkgdir ' < ${_PKG_DBDIR}/${PKGNAME}/+CONTENTS | \ + while read tag dir; do ${MKDIR} ${PREFIX}/$$dir; done + +_pkgformat-install-clean: .PHONY _pkgformat-clean-metadata diff --git a/mk/pkgformat/pkg/list-dependencies b/mk/pkgformat/pkg/list-dependencies new file mode 100755 index 00000000000..a7c6d9c37ae --- /dev/null +++ b/mk/pkgformat/pkg/list-dependencies @@ -0,0 +1,67 @@ +#!/bin/sh +# +###################################################################### +# +# NAME +# list-dependencies -- build package dependencies list +# +# SYNOPSIS +# list-dependencies bootstrap build full +# +# DESCRIPTION +# For each (reduced) dependency a line of the following format is +# printed: +# +# <depends_type> <pattern> <directory> +# +# Valid dependency types are "bootstrap", "build" and "full". +# +# ENVIRONMENT +# AWK +# Path to the awk interpreter. +# +# PKGSRCDIR +# Root directory of the pkgsrc tree. +# +# SED +# Path to the sed command. +# +# The following variables are used by the reduce-depends.awk script: +# +# PKG_ADMIN +# Path to the pkg_admin command. +# +# PWD_CMD +# Path to the pwd command. +# +###################################################################### + +: ${ECHO:=echo} + +set -e + +trap "exit 1" USR1 + +reduce_depends() { + ${AWK} -f ${PKGSRCDIR}/mk/pkgformat/pkg/reduce-depends.awk "$1" \ + || kill -USR1 $$ +} + +print_entries() { + reduce_depends "$2" | while read dep; do + pattern=`${ECHO} "$dep" | ${SED} -e "s,:.*,,"` + dir=`${ECHO} "$dep" | ${SED} -e "s,.*:,,"` + [ "$pattern" ] + [ "$dir" ] + ${ECHO} "$1 $pattern $dir" + done +} + +if [ $# != 3 ]; then + echo "usage: list-dependencies bootstrap_depends build_depends depends" 1>&2 + exit 1 +fi + +print_entries bootstrap "$1" +print_entries build "$2" +print_entries full "$3" diff --git a/mk/pkgformat/pkg/metadata.mk b/mk/pkgformat/pkg/metadata.mk new file mode 100644 index 00000000000..923a94d53ea --- /dev/null +++ b/mk/pkgformat/pkg/metadata.mk @@ -0,0 +1,415 @@ +# $NetBSD: metadata.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ + +###################################################################### +### The targets below are all PRIVATE. +###################################################################### + +###################################################################### +### +### Temporary package meta-data directory. The contents of this directory +### are copied directly into the real package meta-data directory. +### +PKG_DB_TMPDIR= ${WRKDIR}/.pkgdb + +unprivileged-install-hook: ${PKG_DB_TMPDIR} +${PKG_DB_TMPDIR}: + ${RUN}${MKDIR} ${.TARGET} + +###################################################################### +### +### +BUILD_INFO - Package build environment and settings information +### +_BUILD_INFO_FILE= ${PKG_DB_TMPDIR}/+BUILD_INFO +_BUILD_DATE_cmd= ${DATE} "+%Y-%m-%d %H:%M:%S %z" +_BUILD_HOST_cmd= ${UNAME} -a +_METADATA_TARGETS+= ${_BUILD_INFO_FILE} + +${_BUILD_INFO_FILE}: plist + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN}${RM} -f ${.TARGET}.tmp + ${RUN} (${_BUILD_DEFS:NPATH:@v@${ECHO} ${v}=${${v}:Q} ;@}) \ + > ${.TARGET}.tmp +.if !empty(USE_LANGUAGES) + ${RUN}${ECHO} "CC_VERSION=${CC_VERSION}" >> ${.TARGET}.tmp +.endif +.if !empty(USE_TOOLS:Mperl\:run) + ${RUN}${ECHO} "PERL=`${PERL5} --version 2>/dev/null | ${GREP} 'This is perl'`" >> ${.TARGET}.tmp +.endif +.if !empty(USE_TOOLS:Mgmake) + ${RUN}${ECHO} "GMAKE=`${GMAKE} --version | ${GREP} Make`" >> ${.TARGET}.tmp +.endif + ${RUN}${ECHO} "PKGTOOLS_VERSION=${PKGTOOLS_VERSION}" >> ${.TARGET}.tmp +.if defined(HOMEPAGE) + ${RUN}${ECHO} "HOMEPAGE=${HOMEPAGE}" >> ${.TARGET}.tmp +.endif + ${RUN}${ECHO} "CATEGORIES=${CATEGORIES}" >> ${.TARGET}.tmp + ${RUN}${ECHO} "MAINTAINER=${MAINTAINER}" >> ${.TARGET}.tmp +.if defined(OWNER) + ${RUN}${ECHO} "OWNER=${OWNER}" >> ${.TARGET}.tmp +.endif +.if defined(PREV_PKGPATH) + ${RUN}${ECHO} "PREV_PKGPATH=${PREV_PKGPATH}" >> ${.TARGET}.tmp +.endif +.if defined(SUPERSEDES) + ${RUN}${ECHO} "SUPERSEDES=${SUPERSEDES}" >> ${.TARGET}.tmp +.endif + ${RUN}${ECHO} "BUILD_DATE=${_BUILD_DATE_cmd:sh}" >> ${.TARGET}.tmp + ${RUN}${ECHO} "BUILD_HOST=${_BUILD_HOST_cmd:sh}" >> ${.TARGET}.tmp +.if !empty(CHECK_SHLIBS_SUPPORTED:M[yY][eE][sS]) + ${RUN} \ + case ${LDD:Q}"" in \ + "") ldd=`${TYPE} ldd 2>/dev/null | ${AWK} '{ print $$NF }'` ;; \ + *) ldd=${LDD:Q} ;; \ + esac; \ + bins=`${AWK} '/(^|\/)(bin|sbin|libexec)\// { print "${DESTDIR}${PREFIX}/" $$0 } END { exit 0 }' ${_PLIST_NOKEYWORDS}`; \ + case ${OBJECT_FMT:Q}"" in \ + ELF) \ + libs=`${AWK} '/\/lib.*\.so(\.[0-9]+)*$$/ { print "${DESTDIR}${PREFIX}/" $$0 } END { exit 0 }' ${_PLIST_NOKEYWORDS}`; \ + if ${TEST} -n "$$bins" -o -n "$$libs"; then \ + requires=`($$ldd $$bins $$libs 2>/dev/null || ${TRUE}) | ${AWK} '$$2 == "=>" && $$3 ~ "/" { print $$3 }' | ${SORT} -u`; \ + fi; \ + linklibs=`${AWK} '/.*\.so(\.[0-9]+)*$$/ { print "${DESTDIR}${PREFIX}/" $$0 }' ${_PLIST_NOKEYWORDS}`; \ + for i in $$linklibs; do \ + if ${TEST} -r $$i -a ! -x $$i -a ! -h $$i; then \ + ${TEST} ${PKG_DEVELOPER:Uno:Q}"" = "no" || \ + ${ECHO} "$$i: installed without execute permission; fixing (should use [BSD_]INSTALL_LIB)"; \ + ${CHMOD} +x $$i; \ + fi; \ + done; \ + ;; \ + Mach-O) \ + libs=`${AWK} '/\/lib.*\.dylib/ { print "${DESTDIR}${PREFIX}/" $$0 } END { exit 0 }' ${_PLIST_NOKEYWORDS}`; \ + if ${TEST} "$$bins" != "" -o "$$libs" != ""; then \ + requires=`($$ldd $$bins $$libs 2>/dev/null || ${TRUE}) | ${AWK} '/compatibility version/ { print $$1 }' | ${SORT} -u`; \ + fi; \ + ;; \ + esac; \ + requires=`{ for i in $$requires $$requires; do echo $$i; done; \ + ${AWK} '{ print "${PREFIX}/" $$0 }' ${_PLIST_NOKEYWORDS}; } | \ + ${SORT} | uniq -c | awk '$$1 == 2 {print $$2}'`; \ + for i in "" $$libs; do \ + ${TEST} "$$i" != "" || continue; \ + ${ECHO} "PROVIDES=$${i}"; \ + done | ${SED} -e 's,^PROVIDES=${DESTDIR},PROVIDES=,' \ + >> ${.TARGET}.tmp; \ + for req in "" $$requires; do \ + ${TEST} "$$req" != "" || continue; \ + ${ECHO} "REQUIRES=$$req" >> ${.TARGET}.tmp; \ + done +.endif + ${RUN} \ + rm -f ${.TARGET}; \ + sort ${.TARGET}.tmp > ${.TARGET}; \ + rm -f ${.TARGET}.tmp + +###################################################################### +### +### +BUILD_VERSION - Package build files versioning information +### +### We extract the ident strings from all of the important pkgsrc files +### involved in building the package, i.e. Makefile and patches. +### +_BUILD_VERSION_FILE= ${PKG_DB_TMPDIR}/+BUILD_VERSION +_METADATA_TARGETS+= ${_BUILD_VERSION_FILE} + +${_BUILD_VERSION_FILE}: + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN}${RM} -f ${.TARGET}.tmp + ${RUN} \ + exec 1>>${.TARGET}.tmp; \ + for f in ${.CURDIR}/Makefile ${FILESDIR}/* ${PKGDIR}/*; do \ + ${TEST} ! -f "$$f" || ${ECHO} "$$f"; \ + done + ${RUN} \ + exec 1>>${.TARGET}.tmp; \ + ${TEST} -f ${DISTINFO_FILE:Q} || exit 0; \ + ${CAT} ${DISTINFO_FILE} | \ + ${AWK} 'NF == 4 && $$3 == "=" { gsub("[()]", "", $$2); print $$2 }' | \ + while read file; do \ + ${TEST} ! -f "${PATCHDIR}/$$file" || \ + ${ECHO} "${PATCHDIR}/$$file"; \ + done + ${RUN} \ + exec 1>>${.TARGET}.tmp; \ + ${TEST} -d ${PATCHDIR} || exit 0; \ + cd ${PATCHDIR}; for f in *; do \ + case "$$f" in \ + "*"|*.orig|*.rej|*~) ;; \ + patch-*) ${ECHO} "${PATCHDIR}/$$f" ;; \ + esac; \ + done + ${RUN} \ + ${CAT} ${.TARGET}.tmp | \ + while read file; do \ + ${GREP} '\$$NetBSD' $$file 2>/dev/null | \ + ${SED} -e "s|^|$$file:|"; \ + done | \ + ${AWK} '{ sub("^${PKGSRCDIR}/", ""); \ + sub(":.*[$$]NetBSD", ": $$NetBSD"); \ + sub("[$$][^$$]*$$", "$$"); \ + print; }' | \ + ${SORT} -u > ${.TARGET} && ${RM} -f ${.TARGET}.tmp + +###################################################################### +### +### +COMMENT - Package comment file +### +### This file contains the one-line description of the package. +### +_COMMENT_FILE= ${PKG_DB_TMPDIR}/+COMMENT +_METADATA_TARGETS+= ${_COMMENT_FILE} + +${_COMMENT_FILE}: + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN}${ECHO} ${COMMENT:Q} > ${.TARGET} + +###################################################################### +### +### +DESC - Package description file +### +### This file contains the paragraph description of the package. +### +_DESCR_FILE= ${PKG_DB_TMPDIR}/+DESC +_METADATA_TARGETS+= ${_DESCR_FILE} + +${_DESCR_FILE}: ${DESCR_SRC} + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN}${RM} -f ${.TARGET} + ${RUN}${CAT} ${.ALLSRC} > ${.TARGET} +.if defined(HOMEPAGE) + ${RUN}${ECHO} >> ${.TARGET} + ${RUN}${ECHO} "Homepage:" >> ${.TARGET} + ${RUN}${ECHO} ""${HOMEPAGE:Q} >> ${.TARGET} +.endif + +###################################################################### +### +### +DISPLAY - Package message file +### +### This file contains important messages which apply to this package, +### and are shown during installation. +### +.if !defined(MESSAGE_SRC) +. if exists(${PKGDIR}/MESSAGE) +MESSAGE_SRC= ${PKGDIR}/MESSAGE +. else +. if exists(${PKGDIR}/MESSAGE.common) +MESSAGE_SRC= ${PKGDIR}/MESSAGE.common +. endif +. if exists(${PKGDIR}/MESSAGE.${OPSYS}) +MESSAGE_SRC+= ${PKGDIR}/MESSAGE.${OPSYS} +. endif +. if exists(${PKGDIR}/MESSAGE.${MACHINE_ARCH:C/i[3-6]86/i386/g}) +MESSAGE_SRC+= ${PKGDIR}/MESSAGE.${MACHINE_ARCH:C/i[3-6]86/i386/g} +. endif +. if exists(${PKGDIR}/MESSAGE.${OPSYS}-${MACHINE_ARCH:C/i[3-6]86/i386/g}) +MESSAGE_SRC+= ${PKGDIR}/MESSAGE.${OPSYS}-${MACHINE_ARCH:C/i[3-6]86/i386/g} +. endif +. endif +.endif + +.if defined(MESSAGE_SRC) +_MESSAGE_FILE= ${PKG_DB_TMPDIR}/+DISPLAY +_METADATA_TARGETS+= ${_MESSAGE_FILE} + +# Set MESSAGE_SUBST to substitute "${variable}" to "value" in MESSAGE +MESSAGE_SUBST+= PKGNAME=${PKGNAME} \ + PKGBASE=${PKGBASE} \ + PREFIX=${PREFIX} \ + EMULDIR=${EMULDIR} \ + EMULSUBDIR=${EMULSUBDIR} \ + LOCALBASE=${LOCALBASE} \ + X11PREFIX=${X11PREFIX} \ + X11BASE=${X11BASE} \ + PKG_SYSCONFDIR=${PKG_SYSCONFDIR} \ + ROOT_GROUP=${REAL_ROOT_GROUP} \ + ROOT_USER=${REAL_ROOT_USER} + +_MESSAGE_SUBST_SED= ${MESSAGE_SUBST:S/=/}!/:S/$/!g/:S/^/ -e s!\\\${/} + +${_MESSAGE_FILE}: ${MESSAGE_SRC} + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN}${CAT} ${.ALLSRC} | \ + ${SED} ${_MESSAGE_SUBST_SED} > ${.TARGET} + +# Display MESSAGE file and optionally mail the contents to +# PKGSRC_MESSAGE_RECIPIENTS. +# +.PHONY: install-display-message +_pkgformat-register: install-display-message +install-display-message: ${_MESSAGE_FILE} + @${STEP_MSG} "Please note the following:" + @${ECHO_MSG} "" + @${CAT} ${_MESSAGE_FILE} + @${ECHO_MSG} "" +. if !empty(PKGSRC_MESSAGE_RECIPIENTS) + ${RUN} \ + (${ECHO} "The ${PKGNAME} package was installed on `${HOSTNAME_CMD}` at `date`"; \ + ${ECHO} ""; \ + ${ECHO} "Please note the following:"; \ + ${ECHO} ""; \ + ${CAT} ${_MESSAGE_FILE}; \ + ${ECHO} "") | \ + ${MAIL_CMD} -s"Package ${PKGNAME} installed on `${HOSTNAME_CMD}`" ${PKGSRC_MESSAGE_RECIPIENTS} +. endif +.endif # MESSAGE_SRC + +###################################################################### +### +### +PRESERVE - Package preserve file +### +### The existence of this file prevents pkg_delete from removing this +### package unless one "force-deletes" the package. +### +.if defined(PKG_PRESERVE) +_PRESERVE_FILE= ${PKG_DB_TMPDIR}/+PRESERVE +_METADATA_TARGETS+= ${_PRESERVE_FILE} + +${_PRESERVE_FILE}: + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN}${DATE} > ${.TARGET} +.endif + +###################################################################### +### +### +SIZE_PKG - Package size file +### +### This is the total size of the files contained in the package. +### +_SIZE_PKG_FILE= ${PKG_DB_TMPDIR}/+SIZE_PKG +_METADATA_TARGETS+= ${_SIZE_PKG_FILE} + +${_SIZE_PKG_FILE}: plist + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN} \ + ${CAT} ${PLIST} | \ + ${AWK} 'BEGIN { base = "${PREFIX}/" } \ + /^@cwd/ { base = $$2 "/" } \ + /^@/ { next } \ + { print base $$0 }' | \ + ${SORT} -u | \ + ${SED} -e "s,^/,${DESTDIR}/," -e "s/'/'\\\\''/g" -e "s/.*/'&'/" | \ + ${XARGS} -n 256 ${LS} -ld 2>/dev/null | \ + ${AWK} 'BEGIN { s = 0 } { s += $$5 } END { print s }' \ + > ${.TARGET} + +###################################################################### +### +### +SIZE_ALL - Package size-of-dependencies file +### +### This is the total size of the dependencies that this package was +### built against and the package itself. +### +_SIZE_ALL_FILE= ${PKG_DB_TMPDIR}/+SIZE_ALL +_METADATA_TARGETS+= ${_SIZE_ALL_FILE} + +${_SIZE_ALL_FILE}: ${_RDEPENDS_FILE} ${_SIZE_PKG_FILE} + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN} \ + { \ + ${CAT} ${_SIZE_PKG_FILE} && \ + ${_FULL_DEPENDS_CMD} | ${SORT} -u | \ + ${XARGS} -n 256 ${PKG_INFO} -qs; \ + } | \ + ${AWK} 'BEGIN { s = 0 } /^[0-9]+$$/ { s += $$1 } END { print s }' \ + > ${.TARGET} + +###################################################################### +### +### +CONTENTS - Package manifest file +### +### This file contains the list of files and checksums, along with +### any special "@" commands, e.g. @dirrm. +### +_CONTENTS_FILE= ${PKG_DB_TMPDIR}/+CONTENTS +_METADATA_TARGETS+= ${_CONTENTS_FILE} + +_DEPENDS_PLIST= ${WRKDIR}/.PLIST_deps + +${_DEPENDS_PLIST}: ${PLIST} + ${RUN} { \ + ${ECHO} "@name ${PKGNAME}"; \ + ${AWK} '$$1 == "full" { printf "@blddep %s\n@pkgdep %s\n", $$3, $$2; }' < ${_RDEPENDS_FILE}; \ + ${AWK} '$$1 == "bootstrap" || $$1 == "build" { printf "@blddep %s\n", $$3; }' < ${_RDEPENDS_FILE}; \ + ${CAT} ${PLIST}; } > ${.TARGET} + +_PKG_CREATE_ARGS+= -l -U +_PKG_CREATE_ARGS+= -B ${_BUILD_INFO_FILE} +_PKG_CREATE_ARGS+= -b ${_BUILD_VERSION_FILE} +_PKG_CREATE_ARGS+= -c ${_COMMENT_FILE} +_PKG_CREATE_ARGS+= ${_MESSAGE_FILE:D -D ${_MESSAGE_FILE}} +_PKG_CREATE_ARGS+= -d ${_DESCR_FILE} +_PKG_CREATE_ARGS+= -f ${_DEPENDS_PLIST} +_PKG_CREATE_ARGS+= ${PKG_PRESERVE:D -n ${_PRESERVE_FILE}} +_PKG_CREATE_ARGS+= -S ${_SIZE_ALL_FILE} +_PKG_CREATE_ARGS+= -s ${_SIZE_PKG_FILE} +_PKG_CREATE_ARGS+= ${CONFLICTS:D -C ${CONFLICTS:Q}} +_PKG_CREATE_ARGS+= ${INSTALL_FILE:D ${_INSTALL_ARG_cmd:sh}} +_PKG_CREATE_ARGS+= ${DEINSTALL_FILE:D ${_DEINSTALL_ARG_cmd:sh}} + +_PKG_ARGS_INSTALL+= ${_PKG_CREATE_ARGS} +.if ${_USE_DESTDIR} == "no" +_PKG_ARGS_INSTALL+= -p ${PREFIX} +.else +_PKG_ARGS_INSTALL+= -I ${PREFIX} -p ${DESTDIR}${PREFIX} +.endif + +_DEINSTALL_ARG_cmd= if ${TEST} -f ${DEINSTALL_FILE}; then \ + ${ECHO} "-k "${DEINSTALL_FILE:Q}; \ + else \ + ${ECHO}; \ + fi +_INSTALL_ARG_cmd= if ${TEST} -f ${INSTALL_FILE}; then \ + ${ECHO} "-i "${INSTALL_FILE:Q}; \ + else \ + ${ECHO}; \ + fi + +_CONTENTS_TARGETS+= ${_BUILD_INFO_FILE} +_CONTENTS_TARGETS+= ${_BUILD_VERSION_FILE} +_CONTENTS_TARGETS+= ${_COMMENT_FILE} +_CONTENTS_TARGETS+= ${_DEPENDS_FILE} +_CONTENTS_TARGETS+= ${_DESCR_FILE} +_CONTENTS_TARGETS+= ${_MESSAGE_FILE} +_CONTENTS_TARGETS+= ${_DEPENDS_PLIST} +_CONTENTS_TARGETS+= plist +_CONTENTS_TARGETS+= ${_PRESERVE_FILE} +_CONTENTS_TARGETS+= ${_SIZE_ALL_FILE} +_CONTENTS_TARGETS+= ${_SIZE_PKG_FILE} + +${_CONTENTS_FILE}: ${_CONTENTS_TARGETS} + ${RUN}${MKDIR} ${.TARGET:H} + ${RUN}${PKG_CREATE} ${_PKG_ARGS_INSTALL} -O ${PKGFILE:T} > ${.TARGET} + +###################################################################### +### _pkgformat-generate-metadata (PRIVATE) +###################################################################### +### _pkgformat-generate-metadata is a convenience target for generating +### all of the pkgsrc binary package meta-data files. It populates +### ${PKG_DB_TMPDIR} with the following files: +### +### +BUILD_INFO +### +BUILD_VERSION +### +COMMENT +### +CONTENTS +### +DESC +### +DISPLAY +### +PRESERVE +### +SIZE_ALL +### +SIZE_PKG +### +### See the targets above for descriptions of each of those files. +### +.PHONY: _pkgformat-generate-metadata +_pkgformat-generate-metadata: ${_METADATA_TARGETS} + +###################################################################### +### _pkgformat-clean-metadata (PRIVATE) +###################################################################### +### _pkgformat-clean-metadata is a convenience target for removing the +### package meta-data files. This is essentially the reverse action +### of _pkgformat-generate-metadata. +### +.PHONY: _pkgformat-clean-metadata +_pkgformat-clean-metadata: + ${RUN}${RM} -f ${_METADATA_TARGETS} diff --git a/mk/pkgformat/pkg/package.mk b/mk/pkgformat/pkg/package.mk new file mode 100644 index 00000000000..cdee24570f4 --- /dev/null +++ b/mk/pkgformat/pkg/package.mk @@ -0,0 +1,159 @@ +# $NetBSD: package.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ + +.if defined(PKG_SUFX) +WARNINGS+= "PKG_SUFX is deprecated, please use PKG_COMPRESSION" +. if ${PKG_SUFX} == ".tgz" +PKG_COMPRESSION= gzip +. elif ${PKG_SUFX} == ".tbz" +PKG_COMPRESSION= bzip2 +. else +WARNINGS+= "Unsupported value for PKG_SUFX" +. endif +.endif +PKG_SUFX?= .tgz +FILEBASE?= ${PKGBASE} +PKGFILE?= ${PKGREPOSITORY}/${FILEBASE}-${PKGVERSION}${PKG_SUFX} +PKGREPOSITORY?= ${PACKAGES}/${PKGREPOSITORYSUBDIR} +PKGREPOSITORYSUBDIR?= All + +###################################################################### +### package-check-installed (PRIVATE, pkgsrc/mk/package/package.mk) +###################################################################### +### package-check-installed verifies that the package is installed on +### the system. +### +.PHONY: package-check-installed +package-check-installed: + ${RUN} ${PKG_INFO} -qe ${PKGNAME} \ + || ${FAIL_MSG} "${PKGNAME} is not installed." + +###################################################################### +### package-create (PRIVATE, pkgsrc/mk/package/package.mk) +###################################################################### +### package-create creates the binary package. +### +.PHONY: package-create +package-create: package-remove ${PKGFILE} package-links + +_PKG_ARGS_PACKAGE+= ${_PKG_CREATE_ARGS} +_PKG_ARGS_PACKAGE+= -F ${PKG_COMPRESSION} +.if ${_USE_DESTDIR} == "no" +_PKG_ARGS_PACKAGE+= -p ${PREFIX} +.else +_PKG_ARGS_PACKAGE+= -I ${PREFIX} -p ${DESTDIR}${PREFIX} +. if ${_USE_DESTDIR} == "user-destdir" +_PKG_ARGS_PACKAGE+= -u ${REAL_ROOT_USER} -g ${REAL_ROOT_GROUP} +. endif +.endif +.if ${PKG_INSTALLATION_TYPE} == "pkgviews" +_PKG_ARGS_PACKAGE+= -E +.endif + +${PKGFILE}: ${_CONTENTS_TARGETS} + ${RUN} ${MKDIR} ${.TARGET:H} + @${STEP_MSG} "Creating binary package ${.TARGET}" + ${RUN} tmpname=${.TARGET:S,${PKG_SUFX}$,.tmp${PKG_SUFX},}; \ + if ${PKG_CREATE} ${_PKG_ARGS_PACKAGE} "$$tmpname"; then \ + ${MV} -f "$$tmpname" ${.TARGET}; \ + else \ + exitcode=$$?; ${RM} -f "$$tmpname"; exit $$exitcode; \ + fi + +###################################################################### +### package-remove (PRIVATE) +###################################################################### +### package-remove removes the binary package from the package +### repository. +### +.PHONY: package-remove +package-remove: + ${RUN} ${RM} -f ${PKGFILE} + +###################################################################### +### package-links (PRIVATE) +###################################################################### +### package-links creates symlinks to the binary package from the +### non-primary categories to which the package belongs. +### +package-links: delete-package-links +.for _dir_ in ${CATEGORIES:S/^/${PACKAGES}\//} + ${RUN} ${MKDIR} ${_dir_:Q} + ${RUN} [ -d ${_dir_:Q} ] \ + || ${FAIL_MSG} "Can't create directory "${_dir_:Q}"." + ${RUN} ${RM} -f ${_dir_:Q}/${PKGFILE:T} + ${RUN} ${LN} -s ../${PKGREPOSITORYSUBDIR}/${PKGFILE:T} ${_dir_:Q} +.endfor + +###################################################################### +### delete-package-links (PRIVATE) +###################################################################### +### delete-package-links removes the symlinks to the binary package from +### the non-primary categories to which the package belongs. +### +delete-package-links: + ${RUN} ${FIND} ${PACKAGES} -type l -name ${PKGFILE:T} -print \ + | ${XARGS} ${RM} -f + +###################################################################### +### tarup (PUBLIC) +###################################################################### +### tarup is a public target to generate a binary package from an +### installed package instance. +### +_PKG_TARUP_CMD= ${LOCALBASE}/bin/pkg_tarup + +.PHONY: tarup +tarup: package-remove tarup-pkg package-links + +###################################################################### +### tarup-pkg (PRIVATE) +###################################################################### +### tarup-pkg creates a binary package from an installed package instance +### using "pkg_tarup". +### +tarup-pkg: + ${RUN} [ -x ${_PKG_TARUP_CMD} ] || exit 1; \ + ${PKGSRC_SETENV} PKG_DBDIR=${_PKG_DBDIR} PKG_SUFX=${PKG_SUFX} \ + PKGREPOSITORY=${PKGREPOSITORY} \ + ${_PKG_TARUP_CMD} -f ${FILEBASE} ${PKGNAME} + +###################################################################### +### package-install (PUBLIC) +###################################################################### +### When DESTDIR support is active, package-install uses package to +### create a binary package and installs it. +### Otherwise it is identical to calling package. +### + +.PHONY: package-install real-package-install su-real-package-install +.if defined(_PKGSRC_BARRIER) +package-install: package real-package-install +.else +package-install: barrier +.endif + +.if ${_USE_DESTDIR} != "no" +. if !empty(USE_CROSS_COMPILE:M[yY][eE][sS]) +real-package-install: su-real-package-install +. else +real-package-install: su-target +. endif +.else +real-package-install: + @${DO_NADA} +.endif + +su-real-package-install: + @${PHASE_MSG} "Install binary package of "${PKGNAME:Q} +.if !empty(USE_CROSS_COMPILE:M[yY][eE][sS]) + @${MKDIR} ${_CROSS_DESTDIR}${PREFIX} + ${PKG_ADD} -m ${MACHINE_ARCH} -I -p ${_CROSS_DESTDIR}${PREFIX} ${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 + ${RUN} case ${_AUTOMATIC:Q}"" in \ + [yY][eE][sS]) ${PKG_ADD} -A ${PKGFILE} ;; \ + *) ${PKG_ADD} ${PKGFILE} ;; \ + esac +.endif diff --git a/mk/pkgformat/pkg/pkgformat-vars.mk b/mk/pkgformat/pkg/pkgformat-vars.mk new file mode 100644 index 00000000000..dbcf7870bf7 --- /dev/null +++ b/mk/pkgformat/pkg/pkgformat-vars.mk @@ -0,0 +1,92 @@ +# $NetBSD: pkgformat-vars.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# +# This Makefile fragment is included indirectly by bsd.prefs.mk and +# defines some variables which must be defined earlier than where +# pkgformat.mk is included. +# + +PKGSRC_MESSAGE_RECIPIENTS?= # empty + +.if !empty(PKGSRC_MESSAGE_RECIPIENTS) +USE_TOOLS+= mail +.endif + +.if defined(PKG_PRESERVE) +USE_TOOLS+= date +.endif + +# This is the package database directory for the default view. +PKG_DBDIR?= /var/db/pkg + +# _PKG_DBDIR is the actual packages database directory where we register +# packages. +# +.if ${PKG_INSTALLATION_TYPE} == "overwrite" +_PKG_DBDIR= ${_CROSS_DESTDIR}${PKG_DBDIR} +.elif ${PKG_INSTALLATION_TYPE} == "pkgviews" +_PKG_DBDIR= ${_CROSS_DESTDIR}${DEPOTBASE} +.endif + +PKG_ADD_CMD?= ${PKG_TOOLS_BIN}/pkg_add +PKG_ADMIN_CMD?= ${PKG_TOOLS_BIN}/pkg_admin +PKG_CREATE_CMD?= ${PKG_TOOLS_BIN}/pkg_create +PKG_DELETE_CMD?= ${PKG_TOOLS_BIN}/pkg_delete +PKG_INFO_CMD?= ${PKG_TOOLS_BIN}/pkg_info +PKG_VIEW_CMD?= ${PKG_TOOLS_BIN}/pkg_view +LINKFARM_CMD?= ${PKG_TOOLS_BIN}/linkfarm + +# Latest versions of tools required for correct pkgsrc operation. +.if make(replace) && ${_USE_DESTDIR} != "no" +PKGTOOLS_REQD= 20100914 +.else +PKGTOOLS_REQD= 20090528 +.endif + +.if !defined(PKGTOOLS_VERSION) +PKGTOOLS_VERSION!= ${PKG_INFO_CMD} -V 2>/dev/null || echo 20010302 +MAKEFLAGS+= PKGTOOLS_VERSION=${PKGTOOLS_VERSION} +.endif + +# Check that we are using up-to-date pkg_* tools with this file. +.if !defined(NO_PKGTOOLS_REQD_CHECK) && ${PKGTOOLS_VERSION} < ${PKGTOOLS_REQD} +BOOTSTRAP_DEPENDS+= pkg_install>=${PKGTOOLS_REQD}:../../pkgtools/pkg_install +_PKG_INSTALL_DEPENDS= yes +.endif + +AUDIT_PACKAGES?= ${PKG_ADMIN} +_AUDIT_PACKAGES_CMD?= audit-pkg +_EXTRACT_PKGVULNDIR= ${PKG_ADMIN} config-var PKGVULNDIR +DOWNLOAD_VULN_LIST?= ${PKG_ADMIN} fetch-pkg-vulnerabilities +_AUDIT_CONFIG_FILE= pkg_install.conf +_AUDIT_CONFIG_OPTION= IGNORE_URL + +# The binary pkg_install tools all need to consistently to refer to the +# correct package database directory. +# +PKGTOOLS_ARGS?= -K ${_PKG_DBDIR} + +# Views are rooted in ${LOCALBASE}, all packages are depoted in +# ${DEPOTBASE}, and the package database directory for the default view +# is in ${PKG_DBDIR}. +# +PKG_VIEW_ARGS?= -W ${LOCALBASE} -d ${DEPOTBASE} -k ${PKG_DBDIR} + +PKG_ADD?= ${PKG_ADD_CMD} ${PKGTOOLS_ARGS} +PKG_ADMIN?= ${PKG_ADMIN_CMD} ${PKGTOOLS_ARGS} +PKG_CREATE?= ${PKG_CREATE_CMD} ${PKGTOOLS_ARGS} +PKG_DELETE?= ${PKG_DELETE_CMD} ${PKGTOOLS_ARGS} +PKG_INFO?= ${PKG_INFO_CMD} ${PKGTOOLS_ARGS} +PKG_VIEW?= ${PKG_VIEW_CMD} ${PKG_VIEW_ARGS} +LINKFARM?= ${LINKFARM_CMD} + +# "${_PKG_BEST_EXISTS} pkgpattern" prints out the name of the installed +# package that best matches pkgpattern. Use this instead of +# "${PKG_INFO} -e pkgpattern" if the latter would return more than one +# package name. +# +_PKG_BEST_EXISTS?= ${PKG_INFO} -E + +# XXX Leave this here until all uses of this have been purged from the +# XXX public parts of pkgsrc. +# XXX +PKG_BEST_EXISTS= ${_PKG_BEST_EXISTS} diff --git a/mk/pkgformat/pkg/pkgformat.mk b/mk/pkgformat/pkg/pkgformat.mk new file mode 100644 index 00000000000..2652c3da044 --- /dev/null +++ b/mk/pkgformat/pkg/pkgformat.mk @@ -0,0 +1,27 @@ +# $NetBSD: pkgformat.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# +# This Makefile fragment provides variable and target overrides that are +# specific to the pkgsrc native package format. +# + +# PKG_FILELIST_CMD outputs the list of files owned by ${PKGNAME} as +# registered on the system. +# +# For DESTDIR support, just use _DEPENDS_PLIST instead. +# +.if ${_USE_DESTDIR} == "no" +PKG_FILELIST_CMD= ${PKG_INFO} -qL ${PKGNAME:Q} +.else +PKG_FILELIST_CMD= ${SED} -e "/^@/d" -e "s|^|${PREFIX}/|" ${_DEPENDS_PLIST} +.endif + +.include "depends.mk" +.include "check.mk" +.include "metadata.mk" +.include "install.mk" +.include "deinstall.mk" +.include "replace.mk" +.include "package.mk" +.include "views.mk" + +.include "utility.mk" diff --git a/mk/pkgformat/pkg/reduce-depends.awk b/mk/pkgformat/pkg/reduce-depends.awk new file mode 100755 index 00000000000..c27d6429d73 --- /dev/null +++ b/mk/pkgformat/pkg/reduce-depends.awk @@ -0,0 +1,158 @@ +#!/usr/bin/awk -f +# +# $NetBSD: reduce-depends.awk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# +# Copyright (c) 2006 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Johnny C. Lam. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the NetBSD +# Foundation, Inc. and its contributors. +# 4. Neither the name of The NetBSD Foundation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +###################################################################### +# +# NAME +# reduce-depends.awk -- reduce a list of dependencies +# +# SYNOPSIS +# reduce-depends.awk "depends_list" +# +# DESCRIPTION +# reduce-depends.awk removes some extraneous dependencies from the +# dependency list. The dependency list should be passed as a single +# argument, and the output will be a list of the reduced dependencies, +# echo one on a new line. +# +# ENVIRONMENT +# CAT +# PKG_ADMIN +# PWD_CMD +# TEST +# +###################################################################### + +BEGIN { + CAT = ENVIRON["CAT"] ? ENVIRON["CAT"] : "cat" + PKG_ADMIN = ENVIRON["PKG_ADMIN"] ? ENVIRON["PKG_ADMIN"] : "pkg_admin" + PWD_CMD = ENVIRON["PWD_CMD"] ? ENVIRON["PWD_CMD"] : "pwd -P" + TEST = ENVIRON["TEST"] ? ENVIRON["TEST"] : "test" + + PROGNAME = "reduce-depends.awk" + ERRCAT = CAT " 1>&2" + + # Gather all dependencies into the depends array. Index 0 of the + # depends[pkgpath] array is the number of patterns associated with + # that pkgpath. + # + args = ARGV[1] + ARGC = split(args, ARGV); ARGC++ + for (i = 1; i < ARGC; i++) { + pattern = ARGV[i]; sub(":.*", "", pattern) + dir = ARGV[i]; sub(".*:", "", dir) + if (pattern ":" dir != ARGV[i]) { + print "ERROR: [" PROGNAME "] invalid dependency pattern: " ARGV[i] | ERRCAT + exit 1 + } + cmd = TEST " -d " dir + if (system(cmd) == 0) { + cmd = "cd " dir " && " PWD_CMD + while (cmd | getline pkgpath) + if (!(pkgpath in pkgsrcdirs)) { + pkgpaths[P++] = pkgpath + pkgsrcdirs[pkgpath] = dir + } + depends[pkgpath, 0]++; + depends[pkgpath, depends[pkgpath, 0]] = pattern + close(cmd) + } else { + print "ERROR: [" PROGNAME "] " dir " does not exist." | ERRCAT + exit 1 + } + } + + # Reduce dependencies to the strictest set of dependencies it + # can derive from all of depends[...]. It only understands + # dependencies of the form foo>=1.0, and leaves the other + # dependencies undisturbed. + # + # The algorithm takes dependencies of the form foo>=1.0 and + # converts them to foo-1.0. It then compares this pkg name against + # each dependency to see if it satisfies them all. The key fact + # is the the strictest dependency, when converted to a pkg name, + # will satisfy every dependency. + # + for (p = 0; p < P; p++) { + pkgpath = pkgpaths[p] + D = depends[pkgpath, 0]; + match_all = 1; + for (d = 1; d <= D; d++) { + dep = depends[pkgpath, d] + if (dep ~ /[{]/ || \ + dep ~ />=[0-9][0-9\.]*<[0-9]+/ || \ + dep !~ />=[0-9]+/) + { + reduced[N++] = dep ":" pkgsrcdirs[pkgpath] + continue + } + ge_depends[dep] = dep + } + for (dep in ge_depends) { + dep2pkg = dep; sub(">=", "-", dep2pkg) + match_all = 1 + for (pattern in ge_depends) { + cmd = PKG_ADMIN " pmatch \"" pattern "\" " dep2pkg + if (system(cmd) != 0) { + match_all = 0 + break + } + } + if (match_all == 0) continue + reduced[N++] = dep ":" pkgsrcdirs[pkgpath] + break + } + # + # If there are conflicting dependencies, then just pass them + # through and let the rest of the pkgsrc machinery handle it. + # + if (match_all == 0) { + for (d = 1; d <= D; d++) { + dep = depends[pkgpath, d] + reduced[N++] = dep ":" pkgsrcdirs[pkgpath] + } + } + for (dep in ge_depends) + delete ge_depends[dep] + } + + # Output reduced dependencies. + for (n = 0; n < N; n++) + print reduced[n]; +} diff --git a/mk/pkgformat/pkg/register-dependencies b/mk/pkgformat/pkg/register-dependencies new file mode 100755 index 00000000000..148ef8ac340 --- /dev/null +++ b/mk/pkgformat/pkg/register-dependencies @@ -0,0 +1,51 @@ +#!/bin/sh +# +# $NetBSD: register-dependencies,v 1.1 2011/10/15 00:23:09 reed Exp $ +# +###################################################################### +# +# NAME +# register-dependencies -- register package dependencies +# +# SYNOPSIS +# register-dependencies pkgname +# +# DESCRIPTION +# register-dependencies registers a dependency relationship from +# the named package pkgname and the packages passed in via +# standard input. +# +# ENVIRONMENT +# PKG_DBDIR +# This is the package meta-data directory in which the +# packages are registered. By default, this is /var/db/pkg. +# +###################################################################### + +: ${AWK:=awk} +: ${CP:=cp} +: ${ECHO:=echo} +: ${PKG_DBDIR:=/var/db/pkg} +: ${RM:=rm} +: ${TEST:=test} +: ${TOUCH:=touch} +: ${TRUE:=true} + +PKGNAME="$1" + +while read pkg; do + pkgdir="${PKG_DBDIR}/$pkg" + if ${TEST} ! -d "$pkgdir"; then + ${ECHO} 1>&2 "$pkg not found - dependency NOT registered" + continue + fi + req="$pkgdir/+REQUIRED_BY" + tmpreq="$pkgdir/+REQUIRED_BY.$$" + ${TOUCH} $req + ${AWK} -v PKGNAME="${PKGNAME}" \ + 'BEGIN { found = 0 } + $0 == PKGNAME { found = 1 } { print } + END { if (!found) print PKGNAME }' $req > $tmpreq + ${CP} -f $tmpreq $req; ${RM} -f $tmpreq + ${ECHO} "${PKGNAME} requires installed package $pkg" +done diff --git a/mk/pkgformat/pkg/replace.mk b/mk/pkgformat/pkg/replace.mk new file mode 100644 index 00000000000..17a81b32463 --- /dev/null +++ b/mk/pkgformat/pkg/replace.mk @@ -0,0 +1,227 @@ +# $NetBSD: replace.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ +# + +# _pkgformat-replace: +# Updates a package in-place on the system (USE_DESTDIR=no). +# +# _pkgformat-destdir-replace: +# Updates a package in-place on the system (USE_DESTDIR=yes). +# +# See also: +# replace +# +# XXX: The whole replacement, from deinstalling the old package up +# to installing the new package, should be one transaction. It +# currently isn't, and the check-files target for other packages +# can be confused when a +REQUIRED_BY files suddenly disappears. +# +_pkgformat-replace: \ + replace-names \ + replace-tarup \ + replace-preserve-installed-info \ + replace-preserve-required-by \ + deinstall \ + install-clean \ + install \ + replace-fixup-required-by \ + replace-fixup-installed-info \ + .PHONY + +_pkgformat-destdir-replace: \ + replace-names \ + replace-tarup \ + 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}"; \ + ${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}"; \ + ${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* and rebuild tags from this package. +# +# XXX: pkg_admin should not complain on unset with no +INSTALLED_INFO. +# +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; do \ + ${TEST} ! -f ${_PKG_DBDIR}/$$newname/+INSTALLED_INFO || \ + ${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} + ${PKG_ADD} -U -D -m ${MACHINE_ARCH} -I -p ${_CROSS_DESTDIR}${PREFIX} ${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 + ${PKG_ADD} -U -D ${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}${PKG_ADMIN} unset unsafe_depends ${PKGNAME:Q} + ${RUN}${PKG_ADMIN} unset unsafe_depends_strict ${PKGNAME:Q} + ${RUN}${PKG_ADMIN} unset rebuild ${PKGNAME:Q} diff --git a/mk/pkgformat/pkg/resolve-dependencies b/mk/pkgformat/pkg/resolve-dependencies new file mode 100755 index 00000000000..3ee0bba4a89 --- /dev/null +++ b/mk/pkgformat/pkg/resolve-dependencies @@ -0,0 +1,49 @@ +#!/bin/sh +# +###################################################################### +# +# NAME +# resolve-dependencies -- resolve package dependencies +# +# SYNOPSIS +# resolve-dependencies +# +# DESCRIPTION +# resolve-dependencies checks all entries in ${DEPENDS_FILE} +# for existance. The best matching pattern is printed similiar +# to list-dependencies +# +###################################################################### + +: ${CAT:=cat} +: ${ECHO:=echo} +: ${TEST:=test} +: ${TRUE:=true} + +set -e + +DEPENDS_FILE=${_DEPENDS_FILE} +unset _DEPENDS_FILE + +error_msg() { + ${ECHO} "ERROR:" "$*" 1>&2 +} + +find_best() { + ${PKG_INFO} -E "$1" || ${TRUE} +} + +${CAT} ${DEPENDS_FILE} | while read type pattern dir; do + pkg=`find_best "$pattern"` + case "$pkg" in + "") + error_msg "[resolve-dependencies] A package matching \`\`$pattern'' should" + error_msg " be installed, but one cannot be found. Perhaps there is a" + error_msg " stale work directory for $dir?" + exit 1 + ;; + *) + ${ECHO} "$type $pattern $pkg" + ;; + esac +done diff --git a/mk/pkgformat/pkg/utility.mk b/mk/pkgformat/pkg/utility.mk new file mode 100644 index 00000000000..31ef3923186 --- /dev/null +++ b/mk/pkgformat/pkg/utility.mk @@ -0,0 +1,99 @@ +# $NetBSD: utility.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ + +# The 'info' target can be used to display information about a package. +.PHONY: info +info: + ${RUN}${PKG_INFO} "${PKGWILDCARD}" + +# The 'check' target can be used to check an installed package. +.PHONY: check +check: + ${RUN}${PKG_ADMIN} check "${PKGWILDCARD}" + +# The 'list' target can be used to list the files installed by a package. +.PHONY: list +list: + ${RUN}${PKG_INFO} -L "${PKGWILDCARD}" + +###################################################################### +### +### The targets below should probably be removed from pkgsrc. +### +###################################################################### + +# show-downlevel: +# Lists the packages whose installed version does not match the +# current version in pkgsrc. +# +show-downlevel: .PHONY +.if defined(PKG_FAIL_REASON) + ${RUN}${DO_NADA} +.else + ${RUN} \ + found="`${_PKG_BEST_EXISTS} \"${PKGWILDCARD}\" || ${TRUE}`"; \ + if [ "X$$found" != "X" -a "X$$found" != "X${PKGNAME}" ]; then \ + ${ECHO} "${PKGBASE} package: $$found installed, pkgsrc version ${PKGNAME}"; \ + if [ "X$$STOP_DOWNLEVEL_AFTER_FIRST" != "X" ]; then \ + ${ECHO} "stopping after first downlevel pkg found"; \ + exit 1; \ + fi; \ + fi +.endif + +.PHONY: show-installed-depends +show-installed-depends: # will not be removed +.if !empty(DEPENDS) + ${RUN} \ + for i in ${DEPENDS:C/:.*$//:Q:S/\ / /g} ; do \ + echo "$$i =>" `${_PKG_BEST_EXISTS} "$$i"`; \ + done +.endif + +.PHONY: show-needs-update +show-needs-update: _about-to-be-removed +.if !empty(DEPENDS) + ${RUN} \ + ${_DEPENDS_WALK_CMD} -r ${PKGPATH} | \ + while read i; do \ + cd ${PKGSRCDIR}/$$i; \ + eval `${RECURSIVE_MAKE} ${MAKEFLAGS} show-vars-eval VARS='PKGNAME:want PKGWILDCARD:wild'`; \ + have=`${_PKG_BEST_EXISTS} "$$wild" || ${TRUE}`; \ + if [ -z "$$have" ]; then \ + ${ECHO} "$$i => (none) => needs install of $$want"; \ + elif [ "$$have" != "$$want" ]; then \ + ${ECHO} "$$i => $$have => needs update to $$want"; \ + fi; \ + done +.endif + +.PHONY: show-pkgsrc-dir +show-pkgsrc-dir: _about-to-be-removed +.if defined(PKG_FAIL_REASON) + ${RUN}${DO_NADA} +.else + ${RUN} \ + found="`${_PKG_BEST_EXISTS} \"${PKGWILDCARD}\" || ${TRUE}`"; \ + if [ "X$$found" != "X" ]; then \ + ${ECHO} ${PKGPATH}; \ + fi +.endif + +.PHONY: show-depends-options +show-depends-options: + ${RUN} \ + ${_DEPENDS_WALK_CMD} ${PKGPATH} | \ + while read dir; do \ + ${ECHO} "===> Options for $${dir}" && \ + cd ${.CURDIR}/../../$$dir && \ + ${RECURSIVE_MAKE} ${MAKEFLAGS} show-options; \ + done + +# Short aliases +.PHONY: sid +sid: show-installed-depends + +_about-to-be-removed: .USE + @${WARNING_MSG} "This make target (${.TARGET}) is about to be removed. Since you used" + @${WARNING_MSG} "it, it may not be completele useless. Please tell us on the" + @${WARNING_MSG} "tech-pkg""@""NetBSD.org mailing list why you think this target should" + @${WARNING_MSG} "not be removed." diff --git a/mk/pkgformat/pkg/views.mk b/mk/pkgformat/pkg/views.mk new file mode 100644 index 00000000000..db1929f8517 --- /dev/null +++ b/mk/pkgformat/pkg/views.mk @@ -0,0 +1,90 @@ +# $NetBSD: views.mk,v 1.1 2011/10/15 00:23:09 reed Exp $ + +# By default, all packages attempt to link into the views. +.if ${PKG_INSTALLATION_TYPE} == "pkgviews" +BUILD_VIEWS?= yes +.endif + +# DEFAULT_VIEW.${PKGBASE} default view for ${PKGBASE} +# VIEWBASE base location of files at run-time +# +DEFAULT_VIEW.${PKGBASE}?= ${DEFAULT_VIEW} +.if ${PKG_INSTALLATION_TYPE} == "pkgviews" +. if empty(DEFAULT_VIEW.${PKGBASE}:M"") +VIEWBASE= ${LOCALBASE}/${DEFAULT_VIEW.${PKGBASE}} +. else +VIEWBASE= ${LOCALBASE} +. endif +.elif ${PKG_INSTALLATION_TYPE} == "overwrite" +VIEWBASE= ${PREFIX} +.endif +MAKE_ENV+= VIEWBASE=${VIEWBASE} + +PKGVIEWS+= ${DEFAULT_VIEW.${PKGBASE}} + +.if ${PKG_INSTALLATION_TYPE} == "pkgviews" +privileged-install-hook: build-views +.endif + +###################################################################### +### build-views, su-build-views (PRIVATE) +###################################################################### +### build-views adds the package to each view in PKGVIEWS. +### +.PHONY: build-views su-build-views +build-views: su-target + @${STEP_MSG} "Building views for ${PKGNAME}" + +su-build-views: + ${RUN} \ + ${MKDIR} ${LOCALBASE}; \ + for v in ${PKGVIEWS}; do \ + case "$$v" in \ + "") dbdir=${PKG_DBDIR}; viewname=standard ;; \ + *) dbdir=${LOCALBASE}/$$v/.dbdir; viewname=$$v ;; \ + esac; \ + ${STEP_MSG} "Performing package view clash check for ${PKGNAME} in $$viewname view"; \ + pkg=`${PKG_INFO_CMD} -K $$dbdir -e ${PKGBASE} || ${TRUE}`; \ + case "$$pkg" in \ + "") ;; \ + *) ${WARNING_MSG} "${PKGBASE} exists in $$viewname view - package $$pkg ***"; \ + ${WARNING_MSG} "Not hoisting ${PKGNAME} into $$viewname view"; \ + continue; \ + ;; \ + esac; \ + ${STEP_MSG} "Performing package view overwrite check for ${PKGNAME} in $$viewname view"; \ + dups=`${PKGSRC_SETENV} PLIST_IGNORE_FILES=${_PLIST_IGNORE_FILES:Q} ${PKG_VIEW} --view=$$v check ${PKGNAME} || ${TRUE}`; \ + case "$$dups" in \ + "") ;; \ + *) ${WARNING_MSG} "***********************************************************"; \ + ${WARNING_MSG} "**** The following symbolic links will be overwritten *****"; \ + for f in $$dups; do \ + ${LS} -l ${LOCALBASE}/$$v/$$f | ${WARNING_CAT}; \ + done; \ + ${WARNING_MSG} "***********************************************************"; \ + ;; \ + esac; \ + ${STEP_MSG} "Linking package into $$viewname view"; \ + ${PKGSRC_SETENV} PLIST_IGNORE_FILES=${_PLIST_IGNORE_FILES:Q} ${PKG_VIEW} --view=$$v add ${PKGNAME}; \ + done + +###################################################################### +### remove-views, su-remove-views (PRIVATE) +###################################################################### +### remove-views removes the package from each view in PKGVIEWS. +### +.PHONY: remove-views su-remove-views +remove-views: su-target + @${STEP_MSG} "Removing ${PKGNAME} from views" + +su-remove-views: + ${RUN} \ + for v in "" ${PKGVIEWS}; do \ + ${TEST} -n "$$v" || continue; \ + case "$$v" in \ + "") dbdir=${PKG_DBDIR}; viewname=standard ;; \ + *) dbdir=${LOCALBASE}/$$v/.dbdir; viewname=$$v ;; \ + esac; \ + ${STEP_MSG} "Removing package from $$viewname view"; \ + ${PKGSRC_SETENV} PLIST_IGNORE_FILES=${_PLIST_IGNORE_FILES:Q} ${PKG_VIEW} --view=$$v delete ${PKGNAME}; \ + done |