X-Spam-Check-By: sourceware.org Message-ID: <453C180C.4060206@cwilson.fastmail.fm> Date: Sun, 22 Oct 2006 21:17:00 -0400 From: Charles Wilson User-Agent: Thunderbird 1.5.0.7 (Windows/20060909) MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: [patch] cygport Content-Type: multipart/mixed; boundary="------------070805020505080101020202" Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --------------070805020505080101020202 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit The attached patch (+ two new files) enables cygport to build "relocatable" packages using the framework devised by Bruno Haible -- if the upstream source supports it. Currently, only libiconv and gettext support this feature (coincidentally, the upstream maintainer of both packages is...Bruno Haible). A relocated package is compiled using a temporary --prefix, like /tmp/libiconv-reloc-912385{/bin,/share,/lib,...} It is then installed into /usr{/bin,/share,/lib,...} -- but internally, all applications and libraries "figure out" where things are by computing relative paths between "where I thought I was going to be" and "where I actually am installed". So, in our case (1) cygbuild needs to use ${RELOC}/usr/... not just /usr/... (2) cyginstall needs a little tweaking so that things end up in ${D}/${RELOC/usr/... and not ${D}/usr/... (3) pkg_binpkg needs to cd into ${D}${RELOC}, not ${D} before tar'ing things up. There are other minor tweaks -- but if you don't 'import relocatable', then they are all no-ops (e.g. ${RELOC} is empty). That is, the global variable _ENABLE_RELOCATION (initially empty) acts like the _USE_CVS_FETCH/_USE_SVN_FETCH/_USE_GIT_FETCH variables, in that a cygclass sets it in order to modify the behavior of functions defined in the main cygport script. Don't 'import relocatable' -- and behavior is unchanged from current (except for the added postinstall/preremove features, described next). Look for my upcoming official releases of libiconv-1.11 and gettext-0.15 soon, for examples of how to (or not) use the relocation feature for these packages. The attached patch ALSO allows cygports to handle cases where a multi-binpkg project has different postinstall/preinstall scripts for more than one of the subpackages. This also required adding the ability for client cygports to turn off automatic install-info postinstall generation (e.g. in gettext, gettext.info belongs to the gettext-devel subpackage (so gettext.sh can't install it), but libasprintf.info belongs to the gettext subpackage. Both of these changes were necessary to convert libiconv/gettext over to a cygbuild process. NEW FILE: bin/prep_relocated_libtool_la.sh make sure that .la files don't have references to their temporary --prefix. NEW FILE: lib/relocatable.cygclass mainly just "turns on" the relocation support (and "turns off" /usr/lib/cygports/bin/ that don't have appropriate support. 2006-10-21 Charles Wilson <...> * bin/Makefile.am: add new file prep_relocated_libtool_la.sh * bin/prep_relocated_libtool_la.sh: new file * lib/Makefile.am: add new file relocatable.cygclass * lib/relocatable.cygclass: new file * bin/prep_gnu_info.sh: allow cygport client to suppress automatic install-info (useful if: subpackages each have own explicit postinstall scripts, and each subpackage "owns" certain info files. To activate *suppression*, set SUPPRESS_AUTOMATIC_INSTALLINFO to non-empty. Default behavior is unchanged from current. * bin/cygport.in (_ENABLE_RELOCATION): new global variable (_RELOCDIR): new global variable (__init_relocation): new function (__check_relocation): new function (__maybe_relocate): new function (main hook for relocatation support, called by other cygport functions) (cygconf): Add support for ${_RELOCDIR} and --enable-relocatable (docinto): Add support for ${_RELOCDIR} (exeinto): Add support for ${_RELOCDIR} (insinto): Add support for ${_RELOCDIR} (__prepare_relocation_ins): new function sets up top level of ${D} to point to ${D}${_RELOCDIR} (cyginstall): Add support for ${_RELOCDIR}. Optionally call __prepare_relocation_ins. (__prepetc): allow ${C}/${PN}.postinstall and ${C}/${PN}.sh as synonyms for ${C}/postinstall.sh (however, presence of more than one of these causes error message). Allow ${C}/${PN}.preremove as synonym for ${C}/preremove.sh (but presence of both causes error message). Allow for ${C}/${pkg_name[${n}]}.postinstall and/or ${C}/${pkg_name[${n}]}.preremove [n > 1]. (__prepstrip): Add support for ${_RELOCDIR}. Also if relocation is enabled, call prep_relocated_libtool_la.sh (pkg_binpkg): add support for ${_RELOCDIR} (pkg_pkgcheck): add support for ${_RELOCDIR} (finish): don't forget to clean up /tmp/temporary-prefix directory (even though we never actually install anything there; instead we install into ${D}/tmp/temporary-prefix) -- Chuck --------------070805020505080101020202 Content-Type: text/plain; name="cygport.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="cygport.diff" Index: bin/Makefile.am =================================================================== RCS file: /cvsroot/cygwin-ports/cygport/bin/Makefile.am,v retrieving revision 1.2 diff -u -r1.2 Makefile.am --- bin/Makefile.am 7 Aug 2006 23:08:43 -0000 1.2 +++ bin/Makefile.am 22 Oct 2006 06:34:07 -0000 @@ -41,6 +41,7 @@ prep_gnu_info.sh \ prep_gtk2_modules.sh \ prep_libtool_modules.sh \ + prep_relocated_libtool_la.sh \ prep_scrollkeeper_omf.sh EXTRA_DIST = cygport.in Index: bin/cygport.in =================================================================== RCS file: /cvsroot/cygwin-ports/cygport/bin/cygport.in,v retrieving revision 1.26 diff -u -r1.26 cygport.in --- bin/cygport.in 18 Oct 2006 04:27:31 -0000 1.26 +++ bin/cygport.in 22 Oct 2006 06:34:07 -0000 @@ -711,11 +711,47 @@ done } +_ENABLE_RELOCATION= +_RELOCDIR= +__init_relocation() { + if [ -d ${B} ] ; then + if [ -f ${B}/RELOC ] ; then + _RELOCDIR=`cat ${B}/RELOC` + if [ -z "${_ENABLE_RELOCATION}" ] ; then + error "RELOC file exists but relocation is disabled. Clean build dir!" + fi + else + if [ -n "${_ENABLE_RELOCATION}" ] ; then + _RELOCDIR=`mktemp -d /tmp/cygport-reloc-XXXXXX` + echo -n ${_RELOCDIR} > ${B}/RELOC + fi + fi + else + error "cygport internal error: __init_relocation called too early." + fi +} + +__check_relocation() { + if [ -z "${_ENABLE_RELOCATION}" -a -n "${_RELOCDIR}" ] ; then + error "configuration mismatch: relocation disabled but _RELOCDIR=${_RELOCDIR}" + fi + if [ -n "${_ENABLE_RELOCATION}" -a -z "${_RELOCDIR}" ] ; then + error "configuration mismatch: relocation enabled but _RELOCDIR not set" + fi +} +__maybe_relocate() { + __init_relocation + __check_relocation +} + # standard configure call cygconf() { - local confargs="--prefix=/usr --exec-prefix=/usr --bindir=/usr/bin \ - --sbindir=/usr/sbin --libexecdir=/usr/sbin --localstatedir=/var \ - --sysconfdir=/etc" + __maybe_relocate + + local confargs="--prefix=${_RELOCDIR}/usr --exec-prefix=${_RELOCDIR}/usr \ + --bindir=${_RELOCDIR}/usr/bin --sbindir=${_RELOCDIR}/usr/sbin \ + --libexecdir=${_RELOCDIR}/usr/sbin --localstatedir=${_RELOCDIR}/var \ + --sysconfdir=${_RELOCDIR}/etc" local confdir; if [ -n "${CYGCONF_SOURCE}" -a -x ${CYGCONF_SOURCE}/configure ] @@ -733,14 +769,20 @@ case "x$(grep -m 1 'GNU Autoconf' ${confdir}/configure | cut -d ' ' -f 6)" in x2.60) - confargs+=" --datarootdir=/usr/share --docdir=/usr/share/doc/${P}" + confargs+=" --datarootdir=${_RELOCDIR}/usr/share \ + --docdir=${_RELOCDIR}/usr/share/doc/${P}" ;; *) - confargs+=" --datadir=/usr/share --infodir=/usr/share/info \ - --mandir=/usr/share/man" + confargs+=" --datadir=${_RELOCDIR}/usr/share \ + --infodir=${_RELOCDIR}/usr/share/info \ + --mandir=${_RELOCDIR}/usr/share/man" ;; esac + if [ -n "${_ENABLE_RELOCATION}" ] ; then + confargs+=" --enable-relocatable" + fi + # AC_HAVE_MMAP fails despite a working mmap, so we force this to yes # (see http://www.cygwin.com/ml/cygwin/2004-09/msg00741.html # and following thread for details) @@ -835,8 +877,11 @@ /*) error "docinto argument should be only a subdirectory" ;; esac - dodir /usr/share/doc/${P}/${1}; - export _docinto_dir=${1}; + __maybe_relocate + dodir ${_RELOCDIR}/usr/share/doc/${P}/${1}; + + # ICK! + export _docinto_dir=../../../..${_RELOCDIR}/usr/share/doc/${P}/${1}; } # set doexe install dir @@ -846,8 +891,14 @@ error "exeinto accepts only one argument"; fi - dodir ${1}; - export _exeinto_dir=${1}; + case ${1} in + /*) ;; + *) error "exeinto argument must be absolute" ;; + esac + + __maybe_relocate + dodir ${_RELOCDIR}${1}; + export _exeinto_dir=${_RELOCDIR}${1}; } # set doins install dir @@ -857,8 +908,14 @@ error "insinto accepts only one argument"; fi - dodir ${1}; - export _insinto_dir=${1}; + case ${1} in + /*) ;; + *) error "insinto argument must be absolute" ;; + esac + + __maybe_relocate + dodir ${_RELOCDIR}${1}; + export _insinto_dir=${_RELOCDIR}${1}; } # Pre-install steps @@ -870,25 +927,58 @@ find ${B} -type f -exec touch -t $(date +%Y%m%d%H%M.%S) '{}' +; } +__prepare_relocation_ins() { + # This function assumes that __maybe_relocate() has already been + # called, AND that _ENABLE_RELOCATION is non-empty. + + # need to set up some symlinks so cygport functions that lack + # dir change support will be fooled into putting things into ${_RELOCDIR}. + if [ ! -d ${D}${_RELOCDIR} ] + then + mkdir -p ${D}${_RELOCDIR} + fi + + for d in $@ + do + case ${d} in + /* ) ;; + *) d=/${d} + esac + if [ ! -d ${D}${_RELOCDIR}${d} ] + then + mkdir -p ${D}${_RELOCDIR}${d} + fi + if [ ! -e ${D}${d} ] ; then + (cd ${D} && ln -fs ${_RELOCDIR##/}${d} ${d##/}) + fi + done +} + # run 'make install' cyginstall() { + __maybe_relocate + + if [ -n "${_ENABLE_RELOCATION}" ] ; then + __prepare_relocation_ins etc var usr + fi + case ${USE_DESTDIR:-1} in 1|[Yy]|[Yy][Ee][Ss]) make ${MAKEOPTS} install DESTDIR=${D} "${@}" || error "make install DESTDIR failed" ;; 0|[Nn]|[Nn][Oo]) make ${MAKEOPTS} install \ - prefix=${D}/usr \ - bindir=${D}/usr/bin/ \ - includedir=${D}/usr/include \ - libdir=${D}/usr/lib \ - sbindir=${D}/usr/sbin \ - libexecdir=${D}/usr/sbin \ - datadir=${D}/usr/share \ - infodir=${D}/usr/share/info \ - mandir=${D}/usr/share/man \ - localstatedir=${D}/var \ - sysconfdir=${D}/etc \ + prefix=${D}${_RELOCDIR}/usr \ + bindir=${D}${_RELOCDIR}/usr/bin/ \ + includedir=${D}${_RELOCDIR}/usr/include \ + libdir=${D}${_RELOCDIR}/usr/lib \ + sbindir=${D}${_RELOCDIR}/usr/sbin \ + libexecdir=${D}${_RELOCDIR}/usr/sbin \ + datadir=${D}${_RELOCDIR}/usr/share \ + infodir=${D}${_RELOCDIR}/usr/share/info \ + mandir=${D}${_RELOCDIR}/usr/share/man \ + localstatedir=${D}${_RELOCDIR}/var \ + sysconfdir=${D}${_RELOCDIR}/etc \ ${@} \ || error "make install No-DESTDIR failed" ;; @@ -974,16 +1064,62 @@ __prepetc() { local d; local s; + local -i n=1 + local -i count=0 + + # handle some conflicts between default behavior... + if [ -f ${C}/${PN}.sh ]; then count+=1 ; fi + if [ -f ${C}/postinstall.sh ]; then count+=1 ; fi + if [ -f ${C}/${PN}.postinstall ]; then count+=1 ; fi + if (( $count > 1 )) + then + error "Can have only one of ${PN}.sh, ${PN}.postinstall, and postinstall.sh" + fi + + count=0 + if [ -f ${C}/preremove.sh ]; then count+=1 ; fi + if [ -f ${C}/${PN}.preremove ]; then count+=1 ; fi + if (( $count > 1 )) + then + error "Can have only one of ${PN}.preremove, preremove.sh" + fi + + # do "main" postinstall if present + for f in ${PN}.sh ${PN}.postinstall postinstall.sh + do + if [ -f ${C}/${f} ] + then + dodir /etc/postinstall; + cat >> ${D}/etc/postinstall/${PN}.sh < ${C}/${f} + break + fi + done - for s in postinstall preremove + # do "main" preremove if present + # look for: ${PN}.preremove, preremove.sh + for f in ${PN}.preremove preremove.sh do - if [ -f ${C}/${s}.sh ] + if [ -f ${C}/${f} ] then - dodir /etc/${s}; - cat >> ${D}/etc/${s}/${PN}.sh < ${C}/${s}.sh; + dodir /etc/preremove; + cat >> ${D}/etc/preremove/${PN}.sh < ${C}/${f}; fi done + # now do other postinstall/preremove scripts if present + while [ -n "${pkg_name[${n}]}" ] + do + for s in postinstall preremove + do + if [ -f ${C}/${pkg_name[${n}]}.${s} ] + then + dodir /etc/${s}; + cat >> ${D}/etc/${s}/${pkg_name[${n}]}.sh < ${C}/${pkg_name[${n}]}.${s} + fi + done + n+=1 + done + if [ -f ${C}/profile.d.sh ] then exeinto /etc/profile.d; @@ -1058,7 +1194,8 @@ __prepstrip() { local exe; - + __maybe_relocate + cd ${D}; echo "Stripping executables:"; @@ -1076,6 +1213,12 @@ done find * -name '*.la' -exec prep_libtool_modules.sh '{}' + || error "Libtool module postinstall failed" + + if [ -n "${_ENABLE_RELOCATION}" ] + then + find * -name '*.la' -exec prep_relocated_libtool_la.sh ${_RELOCDIR} '{}' + ||\ + error "Relocated libtool postinstall failed" + fi } src_postinst() { @@ -1140,8 +1283,9 @@ pkg_binpkg() { local -i n=0; + __maybe_relocate - cd ${D}; + cd ${D}${_RELOCDIR}; __step "Creating binary package(s)"; @@ -1176,7 +1320,8 @@ local tmp1="${T}/tmptar.log"; local tmp2="${T}/tmpfind.log"; - cd ${D}; + __maybe_relocate + cd ${D}${_RELOCDIR}; __step "Checking packages for missing or duplicate files"; rm -f ${tmp1} ${tmp2}; @@ -1418,6 +1563,7 @@ finish() { local -i n=0; + __maybe_relocate cd ${top}; __step "Removing work directory in 5 seconds..."; @@ -1443,6 +1589,16 @@ rmdir ${workdir}; + # in relocation mode, mktemp created an actual directory in /tmp. + # nothing was ever installed there, but we should clean it up, too. + if [ -n "${_ENABLE_RELOCATION}" ] + then + if [ -d "${_RELOCDIR}" ] + then + rmdir ${_RELOCDIR}; + fi + fi + __step "Finished."; } Index: bin/prep_gnu_info.sh =================================================================== RCS file: /cvsroot/cygwin-ports/cygport/bin/prep_gnu_info.sh,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 prep_gnu_info.sh --- bin/prep_gnu_info.sh 14 Jun 2006 01:16:16 -0000 1.1.1.1 +++ bin/prep_gnu_info.sh 22 Oct 2006 06:34:07 -0000 @@ -20,12 +20,16 @@ gzip -q ${infopage} done -dodir /etc/postinstall -for infopage in $(find ${D}/usr/share/info -type f) -do - cat >> ${D}/etc/postinstall/${PN}.sh <<-_EOF +if [ -z "${SUPPRESS_AUTOMATIC_INSTALLINFO}" ] +then + dodir /etc/postinstall + for infopage in $(find ${D}/usr/share/info -type f) + do + cat >> ${D}/etc/postinstall/${PN}.sh <<-_EOF /usr/bin/install-info --dir-file=/usr/share/info/dir --info-file=/usr/share/info/${infopage##*/} _EOF -done -echo >> ${D}/etc/postinstall/${PN}.sh + done + echo >> ${D}/etc/postinstall/${PN}.sh +fi + Index: lib/Makefile.am =================================================================== RCS file: /cvsroot/cygwin-ports/cygport/lib/Makefile.am,v retrieving revision 1.5 diff -u -r1.5 Makefile.am --- lib/Makefile.am 18 Aug 2006 01:36:10 -0000 1.5 +++ lib/Makefile.am 22 Oct 2006 06:34:07 -0000 @@ -21,6 +21,7 @@ pygtk.cygclass \ python.cygclass \ qt3.cygclass \ + relocatable.cygclass \ ruby.cygclass \ ruby-gnome2.cygclass \ svn.cygclass \ --------------070805020505080101020202 Content-Type: text/plain; name="prep_relocated_libtool_la.sh" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="prep_relocated_libtool_la.sh" #!/bin/bash ################################################################################ # # prep_relocated_libtool_la.sh - removes ${_RELOCDIR} references from .la files # Part of cygport - Cygwin packaging application # Copyright (C) 2006 Charles Wilson # Distributed under the terms of the GNU General Public License v2 # # Invoke as: # if [ -n "${_ENABLE_RELOCATION}" ] # then # prep_relocated_libtool_la.sh ${_RELOCDIR} list-of-la-files # fi # ################################################################################ set -e declare -r ltversion="$(/usr/bin/libtool --version | /bin/grep ltmain.sh)" _RELOCDIR=$1 shift if [ -z "${_RELOCDIR}" ] then echo "internal error: bad call to prep_relocated_libtool_la.sh: _RELOCDIR empty" exit 1 fi case "${_RELOCDIR}" in *.la ) echo "internal error: bad call to prep_relocated_libtool_la.sh: _RELOCDIR=${_RELOCDIR}" exit 1 ;; /* ) ;; * ) echo "internal error: _RELOCDIR must be an absolute path: _RELOCDIR=${_RELOCDIR}" exit 1 ;; esac echo "Fixing relocated libtool modules:" for lib_la in "${@}" do if [ ! -f ${lib_la} ] then error "file ${lib_la} does not exist!" fi if ! grep -q "libtool library file" ${lib_la} then continue # go to next iteration of for loop fi echo " ${lib_la}" new_lib_la=${lib_la}.new cat ${lib_la} | sed -e "/^dependency_libs=/s,${_RELOCDIR},,g" \ -e "/^libdir=/s,${_RELOCDIR},,g" > ${new_lib_la} mv ${new_lib_la} ${lib_la} done --------------070805020505080101020202 Content-Type: text/plain; name="relocatable.cygclass" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="relocatable.cygclass" ################################################################################ # # relocatable.cygclass - functions for building packages that use Bruno Haible's # relocation framework (e.g. libiconv and gettext, with # --enable-relocatable) # # Copyright (C) 2006 Charles Wilson # Distributed under the terms of the GNU General Public License v2 # ################################################################################ _ENABLE_RELOCATION=1 relocatable_conf() { cygconf } relocatable_install() { cyginstall } ### the following do not have support for dir changes, disallow dolib() { error "/usr/lib/cygport/bin/dolib needs dir change support." ; } dobin() { error "/usr/lib/cygport/bin/dobin needs dir change support." ; } doman() { error "/usr/lib/cygport/bin/doman needs dir change support." ; } dosbin() { error "/usr/lib/cygport/bin/dosbin needs dir change support." ; } doicon() { error "/usr/lib/cygport/bin/doicon needs dir change support." ; } domenu() { error "/usr/lib/cygport/bin/domenu needs dir change support." ; } newbin() { error "/usr/lib/cygport/bin/newbin needs dir change support." ; } newman() { error "/usr/lib/cygport/bin/newman needs dir change support." ; } newicon() { error "/usr/lib/cygport/bin/newicon needs dir change support." ; } newmenu() { error "/usr/lib/cygport/bin/newmenu needs dir change support." ; } ### use dosym with care: both arguments must be specified with ${RELOCDIR} ### ditto for dodir: argument must be specified with ${RELOCDIR} --------------070805020505080101020202 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --------------070805020505080101020202--