2016-02-13 71 views
0

我一直在開發兩個由CMake構建的C++庫。其中一個庫(ProjectB)有一個由SWIG生成的Python包裝器,它依賴於其他庫(ProjectA)。在OS X上dlopen錯誤「不安全地使用相對路徑」El Capitan

這些庫在Linux和OS X Yosemite或更早版本上運行良好。但是當我在El Capitan中導入ProjectB的Python包裝時,出現以下錯誤。

$ python 
>>> import project_b 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "project_b.py", line 28, in <module> 
    _project_b = swig_import_helper() 
    File "project_b.py", line 24, in swig_import_helper 
    _mod = imp.load_module('_project_b', fp, pathname, description) 
ImportError: dlopen(./_project_b.so, 2): Library not loaded: libProjectA.dylib 
    Referenced from: /Users/oxon/cmake_test/ProjectB_build/_project_b.so 
    Reason: unsafe use of relative rpath libProjectA.dylib in ./_project_b.so with restricted binary 

我認爲這是關係到埃爾卡皮坦的新的安全技術,如果他們是通過一個相對路徑稱爲/usr/local/lib下安裝動態庫無法加載。事實上,otool -L顯示我的Python包裝(_project_b.so)具有到ProjectA的相對路徑(libProjectA.dylib,它安裝在/usr/local/lib下)。

$ otool -L _project_b.so 
_project_b.so: 
    /System/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.10) 
    libProjectA.dylib (compatibility version 0.0.0, current version 0.0.0) 
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1) 

問題:我想知道如何在這些項目中修改我的CMakeLists.txt修復此錯誤。如何通過絕對路徑鏈接libProjectA.dylib

我知道install_name_tool命令可以將相對路徑更改爲絕對路徑。但我不想讓我的圖書館的用戶每次都這樣做。所以我想在CMakeLists.txt中解決這個問題。

ProjectB/exeB然而,工作正常,沒有rpath問題,即使它也使用libProjectB.dyliblibProjectA.dylib


這裏是項目A的目錄結構,

ProjectA 
├── CMakeLists.txt 
├── ProjectAConfig.cmake 
├── include 
│   └── ProjectA 
│    └── MyClassA.h 
└── src 
    └── MyClassA.cxx 

項目B的和。

ProjectB 
├── CMakeLists.txt 
├── exeB.cxx 
├── include 
│   └── ProjectB 
│    └── MyClassB.h 
├── project_b.i 
└── src 
    └── MyClassB.cxx 

我按照以下步驟完成了構建過程。

$ pwd 
/Users/oxon/cmake_test 
$ ls 
ProjectA  ProjectA_build ProjectB  ProjectB_build 
$ cd ProjectA_build 
$ cmake ../ProjectA 
$ make 
$ sudo make install 
$ cd ../ProjectB_build 
$ cmake ../ProjectB 
$ make 
$ python 
>>> import project_b 

您可以從 https://github.com/akira-okumura/stackoverflow_question

回答

2

下載我最小的例子ProjectB/CMakeLists.txt添加以下行已經解決了該問題。

if(APPLE) 
    set(CMAKE_MACOSX_RPATH TRUE) 

# The following settings were copied from 
# https://cmake.org/Wiki/CMake_RPATH_handling 
# to avoid the rpath issue that appears on OS X El Capitan 

    # use, i.e. don't skip the full RPATH for the build tree 
    set(CMAKE_SKIP_BUILD_RPATH FALSE) 

    # when building, don't use the install RPATH already 
    # (but later on when installing) 
    set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) # Changed to TRUE by A.O. 

    set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 

    # add the automatically determined parts of the RPATH 
    # which point to directories outside the build tree to the install RPATH 
    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 

    # the RPATH to be used when installing, but only if it's not a system directory 
    list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) 
    if("${isSystemDir}" STREQUAL "-1") 
    set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 
    endif("${isSystemDir}" STREQUAL "-1") 
endif() 

CMAKE_BUILD_WITH_INSTALL_RPATH選項從FALSE改爲TRUE以允許用戶在安裝項目B庫之前測試import project_b build目錄下。

相關問題