Teivaz
Teivaz

Reputation: 5675

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?

Upvotes: 3

Views: 727

Answers (1)

Siguza
Siguza

Reputation: 23850

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

Upvotes: 1

Related Questions