summaryrefslogtreecommitdiff
path: root/mk/pkgformat
diff options
context:
space:
mode:
Diffstat (limited to 'mk/pkgformat')
-rw-r--r--mk/pkgformat/README69
-rw-r--r--mk/pkgformat/bsd.pkgformat-vars.mk11
-rw-r--r--mk/pkgformat/bsd.pkgformat.mk7
-rw-r--r--mk/pkgformat/pkg/check.mk25
-rw-r--r--mk/pkgformat/pkg/deinstall.mk57
-rw-r--r--mk/pkgformat/pkg/depends.mk181
-rw-r--r--mk/pkgformat/pkg/install.mk75
-rwxr-xr-xmk/pkgformat/pkg/list-dependencies67
-rw-r--r--mk/pkgformat/pkg/metadata.mk415
-rw-r--r--mk/pkgformat/pkg/package.mk159
-rw-r--r--mk/pkgformat/pkg/pkgformat-vars.mk92
-rw-r--r--mk/pkgformat/pkg/pkgformat.mk27
-rwxr-xr-xmk/pkgformat/pkg/reduce-depends.awk158
-rwxr-xr-xmk/pkgformat/pkg/register-dependencies51
-rw-r--r--mk/pkgformat/pkg/replace.mk227
-rwxr-xr-xmk/pkgformat/pkg/resolve-dependencies49
-rw-r--r--mk/pkgformat/pkg/utility.mk99
-rw-r--r--mk/pkgformat/pkg/views.mk90
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