LIBRARY


General Form:

LIBRARY ADD [strexpr1 =] strexpr2
LIBRARY USE strexpr2
LIBRARY REMOVE strexpr1
LIBRARY REMOVE ALL
Where:
strexpr1 = a string expression naming the module
strexpr2 = a string expression representing the module filename

The LIBRARY statement allows the mapping in and out of shared KCML libraries, commonly called globals. It is a generalization of the original SELECT @PART process global in the following ways

A library is a shareable image of program code created with the kc6 compiler on a system running the same type of KCML. Putting subroutines, DEFRECORDs, FLDs and constants into shared libraries improves the modularity of a system and removes the need for complex overlaying. Libraries have hardware dependencies on byte ordering, word size and and alignment and while they can be exchanged between similar platforms, e.g. Linux and Unixware, or NT and Windows 95, they are not generally interopable unlike SAVEd programs which are transportable between dissimilar architectures.

LIBRARY ADD is used in an executing program to add a new library onto the end of the list of current libraries. This list is presumed to start with the original foreground program which can be considered as the main library module. A library is named with a name which can later be used in a LIBRARY REMOVE to unload the library. The second string expression is the name of the file containing the library image. If only one string is supplied, KCML will invent the library name from the filename by dropping directory qualifiers and any extension.

Once loaded with a LIBRARY ADD, a library stays mapped into memory until explicitly dropped with a LIBRARY REMOVE or until a CLEAR. In particular they are preserved across a LOAD or a CLEAR P. All the currently loaded libraries can be dropped by LIBRARY REMOVE ALL.

When searching for a DEFSUB' routine, KCML will look first in the currently executing library (which may be the foreground). If not found there it will search the library list from the start looking for the routine. Remember the foreground process is considered to be the first library in the list so routines placed in the foreground can override secondary library routines.

Libraries can also be used to hold definitions of fields and constants to be looked up using the same algorithm.

Certain variables declared in the library using the PUBLIC DIM statement will be copied to the foreground symbol table when the library is loaded and marked as persistent so they do not get dropped after a program LOAD. Such variables are called library variables and they can be numerics, strings or objects. Fields, records and constants are not considered as library variables and are looked up only when referenced. If the library is later unloaded its library variables revert to being normal foreground symbols and they may well be dropped from the program on the next LOAD.

Variables declared as PRIVATE DIM are not visible from outside the library.

A library can have a constructor function with the special reserved name of 'Constructor() which will be automatically invoked by LIBRARY ADD in order to perform any initialization required by the libraries.

A program can also declare that it needs access to a particular library at resolve time by specifying the library filename in a LIBRARY USE statement. Any constants, FLDs or PUBLIC variables are then immediately available for later declarations. Thus if a particular constant is defined in a library then it can be immediately used to declare a variable after the LIBRARY USE as in

LIBRARY USE "SystemConstants.klib"
DIM SO_PartsTableRow$_SO_PartsTableRow

You can still have constructors in libraries mapped using LIBRARY USE but they are not called until the statement is executed at exection time. If the program contains any LIBRARY USE statements in any context they will be all be loaded in the order they are found in the program. However, because of the conditional flow of code at runtime, they may not all be executed and thus their corresponding constructors are not guaranteed to be executed. You cannot have a LIBRARY USE statement in a library.

Libraries can be comprised of more than one program and compiled together using the kmake utility which will only rebuild a library if one of its components is out of date. The component programs can have their own line number spaces. Each program can have their own constructor function and the compiler will arrange for each to be called in turn when the library is loaded. The make system is driven by a XML build file that enumerates the libraries and their components.

Libraries are generally mapped in as read-only memory to facilitate sharing by multiple processes. However if KCML spotted the presence of a DIM or COM of an @ variable in the library at the time it was compiled, it marks the library header appropriately and KCML will map in the first such library as read-write allowing access to shared @variables. There can only be one such global and @ variables in later libraries will not be visible to the foreground. It is unwise to put program text in the same library as shared @variables.

Compatibility

The LIBRARY statement was originally called MODULE and was renamed in KCML 6.20. Both keywords are acceptible but KCML will always use LIBRARY when recreating program source.

The MODULE statement was introduced in KCML 6.0 and is supported on both Unix and Windows. It is an interim stage and will be replaced by a new implementation in the next major release of KCML. This next implementation will withdraw access to the variables of a global. All access will be through subroutine calls. You should start now on the assumption that you cannot change foreground variables using a function in a global. Make all variables in the library local if possible.

Library variables and constructors were introduced in KCML 6.10. LIBRARY USE appeared first in KCML 6.60.

Optional PRIVATE and PUBLIC keywords for DEFSUB limiting visibility outside of a library were introduced in KCML 6.10.

Library variables in KCML 6.10 were defined with COM but this has been superseded by PUBLIC DIM. COM is still allowed in a library in 6.20 but it will raise an error in future versions of KCML.

Syntax examples:

LIBRARY ADD "MK/libGb" = "./PROGS/MK/libGb"
LIBRARY REMOVE "MK/libGb"
LIBRARY REMOVE ENV("LIBRARY")

See also:

SELECT @PART, LIST M
Tutorial on libraries