Created
May 29, 2012 19:35
-
-
Save memory/2830217 to your computer and use it in GitHub Desktop.
UNCLEAN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -e | |
# just in case (some parts of the ruby build will honor this...) | |
unset DESTDIR | |
export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/local/bin:/usr/local/sbin | |
export INSTALLPREFIX=/export/disk0/wb/bin/ruby-env | |
export ENVNAME=$1 | |
export SYSTEM=$(uname -s) | |
export REPODIR=$(git rev-parse --show-toplevel) | |
export WORKDIR=${REPODIR}/ruby/env-builder | |
export DATADIR=${WORKDIR}/${ENVNAME} | |
export RUBYVERSIONFILE=${DATADIR}/ruby | |
export GEMSVERSIONFILE=${DATADIR}/gems | |
export BUILDROOT=${REPODIR}/bin/target/ruby-env/${ENVNAME} | |
export INSTALLROOT=${INSTALLPREFIX}/${ENVNAME} | |
# we install into buildroot/installroot, and then later on we can | |
# slice off the build root path to get a valid install root | |
export BUILDPATH="${BUILDROOT}${INSTALLROOT}" | |
if [ -z "$ENVNAME" ]; then | |
echo "No env name specified, bailing." | |
exit 1 | |
fi | |
if [ "$SYSTEM" != 'Linux' ]; then | |
echo "Building on non-linux systems is not supported, bailing." | |
exit 1 | |
fi | |
if ! [ -d ${REPODIR}/ruby/env-builder/${ENVNAME} ]; then | |
echo "you don't seem to have set up ${ENVNAME} (needs at least a ruby and gems file)" | |
exit 1 | |
fi | |
if ! (type -P symlinks); then | |
echo "the symlinks command was not found, maybe you need to install it?" | |
exit 1 | |
fi | |
RUBYFULLVER=$(cat ${RUBYVERSIONFILE}) | |
RUBYMAJOR=$(echo ${RUBYFULLVER} | cut -d. -f1-2) | |
# it is not safe to rebuild in place :( | |
### echo removing old build dir | |
rm -rf "${BUILDROOT}" | |
mkdir -p "${BUILDROOT}"/src | |
pushd ${BUILDROOT}/src | |
wget http://ftp.ruby-lang.org/pub/ruby/${RUBYMAJOR}/ruby-${RUBYFULLVER}.tar.gz | |
echo "building ruby into ${BUILDPATH}" | |
tar xvf ruby-${RUBYFULLVER}.tar.gz | |
cd ruby-${RUBYFULLVER} | |
# the --enable-load-relative flag is crucial | |
./configure \ | |
--prefix=${BUILDPATH} \ | |
--enable-shared \ | |
--enable-load-relative \ | |
--disable-install-doc \ | |
--disable-install-rdoc \ | |
--disable-install-capi | |
make -j3 | |
make install | |
popd | |
# optionally, install our gems | |
if [ -f ${GEMSVERSIONFILE} ]; then | |
while read line; do | |
${BUILDPATH}/bin/gem install --no-ri --no-rdoc -V $line | |
done < ${GEMSVERSIONFILE} | |
if (grep -q passenger ${GEMSVERSIONFILE}); then | |
# TODO(n): figure out some way to trigger the apache vs nginx build | |
${BUILDPATH}/bin/passenger-install-apache2-module -a | |
fi | |
fi | |
# don't bother packaging up the source tree | |
rm -rf "${BUILDROOT}/src" | |
# and now, make everything relocatable, which is a harder trick than you'd | |
# think. | |
# Step One: fix up all file paths inside plaintext files. | |
# | |
# in re that ugly perl inline: would anyone be crazy enough to embed spaces, | |
# quotes or backslashes into a ruby library path/file name? answer: it's | |
# ruby, what do _you_ think? (and the sed version is even more eye-gouging) | |
# | |
# shell quoting kung-fu: want to cram both ' and " into a string? It | |
# works like this: | |
# | |
# # foo="'"'"' | |
# # echo $foo | |
# '" | |
# | |
# # bar='"'"'" | |
# # echo $bar | |
# "' | |
# | |
# so: | |
# | |
# perl -pe 's#([ "`'"'"'\\])#\\$1#g' | |
# ^ ^^^^^^^ ^ | |
# q DDqqDqq q | |
# | |
# D=data q=quote delimiter | |
# | |
# ...which is to say, if the shell weren't mangling things: | |
# | |
# perl -pe s#([ "`'\\])#\\$1#g | |
echo fixing build paths in text files | |
txtfiles=$(find ${BUILDROOT} -type f -print0 |xargs -0 grep ${BUILDROOT} | \ | |
egrep -v 'Binary file' | \ | |
cut -d: -f1 | sort | uniq | \ | |
perl -pe 's#([ "`'"'"'\\])#\\$1#g' | \ | |
xargs) | |
if [ -n "$txtfiles" ]; then | |
echo found bad build paths in $txtfiles | |
perl -pi -e"s#${BUILDROOT}##g" $txtfiles | |
fi | |
# Step Two: fix up all file paths inside binary files(!) | |
# | |
# the horror: rvm+ruby's build produces elf executables with absolute RPATH | |
# values for the executables themselves and also any linked shared libraries | |
# inside the ruby/rvm hierarchy, e.g. libruby.so. Luckily, the full RPATH is | |
# BUILDROOT+INSTALLROOT, so we can use a completely sleazy perl one-liner to | |
# shear off BUILDROOT, and replace it with INSTALLROOT(foo), right-padded with | |
# nulls to the length of BUILDROOT. | |
# | |
# elvis wept. | |
echo fixing file paths in binary files | |
binfiles=$(find ${BUILDROOT} -type f -print0 |xargs -0 grep ${BUILDROOT} | \ | |
egrep 'Binary file' | \ | |
cut -d' ' -f3- | sed -e 's/ matches//' | sort | uniq | \ | |
perl -pe 's#([ "`'"'"'\\])#\\$1#g' | \ | |
xargs) | |
if [ -n "$binfiles" ]; then | |
echo found bad paths in $binfiles | |
# note that -0 sets IFS to \0, letting us treat an arbitrary chunk of | |
# binary data like a "line". | |
# | |
# note that we also handle the ugly case of someone embedding a colon- | |
# separated path list inside a null-terminated string. | |
# | |
# to put it mildly, this may not be portable to all possible unix variants. | |
echo $binfiles | xargs \ | |
perl -0 -pi -e \ | |
'$match=$ENV{BUILDROOT}; $count = s#$match##g; $pad = "\0" x ($count * length($match)); s#$#$pad#e;' | |
fi | |
# Step Three: make all internal symlinks relative. | |
echo making all symlinks relative | |
# oy, symlinks fails with a malloc error if you feed it too long an initial path | |
pushd ${BUILDPATH} | |
symlinks -r -c . | |
popd | |
echo "Et Voila!" | |
popd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment