cmakerpmmanpagecpack

CPackRPM compresses Man pages and then cannot find them during packaging


While creating a RPM package containing a man page (which installation path matches a list of known man locations), CPack seems to compress it using GZip, but then complains that the original, uncompressed file cannot be found. How should that functionality be used then?

Consider the following CMakeLists.txt project:

install(FILES test.1 DESTINATION /usr/share/man)
install(FILES test.2 DESTINATION /usr/share/man/man1)

set(CPACK_PACKAGE_NAME "CPackRPM_man_test")
set(CPACK_GENERATOR "RPM")
include(CPack)

When the line containing “test.2” is commented out, make package operation succeeds, — that is, simply packaging a file that is not destined to a true man page location does not cause any trouble. However, when the full project is processed, the following error message is output:

error: File not found: …/_CPack_Packages/Linux/RPM/CPackRPM_man_test-0.1.1-Linux/usr/share/man/man1/test.2

Indeed, that file simply does not exist:

$ cd …/_CPack_Packages/Linux/RPM/CPackRPM_man_test-0.1.1-Linux/usr/share/man
$ ls *
test.1

man1:
test.2.gz

Worth to note is that DEB generator does not have that issue, — simply because CPackDEB operates on original files only. While looking into CPackRPM.cmake module, I was able to locate the code that messes with man page files, but not the code responsible for undoing the mess-up; the former code works unconditionally, — I could not spot any variable that may tell it not to compress man pages.

The only similar discussion I could find dates back to 2014 and was resolved by updating to a more current version of CMake. Since I am also using openSUSE Linux as the original reporter did (the actual release, of course), I tried to switch from the system-provided CMake 3.3.2 to a locally built 3.7.0-rc2, but that did not change a thing. Therefore, taking into account the popularity of CMake, RPM and man, I suppose that if some bug really existed, it should have been fixed long ago, so the one to blame is me. What am I missing here?


Update. Regarding the use of wildcards that was recommended, — i. e. specifying “test.2*” instead of just “test.2”. CMake does not seem to support globbing in install(FILES …) form: it literally searches for test.2* and fails before generating RPM spec file. Several kinds of pattern matching are supported through another form however:

install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION /usr/share/man/man1 FILES_MATCHING PATTERN *.1*)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION /usr/share/man/man2 FILES_MATCHING REGEX "^.+[.]2([.].+)?$")

Although that succeeds, it still does not answer the question of distributing man pages in uncompressed form. Therefore, it looks ugly and counterintuitive.

Worth to mention is how RPM spec file is generated from the originally posted CMakeLists.txt:

%dir "/usr/share/man"
%dir "/usr/share/man/man1"
"/usr/share/man/man1/test.2*"

%config "/usr/share/man/test.1"
%config "/usr/share/man/man1/test.2"

As can be clearly seen, CPackRPM indeed adds an extra wildcarded version of source file name when it belongs to a known man location; unfortunately, it still retains the original (uncompressed) file name, which leads to failure. Perhaps CMake should either warn the user of consequences or even fail early at configuration stage rather than concealing the problem for some later time.


Solution

  • I am giving answer here because even though the question is old, there is no real good answer yet. I am as well had this compression problem with rpm package generation. I found this solution, that works well with both deb and rpm packages:

    install(FILES manfile.1 TYPE MAN)

    Official documentation can be found here: https://cmake.org/cmake/help/latest/command/install.html#install Look for word TYPE with match case.