LID File Format¶
The DRM defines an interchange format for Dylan source files
, but does not define an interchange format for
Dylan libraries. Without such an agreed format, it would be difficult to
import and build libraries developed using another Dylan implementation.
The Library Interchange Description (LID) format solves this problem. It allows you to describe Dylan library sources in a form that any Dylan environment should be able to understand. Open Dylan adopted the LID format to make it easier to port applications from one environment to another.
Note
LID is a convention, and not an extension to the Dylan language.
Note
The Open Dylan environment can convert LID files to its own
internal project file format, the .hdp
file. It can also save project
files as LID files with the File > Save As command in the project
window.
LID files¶
LID works by supplementing each set of library sources with a LID file. A LID file describes a Dylan library using a set of keyword statements. Together, these statements provide enough information to specify and locate the information necessary to build a library from its sources. This means all Dylan libraries designed for interchange consist of at least two files: a LID file, and one or more files containing the library source code.
Thus a LID file performs a similar function to the makefile used in some C and C++ development environments.
LID files have the file extension .lid
.
A LID file consists of a series of keyword/value statements, just like
the Dylan source file interchange format
.
Note that LID keywords are not case-sensitive.
Standard LID Keywords¶
In this section, we describe the standard LID keywords.
Library:¶
LID file keyword
Library: *library-name*
Names the Dylan library being described. The library-name must be the name of the Dylan library that the LID file describes. This keyword is required in every LID file, and it may appear only once per LID file.
Files:¶
LID file keyword
Files: *file-designators*
Associates a set of files with the library named by the Library: keyword. This keyword can appear one or more times per LID file. Every file specified is considered to be associated with the library.
A file designator is something that can be mapped to a concrete file name. Only one file designator can appear per line of the LID file. See File naming conventions for a description of the format of file designators and how they are mapped to concrete file names.
The order in which the designated source files are specified with the Files: keyword in the LID file determines the initialization order across the files within the defined library.
All the files must be specified relative to the same folder (directory) as the LID file.
Synopsis:¶
LID file keyword
Synopsis: *arbitrary text*
A concise description of the library.
Keywords:¶
LID file keyword
Keywords: *comma-separated phrases*
Any number of phrases, separated by commas, that are relevant to the description or use of the library.
Major-Version:¶
LID file keyword
Major-Version: *number*
The current major version number of the library.
Minor-Version:¶
LID file keyword
Minor-Version: *number*
The current minor version number of the library.
Description:¶
LID file keyword
Description: *arbitrary text*
A description of the library. The intention of this keyword is to provide a fuller, less concise description than that given by the Synopsis: keyword.
Comment:¶
LID file keyword
Comment: *arbitrary text*
Any additional comments about the library.
Open Dylan’s LID extensions¶
This section contains extensions to LID that Open Dylan supports.
Tooling Support¶
Platforms¶
Platform-specific LID files should use the Platforms
keyword to indicate
which platforms they apply to. This helps the deft update command decide
which registry files to create. If there is no Platforms
keyword deft
assumes the LID file applies to the current platform and creates a registry
file for its library.
For example, if you have a library with separate LID files for Windows and Unix platforms add this to the Windows LID file:
Platforms: win32
and add this to the Unix LID file:
Platforms: x86_64-linux
x86_64-darwin
x86_64-freebsd
x86_64-netbsd
x86-freebsd
x86-linux
x86-netbsd
Note
We plan to add platform aliases such as “unix” so that it isn’t necessary to list all supported Unix platforms.
Specifying foreign files and resource files¶
The following keywords allow you to specify that files of foreign source code and resource files are a part of the library.
C-Source-Files:¶
LID file keyword
C-Source-Files: *c-source-files*
Identifies one or more C source files which are to be included as part
of the library. Dylan environments copy these files to their build area
and ensure that they are compiled by the appropriate batch file. The
filenames specified must include the .c
suffix.
C-Header-Files:¶
LID file keyword
C-Header-Files: *c-header-files*
Identifies one or more C header files included as part of the library.
Dylan environments copy these files to their build area and ensure that
they are compiled by the appropriate batch file. Any files specified
using the C-Source-Files: or RC-Files: keywords depend on these
header files in order to decide when they need to be recompiled. The
file names given here must include the .h
suffix.
C-Object-Files:¶
LID file keyword
C-Object-Files: *c-object-files*
Identifies one or more C object files included as part of the library.
Dylan environments copy these files to their build area and ensure that
they are compiled by the appropriate batch file and included in the
final output as .DLL
or .EXE
files. The file names given here must
include the .obj
suffix on Windows or .o
on other platforms, except
when using this keyword in conjunction with a static library.
In some situations, a static library needs to be copied into the build area
and linked into the project. This is typically when writing a binding for
an external library written in C. In this situation, the C-Object-Files
keyword may be useful.
RC-Files:¶
LID file keyword
RC-Files: *resource-files*
Identifies one or more resource files to be included as part of the
library. Dylan environments copy these files to their build area and
ensure that they are compiled by the appropriate batch file. The
resulting resource object files are included in the .DLL
or .EXE
built for the library. The file names given here must include the .rc
suffix.
C-Libraries:¶
LID file keyword
C-Libraries: *c-lib-files*
Identifies one or more C libraries to be included in the link phase when building the binary for the library. Paths to search for libraries can also be added with this keyword. Arbitrary linker options cannot be specified using this keyword.
On Windows, the value for this keyword is passed directly to the linker. However, on Unix and macOS, the requirements are a bit more stringent and the arguments should be passed one per line and be one of the following:
-L path
:Add path to the search path for shared libraries.
-llibrary
:Link against the specified shared library. This should be either in the regular linker search path or have a path specified via a
-L
flag.library.a
:Link against the specified static library.
Note
This may cause a problem if you are using this to link a static library that hasn’t been built with
-fPIC
into a shared library.In general, you don’t want to use this keyword to link a static library into a shared library since this keyword propagates to dependent libraries as discussed below.
-F path
:Add path to the search path for frameworks. (macOS only)
-framework framework
:Link against the specified shared library. This should be either in the regular linker search path or have a path specified via a
-F
flag. (macOS only)
Unlike the other keywords described in this section, the C-Libraries: keyword propagates to dependent libraries. For example, suppose library A uses library B, and the LID file for library B specifies
C-Libraries: foo.lib
In this case, both library A and library B are linked against foo.lib.
Specifying compilation details¶
The following keywords control aspects of compilation for the library.
LID:¶
LID keyword
LID: *file-name.lid*
Specifies the name of a LID file to process and includes the settings contained in that file into the current LID file.
This is commonly used to share definitions and settings between platform- or OS-specific LID files.
Jam-Includes:¶
LID keyword
Jam-Includes: *file-name.jam*
Specifies the name of a JAM file to process. This is typically used when integrating with a third party library and needing custom flags for the C compiler or linker.
An example JAM (for a library, not an executable) file might look like:
{
local _dll = [ FDLLName $(image) ] ;
LINKLIBS on $(_dll) += `pkg-config --libs gtk+-3.0` ;
CCFLAGS += `pkg-config --cflags gtk+-3.0` ;
}
The use of backticks `...`
will execute the command enclosed
within and return the output of that command.
Target-Type:¶
Target-Type: *dll or executable*
Specifies whether to generate a shared library (a.k.a, dynamic-link library) or
an executable binary. Possible values are dll
or executable
.
If no target type is specified, Open Dylan builds an executable when the library is specified directly on the compiler command line, or a shared library if the library is only pulled in as a dependency.
Executable:¶
LID keyword
Executable: *name*
Specifies the name of the binary (that is, shared library or executable) file to be generated for this library.
The suffix (.DLL, .EXE, .so) should not be included in the name since the appropriate suffix is determined based on the platform.
If this keyword is not specified, the compiler generates a default name for the executable from the name of the library. With some library names, particularly when you are building a DLL, you may need to specify this keyword to override the default name and avoid conflicts with other DLLs from a third party.
Base-Address:¶
LID keyword
Base-Address: *address*
Note
This keyword is only used on Windows and is ignored on other platforms.
Specifies the base address of the DLL built from this Dylan library. The
address must be a hexadecimal value. For convenience, you can use
either Dylan (#xNNNNNNNN
) or C (0xNNNNNNNN
) notations when
specifying the address.
This base address is ignored when building a .EXE
file.
If this keyword is not specified, the compiler will compute a default base address for the library. However, it is possible for more than one library to end up with the same default base address. If an application uses any of these libraries, all but one of them will have to be relocated when the application starts. This process is automatic, but cuts down on the amount of sharing, increases your application’s memory footprint, and slows down load time. In such circumstances, you may want to give one or more libraries an explicit base address using this keyword.
Linker-Options:¶
LID keyword
Linker-Options: *options*
Specifies additional options and libraries to be passed to the linker when building this binary. Unlike the C-Libraries: keyword, the options and libraries specified here apply only to this Dylan library; they are not propagated to any libraries which use this library.
File naming conventions¶
In practice, importing a source distribution into a Dylan program involves unpacking the source distribution into its own subtree and then informing the environment of the location of the tree root. The environment then walks the entire subtree locating LID files, which describe the libraries in the distribution by giving a name to, and designating the source files associated with, each library.
Importing a Dylan program into the environment in this way requires two things:
That the LID files in the distribution can be identified.
That the file designators supplied to the Files: keyword in LID files can be mapped to the corresponding source filenames on disk.
If you are importing files from a platform that does not insist on, or conventionally use, standard filename suffixes to identify the filetype (such as MacOS), then you must rename your source files as follows:
LID files must be given filenames with the suffix
.lid
.Dylan source files must be given filenames with the suffix
.dylan
.
The file designators that appear in LID files may be a string of characters of any length, constructed from the set of hyphen, underscore, and the mixed-case alphanumeric characters. Note that you do not have to specify the source filename suffix as part of the filename designator. This ensures that the LID files themselves do not need to be edited when importing source code from a platform, such as MacOS, that does not insist on particular filename suffixes to specify the file type.
The name of a LID file is not significant, and in particular need not be the same as the library name. Hierarchical directory structure can be used to organize multi-library systems as long as the files directly associated with each library are in a single directory.
Application example¶
This section contains an example of a complete Dylan application that uses a generic factorial calculation routine to return the value of the factorial of 100. Two libraries are defined: the factorial library provides an implementation of the generic factorial routine, and the factorial-application library provides a method that calls the generic routine and returns the appropriate result.
File: fact.lid. LID file describing the components of the factorial library.
Library: factorial
Synopsis: Provides a naive implementation of the factorial
function
Keywords: factorial, integer, simple, recursive
Files: library
fact
File: library.dylan. Defines the factorial library and its one module.
Module: dylan-user
define library factorial
use dylan;
export factorial;
end;
define module factorial
export fact;
end;
File: fact.dylan. Defines the method for calculating a factorial.
Module: factorial
define generic fact(n);
define method fact(n == 0)
1
end;
define method fact(n)
n * fact(n - 1)
end;
File: app.lid. LID file describing the components of the factorial-application library.
Library: factorial-application
Synopsis: Computes factorial 100
Files: library
app
Start-Module: factorial-application
Start-Function: main
File: library.dylan. Defines the factorial-application library and its one module.
Module: dylan-user
define library factorial-application
use dylan;
use factorial;
end library;
define module factorial-application
use dylan;
use factorial;
end module;
File: app.dylan. Defines a routine that calls the factorial routine.
Module: factorial-application
define method main (#rest ignore)
fact(100)
end method;
The following example demonstrates how files of foreign source code and resource files can be integrated into a Dylan library:
Library: app-with-foreign-code
Synopsis: Uses some C code and resources
Files: dylan-code
C-Source-Files: first.c
second.c
C-Header-Files: headers.h
RC-Files: extra-resources.rc