digitalmars.D.learn - package modules and how to generate a shared library plus .di file (I)
- kdevel (40/40) Dec 07 2017 Given the functions void foo() and void bar() in their source
- Andrea Fontana (3/6) Dec 07 2017 Because module names are not relative to file path, but to import
- Neia Neutuladh (22/24) Dec 07 2017 If you have an editor open with ten tabs pointing to different
- kdevel (19/30) Dec 07 2017 Okay. So I have now
- Adam D. Ruppe (10/14) Dec 07 2017 Unless those files were internal, yes. Public names in modules
- ag0aep6g (2/6) Dec 07 2017 yes
- kdevel (11/17) Dec 07 2017 Gosh! So in my example I need the following structure
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
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
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
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
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
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
On Thursday, 7 December 2017 at 17:58:38 UTC, ag0aep6g wrote:On 12/07/2017 06:53 PM, kdevel wrote: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.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