Установка соответствующего rpath для проекта cmake во время установки

Я работаю над проектом со следующей структурой -

app:
- CMakeLists.txt
- lib/
  - CMakeLists.txt
- main/
  - CMakeLists.txt
  - main.cpp
- build/

Файлы в lib зависят от библиотек Boost C ++ (которых нет в путях поиска ld по умолчанию) и настроены для компиляции в общую библиотеку и связаны с объектным файлом, скомпилированным из main.cpp в окончательный двоичный файл main. Соответствующие части файлов cmake -

CMakeLists.txt верхнего уровня

project(app)

# 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")

add_subdirectory(lib)
add_subdirectory(main)

lib / CMakeLists.txt

file(GLOB src "*.cpp")
add_library(app SHARED ${src})
target_link_libraries(app PUBLIC "-L${BOOST_LIBRARYDIR} -lboost_program_options -lboost_filesystem -lboost_system")
target_include_directories(app PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
install(TARGETS app
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib/static
        RUNTIME DESTINATION bin)

main / CMakeLists.txt

add_executable(main main.cpp)

link_directories(${CMAKE_BINARY_DIR}/src)
target_link_libraries(main LINK_PUBLIC "app")
target_include_directories(main PUBLIC ${PROJECT_SOURCE_DIR}/lib)
install(TARGETS main
        RUNTIME DESTINATION bin)

Я запускаю следующую команду, чтобы построить и установить проект из каталога build:

cmake .. \
  -DBOOST_LIBRARYDIR=<path to boost lib dir> \
  -DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=FALSE \
  -DCMAKE_INSTALL_PREFIX=<path to install dir> && make install

Проблема в том, что последний main двоичный файл в каталогах сборки и установки не настроен с правильным путем к библиотекам Boost -

$ ldd <install prefix>/bin/main 
    libapp.so => <install prefix>/lib/libapp.so (0x00007f03b970f000)
    libboost_program_options.so.1.61.0 => not found
    libboost_system.so.1.61.0 => not found
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f03b9386000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f03b916e000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f03b8d7d000)
    libboost_program_options.so.1.61.0 => not found
    libboost_filesystem.so.1.61.0 => not found
    libboost_system.so.1.61.0 => not found

Вывод аналогичен для двоичного файла в каталоге сборки. Я не уверен, почему библиотеки Boost появляются здесь дважды и почему он не устанавливает правильный путь для библиотек Boost.

Какие изменения мне нужно внести в мой проект cmake, чтобы он установил правильные rpaths?

РЕДАКТИРОВАТЬ: Если я явно установил добавление пути к библиотекам Boost к LD_LIBRARY_PATH и построил проект, они будут правильно установлены в конечном исполняемом файле, но я ищу способ обойти это.

РЕДАКТИРОВАТЬ: Дополнительная информация по запросу.

$ ldd <INSTALL PREFIX>/lib/libapp.so 
    linux-vdso.so.1 (0x00007fff73f63000)
    libboost_program_options.so.1.61.0 => not found
    libboost_filesystem.so.1.61.0 => not found
    libboost_system.so.1.61.0 => not found
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fcb3c284000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fcb3c06c000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcb3bc7b000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fcb3ba77000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fcb3b858000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fcb3b4ba000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fcb3cd14000)

Следующие команды имеют пустой вывод

$ objdump -p <INSTALL PREFIX>/lib/libapp.so | grep RPATH
$ objdump -p <INSTALL PREFIX>/bin/main | grep RPATH

person nsane    schedule 02.01.2020    source источник
comment
target_link_libraries(app PUBLIC, что означает, что приложение зависит от него, но поскольку это общедоступный основной двоичный файл, он также напрямую зависит от него, поэтому они появляются дважды в ldd. * ldd main зависит от приложения, затем рекурсивно libapp.so зависит от boost, и * поскольку они являются PUBLIC в приложении, CMake также добавляет boost как прямую зависимость от bin / main   -  person Mizux    schedule 03.01.2020
comment
почему бы не использовать set_target_properties (main PROPERTIES INSTALL_RPATH $ ORIGIN /../ lib)?   -  person Mizux    schedule 03.01.2020
comment
каков результат ldd libapp.so и результат objdump -p lib/libapp.so | grep RPATH и objdump -p main | grep RPATH?   -  person Mizux    schedule 03.01.2020
comment
Почему бы не добавить $ {BOOST_LIBRARYDIR} в rpath libapp.so? (и основной rpath, если вы используете более старый пакет bintutils, см. github.com/Mizux/SecondaryDependency для объяснения   -  person Mizux    schedule 03.01.2020
comment
Спасибо @Mizux! Я не знал, что PUBLIC на самом деле сделал, потому что документация по cmake не очень информативна. Я обновил свой вопрос запрошенными вами результатами. Тем временем я попытаюсь установить свойство INSTALL_RPATH, как вы упомянули.   -  person nsane    schedule 03.01.2020
comment
согласно вашему objdump, я бы сказал, что rpath пуст для libapp.so и основного двоичного файла. вы можете попробовать добавить set_target_properties(app PROPERTIES INSTALL_RPATH "${BOOST_LIBRARYDIR}") ps: вы также можете использовать objdump -p XXX.so | grep "NEEDED\|RPATH", чтобы увидеть НЕОБХОДИМЫЕ зависимости   -  person Mizux    schedule 04.01.2020
comment
При проверке динамических тегов двоичного файла обязательно используйте grep для PATH вместо RPATH. В некоторых дистрибутивах компоновщик вместо этого помещает вещи в тег RUNPATH, если вы не используете -Wl,--disable-new-dtags: stackoverflow.com/a/52020177   -  person Nicolas Capens    schedule 28.08.2020