c++cmakerpmbuildcpackrpath

rpmbuild check-rpath reports error that path is not absolute, incorrectly


I've been building RPMs using CMake & CPack 3.13.4 on OEL7 for several months without issue. My CMake configuration contained these lines:

SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)

This has allowed me to ensure that the locally built versions of the library are used before any installed versions. Without making any changes to these lines I am suddenly unable to build RPMs any more. I now get this error message:

+ /usr/lib/rpm/check-rpaths
*******************************************************************************
*
* WARNING: 'check-rpaths' detected a broken RPATH and will cause 'rpmbuild'
*          to fail. To ignore these errors, you can set the '$QA_RPATHS'
*          environment variable which is a bitmask allowing the values
*          below. The current value of QA_RPATHS is 0x0000.
*
*    0x0001 ... standard RPATHs (e.g. /usr/lib); such RPATHs are a minor
*               issue but are introducing redundant searchpaths without
*               providing a benefit. They can also cause errors in multilib
*               environments.
*    0x0002 ... invalid RPATHs; these are RPATHs which are neither absolute
*               nor relative filenames and can therefore be a SECURITY risk
*    0x0004 ... insecure RPATHs; these are relative RPATHs which are a
*               SECURITY risk
*    0x0008 ... the special '$ORIGIN' RPATHs are appearing after other
*               RPATHs; this is just a minor issue but usually unwanted
*    0x0010 ... the RPATH is empty; there is no reason for such RPATHs
*               and they cause unneeded work while loading libraries
*    0x0020 ... an RPATH references '..' of an absolute path; this will break
*               the functionality when the path before '..' is a symlink
*          
*
* Examples:
* - to ignore standard and empty RPATHs, execute 'rpmbuild' like
*   $ QA_RPATHS=$[ 0x0001|0x0010 ] rpmbuild my-package.src.rpm
* - to check existing files, set $RPM_BUILD_ROOT and execute check-rpaths like
*   $ RPM_BUILD_ROOT=<top-dir> /usr/lib/rpm/check-rpaths
*  
*******************************************************************************
ERROR   0002: file '/opt/project/lib/libConfigLoader.so.4.0.0' contains an invalid rpath '/opt/project/lib' in [/opt/project/lib]
ERROR   0002: file '/opt/project/lib/libConfigLoaderDb.so.4.0.0' contains an invalid rpath '/opt/project/lib' in [/opt/project/lib]

This seems wrong because it's stating that /opt/project/lib is not an absolute path, which it is.

The permissions of /opt/project/lib are:

[user@c7 ]$ ll -d /opt/
drwxrwxr-x. 10 root root 139 Oct 11 14:31 /opt/
[user@c7 ]$ ll -d /opt/project/
drwxrwx--- 11 root project 114 Oct 11 14:32 /opt/project/
[user@c7 ]$ ll -d /opt/project/lib
drwxrwx--- 2 root project 4096 Oct 11 14:53 /opt/project/lib

I am able to suppress the error by prepending QA_RPATHS=0x0002 to my make command, but I'm concerned that doing this might obscure other errors in future.

I looked into the check-rpaths script (and the check-rpaths-worker script that it uses), and the issue seems to come from this part, where j has been set to the rpath, in this case /opt/project/lib:

            case "$j" in
                (/lib/*|/usr/lib/*|/usr/X11R6/lib/*|/usr/local/lib/*)
                    badness=0;;
                (/lib64/*|/usr/lib64/*|/usr/X11R6/lib64/*|/usr/local/lib64/*)
                    badness=0;;

                (\$ORIGIN|\${ORIGINX}|\$ORIGIN/*|\${ORIGINX}/*)
                    test $allow_ORIGIN -eq 0 && badness=8 || {
                        badness=0
                        new_allow_ORIGIN=1
                    }
                    ;;
                (/*\$PLATFORM*|/*\${PLATFORM}*|/*\$LIB*|/*\${LIB}*)
                    badness=0;;

                (/lib|/usr/lib|/usr/X11R6/lib)
                    badness=1;;
                (/lib64|/usr/lib64|/usr/X11R6/lib64)
                    badness=1;;

                (.*)
                    badness=4;;
                (*) badness=2;;
            esac

(Source)

I don't understand how this ever let /opt/project/lib pass, as from that 'case' statement it would always drop to the (*) case and set badness=2

What else can I try?


Solution

  • I had the same problem.

    In my case, removing the ~/.rpmmacros file has solved the problem.

    (I was running make package with cmake/cpack-generated Makefile on the shared machine. Probably, somebody or something had changed the contents of that file in a way that the following line appeared or got uncommented:

    %__arch_install_post   /usr/lib/rpm/check-rpaths   /usr/lib/rpm/check-buildroot
    

    That seemed to be the reason of the problem in my case.)