From 6bdad51ddfdcf5739a8508eab4bf688f71008207 Mon Sep 17 00:00:00 2001 From: reed Date: Sat, 15 Oct 2011 00:23:07 +0000 Subject: Rename "flavor" to "pkgformat". This is from Anton Panev's GSoC 2011 project to add RPM and DPKG support to pkgsrc. (I am not adding that further support in this commit.) This is just a rename of the existing functionality. Now it will be easy to test the GSoC work by simply putting in a single directory (such as "rpm" or "deb"). See http://addpackageforma.sourceforge.net/ for some details. This is from Anton's CVS, but I made some minor changes: - changed plural pkgformats to singular pkgformat (to be consistent) - fixed a few places (in comments) that were missed - catch up on some additions to flavor not in the pkgforma cvs: PKGSRC_SETENV and _flavor-destdir-undo-replace and undo-destdir-replace-install. --- mk/pkgformat/README | 69 ++++++ mk/pkgformat/bsd.pkgformat-vars.mk | 11 + mk/pkgformat/bsd.pkgformat.mk | 7 + mk/pkgformat/pkg/check.mk | 25 ++ mk/pkgformat/pkg/deinstall.mk | 57 +++++ mk/pkgformat/pkg/depends.mk | 181 ++++++++++++++ mk/pkgformat/pkg/install.mk | 75 ++++++ mk/pkgformat/pkg/list-dependencies | 67 ++++++ mk/pkgformat/pkg/metadata.mk | 415 +++++++++++++++++++++++++++++++++ mk/pkgformat/pkg/package.mk | 159 +++++++++++++ mk/pkgformat/pkg/pkgformat-vars.mk | 92 ++++++++ mk/pkgformat/pkg/pkgformat.mk | 27 +++ mk/pkgformat/pkg/reduce-depends.awk | 158 +++++++++++++ mk/pkgformat/pkg/register-dependencies | 51 ++++ mk/pkgformat/pkg/replace.mk | 227 ++++++++++++++++++ mk/pkgformat/pkg/resolve-dependencies | 49 ++++ mk/pkgformat/pkg/utility.mk | 99 ++++++++ mk/pkgformat/pkg/views.mk | 90 +++++++ 18 files changed, 1859 insertions(+) create mode 100644 mk/pkgformat/README create mode 100644 mk/pkgformat/bsd.pkgformat-vars.mk create mode 100644 mk/pkgformat/bsd.pkgformat.mk create mode 100644 mk/pkgformat/pkg/check.mk create mode 100644 mk/pkgformat/pkg/deinstall.mk create mode 100644 mk/pkgformat/pkg/depends.mk create mode 100644 mk/pkgformat/pkg/install.mk create mode 100755 mk/pkgformat/pkg/list-dependencies create mode 100644 mk/pkgformat/pkg/metadata.mk create mode 100644 mk/pkgformat/pkg/package.mk create mode 100644 mk/pkgformat/pkg/pkgformat-vars.mk create mode 100644 mk/pkgformat/pkg/pkgformat.mk create mode 100755 mk/pkgformat/pkg/reduce-depends.awk create mode 100755 mk/pkgformat/pkg/register-dependencies create mode 100644 mk/pkgformat/pkg/replace.mk create mode 100755 mk/pkgformat/pkg/resolve-dependencies create mode 100644 mk/pkgformat/pkg/utility.mk create mode 100644 mk/pkgformat/pkg/views.mk (limited to 'mk/pkgformat') 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: +# +# +# +# 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: +# +# +# +# "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: +# +# +# +# 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 -- cgit v1.2.3