*************** LID File Format *************** The DRM defines an :drm:`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 :drm:`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 .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan Synopsis: *arbitrary text* A concise description of the library. Keywords: --------- LID file keyword .. code-block:: dylan Keywords: *comma-separated phrases* Any number of phrases, separated by commas, that are relevant to the description or use of the library. Author: ------- LID file keyword .. code-block:: dylan Author: *arbitrary text* The name of the library's author. Major-Version: -------------- LID file keyword .. code-block:: dylan Major-Version: *number* The current major version number of the library. Minor-Version: -------------- LID file keyword .. code-block:: dylan Minor-Version: *number* The current minor version number of the library. Description: ------------ LID file keyword .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan 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. .. _lid-c-libraries: C-Libraries: ^^^^^^^^^^^^ LID file keyword .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan 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. .. _lid-jam-includes: Jam-Includes: ^^^^^^^^^^^^^ LID keyword .. code-block:: dylan 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: ^^^^^^^^^^^^ .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan 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 .. code-block:: dylan 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. .. code-block:: dylan 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. .. code-block:: dylan 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. .. code-block:: dylan 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. .. code-block:: dylan 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. .. code-block:: dylan 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. .. code-block:: dylan 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: .. code-block:: dylan 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