Относительные RPATH при сборке проекта conan / cmake на MacOS - PullRequest
0 голосов
/ 24 ноября 2018

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


Моя первая попытка (при объединении информации из документации conan conanfile.txt для использования пакетов и справочного руководства conan 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, но увидел ту же ошибку.Я не уверен, почему это не сработало, но я перешел к другому подходу, не тратя много времени на его отладку.


Далее я следовал "различным подходам" документации RPC для conanруководство , чтобы в конечном итоге это:

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)

1 Ответ

0 голосов
/ 25 ноября 2018

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

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

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

...