www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - package modules and how to generate a shared library plus .di file (I)

reply kdevel <kdevel vogtner.de> writes:
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?
Dec 07 2017
next sibling parent Andrea Fontana <nospam example.com> writes:
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.
Dec 07 2017
prev sibling parent reply Neia Neutuladh <neia ikeran.org> writes:
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.
Dec 07 2017
parent reply kdevel <kdevel vogtner.de> writes:
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?
Dec 07 2017
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
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.
Dec 07 2017
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
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
Dec 07 2017
parent kdevel <kdevel vogtner.de> writes:
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.
Dec 07 2017