How can I use the GNU Scientific Library in an iOS application?
I tried following this tutorial: http://www.os-scientific.org/devel/gslxcode/index.html. But it seems not to work for iOS this way, only for OS X. After I added the GSL source code to XCode using an "external build system", XCode wants to build the target of that GSL subproject for the OS X SDK instead of the iOS SDK.
Ok! The configuration that worked for me:
sudo ./configure --disable-shared --disable-dependency-tracking
--host=armv7-apple-darwin10 CFLAGS="-I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/include
-I/Library/iPhone/include -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk"
CC="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-gcc-4.2.1"
CPP=cpp LDFLAGS="-isysroot
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk"
Small devices running iOS are 32-bit systems. You will need to rebuild the Gnu Science Library (GSL) for 32-bit machines by configuring the make process as follows: ./configure CFLAGS="-arch i386", then make and link the new library file to your project according to the tutorial in your first attempt.
A revision of the above statement: That advice works fine in getting a build that works for the iOS simulator, but it's not clear that GSL can even be successfully built for the ARMv7 architecture without changing the code base. If it is at all possible, it would appear that one needs a different tool chain for building GSL from the one provided.
It wasn't easy, but these are the steps I took to get it working...
1) Download and extract latest GSL
2) In the gsl directory, ./configure
--disable-shared --disable-dependency-tracking CFLAGS="-DGSL_C99_INLINE -g -O2"
3) Create a Cocoa Touch Static Library project in Xcode.
4) Copy the following headers into the project: config.h, build.h, gsl_machine.h
5) Find the function(s) you want to use in your project. Copy those .c
files into your project.
6) Then track through that function to see what other functions it calls, all the way down to the bottom.
7) Copy into your project all of the .c
files those functions are in.
8) Copy into your project all of the .h
files needed for those function definitions.
9) There is a more elegant way to do this, but for me, I just took the simple route and changed the #include <gsl/xxxxx.h>
statements to #include "xxxxxx.h"
. Comment out any #include
s that you don't actually need.
10) Any function you don't need in those .c
files, you can remove them in order to reduce the number of other includes you need to use. You can either just delete them, but I recommend putting #if 0
and #endif
around them instead. Just in case you missed something and need to include them later.
11) Build and check for errors. If you're missing a function, include the .c
file for that function, rinse, repeat.
I needed to include gsl_cdf_tdist_P()
for my project, and when I tracked down through all of the method calls, this is the list of all of the functions needed. (any function with an * after is one that has already been encountered, so I didn't need to track down through it):
gsl_cdf_tdist_P
cornish_fisher
poly_eval
gsl_cdf_ugaussian_P
gauss_small
gauss_medium
get_del
gauss_large
get_del*
beta_inc_AXPY
gsl_sf_gamma_inc_Q
gsl_sf_gamma_inc_Q_e
gamma_inc_P_series
gamma_inc_D
gsl_sf_lngamma_e
lngamma_1_pade
lngamma_2_pade
lngamma_lanczos
lngamma_sgn_0
lngamma_sgn_sing
gsl_sf_lnfact_e
gsl_sf_lngamma_e*
gsl_sf_psi_int_e
gsl_sf_psi_1_int_e
gsl_sf_psi_n_e
gsl_sf_psi_e
psi_x
cheb_eval_e*
gsl_sf_psi_1_e
psi_n_xg0
gsl_sf_psi_e*
gsl_sf_hzeta_e
gsl_sf_lnfact_e*
gsl_sf_exp_mult_err_e
gsl_sf_hzeta_e*
gsl_sf_lnfact_e*
gsl_sf_exp_mult_err_e*
lngamma_lanczos*
gsl_sf_gammastar_e
gsl_sf_lngamma_e*
gsl_sf_exp_err_e
cheb_eval_e*
gammastar_ser
gsl_sf_exprel_n_CF_e
exprel_n_CF
gamma_inc_Q_asymp_unif
gsl_sf_log_1plusx_mx_e
cheb_eval_e*
gsl_sf_erfc_e
cheb_eval_e*
gamma_inc_Q_series
gamma_inc_Q_CF
gamma_inc_D*
gamma_inc_F_CF
gsl_pow_3
gamma_inc_Q_large_x
gamma_inc_D*
gamma_inc_Q_CF*
gamma_inc_P_series*
gsl_sf_gamma_inc_P
gsl_sf_gamma_inc_P_e
gamma_inc_P_series*
gamma_inc_Q_asymp_unif*
gamma_inc_Q_CF*
gamma_inc_Q_large_x*
gamma_inc_P_series*
gsl_sf_lnbeta
gsl_sf_lnbeta_e
gsl_sf_lnbeta_sgn_e
isnegint
gsl_sf_gammastar_e*
gsl_sf_log_1plusx_e
cheb_eval_e*
gsl_sf_lngamma_sgn_e
lngamma_1_pade*
lngamma_2_pade*
lngamma_lanczos*
lngamma_sgn_0*
lngamma_sgn_sing*
beta_cont_frac
I'm not sure if there is a better way but here is what I do:
I created a new "Cocoa Touch Static Library" project on XCode and put in all the necessary GSL source files I needed. Set the active scheme to "iOS device" if you want to run it on iPhone (otherwise, it will only work on iPhone simulator). Then build the project and you'll get your static GSL library that works on iPhone!