Browse > Home / Computer, How To / Blog article: Building GSL as a Universal Binary - dayel.com

Building GSL as a Universal Binary

September 5th, 2009 Posted in Computer, How To

Quick download link: GSL 1.15 precompiled universal binaries for OS X

GSL

The GSL (Gnu Scientific Library) is a robust set of math routines, very useful for scientific computing.

If you want to link against the GSL and make code that runs on multiple architectures on OS X, you’ll need a universal binary of the library, like this precompiled universal binary of the GSL for OS X, including the ppc, i386 and x86_64 architectures.

Building GSL as a Universal Binary

The script I used to build it is below, and is based on this post.  If you want to compile it yourself, download the latest version of the GSL (.tar.gz file) from here or one of the mirrors, then run the script below in the same directory. If you’re worried about the compiler optimizations affecting accuracy, remove the ‘-O3’ from COMPFLAGS.  The finished libraries are in the ‘libs’ directory and the headers are in ‘include’.  The script makes universal libraries of all of the ‘.a’ files.

#!/usr/bin/env bash

# possible archs: i386 ppc x86_64 ppc64
# note: ppc64 doesn't work in Snow Leopard
ARCHITECTURES="i386 ppc x86_64"

# number of cpus to use during compile
COMPILETHREADS=2

COMPILER=gcc-4.2
#COMPILER=/Developer/usr/bin/llvm-g++-4.2

# configure flags
CONFFLAGS="--disable-shared"

# compiler flags
COMPFLAGS="-O3"

# find the name of the source file
SOURCEFILE=`find . -name "gsl*.tar.gz" -depth 1`
SOURCEFILE=${SOURCEFILE:2:100}
GSLVER=${SOURCEFILE%.tar.gz}

# unzip the main source file
tar -xzf $SOURCEFILE

for ARCH in $ARCHITECTURES
do
echo Compiling for ${ARCH}...

# copy source to new directory
cp -r ${GSLVER} ${GSLVER}_$ARCH
cd ${GSLVER}_$ARCH

# configure for architecture
if [ "$ARCH" != "ppc64" ] ; then  # not sure why we have to do cross compile for ppc64 but not ppc...
env CC="$COMPILER" CFLAGS="-arch $ARCH $COMPFLAGS" LDFLAGS="-arch $ARCH" ./configure $CONFFLAGS --build=$ARCH
else
env CC="$COMPILER" CFLAGS="-arch $ARCH $COMPFLAGS" LDFLAGS="-arch $ARCH" ./configure $CONFFLAGS --host=$ARCH
fi

# compile for architecture
make clean ; nice make -j $COMPILETHREADS

cd ..

done

mkdir include
mkdir libs
cp `find ${GSLVER} -name "*.h"` include

echo
echo
echo Making Universal Binaries...

find ${GSLVER}_$ARCH -name "*.a"

for LIBRARY in `find ${GSLVER}_$ARCH -name "*.a"`
do
echo
LIB=`basename $LIBRARY`
echo Library: $LIB
find . -name $LIB
lipo -create `find . -name $LIB | xargs` -output libs/$LIB
lipo -info libs/$LIB
done

echo
echo Universal Binaries:
echo
lipo -info libs/*.a

13 Responses to “Building GSL as a Universal Binary”

  1. Tomas Knapen says:

    Thanks for this script! It builds all but ppc64 on snow leopard on my mbp. How do you install the resulting .a file, while also generating a .dylib file as a normal configure, make, make install? Thanks again!

    • Mark says:

      You’re welcome!

      I briefly played with building a shared library, and it looks like it isn’t straightforward. If you set ‘--enable-shared‘ in the configure flags, it will still only compile the static library unless it’s for the native architecture. From the output of configure, it looks like libtool is balking at the cross-compile.

      I’m not doing a ‘make install’, because I don’t want it putting stuff into the system directories. I think it safer to just to manually copy the library and includes where you want them, then statically link the ‘.a’ file by dragging it into the libraries section of the project in XCode, and put the GSL include directory in the path.

      As for the ppc64—it looks like they might have pulled support for cross-compiling ppc64 code from Snow Leopard.

  2. Ian Andolina says:

    Hi, I need to build both libgsl.a and libgslcblas.a as universal binaries, but I cannot modify your script to make that happen – how do I do this? Also, I need the *.h include files but in /include I only get a Makefile.in and Makefile.am. I’m on 10.6.1, XCode 3.2/GCC 4.2 and GSL 1.13.

    Thanks for any advice!

    • Mark says:

      I’ve updated the script to make all the ‘.a’ files (including ‘libgslcblas.a’) into universal binaries, and fixed the misplaced ‘.h’ files (moved in v1.13?) Thanks.

  3. produibrut says:

    Hey Mark!

    Thanks for providing the precompiled binaries! I originally compiled gsl 1.14 sources for my mac OSX 10.6 to link with my XCode 3.2 project but only the libgsl.a and libgslblas.a where made; and linking to them was not enough to run gsl_randist functions (even with the proper header files set in build options). ( I would get a xxx$non_lazy_ptr symbol not defined error)…
    but with your precompiled libgsl.a and librandist.a added to the project things work perfectly!

    Thanks again! I’ll have to learn how to compile all the libraries from source.
    Cheers!

    prdtbrt

  4. Bongcheol Park says:

    Thank you for providing this valuable information.
    I really appreciate it.

  5. gabriel says:

    Thanks a lot, the scripts works perfectly.

  6. Al Chou says:

    From http://ascendwiki.cheme.cmu.edu/Binary_installer_for_GSL-1.13_on_Mac_OS_X , how to prevent “make install” from putting files into the system directories, but rather into a local subdirectory of the current directory (DESTDIR needs to be an absolute path):

    mkdir temp_install
    DESTDIR=`pwd`/temp_install make install

  7. Kevin says:

    Great scripts! Just wondering if there is a way to make all the ‘.dylib’ files into uni­ver­sal bina­ries?

    Thank in advance.

  8. roberto says:

    Hello! Thanks for the precompiled libraries :)
    I have always used the code in numerical recipes for scientific computing, and this is my first time trying to link a library outside /usr/local/… I was trying to compile this simple sample.c program with gcc:

    #include
    #include
    int main (void)
    {
    double x = 5.0;
    double y = gsl_sf_bessel_J0 (x);
    printf (“J0(%g) = %.18e\n”, x, y);
    return 0;
    }

    I tried
    gcc -Wall -I/Users/roberto/Desktop/gsl_universal_1.14/include -L/Users/roberto/Desktop/gsl_universal_1.14/libs/ -lgsl sample.c -o sample

    but it can’t find gsl_sf_bessel.h. If I #include instead, gcc can’t find some other headers. If I create gsl directories inside include/ and libs/, then gcc complains that their’s no lgsl library… what I am doing wrong? (thank you in advace!)

    • roberto says:

      I find one solution:
      I have the following directories:
      gsl_universal_1.14/include/gsl/ with .h files
      gsl_universal_1.14/libs/gsl/ with .a files

      First I compile using
      gcc -Wall -I/Users/roberto/Desktop/gsl_universal_1.14/include -L/Users/roberto/Desktop/gsl_universal_1.14/libs/ -c sample.c

      then I link using
      gcc sample.o gsl_universal_1.14/libs/gsl/libgsl.a -o sample

      cheers,
      roberto

  9. jvc says:

    still useful – thanks!

Leave a Reply

*
To prove you're a person (not a spam script), type the security text shown in the picture. Click here to regenerate some new text.
Click to hear an audio file of the anti-spam word