Proposal for a standard for D library naming

Gregor Richards Richards at codu.org
Mon Sep 18 19:30:57 PDT 2006


Amendment #1: Not sure why I thought .add files would be necessary.  The 
entire chain of dependencies is visible at runtime, so it should be no 
problem to detect all of them.  Repost:

A Modest Proposal for Standardization in Naming of D Libraries
--------------------------------------------------------------
(by Gregor Richards)


Outline
-------

At present, there is to my knowledge no standard for naming D
libraries (that is, .a, .lib, .so and .dll files). There's no
immediate problem posed, as there is very little D code that forms
libraries - but with any luck, the amount of code doing so will
increase.

For background on me and why I'm interested in this, both my job and
several of my personal projects involve compilation and linking of
software in UNIX environments, so I'm constantly exposed to
inconsistent libraries.

My experience with the D community has shown that few people at the
moment seem to care about the creation of libraries, but I believe
that desire will increase as popularity does. I consider the fact
that there is no standard for naming to be a significant problem, as
a lack of a clear naming convention will likely make the entire
compilation process difficult (think of autoconf).

I intend to outline in this document a naming convention for library
files which will be easily parseable by both humans and software
(such as [d]build).

Note that this document does not currently target Windows .dll and
.lib files, as I know nothing whatsoever about them. If anyone would
like to step in and make modifications, feel free.


Don't Break from Convention
---------------------------

(This section applies only to UNIX)

The UNIX convention for naming of libraries is:

lib<name>.so.<major>.<minor>.<revision>

with symlinks for each of:

lib<name>.so.<major>.<minor>
lib<name>.so.<major>

and also a symlink of:

lib<name>.so

if the library has its headers installed. There is no compelling
reason to break from this standard, so it is left as such in this
document.

For .a files, the file name is more simple:

lib<name>.a


Packages and Libraries
----------------------

Package names should be directly reflected in the file name of the
library. Furthermore, the fact that this library is written in D
should also be in the name of the library. To this end, the basic
form is:

libD.<package name>.<extension>

Of course, packages are more complex than that, with subpackages,
etc. The division becomes more complex for packages such as:

a.*
a.b.*
a.c.*
a.d.*

Each library must only be inclusive of /modules/ in the package, not
subpackages (though it may be either at the creator's whimsy). One
way to comply would be to simply have a single file:

libD.a.<extension>

However, if one wanted to subdivide, it could also have several:

libD.a.b.<extension>
libD.a.c.<extension>
libD.a.d.<extension>

Now let's imagine the situation of the package 'a' having a module
named 'foo'. a.foo doesn't belong in its own library (we've already
determined that libraries correspond to packages), so it will go into
its own file:

libD.a.<extension>

With this subdivision, we now have four files:

libD.a.<extension>
libD.a.b.<extension>
libD.a.c.<extension>
libD.a.d.<extension>

Now, in all likelihood, one or all of the subpackages depend on
modules in the superpackage. Luckily, this is trivial to detect in a
build system. Since all of the imports will be iterated over, a list
of packages to test for can be built that is guaranteed to capture
everything (so long as the installation is complete).


Version Hell
------------

(Or DLL Hell as it's affectionately known on Windows)

Version Hell isn't too bad with UNIX-style .so files, so long as
people comply to this simple standard:

1) Only increase the major version if you've made non-backwards-
    compatible changes.
2) Increase the minor version when you've added but not removed
    symbols.
3) Increase the revision for all other changes.
4) Don't worry about D ABI changes - they're well beyond the scope of
    library naming convention.

I would recommend that a .DLL version of this spec incorporate some
sort of versioning similar to UNIX.


Build Tools
-----------

With this setup, a build tool (such as build) has a very trivial task
to generate a library name from an import. It simply needs to,
starting with the most specific and expanding to the most general,
check whether files corresponding to the name exist. So, if an import
for a.b.c.d.e.f.g had been specified and the imported file was not in
the included source, it would search (in this order):

libD.a.b.c.d.e.f.g.so
libD.a.b.c.d.e.f.g.a
libD.a.b.c.d.e.f.so
libD.a.b.c.d.e.f.a
libD.a.b.c.d.e.so
libD.a.b.c.d.e.a
libD.a.b.c.d.so
libD.a.b.c.d.a
libD.a.b.c.so
libD.a.b.c.a
libD.a.b.so
libD.a.b.a
libD.a.so
libD.a.a

If none of them were found, it fails. Because each file carries its
own dependencies, the build tool only needs to link against the one
it found (and know how to read .add files) to get all of the symbols
resolved.

The generation of these files is a bit more complex, but any build
tool would only need a tiny bit of input from the user (exactly where
to subdivide) to be able to produce them.


Questions?
----------

If anything is confusing here, please respond, and I will attempt to
clarify. It's all quite clear in my head :)



More information about the Digitalmars-d mailing list