www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Module static constructor doesn't work?

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
I have the following code:

// lib1/lib.d
module lib;

import std.stdio;

static this()
{
     writeln("+" ~ __FILE__);
}

static ~this()
{
     writeln("-" ~ __FILE__);
}

// main.d
int main()
{
     import std.stdio;
     writeln("hello");
     return 0;
}

So if I compile lib.d and main.d together then ctor/dtor are 
called:
$ dmd.exe main.d lib1/lib.d && main.exe
+lib1\lib.d
hello
-lib1\lib.d

But if I create library from lib.d first and then link it with 
main.d then ctor/dtor are not called:
$ dmd.exe -lib lib1/lib.d -od=lib1
$ dmd.exe main.d lib1/lib.lib && main.exe
hello
Aug 08 2019
next sibling parent Dukc <ajieskola gmail.com> writes:
On Thursday, 8 August 2019 at 14:55:37 UTC, Andrey Zherikov wrote:
 I have the following code:

 // lib1/lib.d
 module lib;

 import std.stdio;

 static this()
 {
     writeln("+" ~ __FILE__);
 }

 static ~this()
 {
     writeln("-" ~ __FILE__);
 }

 // main.d
 int main()
 {
     import std.stdio;
     writeln("hello");
     return 0;
 }

 So if I compile lib.d and main.d together then ctor/dtor are 
 called:
 $ dmd.exe main.d lib1/lib.d && main.exe
 +lib1\lib.d
 hello
 -lib1\lib.d

 But if I create library from lib.d first and then link it with 
 main.d then ctor/dtor are not called:
 $ dmd.exe -lib lib1/lib.d -od=lib1
 $ dmd.exe main.d lib1/lib.lib && main.exe
 hello
I'm looking only quickly without being sure about this, but I suspect you are only linking in the binary of `lib.d`. If you do that, you need to generate or define a header file for `lib.d`. Probably a better idea is to just use the first compiler invocation. It should generate an object file of `lib.d` that is only recompiled if you change source code of `lib.d`. If for some reason you need a `.lib` file, I think you want to still include `lib.d`. The compiler needs it to know how to use the pregenerated binary, including calling those module constructors you described. But take this with a grain of salt, because I haven't done that before and don't know the details.
Aug 08 2019
prev sibling next sibling parent reply a11e99z <black80 bk.ru> writes:
On Thursday, 8 August 2019 at 14:55:37 UTC, Andrey Zherikov wrote:
 I have the following code:

 // main.d
 int main()
 {
     import std.stdio;
     writeln("hello");
     return 0;
 }

 But if I create library from lib.d first and then link it with 
 main.d then ctor/dtor are not called:
 $ dmd.exe -lib lib1/lib.d -od=lib1
 $ dmd.exe main.d lib1/lib.lib && main.exe
 hello
try to add to main.d:
 import lib1.lib;
Aug 08 2019
parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Thursday, 8 August 2019 at 16:04:33 UTC, a11e99z wrote:
 On Thursday, 8 August 2019 at 14:55:37 UTC, Andrey Zherikov 
 wrote:
 I have the following code:

 // main.d
 int main()
 {
     import std.stdio;
     writeln("hello");
     return 0;
 }

 But if I create library from lib.d first and then link it with 
 main.d then ctor/dtor are not called:
 $ dmd.exe -lib lib1/lib.d -od=lib1
 $ dmd.exe main.d lib1/lib.lib && main.exe
 hello
try to add to main.d:
 import lib1.lib;
Actually importing solved the issue although it's not ideal solution IMO. Thanks for your help!
Aug 08 2019
prev sibling parent kinke <kinke gmx.net> writes:
On Thursday, 8 August 2019 at 14:55:37 UTC, Andrey Zherikov wrote:
 But if I create library from lib.d first and then link it with 
 main.d then ctor/dtor are not called:
For this to work as expected, the `lib.obj` object file needs to be linked into the final executable. As main.d doesn't need anything from lib.d, the linker will skip it by default if it's in a static library. An `import lib1.lib` isn't enough, you need to reference some symbol in main.d. Or instruct the linker to use all object files in the static library (e.g., via /WHOLEARCHIVE with the MS linker).
Aug 08 2019