0

In my project, I use cmake to construct the building system, I need to build an external project(here, I take zeromq for example) with ExternalProject_add, then pack the compiled binaries in a RPM package, but I need the generated RPM to have correct "PROVIDES" information to tell which libraries it provides, just like below

libzmq.so.5()(64bit)
zeromq = 4.1.2-1.el7
zeromq(x86-64) = 4.1.2-1.el7

But somehow, with setting CPACK_RPM_PACKAGE_AUTOPROV to 1, the built RPM still doesn't have correct 'PROVIDES' information, I will get 'PROVIDES' information below, without the provided libraries information

zeromq = 4.1.2-1
zeromq(x86-64) = 4.1.2-1

the CMakeLists.txt(just some key content) for this is

cmake_minimum_required (VERSION 3.4.0 FATAL_ERROR)    
set(COMP zeromq)
set(CompVersion 4.1.2)
set(CompURL http://download.zeromq.org/zeromq-${CompVersion}.tar.gz)
set(CompMD5 159c0c56a895472f02668e692d122685)

project(${COMP}  VERSION ${CompVersion})
include(ExternalProject)

ExternalProject_add(${COMP}
  PREFIX            ${COMP}
  URL               ${CompURL}
  URL_MD5           ${CompMD5}
  CONFIGURE_COMMAND <SOURCE_DIR>/configure --without-libsodium --prefix=${CMAKE_INSTALL_PREFIX})

install(FILES ${CMAKE_INSTALL_PREFIX}/lib/libzmq.so.5
              ${CMAKE_INSTALL_PREFIX}/lib/libzmq.so
              ${CMAKE_INSTALL_PREFIX}/lib/libzmq.so.5.0.0
        DESTINATION lib64)

string(REPLACE "." ";" VERSION_LIST ${PROJECT_VERSION})
list(LENGTH VERSION_LIST VERSION_LIST_LENGTH)
list(GET VERSION_LIST 0 CPACK_PACKAGE_VERSION_MAJOR)
list(GET VERSION_LIST 1 CPACK_PACKAGE_VERSION_MINOR)
if(VERSION_LIST_LENGTH GREATER 2)
  list(GET VERSION_LIST 2 CPACK_PACKAGE_VERSION_PATCH)
endif()


set(CPACK_GENERATOR "RPM")
set(CPACK_PACKAGE_VENDOR "Test")
set(CPACK_RPM_PACKAGE_GROUP "3rd-party-software")
set(CPACK_RPM_PACKAGE_AUTOPROV 1)
set(CPACK_RPM_PACKAGE_AUTOREQ 0)

set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
  /usr/lib
  /usr/lib64)
set(CPACK_RPM_COMPONENT_INSTALL OFF)

include(CPack)

Does someone know why this "CPACK_RPM_PACKAGE_AUTOPROV" option doesn't take effect? how can I make it auto generates these 'PROVIDES' information in the RPM? thanks for your time and it will be very appreciated if you can provide some hints.

Rex
  • 1
  • 1

2 Answers2

0

CPACK_RPM_PACKAGE_AUTOPROV variable, by its description:

May be used to enable (1, yes) or disable (0, no) automatic listing of shared libraries that are provided by the package.

affects only on targets created by add_library(SHARED).

Neither CMake nor CPack tries to deduce file's type from their extension, that's why manually installed files (via install(FILES)) are not affected.

For add given files to PROVIDES list, use variable CPACK_RPM_PACKAGE_PROVIDES:

May be used to set RPM dependencies (provides). The provided package list of an RPM file could be printed with:

rpm -qp --provides file.rpm

Community
  • 1
  • 1
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • thanks, but it's strange that, for the same project, if enables 'CPACK_RPM_PACKAGE_AUTOREQ', it works and generates the 'REQUIRENAME' information in the RPM packages. as my understanding, if the option only for libraries added by 'add_library', the option 'CPACK_RPM_PACKAGE_AUTOREQ' shall behave the same, right? – Rex Mar 25 '16 at 07:22
  • I need to add many such kind of projects, if add the 'PROVIDES' information manually, it needs much time. but still thanks :) – Rex Mar 25 '16 at 07:25
  • Is option `CPACK_RPM_PACKAGE_AUTOREQ` detects libraries, from which `libzmq.so` depends? Or how this option correlates with that 3d-party library? – Tsyvarev Mar 25 '16 at 07:46
  • I don't know, but with enabling CPACK_RPM_PACKAGE_AUTOREQ, below informations are added in REQUIRENAME of the RPM /bin/sh /bin/sh /bin/sh libzmq.so.5()(64bit) rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(PayloadIsXz) <= 5.2-1 – Rex Mar 25 '16 at 07:50
  • It looks like CPack(CMake) detects, that `libzmq.so` is needed for your package, because some of your library (created with `add_library`) links it. **As if you doesn't install this libfile manually**. No controversals with `CPACK_RPM_PACKAGE_AUTOPROV` behavior. – Tsyvarev Mar 25 '16 at 08:47
  • okay, do you have some ideas that how can I auto-generate the PROVIDES information? – Rex Mar 25 '16 at 08:57
  • Every time you install library with `install(FILES)` you may accumulate this library in some list variable(or global property). At the end you may assign this variable to `CPACK_RPM_PACKAGE_PROVIDES`. – Tsyvarev Mar 25 '16 at 09:09
  • I tried this solution, generating the libraries info needs that the libraries are built and installed, then I can use /usr/lib/rpm/find-provides to fetch the 'provides' information, but the setting on "CPACK_RPM_PACKAGE_PROVIDES" is set before building the libraries. it makes me crazy... – Rex Mar 25 '16 at 09:19
  • From my experiment, the argument to `CPACK_RPM_PACKAGE_PROVIDES` shall be a comma separated list (while cmake generates semi-column separated list). @Tsyvarev could you maybe advertise this point in your answer? In order for my package to provide a correct list of _provides_ I had to `string(REPLACE ";" " " CPACK_RPM_PACKAGE_PROVIDES "${CPACK_RPM_PACKAGE_PROVIDES})`. At least, I hope my understanding is right ^^ – Vser Dec 18 '18 at 10:56
  • @Vser: I agree that nature of variable `CPACK_RPM_PACKAGE_PROVIDES` is important, but I have a little experience with CPack, so I feel that I shouldn't post anything except documentation excerpts (or make conclusions which are purely CMake-related - in that area my understanding is good). You may create your own answer, and describe this specifics in it. I would be glad to refer to your answer from the mine. – Tsyvarev Dec 18 '18 at 12:02
  • 1
    @Tsyvarev There is in fact a simpler solution to that problem. See my answer below :) – Vser Dec 18 '18 at 14:20
0

Using install(PROGRAMS instead of install(FILES generates correct provides in the rpm for .so files (at least with cmake 3.13). As per the documentation:

The PROGRAMS form is identical to the FILES form except that the default permissions for the installed file also include OWNER_EXECUTE, GROUP_EXECUTE, and WORLD_EXECUTE. This form is intended to install programs that are not targets, such as shell scripts.

Maybe the documentation could add that it's suitable for shared libs too.

If you want to stick to CPACK_RPM_PACKAGE_PROVIDES, beware that the variable has to be a comma separated list.

(Maybe another possible addition to the documentation).

Vser
  • 578
  • 4
  • 18