Let's enhance our example and transform the
logging subsystem into a
library. In order to do so, a few changes need to be made to logging.gpr.
A number of specific attributes needs to be defined: at least
Library_Dir; in addition, a number of other attributes can be used
to specify specific aspects of the library. For readability, it is also
recommended (although not mandatory), to use the qualifier
front of the
Object_Dirdirectory. When all sources of a library are compiled, some of the compilation artifacts, including the library itself, are copied to the library_dir directory. This directory must exists and be writable. It must also be different from the object directory so that cleanup activities in the Library_Dir do not affect recompilation needs.
Here is the new version of logging.gpr that makes it a library:
library project Logging is -- "library" is optional for Library_Name use "logging"; -- will create "liblogging.a" on Unix for Object_Dir use "obj"; for Library_Dir use "lib"; -- different from object_dir end Logging;
Once the above two attributes are defined, the library project is valid and is enough for building a library with default characteristics. Other library-related attributes can be used to change the defaults:
"relocatable"(the latter is a synonym for dynamic). It indicates which kind of library should be build (the default is to build a static library, that is an archive of object files that can potentially be linked into a static executable). When the library is set to be dynamic, a separate image is created that will be loaded independently, usually at the start of the main program execution. Support for dynamic libraries is very platform specific, for instance on Windows it takes the form of a DLL while on GNU/Linux, it is a dynamic elf image whose suffix is usually .so. Library project files, on the other hand, can be written in a platform independent way so that the same project file can be used to build a library on different operating systems.
If you need to build both a static and a dynamic library, it is recommended use two different object directories, since in some cases some extra code needs to be generated for the latter. For such cases, one can either define two different project files, or a single one which uses scenarios to indicate at the various kinds of library to be build and their corresponding object_dir.
Library_Dirdirectory, but as for the executables where we have a separate
Exec_Dirattribute, you might want to put them in a separate directory since there can be hundreds of them. The same restrictions as for the
"soname"). If the library file name (built from the
Library_Name) is different from the
Library_Version, then the library file will be a symbolic link to the actual file whose name will be
Library_Version. This follows the usual installation schemes for dynamic libraries on many Unix systems.
project Logging is Version := "1"; for Library_Dir use "lib"; for Library_Name use "logging"; for Library_Kind use "dynamic"; for Library_Version use "liblogging.so." & Version; end Logging;
After the compilation, the directory lib will contain both a libdummy.so.1 library and a symbolic link to it called libdummy.so.
Linker.Switchesdefined in the main project. This is useful when a particular subsystem depends on an external library: adding this dependency as a
Linker_Optionsin the project of the subsystem is more convenient than adding it to all the
Linker.Switchesof the main projects that depend upon this subsystem.