auriamg / macdylibbundler

Utility to ease bundling libraries into executables for OSX
MIT License
550 stars 83 forks source link

Add rpath support #31

Closed pamarcos closed 6 years ago

pamarcos commented 6 years ago

Current version of dylibbundler does not support rpath references in libraries. Consider the following example:

test:
        @rpath/libsdl2pp.dylib (compatibility version 0.0.0, current version 0.0.0)
        /Users/pablo/Repos/test/subprojects/install/lib/libSDL2_ttf-2.0.0.dylib (compatibility version 15.0.0, current version 15.0.0)
        /Users/pablo/Repos/test/subprojects/install/lib/libSDL2-2.0.0.dylib (compatibility version 9.0.0, current version 9.0.0)
        /Users/pablo/Repos/test/subprojects/install/lib/libSDL2_mixer-2.0.0.dylib (compatibility version 3.0.0, current version 3.0.0)
        /Users/pablo/Repos/test/subprojects/install/lib/libSDL2_image-2.0.0.dylib (compatibility version 3.0.0, current version 3.1.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)

Then, running the current version of dylibbundler:

dylibbundler -od -b -x test -d libs -p @executable_path/libs
* Collecting dependencies...
/!\ WARNING : Library libsdl2pp.dylib  has an incomplete name (location unknown)
Please specify now where this library can be found (or write 'quit' to abort):

Even though the test binary does include one rpath directory:

Load command 19
          cmd LC_RPATH
      cmdsize 72
         path /Users/pablo/Repos/test/release/subprojects/sdl2pp (offset 12)

This change aims to add support for such rpath references. It basically collects all rpaths using otool -l and looking for LC_RPATH in each dependency. Then, whenever there is an @rpath, it tries to look for that file in all rpaths collected.

In the previous given example, this the the dependencies for the resulting binary when running dylibbundler -od -b -x test -d libs -p @executable_path/libs:

test:
        @executable_path/libs/libsdl2pp.dylib (compatibility version 0.0.0, current version 0.0.0)
        @executable_path/libs/libSDL2_ttf-2.0.0.dylib (compatibility version 15.0.0, current version 15.0.0)
        @executable_path/libs/libSDL2-2.0.0.dylib (compatibility version 9.0.0, current version 9.0.0)
        @executable_path/libs/libSDL2_mixer-2.0.0.dylib (compatibility version 3.0.0, current version 3.0.0)
        @executable_path/libs/libSDL2_image-2.0.0.dylib (compatibility version 3.0.0, current version 3.1.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)

I did a little refactoring to avoid code duplication and tried to adapt to the current code style. I'm all ears for any kind of change that may be needed, so feedback is welcome.

auriamg commented 6 years ago

Thanks, that looks good. I must admit I don't have much time to test in details, but the code looked quite fine to me, hopefully that can help people

auriamg commented 6 years ago

@pamarcos The definition for "isRpath" seems to be missing, see #32

pamarcos commented 6 years ago

Shame on me, I had some extra stuff to help me debug and I did not include that chunk by mistake using git add -p. Apologies, but it's already fixed in https://github.com/auriamg/macdylibbundler/pull/33