我有一个依赖于Intel TBB(需要使用共享库)的简单C ++项目。我正在尝试使用结合了CMake的Conan软件包管理器来构建它,并且我已经能够使用此设置添加没有问题的非共享依赖项。
我的第一次尝试(结合来自conan's conanfile.txt documentation for using packages和conan's conanfile.py reference guide的信息)使用了conanfile.py
,如下所示:
import os
from conans import ConanFile, CMake
class MyProjectConan(ConanFile):
settings = 'os', 'compiler', 'build_type', 'arch'
requires = 'TBB/2018_U6@conan/stable'
generators = 'cmake'
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def imports(self):
self.copy('*.dll', src='bin', dst='bin')
self.copy('*.dylib*', src='lib', dst='bin')
self.copy('*.so', src='lib', dst='bin')
和这样的CMakeLists.txt
:
cmake_minimum_required(VERSION 2.8.12)
project(MyProject)
add_definitions("-std=c++17")
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
add_executable(main src/main.cpp)
target_link_libraries(main ${CONAN_LIBS})
(我的src/main.cpp
只是the test file for the TBB package的直接副本)
这很不错;
conan install -if build .
conan build -bf build .
但是运行./build/bin/main
失败并出现以下错误:
dyld: Library not loaded: @rpath/libtbb.dylib Referenced from: <project-dir>/./build/bin/main Reason: image not found Abort trap: 6
我在MacOS上,并且此错误类似于known (but apparently fixed) issue,因此我尝试从其自己的目录运行二进制文件。 cd build/bin; ./main
,但看到相同的错误。我不确定为什么这行不通,但是我转而使用另一种方法,而没有花很多时间调试它。
接下来,我跟随conan documentation's "different approaches" for RPATHs guide结束:
class MyProjectConan(ConanFile):
# (rest of class is same as before)
def imports(self):
self.copy('*.dll', src='bin', dst='bin')
self.copy('*.dylib*', src='lib', dst='lib') # changed bin to lib
self.copy('*.so', src='lib', dst='lib') # changed bin to lib
这:
cmake_minimum_required(VERSION 2.8.12)
project(MyProject)
add_definitions("-std=c++17")
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(KEEP_RPATHS)
if(APPLE)
set(CMAKE_INSTALL_RPATH "@executable_path/../lib")
else()
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
endif()
add_executable(main src/main.cpp)
target_link_libraries(main ${CONAN_LIBS})
哪个甚至可以运行!但是,当我检查可执行文件时,发现它引用了/Users/me/.conan/data/TBB/2018_U6/conan/stable/package/03db91a62823ebc2b1df6e5cf549c2f674116656/lib
,这显然不是该代码应该执行的操作(我本来希望看到@rpath/../lib
或类似的文件)。我还验证了二进制文件确实在使用此路径,而不是在其同级lib
文件夹中放置的文件。
这时我被卡住了。我可以看到CMake具有a few options for RPATH handling,但是看起来没有什么特别重要,而且我不理解为什么第二次尝试中的代码(直接从柯南的文档中获取)不起作用。
要使共享库与柯南一起工作,我需要怎么做? (理想情况下是跨平台的,但至少在MacOS上如此)
答案 0 :(得分:3)
在逐一查看CMake的other variables之后,我在第二次尝试中发现了问题。
缺少的设置是这样的:
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
希望可以将其添加到Conan文档中,因为启用该功能后,所有操作均应按应有的方式进行。作为最终参考,我的构建文件是:
from conans import ConanFile, CMake
class MyProjectConan(ConanFile):
settings = ('os', 'compiler', 'build_type', 'arch')
requires = (
'TBB/2018_U6@conan/stable',
)
generators = 'cmake'
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def imports(self):
self.copy('*.dll', src='bin', dst='bin')
self.copy('*.dylib*', src='lib', dst='lib')
self.copy('*.so', src='lib', dst='lib')
cmake_minimum_required(VERSION 2.8.12)
project(MyProject)
add_definitions("-std=c++11") # to use 17, must also set '-s cppstd=17' on conan install
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(KEEP_RPATHS)
if(APPLE)
set(CMAKE_INSTALL_RPATH "@executable_path/../lib")
else()
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
endif()
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) # <-- this is the line which is missing in the Conan documentation!
add_executable(main src/main.cpp)
target_link_libraries(main ${CONAN_LIBS})
conan install -if build .
conan build -bf build .
./build/bin/main
只要生成的bin和lib目录仍然是同级,它就可以正常工作。输出二进制仅包含相对路径;没有机器专用的路径。