Building a Stand-alone Library (GNAT User’s Guide for Native Platforms)

#### 3.9.3.2 Building a Stand-alone Library ¶

GNAT’s Project facility provides a simple way of building and installing stand-alone libraries; see the ‘Stand-alone Library Projects’ section in the ‘GNAT Project Manager’ chapter of the GPRbuild User’s Guide. To be a Stand-alone Library Project, in addition to the two attributes that make a project a Library Project (`Library_Name` and `Library_Dir`; see the ‘Library Projects’ section in the ‘GNAT Project Manager’ chapter of the ‘GPRbuild User’s Guide’), you must define the attribute `Library_Interface`. For example:

    for Library_Dir use "lib_dir";
    for Library_Name use "dummy";
    for Library_Interface use ("int1", "int1.child");

Attribute `Library_Interface` has a non-empty string list value, each string in the list designating a unit contained in an immediate source of the project file.

When a Stand-alone Library is built, the binder is first invoked to build a package whose name depends on the library name (`b~dummy.ads/b` in the example above). This binder-generated package includes initialization and finalization procedures whose names depend on the library name (`dummyinit` and `dummyfinal` in the example above). The object corresponding to this package is included in the library.

You must ensure timely (e.g., prior to any use of interfaces in the SAL) calling of these procedures if a static SAL is built, or if a shared SAL is built with the project-level attribute `Library_Auto_Init` set to `"false"`.

For a Stand-Alone Library, only the `ALI` files of the Interface Units (those that are listed in attribute `Library_Interface`) are copied to the Library Directory. As a consequence, only the Interface Units may be imported from Ada units outside of the library. If other units are imported, the binding phase will fail.

You can also build an encapsulated library where not only the code to elaborate and finalize the library is embedded but also ensure that the library is linked only against static libraries. That means that an encapsulated library only depends on system libraries: all other code, including the GNAT runtime, is embedded. To build an encapsulated library you must set attribute `Library_Standalone` to `encapsulated`:

    for Library_Dir use "lib_dir";
    for Library_Name use "dummy";
    for Library_Kind use "dynamic";
    for Library_Interface use ("int1", "int1.child");
    for Library_Standalone use "encapsulated";

The default value for this attribute is `standard` in which case a stand-alone library is built.

You may specify the attribute `Library_Src_Dir` for a Stand-Alone Library. `Library_Src_Dir` has a single string value. Its value must be the path (absolute or relative to the project directory) of an existing directory. This directory cannot be the object directory or one of the source directories, but it can be the same as the library directory. The sources of the Interface Units of the library that are needed by an Ada client of the library are copied to the designated directory, called the Interface Copy directory, when the library is built. These sources include the specs of the Interface Units, but they may also include bodies and subunits when pragmas `Inline` or `Inline_Always` are used or when there is a generic unit in the spec. Before the sources are copied to the Interface Copy directory, the building process makes an attempt to delete all files in the Interface Copy directory.

Building stand-alone libraries by hand is somewhat tedious, but for those occasions when it is necessary here are the steps that you need to perform:

- Compile all library sources.
- Invoke the binder with the switch `-n` (No Ada main program), with all the `ALI` files of the interfaces, and with the switch `-L` to give specific names to the `init` and `final` procedures. For example:

      $ gnatbind -n int1.ali int2.ali -Lsal1

- Compile the binder generated file:

      $ gcc -c b~int2.adb

- Link the dynamic library with all the necessary object files, passing to the linker the names of the `init` (and possibly `final`) procedures for automatic initialization (and finalization). You should place the built library in a different directory than the object files.
- Copy the `ALI` files of the interface to the library directory, add in this copy an indication that it is an interface to a SAL (i.e., add a word `SL` on the line in the `ALI` file that starts with letter ‘P’) and make the modified copy of the `ALI` file read-only.

Using SALs is not different from using other libraries (see Using a library).