[CMake] Weirdness with shared library, RPATH policy on MacOS

Chris Wolf cw10025 at gmail.com
Sat Aug 14 12:26:38 EDT 2010



On 8/14/10 10:31 AM, Michael Wild wrote:
> 
> On 14. Aug, 2010, at 15:13 , Chris Wolf wrote:
> 
>>
>>
>> On 8/14/10 3:35 AM, Michael Wild wrote:
>>>
>>> On 13. Aug, 2010, at 20:58 , Michael Wild wrote:
>>> [...]
>>>>
>>>> Sure, http://repo.or.cz/w/freefoam.git/shortlog/refs/heads/pu, but it's pretty complex...
>>>>
>>>> Michael
>>>
>>> Attached is a tiny project which works for me on both Linux and Mac.
>>>
>>> Michael
>>>
>>
>> That's awesome! Thanks so much.  From your example, and looking at the documentation:
>> http://www.cmake.org/Wiki/CMake_RPATH_handling#Always_full_RPATH
>>
>> ...I can see the difference now - you are setting CMAKE_INSTALL_NAME_DIR. 
>> (which is not needed or used on Linux/ELF)
>>
>> What I had been trying to do along these lines was a per-target setting:
>>
>> set_target_properties(usbDynamic PROPERTIES INSTALL_NAME_DIR "/tmp/local/lib")
>>
>> -=or=-
>>
>> set_target_properties(usbDynamic PROPERTIES INSTALL_RPATH "/tmp/local/lib/libusb-1.dylib"")
>>
>> -=or=-
>>
>> set_target_properties(usbDynamic PROPERTIES
>>   INSTALL_RPATH "/tmp/local/lib/libusb-1.dylib"
>>   INSTALL_NAME_DIR "/tmp/local/lib")
>>
>> None of those were working for me.
>>
>> I will incorporate your setting in my project.
>>
>> Thanks,
>>
>>   -Chris
> 
> 
> Aaaah, I see. The INSTALL_RPATH should have been /tmp/local/lib. And RPATH is only a Linux thing, while install_name is a Mac OS X thing ;-)
> 
> Michael

Actually, "/tmp/local/lib" is just for testing - my intention is to use "/usr/local/lib".

Also RPATH on Mac OSX is no different then Linux, SunOS, etc. - only the mechanism to change it is.

For example, CMake appears to use perform direct modification of ELF-formatted binaries, 
apparently to avoid relinking upon installation (i.e. running the generated cmake_install.cmake)

It does this via the undocumented FILE(RPATH_CHANGE,.., FILE(RPATH_REMOVE,... routines.
which are called indirectly via 
cmInstallTargetGenerator::PostReplacementTweaks/cmInstallTargetGenerator::AddChrpathPatchRule

For some reason (maybe to accommodate frameworks) instead of polymorphically implementing
cmSystemTools::ChangeRPath and cmSystemTools::RemoveRPath to handle the ELF *or* Darwin
cases (which would have allowed AddChrpathPatchRule to work for ELF *and* Darwin) 
- a separate piece of logic was implemented for PostReplacementTweaks called,
cmInstallTargetGenerator::AddInstallNamePatchRule, which invokes the OSX utility
"install_name_tool" to change the RPATH in shared libraries and executables.

The way I see it (and I could be wrong) there is divergence between the logic of
AddChrpathPatchRule (ELF RPATH logic) and AddInstallNamePatchRule (Darwin RPATH logic)

Ideally, if cmSystemTools::ChangeRPath and cmSystemTools::RemoveRPath  were 
polymorphic for ELF and Darwin, you would only need AddChrpathPatchRule and not
AddInstallNamePatchRule, such that the FILE(RPATH_CHANGE,.., FILE(RPATH_REMOVE
routines would function the same for ELF and Darwin and the generated
"cmake_install.cmake" would look the same for both of these platforms - as a result,
the documented behavior (http://www.cmake.org/Wiki/CMake_RPATH_handling)
would be identical for ELF and Darwin cases.

Well, that's my two cents...

Thanks again for your help,

  -Chris


More information about the CMake mailing list