How to set the runtime path (-rpath) of an executable with gcc under Mac OSX?

40,441

Found by experimentation, and inspecting the command lines generated by Xcode for a reference rpath demo project by Dave Driblin:

otool -L shows you the install name of the linked libraries. To get @rpath to work, you need to change the install name of the library:

$ gcc -dynamiclib blah.o -install_name @rpath/t/libblah.dylib -o libblah.dylib
$ mkdir t ; mv libblah.dylib t/
$ gcc main.c -lblah -L`pwd`/t -Xlinker -rpath -Xlinker `pwd`
Share:
40,441
maxschlepzig
Author by

maxschlepzig

My name is Georg Sauthoff. 'Max Schlepzig' is just a silly old pseudonym (I am hesitant to change it because existing @-replies will not be updated) I studied computer science In my current line of work, I work on trading system software and thus care about low-latency

Updated on July 09, 2022

Comments

  • maxschlepzig
    maxschlepzig almost 2 years

    I want to set under Mac OSX the runtime path of an executable (for the linker) at compile time, such that shared libraries at non-standard locations are found by the dynamic linker at program start.

    Under Linux this is possible with -Xlinker -rpath -Xlinker /path/to (or using -Wl,-rpath,/path/to) and under Solaris you can add -R/path/to to the compiler command line.

    I found some information that Mac OS X gcc has -rpath support since 10.5, i.e. since ~ 2008.

    I tried to get it working with a minimal example - without success:

    $ cat blah.c 
    int blah(int b)
    {
      return b+1;
    }
    

    And:

    $ cat main.c 
    
    #include <stdio.h>
    
    int blah(int);
    
    int main ()
    {
      printf("%d\n", blah(22));
      return 0;
    }
    

    Compiled it like this:

    $ gcc -c  blah.c
    $ gcc -dynamiclib blah.o -o libblah.dylib
    $ gcc main.c -lblah -L`pwd`  -Xlinker -rpath -Xlinker `pwd`/t
    

    Now the test:

    $ mkdir t
    $ mv libblah.dylib t
    $ ./a.out
    dyld: Library not loaded: libblah.dylib
      Referenced from: /Users/max/test/./a.out
      Reason: image not found
    Trace/BPT trap
    

    Thus the question: How to I set the runtime path for the linker under Mac OSX?

    Btw, setting DYLD_LIBRARY_PATH works - but I don't want to use this hack.

    Edit: Regarding otool -L:

    $ otool -L a.out 
    a.out:
            libblah.dylib (compatibility version 0.0.0, current version 0.0.0)
            /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
    

    It seems that otool -L only prints the library names (and probable the locations at link time) the executable was linked against and no runtime path information.

    • ephemient
      ephemient over 13 years
      I don't have an OS X system but searching around, install_name_tool can add rpaths to your binary. Not sure why yours isn't working — what does otool -L say?
    • codesniffer
      codesniffer about 4 years
      Use otool -l <file> and search for the LC_RPATH sections to see the paths that a binary (library or exe) is setup to search for dependent libs.
    • codesniffer
      codesniffer about 4 years
      This page is helpful to understand rpath on Mac: https://blog.krzyzanowskim.com/2018/12/05/rpath-what/
  • maxschlepzig
    maxschlepzig over 13 years
    Yes, this works. Given that there are existing semantics of -rpath on other Unix-like OS, Apples deviating implementation seems a bit awkward. At least they should document it in their version of the gcc man-page.
  • cdunn2001
    cdunn2001 almost 13 years
    @Karel is correct, but this might be helpful as well, if you want a more complete list of alternatives.
  • codesniffer
    codesniffer about 4 years
    Use otool -l <file> and search for the LC_RPATH sections to see the paths that a binary (library or exe) is setup to search for dependent libs.
  • dstromberg
    dstromberg almost 3 years
    @cdunn2001 Your link appears to be dead.
  • cdunn2001
    cdunn2001 almost 3 years
    @dstromberg, You're right. But this links the same dead link with more elucidation and explains how to use install_name_tool, which is what I use to set the rpath.