Project

General

Profile

Actions

Bug #2705

closed

Install Path is not set in dylibs (shared libs) on OS X

Added by Alexander Theißen almost 11 years ago. Updated almost 11 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Target version:
Start date:
02/23/2014
Due date:
% Done:

0%

Estimated time:

Description

The OS X dynamic loader is special in a way that it doesn't look in some predefined locations to discover the referenced shared libs when an application is launched.

Instead the path to the linked dylib is stored in the mach-o binary. These entries are generated at link time.

Every dylib has an install name embedded inside the mach-o header. This is the path to the library itself. When the linker links against a dylib it reads the install name and writes it to the currently building binary as dependency.

What the wt build script fails to do is setting this install name. So it uses the default which is just the name of the lib without a path. This mean the loader just searches in the current working dir and fails to find the dylibs in their installation location.

Alexanders-iMac:lib alexander$ pwd
/opt/wt/lib
Alexanders-iMac:lib alexander$ otool -L libwthttp.3.3.1.dylib 
libwthttp.3.3.1.dylib:
    libwthttp.36.dylib (compatibility version 36.0.0, current version 3.3.1)
    libwt.36.dylib (compatibility version 36.0.0, current version 3.3.1)
    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
    /usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 50.0.0)
    /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 50.0.0)
    /usr/local/lib/libboost_thread-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_program_options-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_system-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_filesystem-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_date_time-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_random-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_regex-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_signals-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

You can pass -install_name to the linker to set the install name. Maybe there are some predefined functions in cmake to do this. I don't use cmake.

Actions #1

Updated by Wim Dumon almost 11 years ago

  • Status changed from New to Feedback

So maybe we should set this property? Could you test that and report if it works?

http://cmake.org/cmake/help/v2.8.10/cmake.html#prop_tgt:INSTALL_NAME_DIR

Actions #2

Updated by Wim Dumon almost 11 years ago

Just found some extra information: http://www.cmake.org/Wiki/CMake_RPATH_handling

If I understand correctly cmake strips install_dir information on installation, maybe it helps if you change the defaults for some of the configuration options described there.

Actions #3

Updated by Alexander Theißen almost 11 years ago

I added this to the CMakeLists.txt in the root dir:

SET (CMAKE_SKIP_BUILD_RPATH FALSE)

SET (CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

SET (CMAKE_INSTALL_RPATH \"${CMAKE_INSTALL_PREFIX}/lib\")

SET (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

Had no effect. I guess I have to set INSTALL_NAME_DIR on every target. But that means the full path is set even when not installing.

Actions #4

Updated by Alexander Theißen almost 11 years ago

I meant:

SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
Actions #5

Updated by Koen Deforche almost 11 years ago

  • Status changed from Feedback to InProgress
  • Assignee set to Koen Deforche
  • Target version set to 3.3.2

Hey,

I'm going to try this as well!

Regards,

koen

Actions #6

Updated by Koen Deforche almost 11 years ago

  • Status changed from InProgress to Feedback

Hey,

I found that by adding, in addition to the above, "SET (CMAKE_MACOSX_RPATH TRUE)" things started to move. Can you see if that's indeed the behavior you want?

Apparently this is available only since CMake 2.8.12: http://www.kitware.com/blog/home/post/510

Regards,

koen

Actions #7

Updated by Alexander Theißen almost 11 years ago

It works now. I need to apply the following settings and set the RPATH (-rpath linker flag) on my own wt application.

# this is the new setting with 2.8.12 which makes the install name use @rpath
# you can check the install name with: otool -D <file>
set(CMAKE_MACOSX_RPATH TRUE)

# these 3 settings are to set the RPATH on the libs which will be substituted for @rpath at runtime
# you can check the RPATH with: otool -l <file> | grep LC_RPATH -A2
SET(CMAKE_SKIP_BUILD_RPATH  FALSE) # activate the whole thing
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)  # we only need the RPATH when the lib is installed (otherwise use full path to source tree)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

The second block is important so that the different wt libs can find each other. Every lib or executable you link against wt therefore needs to set an appropriate RPATH. That makes it easily relocatable without messing with install_name_tool. If you get this code upstream and put a notice about setting the RPATH in the INSTALL, it would be appreciated.

Actions #8

Updated by Koen Deforche almost 11 years ago

  • Status changed from Feedback to Resolved

Hey,

Thanks for your help with this.

Regards,

koen

Actions #9

Updated by Koen Deforche almost 11 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF