chacham15
chacham15

Reputation: 14281

How can I specify the rpath in a dylib?

I have a library: libfoo.dylib. The problem is illustrated in the commands:

$ install_name_tool -id "@rpath/libfoo.dylib" libfoo.dylib
$ install_name_tool -add_rpath "@executable_path/" libfoo.dylib
$ gcc -o foo foo.c -lfoo
$ ./foo #<==== I want this to work
dyld: Library not loaded: @rpath/libfoo.dylib
  Referenced from: ~/./foo
  Reason: image not found
$ install_name_tool -add_rpath "@executable_path/" foo #<=== I dont want to have to specify here where to look for the library
$ ./foo
Hello World

How do I achieve the goal of not having to specify at executable compile where the library is?

Upvotes: 4

Views: 12088

Answers (2)

bdash
bdash

Reputation: 18308

I must confess that I'm a little confused as to what you're trying to achieve. The entire point of using the runpath search path is that the images loading the library define the search path to be used when loading the library. What you're asking for is for the library to define where the executable should find it. That can be accomplished without using the runpath search path by simply setting the install name of the dylib to the appropriate value. Based on your particular example, it sounds like you want to set the install name to something like @loader_path/libfoo.dylib. Consider the following, which is along the same lines of your sample:

$ cat a.c 
int a(void)
{
    return 1;
}
$ cc -install_name "@loader_path/liba.dylib" -dynamiclib -o liba.dylib a.c 
$ cat main.c
#include <stdio.h>

extern int a(void);

int main(int argc, char **argv)
{
    fprintf(stderr, "A: %d\n", a());
    return 0;
}
$ cc -L. -la -o main main.c
$ ./main
A: 1
$ 

The library tells executables that link against it how to find it by setting its install name, and nothing special needs to be done when linking the executable to have it find the library at runtime.

Upvotes: 2

rectummelancolique
rectummelancolique

Reputation: 2247

The only thing you need is to tell the linker to add the rpath in your binary. Actually, you tell gcc to tell the linker in the following way:

$ gcc -o foo foo.c -lfoo -Wl,-rpath=/some/path

Now if you use objdump to see what's in there:

$ objdump -x ./foo | less

You will see under Dynamic Section somthing like RPATH /some/path.

If having to type the same -Wl,-rpath=... is too cumbersome, ld accepts the @file option (I don't know about dyld but I suppose it does too):

$ echo "-rpath=/some/path" > ./ld-options
$ gcc ./foo.c -o foo -Wl,@ld-options

Upvotes: -1

Related Questions