cmakefile-permissionsrpmcpack

How to set directory permission bits in an RPM file built by CMake?


I'm creating an RPM file using CMake's RPM support. I have found that the permissions of directories created on installation of the RPM depend on the umask of the user who created the RPM. I have tried setting CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS but that does not seem to help.


Solution

  • The creation of RPM files in CMake/CPack follows two steps. First, a temporary directory structure is created under subdirectories of _CPack_Packages/. Then, this temporary directory structure is used to create the RPM file.

    When CPack implicitly creates temporary directories, it uses the CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable to request particular permissions. Under normal operation of mkdir(), this is modified by the process umask. For example, under umask 022 and the following statement in the CMakeLists.txt file:

    set(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
        OWNER_READ OWNER_WRITE OWNER_EXECUTE
        GROUP_READ GROUP_EXECUTE
        WORLD_READ WORLD_EXECUTE)
    

    the directory permissions will be

    drwxr-xr-x
    

    Under umask 027, the permissions will be

    drwxr-x---
    

    When the second step of the RPM build is performed, the generated RPM .spec file contains:

    %files
    %defattr(-,root,root,-)
    

    and the permissions embedded in the RPM file are copied from the actual temporary directories created by CMake. If the software installed by the RPM expects to be able to read the installed files by any user, then the installation would fail to work correctly.

    The solution is to use CPACK_RPM_DEFAULT_DIR_PERMISSIONS instead, like this:

    set(CPACK_RPM_DEFAULT_DIR_PERMISSIONS
        OWNER_READ OWNER_WRITE OWNER_EXECUTE
        GROUP_READ GROUP_EXECUTE
        WORLD_READ WORLD_EXECUTE)
    

    When using this setting, the generated .spec file contains:

    %files
    %defattr(-,root,root,755)
    

    where 755 is the specific permissions applied upon installation of the RPM. In this situation, the permission bits of the temporary files created by CMake (which would still be subject to umask adjustment) are no longer relevant.

    When RPM .spec files are crafted by hand, it would of course be good practice to explicitly set the installed file and directory permissions as needed. The above shows how to accomplish this using CMake's RPM creation support.