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/<SCRIPTS> 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
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} "[EMAIL
PROTECTED]" || 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 \
[EMAIL PROTECTED] \
|| 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 \
#!/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 "[EMAIL PROTECTED]"
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
################################################################################
#
# 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}
--
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/