0

I am making a package manager, and would like to ensure the packages use the correct dependent library by setting rpath option at compile time. But it surprised me in OS X (10.11), here is the problem:

$ otool -L /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951 
/opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951:
    /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
    /opt/starman/software/isl/0.17.1/104994def2b7fb2dae7950b42205eb718a46ee0c/lib/libisl.15.dylib (compatibility version 18.0.0, current version 18.1.0)
    /opt/starman/software/mpc/1.0.3/6058925218009b8ab17e07333dc54de334134f6e/lib/libmpc.3.dylib (compatibility version 4.0.0, current version 4.0.0)
    /opt/starman/software/mpfr/3.1.4/f142dfcda3b56650a8c9cfe2fdd09ffdf7283a00/lib/libmpfr.4.dylib (compatibility version 6.0.0, current version 6.4.0)
    /opt/starman/software/gmp/6.1.0/0ec8ef118d09cb33f83559685d006f56a74f865c/lib/libgmp.10.dylib (compatibility version 14.0.0, current version 14.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

see gmp version is 14.0.0.

$ /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951 
dyld: Library not loaded: /opt/starman/software/gmp/6.1.0/0ec8ef118d09cb33f83559685d006f56a74f865c/lib/libgmp.10.dylib
  Referenced from: /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951
  Reason: Incompatible library version: f951 requires version 14.0.0 or later, but libgmp.10.dylib provides version 13.0.0
Trace/BPT trap: 5

It says gmp in the correct path is not loaded since its version is 13.0.0, but it is 14.0.0! I know I have an older version gmp installed in another path, so after I remove its lib path from DYLD_LIBRARY_PATH, the problem is gone, but shouldn't rpath solve this problem?

Why dyld prints the correct path of gmp, but actually uses the wrong old? Is there any tricks in OS X? Thanks for help!

EDIT 1: The version of /opt/starman/software/gmp/6.1.0/0ec8ef118d09cb33f83559685d006f56a74f865c/lib/libgmp.10.dylib is checked as

$ otool -l /opt/starman/software/gmp/6.1.0/0ec8ef118d09cb33f83559685d006f56a74f865c/lib/libgmp.10.dylib
...
      cmdsize 120
         name /opt/starman/software/gmp/6.1.0/0ec8ef118d09cb33f83559685d006f56a74f865c/lib/libgmp.10.dylib (offset 24)
   time stamp 1 Thu Jan  1 08:00:01 1970
      current version 14.0.0
compatibility version 14.0.0
...

And the older gmp is

$ otool -l /opt/software/gmp/6.0.0a/0/lib/libgmp.10.dylib
...
         name @rpath/lib/libgmp.dylib (offset 24)
   time stamp 1 Thu Jan  1 08:00:01 1970
      current version 13.0.0
compatibility version 13.0.0
...

EIDT 2

According to 0xced, I run debug the loading process as (The full output is here):

$ export DYLD_PRINT_LIBRARIES="1"
$ /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951
dyld: loaded: /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951
dyld: loaded: /usr/lib/libiconv.2.dylib
dyld: loaded: /opt/starman/software/isl/0.17.1/104994def2b7fb2dae7950b42205eb718a46ee0c/lib/libisl.15.dylib
dyld: loaded: /opt/software/packman.active/lib/libmpc.3.dylib
dyld: loaded: /opt/software/packman.active/lib/libmpfr.4.dylib
dyld: loaded: /opt/software/packman.active/lib/libgmp.10.dylib
dyld: unloaded: /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951
dyld: unloaded: /opt/starman/software/isl/0.17.1/104994def2b7fb2dae7950b42205eb718a46ee0c/lib/libisl.15.dylib
dyld: unloaded: /opt/software/packman.active/lib/libmpc.3.dylib
dyld: unloaded: /opt/software/packman.active/lib/libmpfr.4.dylib
dyld: unloaded: /opt/software/packman.active/lib/libgmp.10.dylib
dyld: Library not loaded: /opt/starman/software/gmp/6.1.0/0ec8ef118d09cb33f83559685d006f56a74f865c/lib/libgmp.10.dylib
  Referenced from: /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951
  Reason: Incompatible library version: f951 requires version 14.0.0 or later, but libgmp.10.dylib provides version 13.0.0
Trace/BPT trap: 5
Li Dong
  • 1,088
  • 2
  • 16
  • 27
  • What's rpath got to do with the question? Are you sure that version of the `gmp` library is 14 and not 13? – Droppy Jun 02 '16 at 09:42
  • Because the `gmp` library path is hardcoded in `f951`, and I think this is the effect of `rpath`. The versions of the two `gmp` on my computer are shown above by using `otool -l`. – Li Dong Jun 02 '16 at 09:56

1 Answers1

0

I don't understand why the f951 binary would load /opt/software/gmp/6.0.0a/0/lib/libgmp.10.dylib (version 13) rather than /opt/starman/software/gmp/6.1.0/0ec8ef118d09cb33f83559685d006f56a74f865c/lib/libgmp.10.dylib (version 14) which is specified with an absolute path and not a relative @rpath.

Maybe it’s loaded indirectly via another library, e.g. libisl.15.dylib, libmpc.3.dylib or libmpfr.4.dylib which could have an @rpath reference to libgmp.10.dylib?

To diagnose this issue, I suggest you to run the main executable like this:

$ DYLD_PRINT_RPATHS=YES /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951

This will print all rpath expansions (both failure and success) and will probably give you the answer to your question.

0xced
  • 25,219
  • 10
  • 103
  • 255
  • Thanks for help! I checked those dylibs, and they all loaded the correct `gmp`. I also run `f951` with `DYLD_PRINT_RPATHS=YES`, but it does not print more information. – Li Dong Jun 08 '16 at 03:05
  • I export `DYLD_PRINT_LIBRARIES` to 1 referring `https://gist.github.com/wycats/1627976`, and it printed. The full output is [here](https://gist.github.com/dongli/c0b8153573db0332ef519c74341cd264) – Li Dong Jun 08 '16 at 03:13
  • Does it work if you remove `/opt/software/packman.active/lib` from your `DYLD_LIBRARY_PATH` environment variable? – 0xced Jun 08 '16 at 06:37
  • Can you please try the **exact command** in my answer, i.e. `DYLD_PRINT_RPATHS=YES /opt/starman/software/gcc/6.1.0/83894f21d07366be296600ec031ae4f6241381d9/libexec/gcc/x86_64-apple-darwin15.5.0/6.1.0/f951` ? You should get rpath debug logs. – 0xced Jun 09 '16 at 13:42
  • I have tried exactly as your command, and it printed no debug logs. – Li Dong Jun 09 '16 at 13:46
  • Does it work if you try to print rpath debug logs on another executable, for example, Xcode? `DYLD_PRINT_RPATHS=YES /Applications/Xcode.app/Contents/MacOS/Xcode` – 0xced Jun 09 '16 at 13:48
  • If `libgmp.10.dylib` is loaded from `/opt/software/packman.active/lib` then it probably means that one of your dylib is referencing it without an absolute path. And since `DYLD_LIBRARY_PATH` contains `/opt/software/packman.active/lib` it's loaded from there. You should check all your dylibs with `otool -L` to see if there's a dependency without an absolute path. – 0xced Jun 10 '16 at 06:36