【问题标题】:dlopen error "unsafe use of relative rpath" on OS X El CapitanOS X El Capitan 上的 dlopen 错误“不安全地使用相对 rpath”
【发布时间】:2016-02-13 08:22:11
【问题描述】:

我一直在开发两个由 CMake 构建的 C++ 库。其中一个库 (ProjectB) 有一个由 SWIG 生成的 Python 包装器,它依赖于另一个库 (ProjectA)。

这些库在 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

我认为这与El Capitan的新安全技术有关,安装在/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


这里是ProjectA的目录结构,

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

和ProjectB。

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

【问题讨论】:

    标签: python c++ macos cmake swig


    【解决方案1】:

    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,以允许用户在安装 ProjectB 库之前在 build 目录下测试 import project_b

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多