>>> 2- once again, why not use the linker support for initialization?
>>> If behavior has to depend on whether ECL was initialized yet,
>>> the initialization could consider in calling ecl_register_init_function,
>>> which depending on whether ECL was booted, would either call the function
>>> and/or add it to a hook.
>>> See once again attached files on how to use linker support for
>>> initialization.
>>
>> Fact that we might bundle many objects in one archive doesn't mean that
>> they don't have dependencies on one another. *I think* that we have to
>> strictly control initialization order. It's possible that I'm wrong here
>> though.
>>
It *is* possible to strictly control initialization order while using
linker functions:
either ensure that you link objects in the correct order (duh),
and/or have your ensure_foo_initialized functions explicitly call each other.
>> Also do we want to *always* initialize *everything* what is linked? We
>> may have compiled-in support for number of lisp libraries in one module
>> just for conveniance and require them on demand depending on the
>> application using our code.
>>
There again, the linker-called code could "just" register the initialization
function to be called later, if that's what you want.
>> I'm guessing here since it's a design decision made by someone
>> else. Your proposition is surely worth investigating - it is like it is
>> because it was that way when I approached the codebase.
>>
Some decisions that might have made sense 30 years ago when C++
was a new thing and linkers didn't specially support constructors
don't make sense 30 years later when linkers do.
I'll attach my proof-of-concept code, that didn't make it to the list.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
I'd rather write programs that write programs than write programs — Dick Sites
/*
gcc -W -Wall -Os -fPIC -Wl,-init,constructor1_init -shared -o constructor1.so constructor1.c &&
gcc -W -Wall -Os -o constructor0 constructor0.c -ldl &&
./constructor0
*/
#include <stdio.h>
#include <dlfcn.h>
#define SECTION( S ) __attribute__ ((section ( S )))
#pragma GCC diagnostic ignored "-Wunused-variable"
__asm__(".section .init \n call init0extern \n .section .text\n");
extern void init0extern(void) {
printf ("init0extern\n");
}
static void ctor0static(void) {
printf("ctor0static -- SHOULDN'T BE CALLED!\n");
}
static void (*ctor0static_ptr)(void) SECTION(".ctors") =ctor0static; // won't be called.
static void ctor0extern(void) {
printf("ctor0extern\n");
}
/*extern*/ void (*ctor0extern_ptr)(void) SECTION(".ctors") =ctor0extern;
__attribute__((constructor (110)))
static void constructor0static110() {
printf("constructor0static110\n");
}
__attribute__((constructor (130)))
static void constructor0static130() {
printf("constructor0static130\n");
}
__attribute__((constructor (120)))
extern void constructor0extern120() {
printf("constructor0extern120\n");
}
typedef void thunk(void);
static void constructor0static(void) {
printf("constructor0static\n");
}
thunk* constructor0static_ptr = constructor0static;
extern int main (int argc, char** argv) {
(void)argc; (void)argv;
printf("Hello, World!\n");
(*constructor0static_ptr)();
void* dl = dlopen("./constructor1.so", RTLD_LOCAL|RTLD_NOW); // RTLD_GLOBAL|RTLD_NOW
printf("dl = %p\n", dl);
if (!dl) {
printf("dlerror(): %s\n", dlerror());
}
thunk* c1 = (thunk*) dlsym(dl, "constructor1");
printf("constructor1 = %p\n", c1);
if (c1) {
(*c1)();
} else {
printf("dlerror(): %s\n", dlerror());
}
return 0;
}
#include <stdio.h>
#define SECTION( S ) __attribute__ ((section ( S )))
#pragma GCC diagnostic ignored "-Wunused-variable"
static void init1static(void) {
printf ("init1static\n");
}
static void init1static_caller(void) {
__asm__(".section .init");
init1static();
__asm__(".section .text\n");
}
static void ctor1static(void) {
printf("ctor1static -- SHOULDN'T BE CALLED!\n");
}
static void (*ctor1static_ptr)(void) SECTION(".ctors") =ctor1static; // won't be called.
static void ctor1extern(void) {
printf("ctor1extern\n");
}
/*extern*/ void (*ctor1extern_ptr)(void) SECTION(".ctors") =ctor1extern;
__attribute__((constructor (111)))
static void constructor1static111(void) {
printf("constructor1static111\n");
}
__attribute__((constructor (131)))
static void constructor1static131(void) {
printf("constructor1static131\n");
}
__attribute__((constructor (121)))
extern void constructor1extern121(void) {
printf("constructor1extern121\n");
}
extern void constructor1(void) {
printf("constructor1\n");
}
extern void constructor1_init(void) {
printf("constructor1_init\n");
}