Sign up

pre-initialization hooks in gtkd

I had a problem recently in a gtkd program i wrote. The program could only find a certain shared library (libatk) if the environment variable GTK_BASEPATH was set; otherwise, it would throw an exception before main() started.

I did not want to set that environment variable, or any environment variable, either on the command line or in a shell initialization script. Instead i wanted to set it from within the executable.

I did not have a solution for this, but Rikki Cattermole told me about pragma crtconstructor. So now i have a short function which runs after the c-runtime is setup but before the d-runtime is, and it sets GTKBASEPATH. Right now, it looks like this:

pragma( crt_constructor ) extern( C ) void _env_setup( ) {
  import core.sys.posix.stdlib : getenv, putenv;
  auto val = getenv( cast( const char * ) "GTK_BASEPATH".ptr );
  if ( val ) {
    writeln( "GTK_BASEPATH already has a value, not setting" );
  } else {
    writeln( "Setting GTK_BASEPATH to /opt/local/lib" );
    putenv(cast(char*)"GTK_BASEPATH=/opt/local/lib".ptr);
  }
}

This works, at least for dmd (and given a std.stdio import for the writeln), but actually it's not really doing all i want.

I would like to write an arbitrary amount of d code, including routines that require GC, that runs before gtkd does. (For the crt_constructor code, one is limited in what can be written. Nothing that requires GC can be written, because the d runtime has not yet been set up.)

In some cases, for example if the program gets a --version or a --help argument, i would not want to run gtkd at all, but just exit(0) out; in these cases, lack of a shared library does not matter.

And if a shared library is missing, maybe the software might query the user directly on where to find it (using stdout/stdin question/response).

So, are there any pre-initialization hooks in gtkd that i can assign that will be guaranteed to be called before any serious initialization is run (especially before any shared libraries are loaded)?

Or are there other alternatives to the crt_constructor pragma?

This is not urgent, since Rikki's code works for me, but on the d language forum it was suggested that i check with the gtkd forum also.

Re: pre-initialization hooks in gtkd

On 17-10-2023 01:42, dan hitt wrote:

So, are there any pre-initialization hooks in gtkd that i can assign
that will be guaranteed to be called before any serious initialization
is run (especially before any shared libraries are loaded)?

GtkD loads the libraries in the static constructors, and doesn't provide
a way to anything before that other than what D itself provides with
pragma crt_constructor.

Re: pre-initialization hooks in gtkd

On Tue, 17 Oct 2023 19:17:22 +0200, Mike Wey wrote:

On 17-10-2023 01:42, dan hitt wrote:

So, are there any pre-initialization hooks in gtkd that i can assign
that will be guaranteed to be called before any serious initialization
is run (especially before any shared libraries are loaded)?

GtkD loads the libraries in the static constructors, and doesn't provide
a way to anything before that other than what D itself provides with
pragma crt_constructor.

Re: pre-initialization hooks in gtkd

On Tue, 17 Oct 2023 19:17:22 +0200, Mike Wey wrote:

On 17-10-2023 01:42, dan hitt wrote:

So, are there any pre-initialization hooks in gtkd that i can assign
that will be guaranteed to be called before any serious initialization
is run (especially before any shared libraries are loaded)?

GtkD loads the libraries in the static constructors, and doesn't provide
a way to anything before that other than what D itself provides with
pragma crt_constructor.

Thanks Mike for clarifying the point, and for shepherding gtkd along to
this point where it is productive every day on every computer.

(And if this message gets posted twice, sorry, somehow i was trying
to log in and post at the same time.)