Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking to an executable on OSX

On Windows it is possible to dynamically link to an executable with exported symbols. For example following code:

// main.c
void __declspec(dllexport) interface_function() {}
int main() {}

// ext.c
void interface_function();
void extension_function() {
    interface_function();
}

With

cl.exe main.c
cl.exe ext.c /LD /link main.lib

would produce an executable main.exe, a static library main.lib for implicit linking, and a dynamic library ext.dll.

Similar behavior can be achieved in OSX with shared libraries:

// main.c
void interface_function() {}
int main() {}

// ext.c
void interface_function();
void extension_function() {
    interface_function();
}

With

gcc main.c -o main
gcc ext.c -bundle -bundle_loader main -o ext.bundle

it is virtually equivalent to the Windows setup.

But for dynamiclib:

> gcc ext.c -dynamiclib -o ext.dylib

and shared:

> gcc ext.c -shared -o ext.so

I cannot get them to work because of undefined symbols on one hand and unable to load an executable with -l flag on the other.

I can let them resolve undefined symbols in runtime with -undefined dynamic_lookup. But this is not a sustainable way because all the link errors are now happening in run-time instead.

Is there a way to provide the list of symbols to dynamically load from an executable when linking as -shared and -dynamiclib?

like image 303
Teivaz Avatar asked Dec 19 '25 22:12

Teivaz


1 Answers

Yes this is possible, but then you'll want to create a bundle rather than a shared library (see this answer for more detail).

If you have a main application like so:

#include <stdio.h>
#include <dlfcn.h>

int func(void)
{
    return 42;
}

int main(void)
{
    void *dl = dlopen("plugin.so", RTLD_LOCAL);
    if(!dl) return -1;

    int (*derp)(void) = dlsym(dl, "derp");
    if(!derp) return -1;

    printf("derp(): %i\n", derp());

    return 0;
}
clang -o main main.c -Wall -Wl,-export_dynamic

Then you can compile bundles against it like so:

int func(void);

int derp(void)
{
    return -func();
}
clang -o plugin.so plugin.c -Wall -bundle -bundle_loader ./main
like image 197
Siguza Avatar answered Dec 21 '25 14:12

Siguza