dlopen错误“相对rpath的不安全使用”在OS X El Capitan上

2024-09-29 21:27:17 发布

您现在位置:Python中文网/ 问答频道 /正文

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

这些库在Linux和OS X Yosemite或更早版本上运行良好。但是当我在elcapitan上导入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下)。在

^{pr2}$

问题:我想知道如何通过修改CMakeLists.txt文件在这些项目中。如何通过绝对路径链接libProjectA.dylib?在

我知道install_name_tool命令可以将相对路径更改为绝对路径。但我不想让我的图书馆的用户每次都这么做。所以我想解决这个问题CMakeLists.txt文件. 在

然而,ProjectB/exeB即使它也使用libProjectB.dylib和{},没有rpath问题也可以正常工作。在


这是ProjectA的目录结构

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


Tags: inimportbuildtxtprojectcmakesoline
1条回答
网友
1楼 · 发布于 2024-09-29 21:27:17

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库之前在构建目录下测试import project_b。在

相关问题 更多 >

    热门问题