Go to the first, previous, next, last section, table of contents.
This chapter describes how to compile programs that use GSL, and introduces its conventions.
The library is written in ANSI C and is intended to conform to the ANSI C standard. It should be portable to any system with a working ANSI C compiler.
The library does not rely on any non-ANSI extensions in the interface it exports to the user. Programs you write using GSL can be ANSI compliant. Extensions which can be used in a way compatible with pure ANSI C are supported, however, via conditional compilation. This allows the library to take advantage of compiler extensions on those platforms which support them.
When an ANSI C feature is known to be broken on a particular system the library will exclude any related functions at compile-time. This should make it impossible to link a program that would use these functions and give incorrect results.
To avoid namespace conflicts all exported function names and variables
have the prefix
gsl_, while exported macros have the prefix
The library header files are installed in their own `gsl' directory. You should write any preprocessor include statements with a `gsl/' directory prefix thus,
If the directory is not installed on the standard search path of your
compiler you will also need to provide its location to the preprocessor
as a command line flag. The default location of the `gsl'
directory is `/usr/local/include/gsl'. A typical compilation
command for a source file `app.c' with the GNU C compiler
gcc -I/usr/local/include -c app.c
This results in an object file `app.o'. The default
include path for
gcc searches `/usr/local/include' automatically so
-I option can be omitted when GSL is installed in its default
The library is installed as a single file, `libgsl.a'. A shared version of the library is also installed on systems that support shared libraries. The default location of these files is `/usr/local/lib'. To link against the library you need to specify both the main library and a supporting CBLAS library, which provides standard basic linear algebra subroutines. A suitable CBLAS implementation is provided in the library `libgslcblas.a' if your system does not provide one. The following example shows how to link an application with the library,
gcc app.o -lgsl -lgslcblas -lm
The following command line shows how you would link the same application with an alternative blas library called `libcblas',
gcc app.o -lgsl -lcblas -lm
For the best performance an optimized platform-specific CBLAS
library should be used for
-lcblas. The library must conform to
the CBLAS standard. The ATLAS package provides a portable
high-performance BLAS library with a CBLAS interface. It is
free software and should be installed for any work requiring fast vector
and matrix operations. The following command line will link with the
ATLAS library and its CBLAS interface,
gcc app.o -lgsl -lcblas -latlas -lm
For more information see section BLAS Support.
gsl-config provides information on the local version
of the library. For example, the following command shows that the
library has been installed under the directory `/usr/local',
bash$ gsl-config --prefix /usr/local
Further information is available using the command
To run a program linked with the shared version of the library it may be
necessary to define the shell variable
LD_LIBRARY_PATH to include
the directory where the library is installed. For example,
To compile a statically linked version of the program instead, use the
-static flag in
gcc -static app.o -lgsl -lgslcblas -lm
For applications using
autoconf the standard macro
AC_CHECK_LIB can be used to link with the library automatically
configure script. The library itself depends on the
presence of a CBLAS and math library as well, so these must also be
located before linking with the main
libgsl file. The following
commands should be placed in the `configure.in' file to perform
AC_CHECK_LIB(m,main) AC_CHECK_LIB(gslcblas,main) AC_CHECK_LIB(gsl,main)
Assuming the libraries are found the output during the configure stage looks like this,
checking for main in -lm... yes checking for main in -lgslcblas... yes checking for main in -lgsl... yes
If the library is found then the tests will define the macros
HAVE_LIBM and add
-lgsl -lgslcblas -lm to the variable
The tests above will find any version of the library. They are suitable for general use, where the versions of the functions are not important. An alternative macro is available in the file `gsl.m4' to test for a specific version of the library. To use this macro simply add the following line to your `configure.in' file instead of the tests above:
AM_PATH_GSL(GSL_VERSION, [action-if-found], [action-if-not-found])
GSL_VERSION should be the two or three digit
MAJOR.MINOR or MAJOR.MINOR.MICRO version number of the release
you require. A suitable choice for
AC_MSG_ERROR(could not find required version of GSL)
Then you can add the variables
your Makefile.am files to obtain the correct compiler flags.
GSL_LIBS is equal to the output of the
GSL_CFLAGS is equal to
command. For example,
libgsdv_la_LDFLAGS = \ $(GTK_LIBDIR) \ $(GTK_LIBS) -lgsdvgsl $(GSL_LIBS) -lgslcblas
Note that the macro
AM_PATH_GSL needs to use the C compiler so it
should appear in the `configure.in' file before the macro
AC_LANG_CPLUSPLUS for programs that use C++.
inline keyword is not part of ANSI C and the library does not
export any inline function definitions by default. However, the library
provides optional inline versions of performance-critical functions by
conditional compilation. The inline versions of these functions can be
included by defining the macro
HAVE_INLINE when compiling an
gcc -c -DHAVE_INLINE app.c
If you use
autoconf this macro can be defined automatically.
The following test should be placed in your `configure.in' file,
AC_C_INLINE if test "$ac_cv_c_inline" != no ; then AC_DEFINE(HAVE_INLINE,1) AC_SUBST(HAVE_INLINE) fi
and the macro will then be defined in the compilation flags or by
including the file `config.h' before any library headers. If you
do not define the macro
HAVE_INLINE then the slower non-inlined
versions of the functions will be used instead.
Note that the actual usage of the inline keyword is
inline, which eliminates unnecessary function definitions in GCC.
If the form
extern inline causes problems with other compilers a
stricter autoconf test can be used, see section Autoconf Macros.
The extended numerical type
long double is part of the ANSI C
standard and should be available in every modern compiler. However, the
long double is platform dependent, and this should
be considered when using it. The IEEE standard only specifies the
minimum precision of extended precision numbers, while the precision of
double is the same on all platforms.
In some system libraries the
stdio.h formatted input/output
scanf are not implemented correctly
long double. Undefined or incorrect results are avoided by
testing these functions during the
configure stage of library
compilation and eliminating certain GSL functions which depend on them
if necessary. The corresponding line in the
looks like this,
checking whether printf works with long double... no
long double formatted input/output does not
work on a given system it should be impossible to link a program which
uses GSL functions dependent on this.
If it is necessary to work on a system which does not support formatted
long double input/output then the options are to use binary
formats or to convert
long double results into
reading and writing.
To help in writing portable applications GSL provides some
implementations of functions that are found in other libraries, such as
the BSD math library. You can write your application to use the native
versions of these functions, and substitute the GSL versions via a
preprocessor macro if they are unavailable on another platform. The
substitution can be made automatically if you use
example, to test whether the BSD function
hypot is available you
can include the following line in the configure file `configure.in'
for your application,
and place the following macro definitions in the file `config.h.in',
/* Substitute gsl_hypot for missing system hypot */ #ifndef HAVE_HYPOT #define hypot gsl_hypot #endif
The application source files can then use the include command
#include <config.h> to substitute
gsl_hypot for each
hypot is not available.
In most circumstances the best strategy is to use the native versions of these functions when available, and fall back to GSL versions otherwise, since this allows your application to take advantage of any platform-specific optimizations in the system library. This is the strategy used within GSL itself.
The main implementation of some functions in the library will not be optimal on all architectures. For example, there are several ways to compute a Gaussian random variate and their relative speeds are platform-dependent. In cases like this the library provides alternate implementations of these functions with the same interface. If you write your application using calls to the standard implementation you can select an alternative version later via a preprocessor definition. It is also possible to introduce your own optimized functions this way while retaining portability. The following lines demonstrate the use of a platform-dependent choice of methods for sampling from the Gaussian distribution,
#ifdef SPARC #define gsl_ran_gaussian gsl_ran_gaussian_ratio_method #endif #ifdef INTEL #define gsl_ran_gaussian my_gaussian #endif
These lines would be placed in the configuration header file `config.h' of the application, which should then be included by all the source files. Note that the alternative implementations will not produce bit-for-bit identical results, and in the case of random number distributions will produce an entirely different stream of random variates.
Many functions in the library are defined for different numeric types.
This feature is implemented by varying the name of the function with a
type-related modifier -- a primitive form of C++ templates. The
modifier is inserted into the function name after the initial module
prefix. The following table shows the function names defined for all
the numeric types of an imaginary module
gsl_foo with function
gsl_foo_fn double gsl_foo_long_double_fn long double gsl_foo_float_fn float gsl_foo_long_fn long gsl_foo_ulong_fn unsigned long gsl_foo_int_fn int gsl_foo_uint_fn unsigned int gsl_foo_short_fn short gsl_foo_ushort_fn unsigned short gsl_foo_char_fn char gsl_foo_uchar_fn unsigned char
The normal numeric precision
double is considered the default and
does not require a suffix. For example, the function
gsl_stats_mean computes the mean of double precision numbers,
while the function
gsl_stats_int_mean computes the mean of
A corresponding scheme is used for library defined types, such as
gsl_matrix. In this case the modifier is
appended to the type name. For example, if a module defines a new
type-dependent struct or typedef
gsl_foo it is modified for other
types in the following way,
gsl_foo double gsl_foo_long_double long double gsl_foo_float float gsl_foo_long long gsl_foo_ulong unsigned long gsl_foo_int int gsl_foo_uint unsigned int gsl_foo_short short gsl_foo_ushort unsigned short gsl_foo_char char gsl_foo_uchar unsigned char
When a module contains type-dependent definitions the library provides individual header files for each type. The filenames are modified as shown in the below. For convenience the default header includes the definitions for all the types. To include only the double precision header, or any other specific type, file use its individual filename.
#include <gsl/gsl_foo.h> All types #include <gsl/gsl_foo_double.h> double #include <gsl/gsl_foo_long_double.h> long double #include <gsl/gsl_foo_float.h> float #include <gsl/gsl_foo_long.h> long #include <gsl/gsl_foo_ulong.h> unsigned long #include <gsl/gsl_foo_int.h> int #include <gsl/gsl_foo_uint.h> unsigned int #include <gsl/gsl_foo_short.h> short #include <gsl/gsl_foo_ushort.h> unsigned short #include <gsl/gsl_foo_char.h> char #include <gsl/gsl_foo_uchar.h> unsigned char
The library header files automatically define functions to have
extern "C" linkage when included in C++ programs.
The library assumes that arrays, vectors and matrices passed as
modifiable arguments are not aliased and do not overlap with each other.
This removes the need for the library to handle overlapping memory
regions as a special case, and allows additional optimizations to be
used. If overlapping memory regions are passed as modifiable arguments
then the results of such functions will be undefined. If the arguments
will not be modified (for example, if a function prototype declares them
const arguments) then overlapping or aliased memory regions
can be safely used.
The library can be used in multi-threaded programs. All the functions
are thread-safe, in the sense that they do not use static variables.
Memory is always associated with objects and not with functions. For
functions which use workspace objects as temporary storage the
workspaces should be allocated on a per-thread basis. For functions
which use table objects as read-only memory the tables can be used
by multiple threads simultaneously. Table arguments are always declared
const in function prototypes, to indicate that they may be
safely accessed by different threads.
There are a small number of static global variables which are used to control the overall behavior of the library (e.g. whether to use range-checking, the function to call on fatal error, etc). These variables are set directly by the user, so they should be initialized once at program startup and not modified by different threads.
Where possible the routines in the library have been written to avoid
dependencies between modules and files. This should make it possible to
extract individual functions for use in your own applications, without
needing to have the whole library installed. You may need to define
certain macros such as
GSL_ERROR and remove some
statements in order to compile the files as standalone units. Reuse of
the library code in this way is encouraged, subject to the terms of the
GNU General Public License.
Go to the first, previous, next, last section, table of contents.