Making a Task

Compiling and Linking

The steps necessary to transform SPP code into a working program are:

  1. Preprocesses SPP to Ratfor and then to Fortran

  2. Translate Ratfor to Fortran

  3. Compile Fortran to object code

  4. Link object with IRAF and system libraries resulting in executable binary

These could be performed individually and manually. However, to provide a simple and portable mechanism (remember that the goal is for IRAF to be host independent), IRAF provides tools to do this. While the tools are straightforward for simple cases, they provide the power to handle more sophisticated operations.


The mkpkg utility is used to make or update IRAF packages or libraries. It is the highest level means of compiling and linking in the IRAF environment. There is a mkpkg command available in the cl as well as the host environment. Usage is identical in either case, except that the details of when a particular argument may need to be quoted will vary depending on the command language used. It is analogous to the make utility in Unix in that it not only performs compilation and linking, but it also performs enough revision control to perform only the needed updates. While mkpkg uses several command line options to control its operation, the particular actions to perform are specified in a text file, the mkpkg file.

This section provides only the briefest introduction to mkpkg. For a complete discussion see the help pages in the cl by typing help mkpkg.

mkpkg provides two major facilities: a library update capability and a macro preprocessor. The macro preprocessor provides symbol definition and replacement, conditional execution, and a number of built-in commands. The usefulness of these facilities is enhanced by the ability of mkpkg to update entire directory trees, or to enter the hierarchy of mkpkg descriptors at any level. For example, typing mkpkg in the root directory of IRAF will make or update the entire system, whereas in the iraf$sys directory mkpkg will update only the system libraries, and in the iraf$sys/fio directory mkpkg will update only the fio portion of the system library libsys.a.

The mkpkg utility is quite simple to use to maintain small packages or libraries, despite its full complexity of the discussion which follows. The reader is encouraged to study several examples of working mkpkg files before reading further; examples will be found throughout the IRAF system. The mkpkg files for applications packages tend to be very similar to one another, and it is quite possible to successfully copy and modify the mkpkg file from another package without studying the reference information given here. A very simple mkpkg file is shown below:

$omake imtoal.x 
$link imtoal.o 
This will compile and link the SPP program in the file named imtoal.x, resulting in an executable program in the file imtoal.e. Note the $ characters beginning the lines. The source file (imtoal.x) is assumed to have a task statement. This type of mkpkg file would be used for the most simple applications with a small number of procedures in one or at most a few source files and requiring no libraries other than the IRAF system libraries. A slightly more complicated example (
Example 4.3) maintains a library for a small package of tasks.

This introduces two features of mkpkg: calling modules and maintaining a library. The $call statement allows different blocks of statements to be executed. These are named by labels terminated by a colon. Note that each module block must terminate with a semicolon. Otherwise, the following block will also be executed. A block may also be called directly as an entry point by specifying the label name on the mkpkg command line, for example:

mkpkg update 
The $update command maintains the library of procedures for the package (tutor in this case). The label tutor.a delimits the "dependencies" section which lists include files used by each source file. A source file will be compiled if either the source itself or any of the include files upon which it depends has changed since the last update. Note also the -o option on the $link statement, specifying the name of the output executable binary file. A library may include references to libraries in other directories, using the @ syntax. These are mkpkg file in the specified directory. A $link statement may reference other libraries in addition to the implicit IRAF system libraries and local libraries defined in the current mkpkg. If these reside in the IRAF system (or an external package) library directory, they may be referenced using a -l prefix. For example:

$link x_stplot.o stplot.a -ltbtables -lxtools -o xx_stplot.e
Most often, an installed package will maintain binary executables in a common directory. These are maintained using mkpkg with the $move command:

$move xx_stplot.e stsdasbin$x_stplot.e 
This example is from the STSDAS external package, hence the symbol stsdasbin pointing to the location of the binary. Note that the executable is renamed in the move. The original has a prefix xx_ while the target file has the prefix x_. This is conventional for tasks installed in packages. This permits the package to be remade without disturbing the installed binary until necessary. Even though the binaries are installed in a directory separate from the package directory, the tasks are defined pointing to the package directory as the location of the executable.


The xc utility is a machine independent program for compiling and linking IRAF tasks or files. The xc utility may also be used to compile or link non-IRAF files and tasks. The VMS version of xc supports all of the important flags except -D which VMS C doesn't support in any way. It can be used to generate Fortran from SPP or Ratfor code, to compile any number of files, and then link them if desired. xc accepts and maps IRAF virtual filenames, but since it is a standalone utility (i.e., it need not run in the cl), the environment is not passed, hence logical names for directories cannot be used. Table 4.1 shows the IRAF virtual file name extensions that are supported by xc:

Table 4.1: XC-supported Virtual File Name Extensions.

xc is available both in the cl, via the foreign task interface, and as a standalone task callable in the host system. Usage is equivalent in either case. The simple example below compiles and links the source file mytask.x to produce the executable mytask.e.

xc mytask.x 
The next example compiles but does not link mytask.x and the support file util.x.

xc -c file.x util.x 
Now link these for debugging and link in the library libdeboor.a (the DeBoor spline routines in the lib directory).

xc -x file.o util.o -ldeboor 
xc is often combined with mkpkg to automatically maintain large packages or libraries. For complete information on xc see the help pages in the cl by typing help xc.

Generic Preprocessor

The generic preprocessor is provided in addition to SPP to convert a generic operator into a set of type specific operators. Since Fortran requires that the data types of the calling and called procedure arguments match, it is the programmer's responsibility to ensure this. The generi preprocessor makes this easier. By coding only generic operators, the programmer only has to maintain a single piece of code, reducing the possibility of an error, and greatly reducing the amount of work.

Note that this section is taken substantially verbatim from the help text for the generic task. Type help generic in the cl to see it. The term "operator" here in general refers to an SPP procedure or function. The generic preprocessor takes as input files written in either the IRAF SPP language or C with embedded preprocessor directives and keywords. The calling sequence for the preprocessor (on the Unix system) is as follows:

generic [-t types] [-p prefix] [-o outfile] file [file...] 
Any number of files may be processed.


The following (optional) flags are provided to control the types and names of the generated files:


The action of the preprocessor is directed by placing $xxx directives in the text to be processed. The identifiers INDEF and PIXEL are also known to the preprocessor, and will be replaced by their type specific equivalents. INDEF will be replaced by INDEFS, INDEFI, etc., and PIXEL will be replaced by short, int, real, etc. in the generated text. Comments (#... or /*...*/), quoted strings ("...") and
escaped lines (^%) are passed on unchanged.

The generic operator shown in Example 4.4 computes the square root of a vector. The members of the generic family would be called asqrs, asqri, and so on.

The operators are explained in the following list.

Nesting is permitted. Conditional statements need not be left justified, i.e., white space may be placed between the beginning of the line (BOL) and a $xx preprocessor directive.

Doubly Generic Operators

The preprocessor can also be used to generate doubly generic operators (operators which have two type suffixes). A good example is the type conversion operator achtxy, which converts a vector of type x to a vector of type y. If there are seven datatypes (c, s, i, l, r, d, x), this generic family will consist of 49 members. Doubly generic programs are preprocessed once to expand the first suffix, then each file generated by the first pass is processed to expand the second suffix. On the Unix system, this might be done by a command such as

generic acht.x; generic -p dir/ acht[silrd].x 
rm acht[silrd].x 
This would expand acht in the current directory (generating five files), then expand each of the acht$t files in the subdirectory dir/, creating a total of 25 files in the subdirectory. The final command removes the 5 intermediate files.

For an example of double generic code, see source for the vops procedure family acht() in vops$acht.gx.

Parameter Files

Each logical task that reads parameters from the cl using clio may specify attributes of those parameters using a parameter file. Parameter attributes include the name, data type, default value, and others. The file is a text file created by the programmer and should be located in the same directory as the physical task. There is one parameter file for each logical task. Its root name is the same as the name of the associated logical task and there is an extension .par. Each task parameter is described by an entry in the parameter file consisting of positional fields separated by commas:

All of the fields after value are optional. Fields may be omitted with adjacent commas.

Table 4.2: cl Parameter Data Types.

Note that there is no distinction between sizes of numeric parameters; i.e., there is no concept of a "short" integer or a "double precision" floating point parameter. The character * preceding a type attribute indicates a "list structured" parameter. The cursor parameters must be declared as list structured: *gcur and *imcur. A pset specifies a pointer to another parameter file. See the document Named External Parameter Sets in the CL [Tody86] for a complete description (on line in the IRAF file doc$

"Graphics color" 
There are other fields as well that are slightly beyond this brief explanation. For a more detailed explanation of parameter files and parameter fields, see the CL Programmer's Manual [Downey82], a copy of which is on line in the file iraf$doc/

Table 4.1: - XC-supported Virtual File Name Extensions.
Generic Preprocessor
Doubly Generic Operators
Parameter Files
Table 4.2: - cl Parameter Data Types.

Generated with CERN WebMaker