January 21, 2021
I need your help even after reading the documentation[1] and some of druntime source code.

This is all on Linux (Ubuntu).

I have a D shared library (let's call it libparent.so) that dynamically and conditionally loads other D shared libraries (let's call one of them libchild.so).

The parent library is supposed to be used by D, C++, and Python programs; so it defines a 'pragma(crt_constructor)'[2] function which calls rt_init() to initialize the D runtime.

The parent library calls Runtime.loadLibrary() to load libchild.so. What is important here is that the 'shared static this' section of the child gets called and everybody is happy in most of our use cases:

- D runtime is initialized by the parent

- The 'shared static this' of the child is called upon loadLibrary

Unfortunately, things break when the parent library is loaded from a distance. :) In this case, the parent library is *not* linked with the program or loaded by it directly:

1) A Python program that loads

2) a Python module that loads

3) a SIP Python extension module (mylib_sip.so, which is generated C code from SIP (I learned that SIP is a QT thing)) that links with

4) a user library in C++ (mylib.so) that loads

5) our libparent.so mentioned above.

THE PROBLEM:

- GOOD: The 'pragma(crt_constructor)' function of libparent.so gets called

- GOOD: Runtime.loadLibrary() for the child succeeds (dlsym works too)

- BAD: The 'shared static this' of libchild.so is not called

(Note: Others have reported that things work when children are loaded in different orders. Hmmm... Could this be related? I've seen code in druntime about module ctor dependencies and their ordering before execution.)

Am I missing crucial steps or making wrong assumptions here?

Can you think of a workaround to force calling module ctors of child library? I tried dlsym'ing and calling two functions with names "init" in them but it did not run the 'shared static this' of the child either. (Minor complication: The module ctors do get called when linked in other use cases; so, my calling ctors explicitly would be extra in those cases, but luckily the ctors are idempotent.)

How about thread_attachThis? (I ask because everything works without thread_attachThis in other use cases even when we are loaded into another Python program! Oh... it must be because rt_init() gets called from the Python thread and rt_init already attaches this thread.) I tried this as well but there are so many dimensions that I may have missed the right combination that would work.

Thank you,
Ali

[1] https://dlang.org/articles/dll-linux.html

[2] https://dlang.org/spec/pragma.html#crtctor