DESTDIR should not interfere with PREFIX. PREFIX is really the run-time location of the port. DESTDIR is where it gets installed. These may not be the same thing. Unfortunately, bsd.port.mk simply prefixes LOCALBASE, X11BASE & LINUXBASE with DESTDIR. If PREFIX is not specified to override these values, PREFIX will contain DESTDIR. Not only bsd.port.mk, but many port Makefiles are broken in this regard. For example, many post-install targets specify something like: ${INSTALL_PROGRAM} ${WRKSRC}/foo ${PREFIX}/bin They should probably read: ${INSTALL_PROGRAM} ${WRKSRC}/foo ${DESTDIR}/${PREFIX}/bin But, before we fix the ports, we have to fix bsd.port.mk The included patch does that. If anyone seriously tries to use DESTDIR for its intended use, many ports won't work anyway. Please commit the patch to bsd.port.mk Feel free to try it out first. Send me feedback. Ask for its commit in freebsd-ports. Pester portmgr@FreeBSD.org It's a large step in fixing the problem with the ports system's inability to install in non-standard paths. It's time we fixed this. Fix: First, give a heads up that the following patch will be applied in, say, a week or two. Notify maintainers about it and have them fix their ports to handle DESTDIR & PREFIX correctly in preparation for this commit. Then apply the following patch to bsd.port.mk and commit. Then tell maintainers to commit their fixed ports. $ cvs diff -u bsd.port.mk How-To-Repeat: Let's suppose you want to install a port for system B on a removable drive bay on system A... sudo mount /dev/da1s1g /mnt_B/usr sudo mount /dev/da1s1a /mnt_B/root Now I want to install, say, the glib port to /mnt_B/usr/local. cd /usr/ports/devel/glib12 sudo make DESTDIR=/mnt_B PKG_DBDIR=/mnt_B/root/var/db/pkg install umount /mnt_B/root umount /mnt_B/usr Now, move the disk to system B and boot it. Now, run /usr/local/bin/glib-config --cflags and get: -I/mnt_B/usr/local/include/glib12 That is wrong. It should read -I/usr/local/include/glib12
Responsible Changed From-To: freebsd-ports->portmgr Over to portmgr for a look see.
The first patch had one small bit missing. It failed to put DESTDIR in the mtree command. The revised patch below fixes this (in the last hunk, #7). note: These DESTDIR fixes don't work when PREFIX is relative and DESTDIR is empty. The dest/prefix combos should probably be written: ${DESTDIR}${PREFIX} without the intervening /, and leave it up to users to append a trailing / to DESTDIR if needed. Or we could do something that will add a trailing / to DESTDIR if it is non-empty, but I haven't figured out a good way to do this in a Makefile yet. $ cvs diff -u bsd.port.mk Index: bsd.port.mk =================================================================== RCS file: /base/FreeBSD-CVS/ports/Mk/bsd.port.mk,v retrieving revision 1.367 diff -u -r1.367 bsd.port.mk --- bsd.port.mk 2001/05/23 02:46:52 1.367 +++ bsd.port.mk 2001/06/20 14:37:54 @@ -600,9 +600,22 @@ .else PORTSDIR?= /usr/ports .endif -LOCALBASE?= ${DESTDIR}/usr/local -X11BASE?= ${DESTDIR}/usr/X11R6 -LINUXBASE?= ${DESTDIR}/compat/linux +LOCALBASE?= /usr/local +X11BASE?= /usr/X11R6 +LINUXBASE?= /compat/linux +.if defined(DESTDIR) +.if defined(USE_GMAKE) +# Tell gmake makefiles to override any local definition of DESTDIR with +# our definition. +MAKE_ARGS+= DESTDIR=${DESTDIR} +.else +# FreeBSD's make is not the same as gmake in being able to override VAR=FOO +# style definitions in the makefile with VAR=SOMETHING_ELSE passed on the +# command line to make, but we can use -E to get similar behavior. +MAKE_ARGS+= -E DESTDIR +MAKE_ENV+= DESTDIR=${DESTDIR} +.endif +.endif DISTDIR?= ${PORTSDIR}/distfiles _DISTDIR?= ${DISTDIR}/${DIST_SUBDIR} .if defined(USE_BZIP2) @@ -1064,7 +1077,7 @@ PKG_DELETE?= /usr/sbin/pkg_delete PKG_INFO?= /usr/sbin/pkg_info .if !defined(PKG_ARGS) -PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} +PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -s ${DESTDIR}/${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} .if exists(${PKGINSTALL}) PKG_ARGS+= -i ${PKGINSTALL} .endif @@ -1271,7 +1284,8 @@ WRKDIR=${WRKDIR} WRKSRC=${WRKSRC} PATCHDIR=${PATCHDIR} \ SCRIPTDIR=${SCRIPTDIR} FILESDIR=${FILESDIR} \ PORTSDIR=${PORTSDIR} DEPENDS="${DEPENDS}" \ - PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} + PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} \ + DESTDIR=${DESTDIR} .if defined(BATCH) SCRIPTS_ENV+= BATCH=yes @@ -1302,7 +1316,7 @@ else \ { print "broken"; exit; } \ } \ - }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) $${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' + }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) ${DESTDIR}/$${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' .if ${__pmlinks:Mbroken} == "broken" .BEGIN: @${ECHO} "${PKGNAME}: Unable to parse MLINKS." @@ -1322,30 +1336,31 @@ .for sect in 1 2 3 4 5 6 7 8 9 .if defined(MAN${sect}) -_MANPAGES+= ${MAN${sect}:S%^%${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} +JUNK=1 +_MANPAGES+= ${MAN${sect}:S%^%${DESTDIR}/${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} .endif .endfor .if defined(MANL) -_MANPAGES+= ${MANL:S%^%${MANLPREFIX}/man/${lang}/manl/%} +_MANPAGES+= ${MANL:S%^%${DESTDIR}/${MANLPREFIX}/man/${lang}/manl/%} .endif .if defined(MANN) -_MANPAGES+= ${MANN:S%^%${MANNPREFIX}/man/${lang}/mann/%} +_MANPAGES+= ${MANN:S%^%${DESTDIR}/${MANNPREFIX}/man/${lang}/mann/%} .endif .endfor .if defined(_MLINKS) && make(generate-plist) -_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' +_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' | ${SED} 's,^${DESTDIR}/,,' .else _TMLINKS= .endif .if defined(_MANPAGES) && defined(NOMANCOMPRESS) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}/^^:S^${PREFIX}/^^:S/""//:S^//^/^g} .elif defined(_MANPAGES) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}/^^:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} .endif .if defined(_MANPAGES) && ${MANCOMPRESSED} == "yes" @@ -1962,10 +1977,10 @@ .if make(real-install) @${MKDIR} ${PREFIX} @if [ `id -u` != 0 ]; then \ - if [ -w ${PREFIX}/ ]; then \ + if [ -w ${DESTDIR}/${PREFIX}/ ]; then \ ${ECHO_MSG} "Warning: not superuser, you may get some errors during installation."; \ else \ - ${ECHO_MSG} "Error: ${PREFIX}/ not writable."; \ + ${ECHO_MSG} "Error: ${DESTDIR}/${PREFIX}/ not writable."; \ ${FALSE}; \ fi; \ fi @@ -1976,7 +1991,7 @@ ${ECHO} "Copy it from a suitable location (e.g., /usr/src/etc/mtree) and try again."; \ exit 1; \ else \ - ${MTREE_CMD} ${MTREE_ARGS} ${PREFIX}/ >/dev/null; \ + ${MTREE_CMD} ${MTREE_ARGS} ${DESTDIR}/${PREFIX}/ >/dev/null; \ fi; \ else \ ${ECHO_MSG} "Warning: not superuser, can't run mtree."; \
I've updated the patch to 1) match the latest bsd.port.mk in the repository 2) change occurrences of ${DESTDIR}/${PREFIX} to the more standard ${DESTDIR}${PREFIX} (see 'note:' in my last followup discussing this) For #2, I also added a check to make sure DESTDIR is an absolute path (otherwise, when make is invoked down in work/..., it points to the wrong place) and to make sure DESTDIR ends in a / if PREFIX doesn't start with a / so the paths don't run together. Set IGNORE_ABSPATH_CHECKS=yes to ignore these checks. Here is the revised patch: $ cvs diff -u bsd.port.mk Index: bsd.port.mk =================================================================== RCS file: /base/FreeBSD-CVS/ports/Mk/bsd.port.mk,v retrieving revision 1.372 diff -u -r1.372 bsd.port.mk --- bsd.port.mk 2001/07/10 07:50:17 1.372 +++ bsd.port.mk 2001/07/20 23:12:03 @@ -606,9 +606,41 @@ .else PORTSDIR?= /usr/ports .endif -LOCALBASE?= ${DESTDIR}/usr/local -X11BASE?= ${DESTDIR}/usr/X11R6 -LINUXBASE?= ${DESTDIR}/compat/linux +LOCALBASE?= /usr/local +X11BASE?= /usr/X11R6 +LINUXBASE?= /compat/linux + +IGNORE_ABSPATH_CHECKS?= no +.if (${IGNORE_ABSPATH_CHECKS:L} != yes) +.if defined(DESTDIR) +.if (${DESTDIR} != "") && (${DESTDIR:C,(^.).*,\1,} != "/") +.BEGIN: + @${ECHO} "DESTDIR must be defined as an absolute path so that when 'make'" + @${ECHO} "is invoked in the work area DESTDIR points to the right place." + @${FALSE} +.elif (${DESTDIR} != "") && (${DESTDIR:C,^.*(/)$$,\1,} != "/") \ + && (${PREFIX:C,(^.).*,\1,} != "/") +.BEGIN: + @${ECHO} "DESTDIR must be defined with a trailing slash if PREFIX is not\ + an absolute path." + @${FALSE} +.endif +.endif +.endif + +.if defined(DESTDIR) +.if defined(USE_GMAKE) +# Tell gmake makefiles to override any local definition of DESTDIR with +# our definition. +MAKE_ARGS+= DESTDIR=${DESTDIR} +.else +# FreeBSD's make is not the same as gmake in being able to override VAR=FOO +# style definitions in the makefile with VAR=SOMETHING_ELSE passed on the +# command line to make, but we can use -E to get similar behavior. +MAKE_ARGS+= -E DESTDIR +MAKE_ENV+= DESTDIR=${DESTDIR} +.endif +.endif DISTDIR?= ${PORTSDIR}/distfiles _DISTDIR?= ${DISTDIR}/${DIST_SUBDIR} .if defined(USE_BZIP2) @@ -1070,7 +1102,7 @@ PKG_DELETE?= /usr/sbin/pkg_delete PKG_INFO?= /usr/sbin/pkg_info .if !defined(PKG_ARGS) -PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} +PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -s ${DESTDIR}${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} .if exists(${PKGINSTALL}) PKG_ARGS+= -i ${PKGINSTALL} .endif @@ -1277,7 +1309,8 @@ WRKDIR=${WRKDIR} WRKSRC=${WRKSRC} PATCHDIR=${PATCHDIR} \ SCRIPTDIR=${SCRIPTDIR} FILESDIR=${FILESDIR} \ PORTSDIR=${PORTSDIR} DEPENDS="${DEPENDS}" \ - PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} + PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} \ + DESTDIR=${DESTDIR} .if defined(BATCH) SCRIPTS_ENV+= BATCH=yes @@ -1308,7 +1341,7 @@ else \ { print "broken"; exit; } \ } \ - }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) $${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' + }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) ${DESTDIR}$${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' .if ${__pmlinks:Mbroken} == "broken" .BEGIN: @${ECHO} "${PKGNAME}: Unable to parse MLINKS." @@ -1328,30 +1361,31 @@ .for sect in 1 2 3 4 5 6 7 8 9 .if defined(MAN${sect}) -_MANPAGES+= ${MAN${sect}:S%^%${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} +JUNK=1 +_MANPAGES+= ${MAN${sect}:S%^%${DESTDIR}${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} .endif .endfor .if defined(MANL) -_MANPAGES+= ${MANL:S%^%${MANLPREFIX}/man/${lang}/manl/%} +_MANPAGES+= ${MANL:S%^%${DESTDIR}${MANLPREFIX}/man/${lang}/manl/%} .endif .if defined(MANN) -_MANPAGES+= ${MANN:S%^%${MANNPREFIX}/man/${lang}/mann/%} +_MANPAGES+= ${MANN:S%^%${DESTDIR}${MANNPREFIX}/man/${lang}/mann/%} .endif .endfor .if defined(_MLINKS) && make(generate-plist) -_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' +_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' | ${SED} 's,^${DESTDIR},,' .else _TMLINKS= .endif .if defined(_MANPAGES) && defined(NOMANCOMPRESS) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}^^:S^${PREFIX}/^^:S/""//:S^//^/^g} .elif defined(_MANPAGES) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}^^:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} .endif .if defined(_MANPAGES) && ${MANCOMPRESSED} == "yes" @@ -1969,12 +2003,12 @@ @cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} run-depends lib-depends .endif .if make(real-install) - @${MKDIR} ${PREFIX} + @${MKDIR} ${DESTDIR}${PREFIX} @if [ `id -u` != 0 ]; then \ - if [ -w ${PREFIX}/ ]; then \ + if [ -w ${DESTDIR}${PREFIX}/ ]; then \ ${ECHO_MSG} "Warning: not superuser, you may get some errors during installation."; \ else \ - ${ECHO_MSG} "Error: ${PREFIX}/ not writable."; \ + ${ECHO_MSG} "Error: ${DESTDIR}${PREFIX}/ not writable."; \ ${FALSE}; \ fi; \ fi @@ -1985,7 +2019,7 @@ ${ECHO} "Copy it from a suitable location (e.g., /usr/src/etc/mtree) and try again."; \ exit 1; \ else \ - ${MTREE_CMD} ${MTREE_ARGS} ${PREFIX}/ >/dev/null; \ + ${MTREE_CMD} ${MTREE_ARGS} ${DESTDIR}${PREFIX}/ >/dev/null; \ fi; \ else \ ${ECHO_MSG} "Warning: not superuser, can't run mtree."; \
I've updated the patch to 1) match the latest bsd.port.mk in the repository (1.373) 2) check to make sure PREFIX is defined before referencing it with :C (:C doesn't like undefined variables) Here is the revised patch: $ cvs diff -u bsd.port.mk Index: bsd.port.mk =================================================================== RCS file: /base/FreeBSD-CVS/ports/Mk/bsd.port.mk,v retrieving revision 1.373 diff -u -r1.373 bsd.port.mk --- bsd.port.mk 2001/07/25 18:10:16 1.373 +++ bsd.port.mk 2001/07/27 16:42:59 @@ -606,9 +606,43 @@ .else PORTSDIR?= /usr/ports .endif -LOCALBASE?= ${DESTDIR}/usr/local -X11BASE?= ${DESTDIR}/usr/X11R6 -LINUXBASE?= ${DESTDIR}/compat/linux +LOCALBASE?= /usr/local +X11BASE?= /usr/X11R6 +LINUXBASE?= /compat/linux + +IGNORE_ABSPATH_CHECKS?= no +.if (${IGNORE_ABSPATH_CHECKS:L} != yes) +.if defined(DESTDIR) +.if (${DESTDIR} != "") && (${DESTDIR:C,(^.).*,\1,} != "/") +.BEGIN: + @${ECHO} "DESTDIR must be defined as an absolute path so that when 'make'" + @${ECHO} "is invoked in the work area DESTDIR points to the right place." + @${FALSE} +.elif defined(PREFIX) +.if (${DESTDIR} != "") && (${DESTDIR:C,^.*(/)$$,\1,} != "/") \ + && (${PREFIX:C,(^.).*,\1,} != "/") +.BEGIN: + @${ECHO} "DESTDIR must be defined with a trailing slash if PREFIX is not\ + an absolute path." + @${FALSE} +.endif +.endif +.endif +.endif + +.if defined(DESTDIR) +.if defined(USE_GMAKE) +# Tell gmake makefiles to override any local definition of DESTDIR with +# our definition. +MAKE_ARGS+= DESTDIR=${DESTDIR} +.else +# FreeBSD's make is not the same as gmake in being able to override VAR=FOO +# style definitions in the makefile with VAR=SOMETHING_ELSE passed on the +# command line to make, but we can use -E to get similar behavior. +MAKE_ARGS+= -E DESTDIR +MAKE_ENV+= DESTDIR=${DESTDIR} +.endif +.endif DISTDIR?= ${PORTSDIR}/distfiles _DISTDIR?= ${DISTDIR}/${DIST_SUBDIR} .if defined(USE_BZIP2) @@ -1073,7 +1107,7 @@ PKG_DELETE?= /usr/sbin/pkg_delete PKG_INFO?= /usr/sbin/pkg_info .if !defined(PKG_ARGS) -PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} +PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -s ${DESTDIR}${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} .if exists(${PKGINSTALL}) PKG_ARGS+= -i ${PKGINSTALL} .endif @@ -1280,7 +1314,8 @@ WRKDIR=${WRKDIR} WRKSRC=${WRKSRC} PATCHDIR=${PATCHDIR} \ SCRIPTDIR=${SCRIPTDIR} FILESDIR=${FILESDIR} \ PORTSDIR=${PORTSDIR} DEPENDS="${DEPENDS}" \ - PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} + PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} \ + DESTDIR=${DESTDIR} .if defined(BATCH) SCRIPTS_ENV+= BATCH=yes @@ -1311,7 +1346,7 @@ else \ { print "broken"; exit; } \ } \ - }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) $${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' + }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) ${DESTDIR}$${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' .if ${__pmlinks:Mbroken} == "broken" .BEGIN: @${ECHO} "${PKGNAME}: Unable to parse MLINKS." @@ -1331,30 +1366,31 @@ .for sect in 1 2 3 4 5 6 7 8 9 .if defined(MAN${sect}) -_MANPAGES+= ${MAN${sect}:S%^%${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} +JUNK=1 +_MANPAGES+= ${MAN${sect}:S%^%${DESTDIR}${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} .endif .endfor .if defined(MANL) -_MANPAGES+= ${MANL:S%^%${MANLPREFIX}/man/${lang}/manl/%} +_MANPAGES+= ${MANL:S%^%${DESTDIR}${MANLPREFIX}/man/${lang}/manl/%} .endif .if defined(MANN) -_MANPAGES+= ${MANN:S%^%${MANNPREFIX}/man/${lang}/mann/%} +_MANPAGES+= ${MANN:S%^%${DESTDIR}${MANNPREFIX}/man/${lang}/mann/%} .endif .endfor .if defined(_MLINKS) && make(generate-plist) -_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' +_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' | ${SED} 's,^${DESTDIR},,' .else _TMLINKS= .endif .if defined(_MANPAGES) && defined(NOMANCOMPRESS) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}^^:S^${PREFIX}/^^:S/""//:S^//^/^g} .elif defined(_MANPAGES) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}^^:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} .endif .if defined(_MANPAGES) && ${MANCOMPRESSED} == "yes" @@ -1972,12 +2008,12 @@ @cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} run-depends lib-depends .endif .if make(real-install) - @${MKDIR} ${PREFIX} + @${MKDIR} ${DESTDIR}${PREFIX} @if [ `id -u` != 0 ]; then \ - if [ -w ${PREFIX}/ ]; then \ + if [ -w ${DESTDIR}${PREFIX}/ ]; then \ ${ECHO_MSG} "Warning: not superuser, you may get some errors during installation."; \ else \ - ${ECHO_MSG} "Error: ${PREFIX}/ not writable."; \ + ${ECHO_MSG} "Error: ${DESTDIR}${PREFIX}/ not writable."; \ ${FALSE}; \ fi; \ fi @@ -1988,7 +2024,7 @@ ${ECHO} "Copy it from a suitable location (e.g., /usr/src/etc/mtree) and try again."; \ exit 1; \ else \ - ${MTREE_CMD} ${MTREE_ARGS} ${PREFIX}/ >/dev/null; \ + ${MTREE_CMD} ${MTREE_ARGS} ${DESTDIR}${PREFIX}/ >/dev/null; \ fi; \ else \ ${ECHO_MSG} "Warning: not superuser, can't run mtree."; \
I've updated the patch to 1) match the latest bsd.port.mk in the repository (1.381, 20010923) 2) move the DESTDIR fixes to the "post-makefile" section so we define the right MAKE_ARGS based on whether USE_GMAKE is set or not. In some ports (e.g., math/fftw), USE_GMAKE isn't set until after bsd.port.pre.mk is included. Here is the revised patch: $ cvs diff -u bsd.port.mk Index: bsd.port.mk =================================================================== RCS file: /base/FreeBSD-CVS/ports/Mk/bsd.port.mk,v retrieving revision 1.381 diff -u -r1.381 bsd.port.mk --- bsd.port.mk 2001/09/23 00:35:08 1.381 +++ bsd.port.mk 2001/09/25 23:23:19 @@ -608,9 +608,9 @@ .else PORTSDIR?= /usr/ports .endif -LOCALBASE?= ${DESTDIR}/usr/local -X11BASE?= ${DESTDIR}/usr/X11R6 -LINUXBASE?= ${DESTDIR}/compat/linux +LOCALBASE?= /usr/local +X11BASE?= /usr/X11R6 +LINUXBASE?= /compat/linux DISTDIR?= ${PORTSDIR}/distfiles _DISTDIR?= ${DISTDIR}/${DIST_SUBDIR} .if defined(USE_BZIP2) @@ -735,6 +735,42 @@ _POSTMKINCLUDED= yes +IGNORE_ABSPATH_CHECKS?= no +.if (${IGNORE_ABSPATH_CHECKS:L} != yes) +.if defined(DESTDIR) + +.if (${DESTDIR} != "") && (${DESTDIR:C,(^.).*,\1,} != "/") +.BEGIN: + @${ECHO} "DESTDIR must be defined as an absolute path so that when 'make'" + @${ECHO} "is invoked in the work area DESTDIR points to the right place." + @${FALSE} +.elif defined(PREFIX) +.if (${DESTDIR} != "") && (${DESTDIR:C,^.*(/)$$,\1,} != "/") \ + && (${PREFIX:C,(^.).*,\1,} != "/") +.BEGIN: + @${ECHO} "DESTDIR must be defined with a trailing slash if PREFIX is not\ + an absolute path." + @${FALSE} +.endif +.endif + +.endif +.endif # IGNORE_ABSPATH_CHECKS != yes + +.if defined(DESTDIR) +.if defined(USE_GMAKE) +# Tell gmake makefiles to override any local definition of DESTDIR with +# our definition. +MAKE_ARGS+= DESTDIR=${DESTDIR} +.else +# FreeBSD's make is not the same as gmake in being able to override VAR=FOO +# style definitions in the makefile with VAR=SOMETHING_ELSE passed on the +# command line to make, but we can use -E to get similar behavior. +MAKE_ARGS+= -E DESTDIR +MAKE_ENV+= DESTDIR=${DESTDIR} +.endif +.endif + WRKDIR?= ${WRKDIRPREFIX}${.CURDIR}/work .if defined(NO_WRKSUBDIR) WRKSRC?= ${WRKDIR} @@ -1081,7 +1117,7 @@ PKG_DELETE?= /usr/sbin/pkg_delete PKG_INFO?= /usr/sbin/pkg_info .if !defined(PKG_ARGS) -PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} +PKG_ARGS= -v -c ${COMMENT} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -s ${DESTDIR}${PREFIX} -P "`${MAKE} package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | sort -u`" ${EXTRA_PKG_ARGS} .if exists(${PKGINSTALL}) PKG_ARGS+= -i ${PKGINSTALL} .endif @@ -1288,7 +1324,8 @@ WRKDIR=${WRKDIR} WRKSRC=${WRKSRC} PATCHDIR=${PATCHDIR} \ SCRIPTDIR=${SCRIPTDIR} FILESDIR=${FILESDIR} \ PORTSDIR=${PORTSDIR} DEPENDS="${DEPENDS}" \ - PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} + PREFIX=${PREFIX} LOCALBASE=${LOCALBASE} X11BASE=${X11BASE} \ + DESTDIR=${DESTDIR} .if defined(BATCH) SCRIPTS_ENV+= BATCH=yes @@ -1319,7 +1356,7 @@ else \ { print "broken"; exit; } \ } \ - }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) $${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' + }' | ${SED} -e 's \([^/ ][^ ]*\.\(.\)[^. ]*\) ${DESTDIR}$${MAN\2PREFIX}/man/$$$$$$$${__lang}/man\2/\1.gzg' -e 's/ //g' -e 's/MANlPREFIX/MANLPREFIX/g' -e 's/MANnPREFIX/MANNPREFIX/g' .if ${__pmlinks:Mbroken} == "broken" .BEGIN: @${ECHO} "${PKGNAME}: Unable to parse MLINKS." @@ -1339,30 +1376,31 @@ .for sect in 1 2 3 4 5 6 7 8 9 .if defined(MAN${sect}) -_MANPAGES+= ${MAN${sect}:S%^%${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} +JUNK=1 +_MANPAGES+= ${MAN${sect}:S%^%${DESTDIR}${MAN${sect}PREFIX}/man/${lang}/man${sect}/%} .endif .endfor .if defined(MANL) -_MANPAGES+= ${MANL:S%^%${MANLPREFIX}/man/${lang}/manl/%} +_MANPAGES+= ${MANL:S%^%${DESTDIR}${MANLPREFIX}/man/${lang}/manl/%} .endif .if defined(MANN) -_MANPAGES+= ${MANN:S%^%${MANNPREFIX}/man/${lang}/mann/%} +_MANPAGES+= ${MANN:S%^%${DESTDIR}${MANNPREFIX}/man/${lang}/mann/%} .endif .endfor .if defined(_MLINKS) && make(generate-plist) -_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' +_TMLINKS!= ${ECHO} ${_MLINKS} | ${AWK} '{for (i=2; i<=NF; i+=2) print $$i}' | ${SED} 's,^${DESTDIR},,' .else _TMLINKS= .endif .if defined(_MANPAGES) && defined(NOMANCOMPRESS) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}^^:S^${PREFIX}/^^:S/""//:S^//^/^g} .elif defined(_MANPAGES) -__MANPAGES:= ${_MANPAGES:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} +__MANPAGES:= ${_MANPAGES:S^${DESTDIR}^^:S^${PREFIX}/^^:S/""//:S^//^/^g:S/$/.gz/} .endif .if defined(_MANPAGES) && ${MANCOMPRESSED} == "yes" @@ -1980,12 +2018,12 @@ @cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} run-depends lib-depends .endif .if make(real-install) - @${MKDIR} ${PREFIX} + @${MKDIR} ${DESTDIR}${PREFIX} @if [ `id -u` != 0 ]; then \ - if [ -w ${PREFIX}/ ]; then \ + if [ -w ${DESTDIR}${PREFIX}/ ]; then \ ${ECHO_MSG} "Warning: not superuser, you may get some errors during installation."; \ else \ - ${ECHO_MSG} "Error: ${PREFIX}/ not writable."; \ + ${ECHO_MSG} "Error: ${DESTDIR}${PREFIX}/ not writable."; \ ${FALSE}; \ fi; \ fi @@ -1996,7 +2034,7 @@ ${ECHO} "Copy it from a suitable location (e.g., /usr/src/etc/mtree) and try again."; \ exit 1; \ else \ - ${MTREE_CMD} ${MTREE_ARGS} ${PREFIX}/ >/dev/null; \ + ${MTREE_CMD} ${MTREE_ARGS} ${DESTDIR}${PREFIX}/ >/dev/null; \ fi; \ else \ ${ECHO_MSG} "Warning: not superuser, can't run mtree."; \
State Changed From-To: open->feedback This seems like a good idea. I agree that your interpretation of DESTDIR is correct. However, your current patch no longer applies, for obvious reasons. Sorry that nobody looked at your PR before, but I was wondering if you might have maintained this patch over the last (nearly) 3 years. Thanks!
Will Andrews wrote at 17:34 -0700 on Jun 3, 2004: > Synopsis: [patch] DESTDIR is used incorrectly in bsd.port.mk > > State-Changed-From-To: open->feedback > State-Changed-By: will > State-Changed-When: Thu Jun 3 17:31:18 PDT 2004 > State-Changed-Why: > This seems like a good idea. I agree that your interpretation of > DESTDIR is correct. However, your current patch no longer applies, > for obvious reasons. Sorry that nobody looked at your PR before, but > I was wondering if you might have maintained this patch over the last > (nearly) 3 years. Thanks! > > http://www.freebsd.org/cgi/query-pr.cgi?pr=28155 Thanks for the response. It's been a while on this one. I have maintained it some (basically every so often when I merge my Mk/bsd.port.mk with the latest version in CVS). But I had given up on anyone at FreeBSD working it in officially. The most enthusiastic response (prior to this one) I got from anyone who mattered was "Yes, it's wrong, but it's too much work to fix it." Indeed, port maintainers would need a heads up for such a change. There are LOTS of ports (picking one simple one at random: databases/gdbm) that have custom *-install targets that install to ${PREFIX} or ${X11BASE} or ${LOCALBASE} instead of ${DESTDIR}${PREFIX}. Then there are some %%PREFIX%% substitutions that may need fixing with respect to DESTDIR. Some ports don't even work for an alternate definition of PREFIX. But that'd be a different bug. There was so much breakage, that I pretty much gave up trying to do consistent builds (i.e., for a commercial product) outside a chroot. And even in the chroot case, there's a pervasive problem with pkg-plist's and absolute sym links in ports when using pkg_add -p. I had to pull teeth to fix just one of them (see http://www.freebsd.org/cgi/query-pr.cgi?pr=56621). There are other examples (emulators/mtools & lang/perl5.8 to name a couple). Basically anything that has an 'ln' in pkg-plist and uses %D as the link target. One way to address the widespread breakage might be just broadcasting a message to maintainers regarding the impending paradigm correction. It would probably be useful to also add a test to the bento builds to verify things are installed to the right place. It's a hard problem to fix that was broken by an unfortunate implementation of DESTDIR a LONG time ago and is now widespread. But, on the other hand, breaking the current DESTDIR is not such a bad thing since no one can possibly be using it successfully (at least not in any way that couldn't just as easily, and in most cases, more successfully be done using PREFIX). I bet a poll would indicate that no one uses DESTDIR (whether or not the reason for not using DESTDIR is that it's broken). So I'd guess that just fixing it in Mk/* will probably have little impact (and probably no negative impact). Note that there seems to be very little maintainer consideration regarding building/installing to some place other than /usr/local or /usr/X11R6. That may be because the .mk infrastructure makes it too hard. Some ports are better than others, but often only because the underlying package supports it correctly (usually via autoconf generated Makefiles) and the actual port Makefile doesn't do anything to break that. Sorry for the lengthy reply. If you're still reading, I'd be willing to update the patch and write the rudiments of a test that could be used for automated DESTDIR verification if someone at portmgr@ is willing to see this through. Let me know.
This PR is superseded by ports/100555, so it should be closed now. The new patchset is currently being tested on the package building cluster. -- Cheers, Gabor
State Changed From-To: feedback->closed After many long years of neglect, one of our Summer Of Code (SoC) students has picked up this idea and is currently trying to implement it (see the patch in ports/100555, which is currently being tested on the cluster). As will not surprise you, many ports are non-conformant, and we are having to do multiple regression runs to minimize the impact. 2005 and 2006 are the first years in a long time where we've actually started to make progress on the portmgr PR backlog, due to the fact that a) we have a much larger number of i386 machines available to us now; b) we have more portmgr members willing and able to do the regression tests, and c) we have finally gotten buy-in that we need more time with the ports tree unlocked to make progress (effectively, infrastructure work is mutually exclusive with ports tree locks). I am hopeful that we are able to continue to make progress in the last half of this year so that situations like this, which must have been extremely frustrating to the submitter, are less likely to occur in the future.
Mark Linimon wrote at 19:30 GMT on Jul 28, 2006: > After many long years of neglect, one of our Summer Of Code (SoC) stud= ents > has picked up this idea and is currently trying to implement it (see t= he > patch in ports/100555, which is currently being tested on the cluster)= =2E Yes... thanks for picking this up, G=E1bor. I'll look over 100555 and post any comments to that patch there. > As will not surprise you, many ports are non-conformant, and we are ha= ving > to do multiple regression runs to minimize the impact. > = > 2005 and 2006 are the first years in a long time where we've actually > started to make progress on the portmgr PR backlog, due to the fact th= at > a) we have a much larger number of i386 machines available to us now; > b) we have more portmgr members willing and able to do the regression > tests, and c) we have finally gotten buy-in that we need more time wit= h > the ports tree unlocked to make progress (effectively, infrastructure = work > is mutually exclusive with ports tree locks). I am hopeful that we ar= e > able to continue to make progress in the last half of this year so tha= t > situations like this, which must have been extremely frustrating to th= e > submitter, are less likely to occur in the future. Nice to see the progress. It stopped being frustrating long ago... I just gave up and lived with local patches. I'd guess this is a fairly typical response for patch submitters, but that's the nature of the project. I figured that this change was too big to handle with the regression infrastructure we had back then. The response was fairly lukewarm, too, but that was probably because of the daunting testing for this change. Of course, it would have been a bit easier back then from a volume standpoint with half as many ports ;)