Strategy to link/include library

Jacob Carlborg doob at me.com
Wed Jan 16 04:00:53 PST 2013


On 2013-01-16 12:25, o3o wrote:
> Suppose I have the following library structure (from Andrei
> Alexandrescu 'The D Programming Language' pag. 352)
>
> acme
> ├── algebra.d
> └── io
>       └── file.d
>
> // acme/algebra.d
> module algebra;
> import std.stdio;
>
> public void gun() {
>      writeln("algebra->gun");
> }
>
> // acme/io/file.d
> import std.stdio;
> public void fun() {
>      writeln("file->fun");
> }
>
> and suppose I want to use it in this client
>
> acmeClient
> ├── acme.a
> └── client.d
>
>
> // acmeClient/client.d
> import std.stdio;
> import algebra;
> import io.file;
> void main(string[] args) {
>      algebra.gun();
>      gun();
>      fun();
> }
>
> I want link acme.a to my client, so Andrei wrote:
> -----
> The syntax for building a library depends on the implementation;
> on the
> reference implementation, you’d do something like this:
>
> % cd /path/to/acme_impl
> % dmd -lib -ofacme algebra.d gui.d io/file.d io/network.d
>
> The switch -lib instructs the compiler to build a library, and
> the switch
> -of (“output file”) directs the output to a file called acme.lib
> (Windows)
> or acme.a (various Unix-derived systems). With that library in
> tow, all
> you have to do now to get client code running is something like
>
> % dmd client.d acme.lib
> -----
>
> So I write (in acme)
>     $ cd acme
>     $ dmd -lib -ofacme algebra.d io/file.d
>
> in acmeClient
>     $ cd ../acmeClient
>     $ cp ../acme/acme.a .
>     $ dmd client.d acme.a -ofclient
>      app.d(2): Error: module algebra is in file 'algebra.d' which
> cannot be read
>
> instead if I write
>     $ dmd -I../acme acme.a app.d
> it works.
>
> So, if I want to use acme library in my client project I need to
> know
> the entire acme source code. is that correct? Is there an easier
> way?

Yes, it needs to have the source or rather the declarations you want to use.

> I am a C# programmer and with Mono dmcs compiler I can do:
>
> (in acme)
> $ dmcs  -out:acme.a -target:library *.cs
>
> (in acmeClient)
> $ cp ../acme/acme.a .
> $ dmcs -out:client -target:exe -reference:acme.a *.cs
>
> (..to be honest it easy because mono assembly contains metadata
> and
> reference options imports that metadata)

The assemblies contains the needed declarations.

> So, if I use "Module Summaries" (pag 350 Andrei's book),
> $ cd acme
> $ dmd -lib -H doitall.d
>
> doitall.di and doitall.d are identical (except for comments).

It could, and previously did, remove the implementation of all functions 
and methods. But that will prevent CTFE (Compile Time Function 
Evaluation) and inlining functions.

> Is there any "pattern" to use "shared" code inside a project?
> (i.e. manually copy all acme source in a client subdirectory, use
> git subtree, etc.)

You usually place it in a common directory. You then use the -I switch 
to make the compiler aware of this directory. This flag can be but in 
dmd.conf/dm.ini to avoid repeating.

Ideally this should be handled by a package manager and a build tool.

-- 
/Jacob Carlborg


More information about the Digitalmars-d-learn mailing list