PyBootstrapper.sh
author kiorky <kiorky@cryptelium.net>
Fri Oct 03 15:00:18 2008 +0200 (17 months ago)
changeset 25 5015675af464
parent 24 9a8ff07a365a
permissions -rwxr-xr-x
fix md(
     1 #!/usr/bin/env bash
     2 # Copyright (C)2007 'Mathieu PASQUET <kiorky@cryptelium.net> '
     3 # This program is free software; you can redistribute it and/or modify
     4 # it under the terms of the GNU General Public License as published by
     5 # the Free Software Foundation; either version 2 of the License, or
     6 # (at your option) any later version.
     7 # This program is distributed in the hope that it will be useful,
     8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10 # GNU General Public License for more details.
    11 # You should have received a copy of the GNU General Public License
    12 # along with this program; see the file COPYING. If not, write to the
    13 # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    14 version="0.4"
    15 offline=""
    16 
    17 UNAME="$(uname)"
    18 
    19 MD5SUM="$(which md5sum)"
    20 if [[ -f $(which md5 2>/dev/null) ]];then
    21     MD5SUM="md5 -q"
    22 fi
    23 
    24 # export PATH to have bzip2 and our perso binaries everywhere
    25 export PATH="$prefix/bin:$prefix:/sbin:$PATH"
    26 
    27 #another macosx hack
    28 if [[ -f $(which curl 2>&1) ]];then
    29     wget="$(which curl) -a -o"
    30     # freebsd
    31 elif [[ -f $(which fetch 2>&1) ]];then
    32     wget="$(which fetch) -spra -o"
    33 elif [[ -f $(which wget) ]];then
    34     wget="$(which wget)  -c -O"
    35 fi
    36 
    37 
    38 if [[ -f $(which gsed 2>&1) ]];then
    39 SED="$(which gsed)"
    40 else
    41     SED="$(which sed)"
    42 fi 
    43 
    44 gentoo_mirror="http://85.25.128.62"
    45 #gentoo_mirror="ftp://gentoo.imj.fr/pub"
    46 gentoo_mirror="$gentoo_mirror"
    47 
    48 gnu_mirror="http://ftp.gnu.org/pub/gnu"
    49 
    50 readline_mirror="$gentoo_mirror/gentoo/distfiles/readline-5.2.tar.gz"
    51 readline_md5="e39331f32ad14009b9ff49cc10c5e751"
    52 
    53 bz2_mirror="$gentoo_mirror/gentoo/distfiles/bzip2-1.0.4.tar.gz"
    54 bz2_md5="fc310b254f6ba5fbb5da018f04533688"
    55 
    56 zlib_mirror="$gentoo_mirror/gentoo/distfiles/zlib-1.2.3.tar.bz2"
    57 zlib_md5="dee233bf288ee795ac96a98cc2e369b6"
    58 
    59 ncurses_mirror="$gnu_mirror/ncurses/ncurses-5.6.tar.gz"
    60 ncurses_md5="b6593abe1089d6aab1551c105c9300e3"
    61 
    62 python24_mirror="http://www.python.org/ftp/python/2.4.5/Python-2.4.5.tar.bz2"
    63 python24_md5="aade3958cb097cc1c69ae0074297d359"
    64 python25_mirror="http://www.python.org/ftp/python/2.5.2/Python-2.5.2.tar.bz2"
    65 python25_md5="afb5451049eda91fbde10bd5a4b7fadc"
    66 python_mirror=$python25_mirror
    67 python_md5=$python25_md5
    68 
    69 openssl_mirror="http://www.openssl.org/source/openssl-0.9.8h.tar.gz"
    70 openssl_md5="7d3d41dafc76cf2fcb5559963b5783b3"
    71 
    72 ez_mirror="http://peak.telecommunity.com/dist/ez_setup.py"
    73 ez_md5="94ce3ba3f5933e3915e999c26da9563b"
    74 ez_md5="494757ae608c048e1c491c5d4e0a81e6"
    75 ez_md5="ce4f96fd7afac7a6702d7a45f665d176"
    76 
    77 virtualenv_mirror="http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.1.tar.gz"
    78 virtualenv_md5="8931b66dbb799120583dd107aab2fa89"
    79 
    80 hg_mirror="http://hg.intevation.org/files/mercurial-1.0.tar.gz"
    81 hg_md5="9f8dd7fa6f8886f77be9b923f008504c"
    82 
    83 zc_buildout_mirror="http://pypi.python.org/packages/source/z/zc.buildout/zc.buildout-1.0.1.tar.gz"
    84 zc_buildout_md5="438748533cdf043791c98799ed4b8cd3"
    85 
    86 # pretty term colors
    87 GREEN=$'\e[32;01m'
    88 YELLOW=$'\e[33;01m'
    89 RED=$'\e[31;01m'
    90 BLUE=$'\e[34;01m'
    91 NORMAL=$'\e[0m'
    92 
    93 # display an error message and exit
    94 die() {
    95     echo $@
    96     exit -1
    97 }
    98 
    99 # silently enter a directory
   100 qpushd() {
   101     pushd "$1" 2>&1 >> /dev/null
   102 }
   103 
   104 # silently go outside a directory
   105 qpopd() {
   106     popd    2>&1 >> /dev/null
   107 }
   108 
   109 check_md5() {
   110     if [[ "$md5" != "$file_md5" ]];then
   111         echo "WARNING:! md5 for $myfullpath failed : $md5 != $file_md5 !"
   112     fi
   113     if [[ ! -e "$myfullpath" ]];then
   114         die "$myfullpath"
   115     fi
   116 }
   117 
   118 # download in installdir/downloads
   119 # $1: download URL. The last part of the URL will be the file name by default
   120 # $2: file name's md5
   121 # $3: file name
   122 #don't put "/" at the end of the URL or provide a file name
   123 download(){
   124     local md5="$2" myfile="$3" url="$1" mydest=""
   125     if [[ -n "$md5" ]] && [[ -n "$url" ]];then
   126         if [[ ! -e "$download_dir" ]];then
   127             mkdir -p "$download_dir" || die "cant create download dir: $download_dir"
   128         fi
   129         if [[ -z "$myfile" ]];then
   130             myfile="$(give_filename_from_url $url)"
   131         fi
   132         mydest="$download_dir/$myfile"
   133         # offline mode
   134         if [[ ! -f "$mydest" ]] && [[ -n "$offline" ]];then
   135             die "file $mydest does not exists!!!"
   136         fi
   137         if [[ -e "$mydest" ]];then
   138             file_md5="$($MD5SUM $mydest|awk '{print $1}')"
   139         fi
   140         if [[ -z "$offline" ]] && [[ "$md5" != "$file_md5" ]];then
   141             $wget "$mydest" "$url"
   142             file_md5="$($MD5SUM $mydest|awk '{print $1}')"
   143         fi
   144         if [[ "$md5" != "$file_md5" ]];then
   145             die "$myfile doesn't match the md5 "$md5" ($file_md5)"
   146         fi
   147         echo "Downloaded $mydest"
   148     fi
   149 }
   150 
   151 # get mas os patches
   152 get_macos_patches() {
   153     # openssl
   154     download http://distfiles.minitage.org/public/externals/minitage/patches/openssl-0.9.8h-macos.diff d9bca87496daff6a8b51972dbe0ba48a  openssl-0.9.8h-macos.diff
   155     # readline
   156     download http://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-012 e3e9f441c8111589855bc363e5640f6c readline52-012
   157 }
   158 get_win32_patches() {
   159     # readline
   160     # this patch comes from http://gpsim.sourceforge.net/gpsimWin32/packages/readline-5.2-20061112-src.zip
   161     download http://distfiles.minitage.org/public/externals/minitage/patches/readline-5.2-src.diff  a635c45040ffd0c39f46ad6c404f5c85  readline-5.2-src.diff
   162 }
   163 
   164 # usage error
   165 usage(){
   166     echo;echo
   167     echo "${YELLOW} PyBootStrapper $version:"
   168     echo "${BLUE}$0 $RED $0 [-o|--offline] [-2.4] PREFIX"
   169     echo "${GREEN}      Will bootstrap python into PREFIX $NORMAL"
   170     echo "${YELLOW}   If you choose offline mode, put you files into PREFIX/downloads $NORMAL"
   171     echo "${YELLOW}   If you choose to build python2.4 instead of 2.5, add -2.4 to args. $NORMAL"
   172 }
   173 
   174 # make a temporary directory and go inside
   175 # $1: the directory
   176 mkdir_and_gointo(){
   177     local dir="$1"
   178     if [[ -n "$dir" ]];then
   179         local destdir="$tmp_dir/$dir"
   180         if [[ -e "$destdir" ]];then
   181             rm -rf "$destdir" || die "error deleting bad tmp dir $destdir"
   182         fi
   183         mkdir -p "$tmp_dir/$dir" 2> /dev/null || die "cant create dir"
   184         qpushd "$tmp_dir/$dir"
   185     else
   186         die "mkdir_and_gointo: give arg"
   187     fi
   188 }
   189 
   190 set_mac_target() {
   191     if [[ $UNAME == "Darwin"  ]];then
   192         LDFLAGS="$LDFLAGS -mmacosx-version-min=10.5.0"
   193     fi
   194 }
   195 
   196 # $1: name for errors NOT SET TO NULL OR SHOOT IN YOUR FEES
   197 # $@ compile opts
   198 cmmi() {
   199     local myname="$1"
   200     shift
   201     compile_opts="$@"
   202     echo "Running: ./configure $@"
   203     export CFLAGS=" -I$prefix/usr/include"
   204     export CPPFLAGS="$CFLAGS"
   205     export CXXFLAGS="$CFLAGS"
   206     export LDFLAGS=" -Wl,-rpath -Wl,$prefix/lib -Wl,-rpath -Wl,/lib"
   207     export LD_RUN_PATH="$prefix"
   208     set_mac_target
   209     make clean
   210     ./configure $@ || die "$1 config failed"
   211     echo "Compiling:"
   212     make || die "$1 compilation failed"
   213     echo "Installing:"
   214     make install || die "$1 install failed"
   215     unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS LD_RUN_PATH
   216 }
   217 
   218 # return the last part from an URL, basically the file name.
   219 # $1: URL
   220 give_filename_from_url() {
   221     local arg=$1
   222     local url="$(echo "$arg" |"$SED" -re "s:^((http|ftp)\://.*/)([^/]*)(/*)$:\3:g")"
   223     if [[ -z "$url" ]];then
   224         die "Failed to get filename from $arg"
   225     else
   226         echo "$url"
   227     fi
   228 }
   229 
   230 compile_bz2() {
   231     local myfullpath="bz2.tbz2"
   232     local bz2_cflags="-fpic -fPIC -Wall -Winline -O3  -I. -L. -Wl,-rpath -Wl,'$prefix/lib' -Wl,-rpath -Wl,'/lib'"
   233     # check the download is good
   234     download "$bz2_mirror" "$bz2_md5" "$myfullpath"
   235     mkdir_and_gointo "bz2"
   236     tar xzvf "$download_dir/$myfullpath" -C .
   237     cd *
   238     set_mac_target
   239     make CFLAGS="$bz2_cflags"
   240     make install PREFIX="$prefix" || die "make install failed"
   241     for i in libbz2.so.* libbz2.a ;do
   242         if [[  -e "$i" ]];then
   243             cp "$i" "$prefix/lib" || die "shared librairies installation failed"
   244         fi
   245     done
   246     cp bzlib.h "$prefix/include" || die "shared include installation failed"
   247 }
   248 compile_zlib(){
   249     local myfullpath="zlib.tbz2"
   250     # check the download is good
   251     download "$zlib_mirror" "$zlib_md5" "$myfullpath"
   252     mkdir_and_gointo "zlib"
   253     tar xjvf "$download_dir/$myfullpath" -C .
   254     cd *
   255     cmmi  "$myname" --prefix="$prefix" --shared || die "cmmi failed for $myname"
   256     make test || die "zlib test failed"
   257 }
   258 
   259 compile_readline(){
   260     local myfullpath="readline.tgz"
   261     # check the download is good
   262     download "$readline_mirror" "$readline_md5" "$myfullpath"
   263     mkdir_and_gointo "readline"
   264     tar xzvf "$download_dir/$myfullpath" -C .
   265     cd *
   266     if [[ $UNAME  == 'Darwin' ]];then
   267         patch -p0 < "$download_dir/readline52-012"
   268     fi
   269     export CFLAGS=" -I$prefix/include  -I$prefix/include/ncurses"
   270     export CPPFLAGS="$CFLAGS"
   271     export CXXFLAGS="$CFLAGS"
   272     export LDFLAGS=" -Wl,-rpath -Wl,$prefix/lib -Wl,-rpath -Wl,/lib "
   273     export LD_RUN_PATH="$prefix"
   274     set_mac_target
   275     make clean
   276     ./configure -prefix="$prefix"  || die "$1 config failed"
   277     echo "Compiling:"
   278     make || die "$1 compilation failed"
   279     echo "Installing:"
   280     make install || die "$1 install failed"
   281     unset CFLAGS CPPFLAGS LDFLAGS LD_RUN_PATH
   282 }
   283 
   284 compile_ncurses(){
   285     local myfullpath="ncurses.tgz"
   286     # check the download is good
   287     download "$ncurses_mirror" "$ncurses_md5" "$myfullpath"
   288     mkdir_and_gointo "ncurses"
   289     tar xzvf "$download_dir/$myfullpath" -C .
   290     cd *
   291     cmmi  "$myname"  --enable-const --enable-colorfgbg --enable-echo  \
   292     --with-manpage-format=normal --with-rcs-ids --enable-symlinks     \
   293     --disable-termcap --with-shared \
   294     $(if [[ $UNAME != 'Darwin' ]];then echo '--with-libtool';fi) \
   295     --prefix="$prefix" || die "cmmi failed for $myname"
   296 }
   297 
   298 compile_openssl(){
   299     local myfullpath="openssl.tgz" platform=""
   300     # check the download is good
   301     download "$openssl_mirror" "$openssl_md5" "$myfullpath"
   302     mkdir_and_gointo "openssl"
   303     tar xzvf "$download_dir/$myfullpath" -C .
   304     ldflags=" -Wl,-rpath -Wl,'$prefix/lib' -Wl,-rpath -Wl,'/lib'"
   305     cd *
   306     if [[ $UNAME == 'FreeBSD' ]];then
   307         platform='FreeBSD-elf';
   308     fi
   309     if [[ $UNAME == 'Darwin' ]];then
   310         ldflags="$ldflags  -mmacosx-version-min=10.5.0"
   311         platform=''
   312         patch  -p1 < "$download_dir/openssl-0.9.8h-macos.diff"
   313     fi
   314     ./config --prefix="$prefix" shared $ldflags no-fips "$platform"
   315     if [[ $UNAME == 'FreeBSD' ]];then
   316         gsed \
   317         -e 's|^FIPS_DES_ENC=|#FIPS_DES_ENC=|' \
   318         -e 's|^FIPS_SHA1_ASM_OBJ=|#FIPS_SHA1_ASM_OBJ=|' \
   319         -e 's|^SHLIB_EXT=.*$$|SHLIB_EXT=.so.$(SHLIBVER)|' \
   320         -e 's|fips-1.0||' \
   321         -e 's|^SHARED_LIBS_LINK_EXTS=.*$$|SHARED_LIBS_LINK_EXTS=.so|' \
   322         -e 's|^SHLIBDIRS= fips|SHLIBDIRS=|' \
   323         -i  ./Makefile || die "gsed failed"
   324     fi
   325     make || die "make openssl failed"
   326     make install || die "make install openssl failed"
   327 }
   328 
   329 compile_python(){
   330     local myfullpath="python.tbz2"
   331     # check the download is good
   332     download "$python_mirror" "$python_md5" "$myfullpath"
   333     mkdir_and_gointo "python"
   334     tar xjvf "$download_dir/$myfullpath" -C .
   335     cd *
   336     # XXX OSX hack
   337     CFLAGS="  -I$prefix/include -I$prefix/include/ncurses -I.    $([[ $UNAME == 'Darwin' ]] && echo '-mmacosx-version-min=10.5.0  -D__DARWIN_UNIX03 ')"
   338     LDFLAGS=" -Wl,-rpath -Wl,'$prefix/lib' -Wl,-rpath -Wl,'/lib' $([[ $UNAME == 'Darwin' ]] && echo '-mmacosx-version-min=10.5.0')"
   339     export CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
   340     export LD_RUN_PATH="$prefix/lib"
   341     #not using cmmi as i need specific linkings
   342     ./configure  --prefix="$prefix"   \
   343     --enable-shared  --with-bz2 \
   344     $(if [[ $UNAME == 'Darwin' ]];then echo "--enable-toolbox-glue";fi) \
   345     $(if [[ $UNAME != CYGWIN* ]];then echo "--with-fpectl";fi) \
   346     --with-readline --with-zlib \
   347     OPT="$CFLAGS" \
   348     CPPFLAGS="$CFLAGS" \
   349     LDFLAGS="$LDFLAGS" \
   350     --includedir="$prefix/include" \
   351     --libdir="$prefix/lib"|| die "cmmi failed for python"
   352     make || die "python compilation failed"
   353     make install || die "python install failed"
   354     unset CFLAGS CPPFLAGS LDFLAGS OPT LD_RUN_PATH
   355 }
   356 
   357 ez_offline() {
   358     egg="$1"
   359     ez="$(ls $prefix/bin/easy_install*|tail -n1)"
   360     "$ez" -H None -f "$download_dir" "$egg" || die "easy install failed for egg"
   361 }
   362 
   363 installorupgrade_setuptools(){
   364     local myfullpath="ez.py"
   365     # check the download is good
   366     download "$ez_mirror" "$ez_md5" "$myfullpath"
   367     qpushd $prefix
   368     res=$("$python" "$download_dir/$myfullpath")
   369     qpopd
   370     res=$(echo $res|$SED -re "s/.*(-U\s*setuptools).*/reinstall/g")
   371     if [[ "$res" == "reinstall" ]];then
   372        "$python" "$download_dir/$myfullpath" -U setuptools
   373     fi
   374     download "$virtualenv_mirror" "$virtualenv_md5"
   375     if [[ $UNAME == CYGWIN* ]];then
   376         qpushd $prefix/tmp
   377         # openssl
   378         download http://distfiles.minitage.org/public/externals/minitage/patches/virtualenv.win.diff 6c3d9b5f103a380041991d9c0714a73b virtenv.diff 
   379         tar xzvf "$download_dir/virtualenv-1.1.tar.gz"
   380         cd virtualenv-1.1
   381         patch -p0<"$download_dir/virtenv.diff"
   382         "$python" setup.py install
   383     else
   384         ez_offline "VirtualEnv"   || die "VirtualEnv installation failed"
   385     fi
   386     download "$hg_mirror" "$hg_md5"
   387     ez_offline "Mercurial"   || die "VirtualEnv installation failed"
   388     download "$zc_buildout_mirror" "$zc_buildout_md5"
   389     ez_offline  "zc.buildout" || die "zc.buildout installation failed"
   390 }
   391 
   392 bootstrap() {
   393     compile_bz2	     || die "compile_and_install_bz2 failed"
   394     compile_zlib     || die "compile_and_installzlib failed"
   395     compile_ncurses  || die "compile_and_install ncurses failed"
   396     compile_readline || die "compile_and_install_readline failed"
   397     compile_openssl  || die "compile_and_install_openssl failed"
   398     compile_python   || die "compile_and_install_python failed"
   399 }
   400 
   401 main() {
   402     if [[ $UNAME == 'Darwin' ]];then
   403         get_macos_patches
   404     fi
   405     bootstrap
   406     installorupgrade_setuptools || die "install_setuptools failed"
   407     rm -rf "$tmp_dir"/* &
   408     echo "Installation is now finnished."
   409     echo "some cleaning is running in the background and may take a while."
   410     echo "While it's cleaning, the machine can be a bit slower."
   411 }
   412 
   413 create_destination() {
   414     local cli_dir="$1"
   415     if [[ -e "$cli_dir" ]];then
   416         echo "Warning: Directory not empty"
   417     fi
   418     mkdir -p "$cli_dir" || die "Cannot create destination directory"
   419     # absolute path needed for safety
   420     qpushd "$cli_dir"
   421     prefix="$(pwd)"
   422     download_dir="${prefix}/downloads"
   423     tmp_dir="${prefix}/tmp"
   424     python="$prefix/bin/python"
   425     for dir in "$tmp_dir" "$download_dir";do
   426         if [[ ! -d "$dir" ]];then
   427             mkdir "$dir" || die "creation of $dir failed"
   428         fi
   429     done
   430     qpopd
   431 }
   432 
   433 # parse command line
   434 cli_dir=""
   435 # usage is requested
   436 for arg in $@;do
   437     # offline mode
   438     if [[ "$arg" == "-test" ]];then
   439         test_mode="true"
   440     elif [[ "$arg" == "--offline" ]];then
   441         offline="y"
   442     elif [[ "$arg" == "-h" ]] || [[ "$arg" == "--help" ]] ;then
   443         usage
   444         exit
   445     elif [[ $arg == "-2.4" ]] || [[ $arg == "--python-2.4" ]];then
   446         echo "$YELLOW User choosed to Build python-2.4 !$NORMAL"
   447         sleep 2
   448         python_mirror="$python24_mirror"
   449         python_md5="$python24_md5"
   450     elif [[ $arg == "-o" ]] || [[ $arg == "--offline" ]];then
   451         offline="y"
   452     else
   453         cli_dir="$arg"
   454     fi
   455 done
   456 
   457 # about to install
   458 if [[ -z "$cli_dir" ]] && [[ ! -n "$test_mode" ]];then
   459     usage
   460     die "You must precise the directory to bootstrap to."
   461 else
   462     if [[ -z "$test_mode" ]];then
   463         # create_destination will register the $prefix variable !
   464         create_destination "$cli_dir"
   465         main "$prefix"
   466     fi
   467 fi
   468 # vim:set ts=4 sts=4 sw=4 et ai ft=sh tw=80 :