Chapter 2 Creating the CFITSIO Library
2.1 Building the Library
The CFITSIO code is contained in about 40 C source files (*.c) and header
files (*.h). On VAX/VMS systems 2 assembly-code files (vmsieeed.mar and
vmsieeer.mar) are also needed.
CFITSIO has currently been tested on the following platforms:
OPERATING SYSTEM COMPILER
Sun OS gcc and cc (3.0.1)
Sun Solaris gcc and cc
Silicon Graphics IRIX gcc and cc
Silicon Graphics IRIX64 MIPS
Dec Alpha OSF/1 gcc and cc
DECstation Ultrix gcc
Dec Alpha OpenVMS cc
DEC VAX/VMS gcc and cc
HP-UX gcc
IBM AIX gcc
Linux gcc
MkLinux DR3
Windows 95/98/NT Borland C++ V4.5
Windows 95/98/NT/ME/XP Microsoft/Compaq Visual C++ v5.0, v6.0
Windows 95/98/NT Cygwin gcc
MacOS 7.1 or greater Metrowerks 10.+
MacOS-X 10.1 or greater cc (gcc)
CFITSIO will probably run on most other Unix platforms. Cray
supercomputers are currently not supported.
2.1.1 Unix Systems
The CFITSIO library is built on Unix systems by typing:
> ./configure [--prefix=/target/installation/path]
> make (or 'make shared')
> make install (this step is optional)
at the operating system prompt. The configure command customizes the
Makefile for the particular system, then the `make' command compiles the
source files and builds the library. Type `./configure' and not simply
`configure' to ensure that the configure script in the current directory
is run and not some other system-wide configure script. The optional
'prefix' argument to configure gives the path to the directory where
the CFITSIO library and include files should be installed via the later
'make install' command. For example,
> ./configure --prefix=/usr1/local
will cause the 'make install' command to copy the CFITSIO libcfitsio file
to /usr1/local/lib and the necessary include files to /usr1/local/include
(assuming of course that the process has permission to write to these
directories).
The 'make shared' option builds a shared or dynamic version of the
CFITSIO library. When using the shared library the executable code is
not copied into your program at link time and instead the program
locates the necessary library code at run time, normally through
LD_LIBRARY_PATH or some other method. The advantages of using a shared
library are:
1. Less disk space if you build more than 1 program
2. Less memory if more than one copy of a program using the shared
library is running at the same time since the system is smart
enough to share copies of the shared library at run time.
3. Possibly easier maintenance since a new version of the shared
library can be installed without relinking all the software
that uses it (as long as the subroutine names and calling
sequences remain unchanged).
4. No run-time penalty.
The disadvantages are:
1. More hassle at runtime. You have to either build the programs
specially or have LD_LIBRARY_PATH set right.
2. There may be a slight start up penalty, depending on where you are
reading the shared library and the program from and if your CPU is
either really slow or really heavily loaded.
On Mac OS X platforms the 'make shared' command works like on other
UNIX platforms, but a .dylib file will be created instead of .so. If
installed in a nonstandard location, add its location to the
DYLD_LIBRARY_PATH environment variable so that the library can be found
at run time.
On HP/UX systems, the environment variable CFLAGS should be set
to -Ae before running configure to enable "extended ANSI" features.
By default, a set of Fortran-callable wrapper routines are
also built and included in the CFITSIO library. If these wrapper
routines are not needed (i.e., the CFITSIO library will not
be linked to any Fortran applications which call FITSIO subroutines)
then they may be omitted from the build by typing 'make all-nofitsio'
instead of simply typing 'make'. This will reduce the size
of the CFITSIO library slightly.
Most 32-bit operating systems have only supported disk files up to
2.1GB (2**31 bytes) in size. Starting with version 2.1 of CFITSIO,
FITS files larger than this limit (up to 6 terabytes) can be read and
written on platforms which support large files (e.g., Solaris). To
enable this feature, CFITSIO must be compiled with the
`-D_FILE_OFFSET_BITS=64' compiler flag. All programs which link to
the CFITSIO library must also be compiled with this flag or must
include this preprocessor definition at the start of the source code
file. See the `CFITSIO Size Limitations' section in Chapter 4 for
further details.
It may not be possible to staticly link programs that use CFITSIO on
some platforms (namely, on Solaris 2.6) due to the network drivers
(which provide FTP and HTTP access to FITS files). It is possible to
make both a dynamic and a static version of the CFITSIO library, but
network file access will not be possible using the static version.
On VAX/VMS and ALPHA/VMS systems the make_gfloat.com command file may
be executed to build the cfitsio.olb object library using the default
G-floating point option for double variables. The make_dfloat.com and
make_ieee.com files may be used instead to build the library with the
other floating point options. Note that the getcwd function that is
used in the group.c module may require that programs using CFITSIO be
linked with the ALPHA$LIBRARY:VAXCRTL.OLB library. See the example
link line in the next section of this document.
2.1.3 Windows PCs
A precompiled DLL version of CFITSIO is available for IBM-PC users of
the Borland or Microsoft Visual C++ compilers in the files
cfitsiodll_2xxx_borland.zip and cfitsiodll_2xxx_vcc.zip, where
'2xxx' represents the current release number. These zip archives also
contains other files and instructions on how to use the CFITSIO DLL
library.
The CFITSIO library may also be built from the source code using the
makefile.bc or makefile.vcc files. Finally, the makepc.bat file gives
an example of building CFITSIO with the Borland C++ v4.5 compiler
using older DOS commands.
2.1.4 Macintosh PCs
When building on Mac OS-X, users should follow the Unix instructions,
above.
The classic MacOS version (OS 9 or earlier) of the CFITSIO library can
be built by (1) un binhex and unstuff cfitsio_mac.sit.hqx, (2) put
CFitsioPPC.mcp in the cfitsio directory, and (3) load CFitsioPPC.mcp
into CodeWarrior Pro 5 and make. This builds the CFITSIO library for
PPC. There are also targets for both the test program and the speed
test program.
To use the MacOS port you can add Cfitsio PPC.lib to your CodeWarrior
Pro 5 project. Note that this only has been tested for the PPC and
probably won't work on 68k Macs.
2.2 Testing the Library
The CFITSIO library should be tested by building and running
the testprog.c program that is included with the release.
On Unix systems, type:
% make testprog
% testprog > testprog.lis
% diff testprog.lis testprog.out
% cmp testprog.fit testprog.std
On VMS systems,
(assuming cc is the name of the C compiler command), type:
$ cc testprog.c
$ link testprog, cfitsio/lib, alpha$library:vaxcrtl/lib
$ run testprog
The test program should produce a FITS file called `testprog.fit'
that is identical to the `testprog.std' FITS file included with this
release. The diagnostic messages (which were piped to the file
testprog.lis in the Unix example) should be identical to the listing
contained in the file testprog.out. The 'diff' and 'cmp' commands
shown above should not report any differences in the files. (There
may be some minor format differences, such as the presence or
absence of leading zeros, or 3 digit exponents in numbers,
which can be ignored).
The Fortran wrappers in CFITSIO may be tested with the testf77
program on Unix systems with:
% f77 -o testf77 testf77.f -L. -lcfitsio -lnsl -lsocket
or
% f77 -f -o testf77 testf77.f -L. -lcfitsio (under SUN O/S)
or
% f77 -o testf77 testf77.f -Wl,-L. -lcfitsio -lm -lnsl -lsocket (HP/UX)
% testf77 > testf77.lis
% diff testf77.lis testf77.out
% cmp testf77.fit testf77.std
On machines running SUN O/S, Fortran programs must be compiled with the
'-f' option to force double precision variables to be aligned on 8-byte
boundarys to make the fortran-declared variables compatible with C. A
similar compiler option may be required on other platforms. Failing to
use this option may cause the program to crash on FITSIO routines that
read or write double precision variables.
Also note that on some systems, the output listing of the testf77
program may differ slightly from the testf77.std template, if leading
zeros are not printed by default before the decimal point when using F
format.
A few other utility programs are included with CFITSIO; the first four
of this programs can be compiled an linked by typing `make
program_name' where `program_name' is the actual name of the program:
speed - measures the maximum throughput (in MB per second)
for writing and reading FITS files with CFITSIO.
listhead - lists all the header keywords in any FITS file
fitscopy - copies any FITS file (especially useful in conjunction
with the CFITSIO's extended input filename syntax).
cookbook - a sample program that performs common read and
write operations on a FITS file.
iter_a, iter_b, iter_c - examples of the CFITSIO iterator routine
2.3 Linking Programs with CFITSIO
When linking applications software with the CFITSIO library, several
system libraries usually need to be specified on the link command
line. On Unix systems, the most reliable way to determine what
libraries are required is to type 'make testprog' and see what
libraries the configure script has added. The typical libraries that
need to be added are -lm (the math library) and -lnsl and -lsocket
(needed only for FTP and HTTP file access). These latter 2 libraries
are not needed on VMS and Windows platforms, because FTP file access is
not currently supported on those platforms.
Note that when upgrading to a newer version of CFITSIO it is usually
necessary to recompile, as well as relink, the programs that use CFITSIO,
because the definitions in fitsio.h often change.
2.4 Getting Started with CFITSIO
In order to effectively use the CFITSIO library it is recommended that
new users begin by reading the ``CFITSIO Quick Start Guide''. It
contains all the basic information needed to write programs that
perform most types of operations on FITS files. The set of example
FITS utility programs that are available from the CFITSIO web site are
also very useful for learning how to use CFITSIO. To learn even more
about the capabilities of the CFITSIO library the following steps are
recommended:
1. Read the following short `FITS Primer' chapter for an overview of
the structure of FITS files.
2. Review the Programming Guidelines in Chapter 4 to become familiar
with the conventions used by the CFITSIO interface.
3. Refer to the cookbook.c, listhead.c, and fitscopy.c programs that
are included with this release for examples of routines that perform
various common FITS file operations. Type 'make program_name' to
compile and link these programs on Unix systems.
4. Write a simple program to read or write a FITS file using the Basic
Interface routines described in Chapter 5.
5. Scan through the more specialized routines that are described in
the following chapters to become familiar with the functionality that
they provide.
2.5 Example Program
The following listing shows an example of how to use the CFITSIO
routines in a C program. Refer to the cookbook.c program that is
included with the CFITSIO distribution for other example routines.
This program creates a new FITS file, containing a FITS image. An
`EXPOSURE' keyword is written to the header, then the image data are
written to the FITS file before closing the FITS file.
#include "fitsio.h" /* required by every program that uses CFITSIO */
main()
{
fitsfile *fptr; /* pointer to the FITS file; defined in fitsio.h */
int status, ii, jj;
long fpixel = 1, naxis = 2, nelements, exposure;
long naxes[2] = { 300, 200 }; /* image is 300 pixels wide by 200 rows */
short array[200][300];
status = 0; /* initialize status before calling fitsio routines */
fits_create_file(&fptr, "testfile.fits", &status); /* create new file */
/* Create the primary array image (16-bit short integer pixels */
fits_create_img(fptr, SHORT_IMG, naxis, naxes, &status);
/* Write a keyword; must pass the ADDRESS of the value */
exposure = 1500.;
fits_update_key(fptr, TLONG, "EXPOSURE", &exposure,
"Total Exposure Time", &status);
/* Initialize the values in the image with a linear ramp function */
for (jj = 0; jj < naxes[1]; jj++)
for (ii = 0; ii < naxes[0]; ii++)
array[jj][ii] = ii + jj;
nelements = naxes[0] * naxes[1]; /* number of pixels to write */
/* Write the array of integers to the image */
fits_write_img(fptr, TSHORT, fpixel, nelements, array[0], &status);
fits_close_file(fptr, &status); /* close the file */
fits_report_error(stderr, status); /* print out any error messages */
return( status );
}