Thread overview
package modules and how to generate a shared library plus .di file (I)
Dec 07, 2017
kdevel
Dec 07, 2017
Andrea Fontana
Dec 07, 2017
Neia Neutuladh
Dec 07, 2017
kdevel
Dec 07, 2017
Adam D. Ruppe
Dec 07, 2017
ag0aep6g
Dec 07, 2017
kdevel
December 07, 2017
Given the functions void foo() and void bar() in their source files mymod/foo.d and mymod/bar.d. Also I have a

mymod/package.d
```
module mymod;

public import foo : foo;
public import bar : bar;
```

and a client to the library:

main.d
```
import mymod;

void main ()
{
   foo;
   bar;
}
```

It compiles fine with

   $ dmd main.d mymod/foo.d mymod/bar.d

Now I want to link against libmymod.a. First I prepare the library:

   $ dmd -lib -oflibmymod.a mymod/foo.d mymod/bar.d

and then

   $ dmd main.d -L-L. -L-lmymod                                 (*)
   mymod/package.d(3): Error: module foo is in file 'foo.d' which cannot be read
   import path[0] = .../linux/bin64/../../src/phobos
   import path[1] = .../linux/bin64/../../src/druntime/import

In order to make that Error go away I have to change

package.d
```
module mymod;

public import mymod.foo : foo;
public import mymod.bar : bar;
```

Then (*) works as expected. But why do I have to use the prefix "mymod.:" in the
library case?
December 07, 2017
On Thursday, 7 December 2017 at 16:39:14 UTC, kdevel wrote:
> Then (*) works as expected. But why do I have to use the prefix "mymod.:" in the
> library case?

Because module names are not relative to file path, but to import path / compile path afaik.
December 07, 2017
On Thursday, 7 December 2017 at 16:39:14 UTC, kdevel wrote:
> But why do I have to use the prefix "mymod.:" in the
> library case?

If you have an editor open with ten tabs pointing to different files in your source tree, all your imports are uniform -- you don't have to step back and consider where the specific file you're editing is and calculate relative import paths.

You always import a given module with the exact same code. If you copy and paste code between two modules and that contains an import statement, it just works.

If you decide to move a module to a different package, you need to change its module name, move it on disk, and update the stuff that imports it. You don't have to update every import it does.

If you have a source tree like:

pierce/
  db/
    core.d
  controllers/
    feed.d

then feed.d can have `import pierce.db.core;` instead of people being confused about how to refer to the parent directory in a relative imports style.

The tradeoff is that you have to type sometimes as many as twelve extra characters in a handful of lines of code.
December 07, 2017
On Thursday, 7 December 2017 at 17:36:22 UTC, Neia Neutuladh wrote:
> If you have a source tree like:
>
> pierce/
>   db/
>     core.d
>   controllers/
>     feed.d
>
> then feed.d can have `import pierce.db.core;` instead of people being confused about how to refer to the parent directory in a relative imports style.
>
> The tradeoff is that you have to type sometimes as many as twelve extra characters in a handful of lines of code.

Okay. So I have now

   mymod/
      foo.d
      bar.d

Now I compile the library

   $ dmd -lib -oflibmymod.a mymod/foo.d mymod/bar.d

now I want to replace all the source code by a single .di file containing the protoypes. I know that dmd -H generates protoypes. When I use

   $ dmd -H -lib -oflibmymod.a mymod/foo.d mymod/bar.d

I get

   bar.di
   foo.di

at the top level dir. Does that mean, that though the code is bundled in one library (libmymod.a) for the prototypes one has as many .di files as there
were source files?




December 07, 2017
On Thursday, 7 December 2017 at 17:53:25 UTC, kdevel wrote:
> Does that mean, that though the code is bundled in one library (libmymod.a) for the prototypes one has as many .di files as there
> were source files?

Unless those files were internal, yes. Public names in modules are... well, public. They are part of the interface, and that includes the module name (D uses module names for namespace disambiguation and it is part of the link mangle too).

You might want to look at the dmd2/src/druntime folder in the dmd zip. Contrast the import directory to the src directory.

You'll find all public modules are in both, but some internal implementations are in src only (and the compiled library) but not the import interface dir.
December 07, 2017
On 12/07/2017 06:53 PM, kdevel wrote:
> Does that mean, that though the code is bundled in one library (libmymod.a) for the prototypes one has as many .di files as there
> were source files?

yes
December 07, 2017
On Thursday, 7 December 2017 at 17:58:38 UTC, ag0aep6g wrote:
> On 12/07/2017 06:53 PM, kdevel wrote:
>> Does that mean, that though the code is bundled in one library (libmymod.a) for the prototypes one has as many .di files as there
>> were source files?
>
> yes

Gosh! So in my example I need the following structure

   libmymod.a
   main.d
   mymod/
      bar.di
      foo.di
      package.d           (note the extension!)

in order to get

   $ dmd main.d -L-L. -L-lmymod

working.