aboutsummaryrefslogtreecommitdiffstats
path: root/Mk/bsd.port.mk
diff options
context:
space:
mode:
authorkris <kris@FreeBSD.org>2003-07-07 07:54:33 +0800
committerkris <kris@FreeBSD.org>2003-07-07 07:54:33 +0800
commitb8502bb8ebde7be9b077f7590397f933faa4abe9 (patch)
tree98258a554a4caab8fd362026256927bcc54a1687 /Mk/bsd.port.mk
parent314bd7e07f89c9c412bd70ab42533d9042cb19a6 (diff)
downloadfreebsd-ports-gnome-b8502bb8ebde7be9b077f7590397f933faa4abe9.tar.gz
freebsd-ports-gnome-b8502bb8ebde7be9b077f7590397f933faa4abe9.tar.zst
freebsd-ports-gnome-b8502bb8ebde7be9b077f7590397f933faa4abe9.zip
* Attempt to detect and disallow installation of a port with PREFIX
set to a different value to that with which it was configured and built. This is achieved by recording the PREFIX in the build-stage cookies [1] * Add scheme [2], tcl84 and tk84 [5] as virtual categories * Add the PERL_PORT variable and use it to register the dependency on the correct perl port when PERL_LEVEL is set [3] * Add support for USE_AUTOHEADER [4] * Fix 'make maintainer' when MAINTAINER is set to a bogus value (not in user@example.com format). [6] * Add a 'package-recursive' target to create packages for a port and all of its dependencies [7] * Fix command-line overflow errors in 'make readmes' on certain ports, with the bonus of providing a measurable speed-up to readme generation [8] * Fix inclusion of alternative makefiles such as Makefile.inc, Makefile.local, etc. (broken since 1.403) [9] * Reintroduce support for install/deinstall targets checking for older versions of the port, and re-add the deinstall-all target that removes all existing installations of a port (originally introduced in 1.446 and backed out in 1.450). This patch has been reworked to eliminate the corner cases in the previous code. Ports that dynamically generate their ${PLIST} at install-time must now do so before the do-install target is run, e.g. in pre-install. [10] * When installing ports as non-root, use su(1) to execute the targets that require root privilege. This is achieved by splitting up the _INSTALL_SEQ target list into _INSTALL_SUSEQ [11]. PR: 23581 [1], 47238 [2], 48465 [3], 50165 [4], 51985 [6], 52388 [7], 51609 [11] Submitted by: Matt Emmerton <matt@gsicomp.on.ca> [1], Sergey Matveychuk <sem@ciam.ru> [1] [7] [10] [11], Kimura Fuyuki <fuyuki@hadaly.org> [2], "Scot W. Hetzel" <hetzels@westbend.net> [3], Anton Berezin <tobez@FreeBSD.org> [3], nork [4], hsu [5], Mark Linimon <linimon@lonesome.com> [6], hoek [8], sobomax [9], marcus [10] [11], des [11]
Diffstat (limited to 'Mk/bsd.port.mk')
-rw-r--r--Mk/bsd.port.mk205
1 files changed, 159 insertions, 46 deletions
diff --git a/Mk/bsd.port.mk b/Mk/bsd.port.mk
index 1e8bf499f07a..c1fd582de3c1 100644
--- a/Mk/bsd.port.mk
+++ b/Mk/bsd.port.mk
@@ -217,6 +217,8 @@ FreeBSD_MAINTAINER= portmgr@FreeBSD.org
# USE_AUTOCONF (PORT MAY SET THIS VALUE)
# - Implies WANT_AUTOCONF_VER?=213.
# - Causes autoconf execution prior to configure step.
+# USE_AUTOHEADER (PORT MAY SET THIS VALUE)
+# - Implies USE_AUTOCONF.
# WANT_AUTOCONF_VER (PORT MAY SET THIS VALUE)
# - Implies GNU_CONFIGURE=yes.
# - Says that the port wants autoconf; legal values
@@ -229,6 +231,10 @@ FreeBSD_MAINTAINER= portmgr@FreeBSD.org
# - Pass these args to ${AUTOCONF} if ${USE_AUTOCONF_VER}
# is set. If an application sets this value, it should
# use the += form of assignment to append, not overwrite.
+# AUTOHEADER_ARGS (PORT MAY ALTER THIS VALUE)
+# - Pass these args to ${AUTOHEADER} if ${USE_AUTOHEADER}
+# is set. If an application sets this value, it should
+# use the += form of assignment to append, not overwrite.
##
# AUTOMAKE (READ-ONLY)
# - Set to path of GNU automake (default:
@@ -318,6 +324,8 @@ FreeBSD_MAINTAINER= portmgr@FreeBSD.org
# whether a particular dependency is needed, etc.
# PERL_ARCH - Directory name of architecture dependent libraries
# (value: ${ARCH}-freebsd).
+# PERL_PORT - Name of the perl port that is installed
+# (value: perl5)
# SITE_PERL - Directory name where site specific perl packages go.
# This value is added to PLIST_SUB.
##
@@ -541,6 +549,7 @@ FreeBSD_MAINTAINER= portmgr@FreeBSD.org
# reinstall - Install the results of a build, ignoring "already installed"
# flag.
# deinstall - Remove the installation.
+# deinstall-all - Remove all installations with the same PKGORIGIN.
# package - Create a package from an _installed_ port.
# describe - Try to generate a one-line description for each port for
# use in INDEX files and the like.
@@ -691,9 +700,9 @@ FreeBSD_MAINTAINER= portmgr@FreeBSD.org
# by "%%") as defined in PLIST_SUB to generate ${TMPPLIST}. For
# instance, "OSREL=${OSREL}" in PLIST_SUB causes all occurrences of
# "%%OSREL%%" in ${PLIST} to be substituted by the value of OSREL.
-# ${TMPPLIST} is generated between the do-install and post-install
-# stages. If you are generating the packing list on-the-fly, make
-# sure it's generated by the end of do-install!
+# ${TMPPLIST} is generated before the do-install stage. If you are
+# generating the packing list on-the-fly, make sure it's generated before
+# do-install is called!
#
# For package:
#
@@ -756,6 +765,7 @@ CAT?= /bin/cat
CHGRP?= /usr/bin/chgrp
CHMOD?= /bin/chmod
CHOWN?= /usr/sbin/chown
+COMM?= /usr/bin/comm
CP?= /bin/cp
CUT?= /usr/bin/cut
DC?= /usr/bin/dc
@@ -841,22 +851,28 @@ MASTERDIR?= ${.CURDIR}
.if ${MASTERDIR} != ${.CURDIR} && exists(${.CURDIR}/../Makefile.inc)
.include "${.CURDIR}/../Makefile.inc"
+USE_SUBMAKE= yes
.endif
.if exists(${MASTERDIR}/../Makefile.inc)
.include "${MASTERDIR}/../Makefile.inc"
+USE_SUBMAKE= yes
.endif
.if exists(${MASTERDIR}/Makefile.${ARCH}-${OPSYS})
.include "${MASTERDIR}/Makefile.${ARCH}-${OPSYS}"
+USE_SUBMAKE= yes
.elif exists(${MASTERDIR}/Makefile.${OPSYS})
.include "${MASTERDIR}/Makefile.${OPSYS}"
+USE_SUBMAKE= yes
.elif exists(${MASTERDIR}/Makefile.${ARCH})
.include "${MASTERDIR}/Makefile.${ARCH}"
+USE_SUBMAKE= yes
.endif
.if exists(${MASTERDIR}/Makefile.local)
.include "${MASTERDIR}/Makefile.local"
+USE_SUBMAKE= yes
.endif
.if !defined(PORTNAME) || !defined(PORTVERSION) || defined(PKGNAME)
@@ -1174,6 +1190,9 @@ BROKEN="unknown AUTOMAKE version: ${USE_AUTOMAKE_VER}"
USE_AUTOCONF?= yes
WANT_AUTOCONF_VER?= ${USE_AUTOCONF_VER}
.endif # defined(USE_AUTOCONF_VER)
+.if defined(USE_AUTOHEADER)
+USE_AUTOCONF?= yes
+.endif # defined(USE_AUTOHEADER)
.if defined(USE_AUTOCONF)
WANT_AUTOCONF_VER?= ${old_acver}
.endif # defined(USE_AUTOCONF)
@@ -1206,6 +1225,7 @@ CONFIGURE_ENV+= PATH=${autotools_path}:${PATH}
SCRIPTS_ENV+= PATH=${autotools_path}:${PATH}
AUTOCONF_ENV+= PATH=${autotools_path}:${PATH}
AUTOMAKE_ENV+= PATH=${autotools_path}:${PATH}
+AUTOHEADER_ENV+= PATH=${autotools_path}:${PATH}
AUTOTOOLS_ENV+= PATH=${autotools_path}:${PATH}
.endif # defined(autotools_path)
@@ -1405,6 +1425,12 @@ PERL_ARCH?= ${ARCH}-freebsd
.endif
.endif
+.if ${PERL_LEVEL} >= 500800
+PERL_PORT?= perl5.8
+.else
+PERL_PORT?= perl5
+.endif
+
SITE_PERL?= ${LOCALBASE}/lib/perl5/site_perl/${PERL_VER}
PLIST_SUB+= PERL_VERSION=${PERL_VERSION} \
@@ -1430,10 +1456,10 @@ PERL= /usr/bin/perl
PERL5= ${LOCALBASE}/bin/perl${PERL_VERSION}
PERL= ${LOCALBASE}/bin/perl
.if defined(USE_PERL5) || defined(USE_PERL5_BUILD)
-BUILD_DEPENDS+= ${PERL5}:${PORTSDIR}/lang/perl5
+BUILD_DEPENDS+= ${PERL5}:${PORTSDIR}/lang/${PERL_PORT}
.endif
.if defined(USE_PERL5) || defined(USE_PERL5_RUN)
-RUN_DEPENDS+= ${PERL5}:${PORTSDIR}/lang/perl5
+RUN_DEPENDS+= ${PERL5}:${PORTSDIR}/lang/${PERL_PORT}
.endif
.endif
@@ -1461,6 +1487,7 @@ CONFIGURE_ARGS+=--x-libraries=${X11BASE}/lib --x-includes=${X11BASE}/include
.if exists(${PORTSDIR}/../Makefile.inc)
.include "${PORTSDIR}/../Makefile.inc"
+USE_SUBMAKE= yes
.endif
# Special macro for doing in-place file editing using regexps
@@ -1475,12 +1502,12 @@ REINPLACE_CMD?= ${SED} ${REINPLACE_ARGS}
.endif
# Names of cookies used to skip already completed stages
-EXTRACT_COOKIE?= ${WRKDIR}/.extract_done.${PKGNAME}
-CONFIGURE_COOKIE?= ${WRKDIR}/.configure_done.${PKGNAME}
-INSTALL_COOKIE?= ${WRKDIR}/.install_done.${PKGNAME}
-BUILD_COOKIE?= ${WRKDIR}/.build_done.${PKGNAME}
-PATCH_COOKIE?= ${WRKDIR}/.patch_done.${PKGNAME}
-PACKAGE_COOKIE?= ${WRKDIR}/.package_done.${PKGNAME}
+EXTRACT_COOKIE?= ${WRKDIR}/.extract_done.${PKGNAME}.${PREFIX:S/\//_/g}
+CONFIGURE_COOKIE?= ${WRKDIR}/.configure_done.${PKGNAME}.${PREFIX:S/\//_/g}
+INSTALL_COOKIE?= ${WRKDIR}/.install_done.${PKGNAME}.${PREFIX:S/\//_/g}
+BUILD_COOKIE?= ${WRKDIR}/.build_done.${PKGNAME}.${PREFIX:S/\//_/g}
+PATCH_COOKIE?= ${WRKDIR}/.patch_done.${PKGNAME}.${PREFIX:S/\//_/g}
+PACKAGE_COOKIE?= ${WRKDIR}/.package_done.${PKGNAME}.${PREFIX:S/\//_/g}
# How to do nothing. Override if you, for some strange reason, would rather
# do something.
@@ -2124,7 +2151,7 @@ MAINTAINER?= ports@FreeBSD.org
.if !target(maintainer)
maintainer:
- @${ECHO_CMD} ${MAINTAINER}
+ @${ECHO_CMD} "${MAINTAINER}"
.endif
.if !defined(CATEGORIES)
@@ -2141,9 +2168,9 @@ VALID_CATEGORIES+= accessibility afterstep archivers astro audio \
mail math mbone misc multimedia net news \
offix palm parallel perl5 picobsd plan9 portuguese print python \
ruby russian \
- science security shells sysutils \
- tcl76 tcl80 tcl81 tcl82 tcl83 textproc \
- tk42 tk80 tk82 tk83 tkstep80 \
+ scheme science security shells sysutils \
+ tcl76 tcl80 tcl81 tcl82 tcl83 tcl84 textproc \
+ tk42 tk80 tk82 tk83 tk84 tkstep80 \
ukrainian vietnamese windowmaker www \
x11 x11-clocks x11-fm x11-fonts x11-servers x11-toolkits x11-wm zope
@@ -2790,6 +2817,10 @@ do-configure:
@(cd ${CONFIGURE_WRKSRC} && ${SETENV} ${AUTOCONF_ENV} ${AUTOCONF} \
${AUTOCONF_ARGS})
.endif
+.if defined(USE_AUTOHEADER)
+ @(cd ${CONFIGURE_WRKSRC} && ${SETENV} ${AUTOHEADER_ENV} ${AUTOHEADER} \
+ ${AUTOHEADER_ARGS})
+.endif
@if [ -f ${SCRIPTDIR}/configure ]; then \
cd ${.CURDIR} && ${SETENV} ${SCRIPTS_ENV} ${SH} \
${SCRIPTDIR}/configure; \
@@ -2967,15 +2998,33 @@ delete-package-list: delete-package-links-list
.if !target(check-already-installed)
check-already-installed:
.if !defined(NO_PKG_REGISTER) && !defined(FORCE_PKG_REGISTER)
- @if [ -d ${PKG_DBDIR}/${PKGNAME} ]; then \
- ${ECHO_CMD} "===> ${PKGNAME} is already installed - perhaps an older version?"; \
- ${ECHO_CMD} " If so, you may wish to \`\`make deinstall'' and install"; \
- ${ECHO_CMD} " this port again by \`\`make reinstall'' to upgrade it properly."; \
- ${ECHO_CMD} " If you really wish to overwrite the old port of ${PKGNAME}"; \
- ${ECHO_CMD} " without deleting it first, set the variable \"FORCE_PKG_REGISTER\""; \
- ${ECHO_CMD} " in your environment or the \"make install\" command line."; \
- exit 1; \
- fi
+ @${ECHO_MSG} "===> Checking if ${PKGORIGIN} already installed"
+ @already_installed=`${PKG_INFO} -q -O ${PKGORIGIN} 2> /dev/null`; \
+ if [ -n "$${already_installed}" ]; then \
+ for p in $${already_installed}; do \
+ prfx=`${PKG_INFO} -q -p $${p} 2> /dev/null | ${SED} -e 's|^@cwd ||'`; \
+ if [ "x${PREFIX}" = "x$${prfx}" ]; then \
+ df=`${PKG_INFO} -q -f $${p} 2> /dev/null | ${GREP} -v "^@" | ${COMM} -12 - ${TMPPLIST}`; \
+ if [ -n "$${df}" ]; then \
+ found_package=$${p}; \
+ break; \
+ fi; \
+ fi; \
+ done; \
+ fi; \
+ if [ -d ${PKG_DBDIR}/${PKGNAME} -o -n "$${found_package}" ]; then \
+ if [ -d ${PKG_DBDIR}/${PKGNAME} ]; then \
+ ${ECHO_CMD} "===> ${PKGNAME} is already installed"; \
+ else \
+ ${ECHO_CMD} "===> An older version of ${PKGORIGIN} is already installed ($${found_package})"; \
+ fi; \
+ ${ECHO_CMD} " You may wish to \`\`make deinstall'' and install this port again"; \
+ ${ECHO_CMD} " by \`\`make reinstall'' to upgrade it properly."; \
+ ${ECHO_CMD} " If you really wish to overwrite the old port of ${PKGORIGIN}"; \
+ ${ECHO_CMD} " without deleting it first, set the variable \"FORCE_PKG_REGISTER\""; \
+ ${ECHO_CMD} " in your environment or the \"make install\" command line."; \
+ exit 1; \
+ fi
.else
@${DO_NADA}
.endif
@@ -3149,11 +3198,13 @@ _BUILD_DEP= configure
_BUILD_SEQ= build-message pre-build pre-build-script do-build \
post-build post-build-script
_INSTALL_DEP= build
-_INSTALL_SEQ= install-message check-categories check-already-installed \
- check-conflicts check-umask run-depends lib-depends \
- install-mtree pre-install pre-install-script do-install \
- generate-plist post-install post-install-script compress-man \
- run-ldconfig fake-pkg security-check
+_INSTALL_SEQ= install-message check-categories check-conflicts \
+ run-depends lib-depends pre-install pre-install-script \
+ generate-plist check-already-installed
+_INSTALL_SUSEQ= check-umask install-mtree pre-su-install \
+ pre-su-install-script do-install post-install \
+ post-install-script compress-man run-ldconfig fake-pkg \
+ security-check
_PACKAGE_DEP= install
_PACKAGE_SEQ= package-message pre-package pre-package-script \
do-package post-package-script
@@ -3162,7 +3213,7 @@ _PACKAGE_SEQ= package-message pre-package pre-package-script \
fetch: ${_FETCH_SEQ}
.endif
-# Main logick. The loop generates 6 main targets and using cookies
+# Main logic. The loop generates 6 main targets and using cookies
# ensures that those already completed are skipped.
.for target in extract patch configure build install package
@@ -3173,12 +3224,25 @@ ${target}: ${${target:U}_COOKIE}
.if !exists(${${target:U}_COOKIE})
-.if !defined(USE_SUBMAKE)
+.if ${UID} != 0 && defined(_${target:U}_SUSEQ)
+.if defined(USE_SUBMAKE)
+${${target:U}_COOKIE}: ${_${target:U}_DEP}
+ @cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} ${_${target:U}_SEQ}
+.else
${${target:U}_COOKIE}: ${_${target:U}_DEP} ${_${target:U}_SEQ}
+.endif
+ @echo "===> Switching to root credentials for '${target}' target"
+ @cd ${.CURDIR} && \
+ ${SU} root -c "${MAKE} ${__softMAKEFLAGS} ${_${target:U}_SUSEQ}"
+ @echo "===> Returning to user credentials"
@${TOUCH} ${TOUCH_FLAGS} ${.TARGET}
-.else
+.elif defined(USE_SUBMAKE)
${${target:U}_COOKIE}: ${_${target:U}_DEP}
- @cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} ${_${target:U}_SEQ}
+ @cd ${.CURDIR} && \
+ ${MAKE} ${__softMAKEFLAGS} ${_${target:U}_SEQ} ${_${target:U}_SUSEQ}
+ @${TOUCH} ${TOUCH_FLAGS} ${.TARGET}
+.else
+${${target:U}_COOKIE}: ${_${target:U}_DEP} ${_${target:U}_SEQ} ${_${target:U}_SUSEQ}
@${TOUCH} ${TOUCH_FLAGS} ${.TARGET}
.endif
@@ -3237,6 +3301,17 @@ ${stage}-${name}-script:
.endfor
.endfor
+# Special cases for su
+.if !target(pre-su-install)
+pre-su-install:
+ @${DO_NADA}
+.endif
+
+.if !target(pre-su-install-script)
+pre-su-install-script:
+ @${DO_NADA}
+.endif
+
# Patch-libtool
#
# Special target to automatically make libtool using ports use the
@@ -3313,12 +3388,42 @@ reinstall:
.if !target(deinstall)
deinstall:
- @${ECHO_MSG} "===> Deinstalling for ${PKGNAME}"
- @if ${PKG_INFO} -e ${PKGNAME}; then \
- ${PKG_DELETE} -f ${PKGNAME}; \
- else \
- ${ECHO_MSG} "===> ${PKGNAME} not installed, skipping"; \
- fi
+ @${ECHO_MSG} "===> Deinstalling for ${PKGORIGIN}"
+ @found_names=`${PKG_INFO} -q -O ${PKGORIGIN} 2> /dev/null`; \
+ for p in $${found_names}; do \
+ check_name=`${ECHO} $${p} | ${SED} -e 's/-[^-]*$$//'`; \
+ if [ "$${check_name}" = "${PKGBASE}" ]; then \
+ prfx=`${PKG_INFO} -q -p $${p} 2> /dev/null | ${SED} -e 's|^@cwd ||'`; \
+ if [ "x${PREFIX}" = "x$${prfx}" ]; then \
+ ${ECHO_MSG} "===> Deinstalling $${p}"; \
+ ${PKG_DELETE} -f $${p}; \
+ else \
+ ${ECHO_MSG} "===> $${p} has a different PREFIX: $${prfx}, skipping"; \
+ fi; \
+ fi; \
+ done; \
+ if [ -z "$${found_names}" ]; then \
+ ${ECHO_MSG} "===> ${PKGBASE} not installed, skipping"; \
+ fi
+ @${RM} -f ${INSTALL_COOKIE} ${PACKAGE_COOKIE}
+.endif
+
+# Deinstall-all
+#
+# Special target to remove installation of all ports of the same origin
+
+.if !target(deinstall-all)
+deinstall-all:
+ @${ECHO_MSG} "===> Deinstalling for ${PKGORIGIN}"
+ @deinstall_names=`${PKG_INFO} -q -O ${PKGORIGIN} 2> /dev/null`; \
+ if [ -n "$${deinstall_names}" ]; then \
+ for d in $${deinstall_names}; do \
+ ${ECHO_MSG} "===> Deinstalling $${d}"; \
+ ${PKG_DELETE} -f $${d}; \
+ done; \
+ else \
+ ${ECHO_MSG} "===> ${PKGORIGIN} not installed, skipping"; \
+ fi
@${RM} -f ${INSTALL_COOKIE} ${PACKAGE_COOKIE}
.endif
@@ -3940,6 +4045,13 @@ package-depends:
@${PACKAGE-DEPENDS-LIST} | ${AWK} '{print $$1}'
.endif
+# Build packages for port and dependencies
+
+package-recursive: package
+ @for dir in $$(${ALL-DEPENDS-LIST}); do \
+ (cd $$dir; ${MAKE} package-noinstall); \
+ done
+
################################################################
# Everything after here are internal targets and really
# shouldn't be touched by anybody but the release engineers.
@@ -4022,7 +4134,8 @@ readme:
${.CURDIR}/README.html:
@${ECHO_MSG} "===> Creating README.html for ${PKGNAME}"
- @${SED} -e 's|%%PORT%%|'$$(${ECHO_CMD} ${.CURDIR} | \
+ @__softMAKEFLAGS='${__softMAKEFLAGS:S/'/'\''/g}'; \
+ ${SED} -e 's|%%PORT%%|'$$(${ECHO_CMD} ${.CURDIR} | \
${SED} -e 's|.*/\([^/]*/[^/]*\)$$|\1|')'|g' \
-e 's|%%PKG%%|${PKGNAME}|g' \
-e 's|%%COMMENT%%|'"$$(${ECHO_CMD} ${COMMENT:Q})"'|' \
@@ -4032,12 +4145,12 @@ ${.CURDIR}/README.html:
-e 's|%%EMAIL%%|'"$$(${ECHO_CMD} "${MAINTAINER}" | \
${SED} -e 's/([^)]*)//;s/.*<//;s/>.*//')"'|g' \
-e 's|%%MAINTAINER%%|${MAINTAINER}|g' \
- -e 's|%%WEBSITE%%|'"$$(cd ${.CURDIR} && ${MAKE} \
- ${__softMAKEFLAGS} pretty-print-www-site)"'|' \
- -e 's|%%BUILD_DEPENDS%%|'"$$(cd ${.CURDIR} && ${MAKE} \
- ${__softMAKEFLAGS} pretty-print-build-depends-list)"'|' \
- -e 's|%%RUN_DEPENDS%%|'"$$(cd ${.CURDIR} && ${MAKE} \
- ${__softMAKEFLAGS} pretty-print-run-depends-list)"'|' \
+ -e 's|%%WEBSITE%%|'"$$(cd ${.CURDIR} && eval ${MAKE} \
+ $${__softMAKEFLAGS} pretty-print-www-site)"'|' \
+ -e 's|%%BUILD_DEPENDS%%|'"$$(cd ${.CURDIR} && eval ${MAKE} \
+ $${__softMAKEFLAGS} pretty-print-build-depends-list)"'|' \
+ -e 's|%%RUN_DEPENDS%%|'"$$(cd ${.CURDIR} && eval ${MAKE} \
+ $${__softMAKEFLAGS} pretty-print-run-depends-list)"'|' \
-e 's|%%TOP%%|'"$$(${ECHO_CMD} ${CATEGORIES} | \
${SED} -e 's| .*||' -e 's|[^/]*|..|g')"'/..|' \
${TEMPLATES}/README.port >> $@