cpack (создание RPM) игнорирует CMAKE_INSTALL_RPATH (устанавливает для RPATH пустую строку, а не явное значение) - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь провести довольно простой эксперимент с использованием cpack. Цель состоит в том, чтобы создать установщик RPM (используя cpack) с тривиальным исполняемым файлом, который использует внешнюю стороннюю разделяемую библиотеку (называемую libSomeSharedLib.so ).

Структура, которую я хотел бы RPM для установки:

opt
|_cmakeFindPackageTest
  |_bin
    |_cmakeFindPackageTest (an executable)
  |_lib
    |_libSomeSharedLib.so (the shared library)

Я хочу, чтобы RPATH исполняемого файла был /opt/cmakeFindPackageTest/lib (чтобы убедиться, что он использует установленную общую библиотеку).

Полный CMakeLists.txt вставляется внизу , но обратите внимание, что следующие свойства: SET

 15 SET(CMAKE_INSTALL_PREFIX "/opt/cmakeFindPackageTest")
 16 SET( INSTALL_DIR_BIN ${CMAKE_INSTALL_PREFIX}/bin )
 17 SET( INSTALL_DIR_LIB ${CMAKE_INSTALL_PREFIX}/lib )
 18 
 19 SET(CMAKE_INSTALL_RPATH "\${INSTALL_DIR_LIB}")
 20 SET(CMAKE_SKIP_BUILD_RPATH TRUE)
 21 SET(CMAKE_SKIP_INSTALL_RPATH FALSE)

Насколько я понимаю, строки 17,19,20 должны заставить cpack установить RPATH исполняемого файла равным /opt/cmakeFindPackageTest/lib

HOWEVER ...

когда я собираю проект (из чистого) и запускаю cpack для генерации RPM, я вижу это в выводе

bash-4.2$ cpack -V -G RPM
CPack: Enable Verbose
... irrelevant looking output ommitted ...
CPack Verbose: Set runtime path of "/local/bfarnham/workspace/OPC-UA/CMake_examples/cmakeFindPackageTest/build/_CPack_Packages/Linux/RPM/cmakeFindPackageTest-0.0.0-Linux/opt/cmakeFindPackageTest/bin/cmakeFindPackageTest" to ""

RPATH устанавливается пустым! Э? Проверено с помощью readelf - достаточно точно

bash-4.2$ readelf -d ./_CPack_Packages/Linux/RPM/cmakeFindPackageTest-0.0.0-Linux/opt/cmakeFindPackageTest/bin/cmakeFindPackageTest | grep --context=1 -i RPATH
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: []
 0x000000000000000c (INIT)               0x400848

Итак, наконец, вопрос: как мне получить cpack для установки RPATH этого исполняемого файла в RPM?

================ полный CMakeLists.txt =============== *

  1 cmake_minimum_required( VERSION 3.0 )
  2 project( cmakeFindPackageTest CXX )
  3 set (CMAKE_CXX_STANDARD 11)
  4 
  5 list( INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake )
  6 message( STATUS "CMAKE_MODULE_PATH [${CMAKE_MODULE_PATH}]" )
  7 find_package( SomeSharedLib 1.0 REQUIRED MODULE )
  8 message( STATUS "SomeSharedLib_INCLUDE_DIR [${SomeSharedLib_INCLUDE_DIR}]  SomeSharedLib_LIBRARY [${SomeSharedLib_LIBRARY}]" )
  9 
 10 add_executable( cmakeFindPackageTest src/main.cpp )
 11 target_link_libraries( cmakeFindPackageTest SomeSharedLib::SomeSharedLib )
 12 
 13 # =============================== INSTALL DETAILS BELOW THIS POINT ==========================
 14 
 15 SET(CMAKE_INSTALL_PREFIX "/opt/cmakeFindPackageTest")
 16 SET( INSTALL_DIR_BIN ${CMAKE_INSTALL_PREFIX}/bin )
 17 SET( INSTALL_DIR_LIB ${CMAKE_INSTALL_PREFIX}/lib )
 18 
 19 SET(CMAKE_INSTALL_RPATH "\${INSTALL_DIR_LIB}")
 20 SET(CMAKE_SKIP_BUILD_RPATH TRUE)
 21 SET(CMAKE_SKIP_INSTALL_RPATH FALSE)
 22 SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
 23 
 24 SET(CPACK_PACKAGE_NAME cmakeFindPackageTest )
 25 SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "test")
 26 SET(CPACK_PACKAGE_VENDOR "TEST_VENDOR")
 27 SET(CPACK_PACKAGE_RELOCATABLE FALSE)
 28 SET(CPACK_PACKAGE_VERSION_MAJOR "0")
 29 SET(CPACK_PACKAGE_VERSION_MINOR "0")
 30 SET(CPACK_PACKAGE_VERSION_PATCH "0")
 31 
 32 install( TARGETS 
 33   cmakeFindPackageTest
 34   RUNTIME DESTINATION ${INSTALL_DIR_BIN} )
 35 
 36 install( FILES
 37   ${SomeSharedLib_LIBRARY}
 38   DESTINATION ${INSTALL_DIR_LIB} )
 39   
 40 include( CPack )

Ответы [ 2 ]

0 голосов
/ 09 января 2020

Это не ответ; скорее дополнение к исправлению, описанному выше ...

С исправлением выше, cpack генерирует RPM с исполняемым файлом с правильным RPATH. Однако RPM был «сломан»: установка не удалась - несмотря на RPM, содержащий требуемую разделяемую библиотеку, кажется, что cpackRPM почему-то не дал ему соответствующие атрибуты в сгенерированном RPM. Сбой установки, подобный этому

bash-4.2$ sudo yum install cmakeFindPackageTest-0.0.0-Linux.rpm 
Loaded plugins: changelog, fastestmirror, kernel-module, langpacks, protectbase, tsflags, versionlock
Examining cmakeFindPackageTest-0.0.0-Linux.rpm: cmakefindpackagetest-0.0.0-1.x86_64
Marking cmakeFindPackageTest-0.0.0-Linux.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package cmakefindpackagetest.x86_64 0:0.0.0-1 will be installed
--> Processing Dependency: libSomeSharedLib.so()(64bit) for package: cmakefindpackagetest-0.0.0-1.x86_64
Loading mirror speeds from cached hostfile
211 packages excluded due to repository protections
--> Finished Dependency Resolution
Beginning Kernel Module Plugin
Finished Kernel Module Plugin
Error: Package: cmakefindpackagetest-0.0.0-1.x86_64 (/cmakeFindPackageTest-0.0.0-Linux)
           Requires: libSomeSharedLib.so()(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
bash-4.2$ 

Это решается путем указания cpack установить стороннюю библиотеку не как FILE, а как PROGRAM. Ключевой блок CMakeLists.txt:

 22 install( PROGRAMS
 23   ${SomeSharedLib_LIBRARY}
 24   DESTINATION ${INSTALL_DIR_LIB} )

Полный файл CMakeLists.txt вставлен ниже. Это создает RPM с исполняемым RPATH, установленным в каталог lib сайта установки, и совместно используемая библиотека , правильно определившая как общую библиотеку во время установки RPM (т. Е. Решает ' Требуется: Ошибка libSomeSharedLib.so '

  1 cmake_minimum_required( VERSION 3.0 )
  2 project( cmakeFindPackageTest CXX )
  3 set (CMAKE_CXX_STANDARD 11)
  4 
  5 list( INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake )
  6 message( STATUS "CMAKE_MODULE_PATH [${CMAKE_MODULE_PATH}]" )
  7 find_package( SomeSharedLib 1.0 REQUIRED MODULE )
  8 message( STATUS "SomeSharedLib_INCLUDE_DIR [${SomeSharedLib_INCLUDE_DIR}]  SomeSharedLib_LIBRARY [${SomeSharedLib_LIBRARY}]" )
  9 
 10 add_executable( cmakeFindPackageTest src/main.cpp )
 11 target_link_libraries( cmakeFindPackageTest SomeSharedLib::SomeSharedLib )
 12 
 13 SET(CMAKE_INSTALL_PREFIX "/opt/cmakeFindPackageTest" )
 14 SET(INSTALL_DIR_BIN ${CMAKE_INSTALL_PREFIX}/bin)
 15 SET(INSTALL_DIR_LIB ${CMAKE_INSTALL_PREFIX}/lib)
 16 
 17 install( TARGETS 
 18   cmakeFindPackageTest
 19   RUNTIME DESTINATION ${INSTALL_DIR_BIN} )
 20 set_target_properties( cmakeFindPackageTest PROPERTIES INSTALL_RPATH "${INSTALL_DIR_LIB}" )
 21 
 22 install( PROGRAMS
 23   ${SomeSharedLib_LIBRARY}
 24   DESTINATION ${INSTALL_DIR_LIB} )
 25 
 26 SET(CPACK_PACKAGE_NAME cmakeFindPackageTest )
 27 SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "test")
 28 SET(CPACK_PACKAGE_VENDOR "TEST_VENDOR")
 29 SET(CPACK_PACKAGE_RELOCATABLE FALSE)
 30 SET(CPACK_PACKAGE_VERSION_MAJOR "0")
 31 SET(CPACK_PACKAGE_VERSION_MINOR "0")
 32 SET(CPACK_PACKAGE_VERSION_PATCH "0")
 33 
 34 include( CPack )
 35 #include (${PROJECT_SOURCE_DIR}/CMakeEpilogue.cmake)
0 голосов
/ 09 января 2020

Я исправил это, явно установив значение свойства INSTALL_RPATH для исполняемой цели. Таким образом, добавление строки set_target_properties после вызова install

install( TARGETS 
  cmakeFindPackageTest
  RUNTIME DESTINATION ${INSTALL_DIR_BIN} )
set_target_properties( cmakeFindPackageTest PROPERTIES INSTALL_RPATH "/opt/cmakeFindPackageTest/lib" )

Из документации cmake / cpack казалось, что установка переменной CMAKE_INSTALL_RPATH должна была сработать. CMAKE_INSTALL_RPATH чтение документов

rpath для использования для установленных целей.

Список через точку с запятой, определяющий rpath для использования в установленных целях (для платформ, которые поддержать его). Это используется для инициализации целевого свойства INSTALL_RPATH для всех целей.

...