| @cindex standards conformance, ANSI C |
| @cindex ANSI C, use of |
| @cindex C extensions, compatible use of |
| @cindex compatibility |
| This chapter describes how to compile programs that use GSL, and |
| introduces its conventions. |
| |
| @menu |
| * An Example Program:: |
| * Compiling and Linking:: |
| * Shared Libraries:: |
| * ANSI C Compliance:: |
| * Inline functions:: |
| * Long double:: |
| * Portability functions:: |
| * Alternative optimized functions:: |
| * Support for different numeric types:: |
| * Compatibility with C++:: |
| * Aliasing of arrays:: |
| * Thread-safety:: |
| * Deprecated Functions:: |
| * Code Reuse:: |
| @end menu |
| |
| @node An Example Program |
| @section An Example Program |
| |
| The following short program demonstrates the use of the library by |
| computing the value of the Bessel function @math{J_0(x)} for @math{x=5}, |
| |
| @example |
| @verbatiminclude examples/intro.c |
| @end example |
| |
| @noindent |
| The output is shown below, and should be correct to double-precision |
| accuracy, |
| |
| @example |
| @verbatiminclude examples/intro.out |
| @end example |
| |
| @noindent |
| The steps needed to compile this program are described in the following |
| sections. |
| |
| @node Compiling and Linking |
| @section Compiling and Linking |
| @cindex compiling programs, include paths |
| @cindex including GSL header files |
| @cindex header files, including |
| The library header files are installed in their own @file{gsl} |
| directory. You should write any preprocessor include statements with a |
| @file{gsl/} directory prefix thus, |
| |
| @example |
| #include <gsl/gsl_math.h> |
| @end example |
| |
| @noindent |
| 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 @file{gsl} |
| directory is @file{/usr/local/include/gsl}. A typical compilation |
| command for a source file @file{example.c} with the GNU C compiler |
| @code{gcc} is, |
| |
| @example |
| $ gcc -Wall -I/usr/local/include -c example.c |
| @end example |
| |
| @noindent |
| This results in an object file @file{example.o}. The default |
| include path for @code{gcc} searches @file{/usr/local/include} automatically so |
| the @code{-I} option can actually be omitted when GSL is installed |
| in its default location. |
| |
| @menu |
| * Linking programs with the library:: |
| * Linking with an alternative BLAS library:: |
| @end menu |
| |
| @node Linking programs with the library |
| @subsection Linking programs with the library |
| @cindex compiling programs, library paths |
| @cindex linking with GSL libraries |
| @cindex libraries, linking with |
| The library is installed as a single file, @file{libgsl.a}. A shared |
| version of the library @file{libgsl.so} is also installed on systems |
| that support shared libraries. The default location of these files is |
| @file{/usr/local/lib}. If this directory is not on the standard search |
| path of your linker you will also need to provide its location as a |
| command line flag. |
| |
| To link against the library you need to specify |
| both the main library and a supporting @sc{cblas} library, which |
| provides standard basic linear algebra subroutines. A suitable |
| @sc{cblas} implementation is provided in the library |
| @file{libgslcblas.a} if your system does not provide one. The following |
| example shows how to link an application with the library, |
| |
| @example |
| $ gcc -L/usr/local/lib example.o -lgsl -lgslcblas -lm |
| @end example |
| |
| @noindent |
| The default library path for @code{gcc} searches @file{/usr/local/lib} |
| automatically so the @code{-L} option can be omitted when GSL is |
| installed in its default location. |
| |
| @node Linking with an alternative BLAS library |
| @subsection Linking with an alternative BLAS library |
| |
| The following command line shows how you would link the same application |
| with an alternative @sc{cblas} library called @file{libcblas}, |
| |
| @example |
| $ gcc example.o -lgsl -lcblas -lm |
| @end example |
| |
| @noindent |
| For the best performance an optimized platform-specific @sc{cblas} |
| library should be used for @code{-lcblas}. The library must conform to |
| the @sc{cblas} standard. The @sc{atlas} package provides a portable |
| high-performance @sc{blas} library with a @sc{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 |
| @sc{atlas} library and its @sc{cblas} interface, |
| |
| @example |
| $ gcc example.o -lgsl -lcblas -latlas -lm |
| @end example |
| |
| @noindent |
| For more information see @ref{BLAS Support}. |
| |
| @comment The program @code{gsl-config} provides information on the local version |
| @comment of the library. For example, the following command shows that the |
| @comment library has been installed under the directory @file{/usr/local}, |
| |
| @comment @example |
| @comment $ gsl-config --prefix |
| @comment /usr/local |
| @comment @end example |
| @comment @noindent |
| @comment Further information is available using the command @code{gsl-config --help}. |
| |
| @node Shared Libraries |
| @section Shared Libraries |
| @cindex shared libraries |
| @cindex libraries, shared |
| @cindex LD_LIBRARY_PATH |
| To run a program linked with the shared version of the library the |
| operating system must be able to locate the corresponding @file{.so} |
| file at runtime. If the library cannot be found, the following error |
| will occur: |
| |
| @example |
| $ ./a.out |
| ./a.out: error while loading shared libraries: |
| libgsl.so.0: cannot open shared object file: No such |
| file or directory |
| @end example |
| |
| @noindent |
| To avoid this error, define the shell variable @code{LD_LIBRARY_PATH} to |
| include the directory where the library is installed. |
| |
| For example, in the Bourne shell (@code{/bin/sh} or @code{/bin/bash}), |
| the library search path can be set with the following commands: |
| |
| @example |
| $ LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH |
| $ export LD_LIBRARY_PATH |
| $ ./example |
| @end example |
| |
| @noindent |
| In the C-shell (@code{/bin/csh} or @code{/bin/tcsh}) the equivalent |
| command is, |
| |
| @example |
| % setenv LD_LIBRARY_PATH /usr/local/lib:$LD_LIBRARY_PATH |
| @end example |
| |
| @noindent |
| The standard prompt for the C-shell in the example above is the percent |
| character @samp{%}, and should not be typed as part of the command. |
| |
| To save retyping these commands each session they should be placed in an |
| individual or system-wide login file. |
| |
| To compile a statically linked version of the program, use the |
| @code{-static} flag in @code{gcc}, |
| |
| @example |
| $ gcc -static example.o -lgsl -lgslcblas -lm |
| @end example |
| |
| @node ANSI C Compliance |
| @section ANSI C Compliance |
| |
| The library is written in ANSI C and is intended to conform to the ANSI |
| C standard (C89). 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 @code{gsl_}, while exported macros have the prefix |
| @code{GSL_}. |
| |
| @node Inline functions |
| @section Inline functions |
| |
| @cindex inline functions |
| @cindex HAVE_INLINE |
| The @code{inline} keyword is not part of the original ANSI C standard |
| (C89) 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 |
| @code{HAVE_INLINE} when compiling an application, |
| |
| @example |
| $ gcc -Wall -c -DHAVE_INLINE example.c |
| @end example |
| |
| @noindent |
| If you use @code{autoconf} this macro can be defined automatically. If |
| you do not define the macro @code{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 @code{extern |
| inline}, which eliminates unnecessary function definitions in @sc{gcc}. |
| If the form @code{extern inline} causes problems with other compilers a |
| stricter autoconf test can be used, see @ref{Autoconf Macros}. |
| |
| @node Long double |
| @section Long double |
| @cindex long double |
| The extended numerical type @code{long double} is part of the ANSI C |
| standard and should be available in every modern compiler. However, the |
| precision of @code{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 |
| @code{double} is the same on all platforms. |
| |
| In some system libraries the @code{stdio.h} formatted input/output |
| functions @code{printf} and @code{scanf} are not implemented correctly |
| for @code{long double}. Undefined or incorrect results are avoided by |
| testing these functions during the @code{configure} stage of library |
| compilation and eliminating certain GSL functions which depend on them |
| if necessary. The corresponding line in the @code{configure} output |
| looks like this, |
| |
| @example |
| checking whether printf works with long double... no |
| @end example |
| |
| @noindent |
| Consequently when @code{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 |
| @code{long double} input/output then the options are to use binary |
| formats or to convert @code{long double} results into @code{double} for |
| reading and writing. |
| |
| @node Portability functions |
| @section Portability functions |
| |
| 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. |
| |
| For example, after determining whether the BSD function @code{hypot} is |
| available you can include the following macro definitions in a file |
| @file{config.h} with your application, |
| |
| @example |
| /* Substitute gsl_hypot for missing system hypot */ |
| |
| #ifndef HAVE_HYPOT |
| #define hypot gsl_hypot |
| #endif |
| @end example |
| |
| @noindent |
| The application source files can then use the include command |
| @code{#include <config.h>} to replace each occurrence of @code{hypot} by |
| @code{gsl_hypot} when @code{hypot} is not available. This substitution |
| can be made automatically if you use @code{autoconf}, see @ref{Autoconf |
| Macros}. |
| |
| 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. |
| |
| @node Alternative optimized functions |
| @section Alternative optimized functions |
| |
| @cindex alternative optimized functions |
| @cindex optimized functions, alternatives |
| 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 alternative |
| 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, |
| |
| @example |
| #ifdef SPARC |
| #define gsl_ran_gaussian gsl_ran_gaussian_ratio_method |
| #endif |
| #ifdef INTEL |
| #define gsl_ran_gaussian my_gaussian |
| #endif |
| @end example |
| |
| @noindent |
| These lines would be placed in the configuration header file |
| @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. |
| |
| @node Support for different numeric types |
| @section Support for different numeric types |
| |
| 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 @code{gsl_foo} with function |
| @code{fn}, |
| |
| @example |
| 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 |
| @end example |
| |
| @noindent |
| The normal numeric precision @code{double} is considered the default and |
| does not require a suffix. For example, the function |
| @code{gsl_stats_mean} computes the mean of double precision numbers, |
| while the function @code{gsl_stats_int_mean} computes the mean of |
| integers. |
| |
| A corresponding scheme is used for library defined types, such as |
| @code{gsl_vector} and @code{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 @code{gsl_foo} it is modified for other |
| types in the following way, |
| |
| @example |
| 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 |
| @end example |
| |
| @noindent |
| 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 file, or any other specific type, use its individual filename. |
| |
| @example |
| #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 |
| @end example |
| |
| @node Compatibility with C++ |
| @section Compatibility with C++ |
| @cindex C++, compatibility |
| The library header files automatically define functions to have |
| @code{extern "C"} linkage when included in C++ programs. This allows |
| the functions to be called directly from C++. |
| |
| To use C++ exception handling within user-defined functions passed to |
| the library as parameters, the library must be built with the |
| additional @code{CFLAGS} compilation option @option{-fexceptions}. |
| |
| @node Aliasing of arrays |
| @section Aliasing of arrays |
| @cindex aliasing of arrays |
| 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 |
| as @code{const} arguments) then overlapping or aliased memory regions |
| can be safely used. |
| |
| @node Thread-safety |
| @section Thread-safety |
| |
| 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 @dfn{workspace} objects as temporary storage the |
| workspaces should be allocated on a per-thread basis. For functions |
| which use @dfn{table} objects as read-only memory the tables can be used |
| by multiple threads simultaneously. Table arguments are always declared |
| @code{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. |
| |
| @node Deprecated Functions |
| @section Deprecated Functions |
| @cindex deprecated functions |
| |
| From time to time, it may be necessary for the definitions of some |
| functions to be altered or removed from the library. In these |
| circumstances the functions will first be declared @dfn{deprecated} and |
| then removed from subsequent versions of the library. Functions that |
| are deprecated can be disabled in the current release by setting the |
| preprocessor definition @code{GSL_DISABLE_DEPRECATED}. This allows |
| existing code to be tested for forwards compatibility. |
| |
| @node Code Reuse |
| @section Code Reuse |
| @cindex code reuse in applications |
| @cindex source code, reuse in applications |
| 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 @code{GSL_ERROR} and remove some @code{#include} |
| 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. |