Относительные RPATH при сборке проекта conan / cmake на MacOS

У меня есть простой проект C ++ с зависимостью от Intel TBB (который требует использования общих библиотек). Я пытаюсь построить это с помощью диспетчера пакетов Conan в сочетании с CMake, и я уже смог использовать эту настройку, чтобы добавить без общего доступа зависимости без проблем.


Моя первая попытка (объединение информации из Документация conan conanfile.txt для использования пакетов а также conan’s conanfile.py справочное руководство) использовал 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 это просто прямая копия тестовый файл для пакета TBB)

Это построено просто отлично;

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, и эта ошибка похожа на известная (но явно исправленная) проблема, поэтому я попытался запустить двоичный файл из своего собственного каталога; cd build/bin; ./main, но увидел ту же ошибку. Я не уверен, почему это не сработало, но я перешел к другому подходу, не тратя много времени на его отладку.


Затем я последовал за Документация conan «разные подходы» для руководства по RPATH в итоге это:

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 имеет несколько вариантов обработки RPATH, но ничего там не выглядит особенно актуальным, и я не понимаю, почему код в моей второй попытке (взятый непосредственно из документации Конана) не работает.

Что мне нужно сделать, чтобы общая библиотека работала с conan? (идеально кроссплатформенный, но по крайней мере на MacOS)

2

Решение

Я выяснил проблему во второй попытке после просмотра CMake’s другие переменные по одному.

Отсутствует настройка:

set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)

Надеюсь, это можно добавить в документацию Conan, потому что с включенной функцией все работает точно так, как должно. Для окончательной ссылки мои файлы сборки:

conanfile.py

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')

CMakeLists.txt

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 остаются братьями и сестрами. Выходной двоичный файл содержит только относительные пути; нет машинно-специфических путей.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector