Go to the first, previous, next, last section, table of contents.


The stand-alone command-line compiler

Author(s): Daniel Cabeza and the CLIP Group.

Version: 1.3#120 (1999/11/26, 12:5:17 MET)

Version of last change: 0.9#103 (1999/5/30, 19:14:54 MEST)

ciaoc is the Ciao stand-alone command-line compiler. ciaoc can be used to create executables or to compile individual files to object code (to be later linked with other files). All these considerations apply also if the compilation is performed from the interactive top-level shell.

Building executables

An executable can be built from a single file or from a collection of inter-related files. In the case of only one file, this file must define the predicate main/0 or main/1. This predicate is the one which will be called when the executable is started. As an example, consider the following file, called hello.pl:

main :-
     write('Hello world'), 
     nl.

It can be compiled using the ciaoc standalone compiler as follows:

/herme@clip:/tmp
[60]> ciaoc hello

/herme@clip:/tmp
[61]> 

This produces (in Un*x-like systems) an executable called hello, which can then run by simply typing its name:

/herme@clip:/tmp
[61]> hello
Hello world

If the application is composed of several files the process is identical. Assume hello.pl is now:

:- use_module(aux,[p/1]).

main :-
     p(X),
     write(X), 
     nl.

where the file aux.pl contains:

:- module(aux,[p/1]).

p('Hello world').

This can again be compiled using the ciaoc standalone compiler as before:

/herme@clip:/tmp
[60]> ciaoc hello

/herme@clip:/tmp
[61]> hello
Hello world

The invocation of ciaoc hello compiles the file hello.pl and all connected files that may need recompilation -- in this case the file aux.pl. Also, if any library files used had not been compiled previously they would be compiled at this point (See section Intermediate files in the compilation process). Also, if, say, hello.pl is changed and recompiled, the object code resulting from the previous compilation of aux.pl will be reused. This is all done without any need for Makefiles, and considerably accelerates the development process for large applications. This process can be observed by selecting the -v option when invoking ciaoc (which is equivalent to setting the verbose_compilation Prolog flag in the top-level interpreter).

If main/1 is defined instead of main/0 then when the executable is started the argument of main/1 will be instantiated to a list of atoms, each one of them corresponding to a command line option. Consider the file say.pl:

main(Argv) :-
     write_list(Argv), nl.

write_list([]).
write_list([Arg|Args]) :- 
     write(Arg),
     write(' '),
     write_list(Args).

Compiling it and running it results in the following output:

/herme@clip:/tmp
[91]> ciaoc say

/herme@clip:/tmp
[91]> say hello dolly
hello dolly 

The name of the generated executable can be controlled with the -o option (See section Usage (ciaoc)).

Paths used by the compiler during compilation

The compiler will look for files mentioned in commands such as use_module/1 or ensure_loaded/1 in the current directory. Other paths can be added by including them in a file whose name is given to ciaoc using the -u option. This file should contain facts of the predicates file_search_path/2 and library_directory/1 (see the documentation for these predicates and also section Customizing library paths and path aliases for details).

Running the executables generated by the compiler

What the ciaoc compiler generates and how it is started varies somewhat from OS to OS. In general, the product of compiling an application with ciaoc is a shell script that contains the bytecode (the product of the compilation) and invokes the Ciao engine on it (see the first lines of the file). To run the generated executable from a Un*x shell, or from the bash shell that comes with the Cygwin libraries (See section Installation and compilation under Windows) it suffices to type its name at the shell command line, as in the examples above. In a raw Win32 system, an additional .bat file is typically needed to start the application from the command line (or by double-clicking on it). The procedure for creating this .bat file changes somewhat depending on the Win32 operating system used. In Windows NT you can simply copy winNT_skel.bat (located in the win32 directory of the Ciao Prolog distribution) to the directory where the application is, and rename it to the name of the application to run (+ the .bat suffix). In Windows 95/98 you have to use the file win95_skel.bat and change its name as before, but in addition you need to edit it to include the absolute path to the Ciao executable. We apologize for this (temporary) inconvenience, which we will try to smooth out in the near future by generating these .bat files automatically.

Types of executables generated

While the default options used by ciaoc are sufficient for normal use, by selecting other options ciaoc can generate several different types of executables, which offer interesting tradeoffs among size of the generated executable, portability, and startup time:

Dynamic executables:
ciaoc produces by default dynamic executables. In this case the executable produced is a platform-independent file which includes in compiled form all the user defined files. On the other hand, any system libraries used by the application are loaded dynamically at startup. More precisely, any files that appear as library(...) in use_module/1 and ensure_loaded/1 declarations will not be included explicitly in the executable and will intead be loaded dynamically. Is is also possible to mark other path aliases (see the documentation for file_search_path/2) for dynamic loading by using the -d option. Files accessed through such aliases will also be loaded dynamically. Dynamic loading allows making smaller executables. Such executables may be used directly in the same machine in which they were compiled, since suitable paths to the location of the libraries will be included as default in the executable by ciaoc during compilation. The executable can also be used in another machine, even if the architecture and OS are different. The requirement is that the Ciao libraries (which will also include the appropriate Ciao engine for that architecture and OS) be installed in the target machine, and that the CIAOLIB and CIAOENGINE environment variables are set appropriately for the executable to be able to find them (see section Environment variables used by Ciao executables). How to do this differs slightly from OS to OS.
Static executables:
Selecting the -s option ciaoc produces a static executable. In this case the executable produced (again a platform-independent file) will include in it all the auxiliary files and any system libraries needed by the application. Thus, such an executable is almost complete, needing in order to run only the Ciao engine, which is platform-specific.(1) Again, if the executable is run in the same machine in which it was compiled then the engine is found automatically. If the executable is moved to another machine, the executable only needs access to a suitable engine (which can be done by setting the CIAOENGINE environment variable to point to this engine). This type of compilation produces larger executables, but has the advantage that these executables can be installed and run in a different machine, with different architecture and OS, even if Ciao is not installed on that machine. To install (or distribute) such an executable, one only needs to copy the executable file itself and the appropriate engine for the target platform (See section Installing Ciao and section Multiarchitecture support), and to set things so that the executable can find the engine. (2)
Dynamic executables, with lazy loading:
Selecting the -ll option is very similar to the case of dynamic executables above, except that the code in the library modules is not loaded when the program is started but rather it is done during execution, the first time a predicate defined in that file is called. This is advantageous if a large application is composed of many parts but is such that typically only some of the parts are used in each invocation. The Ciao preprocessor, ciaopp, is a good example of this: it has many capabilitites but typically only some of them are used in a given session. An executable with lazy load has the advantage that it starts fast, loading a minimal functionality on startup, and then loads the different modules automatically as needed.

Intermediate files in the compilation process

Compiling an individual source (i.e., .pl) file produces a .itf file and a .po file. The .itf file contains information of the modular interface of the file, such as information on exported and imported predicates and on the other modules used by this module. This information is used to know if a given file should be recompiled at a given point in time and also to be able to detect more errors statically including undefined predicates, mismatches on predicate charaterictics across modules, etc. The .po file contains the platform-independent object code for a file, ready for linking (statically or dynamically).

It is also possible to use ciaoc to explicitly generate the .po file for one or more .pl files by using the -c option.

Usage (ciaoc)

The following provides details on the different command line options available when invoking ciaoc:

ciaoc <MiscOpts> <ExecOpts> [-o <execname>] <file> ...

  Make an executable from the listed files.  If there is
  more than one file, they must be non-module, and the
  first one must include the main predicate.  The -o
  option allows generating an arbitrary executable name.

ciaoc <MiscOpts> <ExecOpts> -a <publishmod> <module>

  Make an active module executable from <module> with
  address publish module <publishmod>.

ciaoc <MiscOpts> -c  <file> ...

  Compile listed files (make .po objects).

<MiscOpts> can be: [-v] [-u <file>]

-v  verbose mode

-u  use <file> for compilation

<ExecOpts> can be: [-s|-e|-l|(-ll <module>)*] (-d <alias>)*

-s  make a static executable (otherwise dynamic files are not included)

-e  make executable with eager load of dynamic files at startup (default)

-l  idem with lazy load of dynamic files (except insecure cases)

-ll force <module> to be loaded lazily,  implies -l

-d  files using this path alias are dynamic (default: library)

default extension for files is '.pl'


Go to the first, previous, next, last section, table of contents.