Previous Home Contents Next

Chapter 16: Separate compilation

16.1 Multiple files

16.2 Libraries

16.3 Source code references to libraries

16.4 Importing from compiled libraries

This chapter describes how to run the Aldor compiler to produce libraries or executable programs from multiple files.



16.1 : Multiple files

Unless a program is very small, it is normal to develop it in stages and to identify parts of it for potential re-use, compiling them separately. Aldor supports separate compilation to platform-independent .ao files. These files contain type information, intermediate code and other information to allow type-safe separate compilation and cross-file optimization. These files have a portable format and it is possible to move them between machines of different architectures, with different character sets, byte orders or floating-point formats. The .ao files can be thought of as platform-independent object files, which may be imported into other Aldor programs or used to generate C or Lisp or object code for a particular platform.

Let us give a a toy example which illustrates the steps one takes to do separate compilation with the Aldor compiler. Suppose we have two files: choose.as, containing some functions, and poker.as, which uses them. These files are shown in Figure figure 16.1. The commands to compile these individual files together are:

Figure 16.1: A progam consisting of two files.

--
-- choose.as: A file providing functions to be used elsewhere.
--
#include "aldor.as"

factorial(n: Integer): Integer ==
        if n <= 2 then n else n * factorial (n-1);

choose(n: Integer, k: Integer): Integer ==
        factorial(n) quo (factorial(k) * factorial(n-k));
--
-- poker.as: A main program using functions from "choose.as".
--
#include "aldor.as"

import from ChooseLib;
import from Integer;

npok := choose(52, 5);
print << "The number of different poker hands is " << npok << newline;      

The first step compiles the file choose.as. The -Fao option causes the compiler to create a platform-independent file, choose.ao, and the -Fo option gives a platform-dependent object file, such as choose.o on Unix, containing machine code. The -O option requests optimized code.

The second step compiles the file poker.as, which uses choose.as. The -lChooseLib=choose.ao option tells the compiler that the library choose.ao is to be made visible within the program as a package named ChooseLib. This -l option could be avoided by using a #library command, as described in section 16.3.

In the third command, the -Fx option directs the compiler to link an executable image from the object files on the command line. The -e option causes the resulting program to begin execution by evaluating the top-level statements of the file poker.as. The -e option also directs the compiler to give the executable file the name poker (possibly with some system-dependent extension, such as .exe under DOS).

Note that if you were using Aldor to compile AXIOM libraries separately, then -Fo options and the link step would not be necessary.



16.2 : Libraries

In order to handle large numbers of separately compiled files, the Aldor compiler allows .ao files to be combined into aggregate .al files. The aggregate library files may be created and maintained on Unix using the ar command. For the platforms for which ar is not available, the Aldor distribution provides a program uniar.

When specifying a library to the compiler with the -lname option,name is treated as a filename if it has a file extension or a directory specification. Otherwise it is treated as a shorthand reference to either or both of the libraries libname.al and libname.a in the current directory or on $LIBPATH.

Examples:

When the Aldor compiler is asked to create an executable file, references to libraries via -l will be passed to the linker, if appropriate. This can be convenient on certain platforms. For example, on Unix, it allows one to have libxxx.al and libxxx.a containing the platform-independent .ao files and the platform-dependent .o files, respectively.



16.3 : Source code referenes to libraries

A separately compiled module can be referenced directly from the source text of a program much the same way that it is referenced from the command line. In a source program, the system command #library plays the same rôle as -l does from the command-line. The treatment of names in the #library system command is exactly the same as in the -l command-line argument (see section 27.5). When using the #library system command, however, remember to put the name in quotation marks.

References to files using #library will be passed to the linker under the same circumstances as the corresponding -l command-line argument.



16.4 : Importing from compiled libraries

Compiled object files (.ao) and compiled libraries ( .al) have the same top-level semantics as Aldor domains: before the symbols defined in a separately compiled file are visible during the compilation of a given source file, the symbols must be imported into the current scope. Before a domain can be imported, it must be given a name. The same is true of compiler object files: before symbols can be imported from an object file or a library, it must be given a name.

Names are assigned to compiler libraries using an extension of the -l syntax and an extension of the #library syntax described in the previous two sections. If the argument to either of these forms is prefixed by a symbol (which should not be enclosed in quotation marks), then the compiler object or library which follows is taken as the definition of a domain whose name is the given symbol. The symbols exported from the newly named domain are exactly those exported from the source code used to produce the compiled object.

Consider the following Aldor source file:

The first two lines specify that the domain Basic, usually provided by the compiler libraries found in the distribution, will, for the extent of the file, be provided by the compiled object file /tmp/mybasic.ao. The #library command specifies a binding for the symbol Basic, and then the import command operates as it does in any other context, extracting the exported symbols from the domain Basic and making them visible in the current scope. Note that, unlike the command line usage, the #library command requires a space, rather than =, between the domain and library names.


Previous Home Contents Next