CMake如何设置rpath,如何给rpath设置相对路径

CMake如何设置rpath

        Linux的可执行文件包括共享对象库文件里面有一个标记,叫做rpath,它是运行时库的搜索目录。换而言之rpath能告诉Linux当执行这个文件的时候如果需要加载其它的共享对象库要去哪个目录下找。在使用GCC时可以这样配置rpath:

g++ -shared -fPIC -o libhelper.so helper.cpp

g++ -o test main.cpp -L. -lhelper -Wl,-rpath,.

        这样,编译出来的可执行程序test在执行时就会尝试在用户命令行执行的当前路径下寻找libhelper.so。

        Cmake默认把rpath设置成构建时生成的共享对象库的绝对路径,而不是安装后的共享对象库的路径。这样直接执行在构建目录中的可执行程序是没问题的,但是安装在特定路径后加载的还是构建目录中的共享对象库,如果构建目录被删除程序就执行不了了。

        Cmake有一个参数,CMAKE_INSTALL_RPATH,它可以改写安装的可执行程序和共享对象库的rpath。使用示例:

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/fc1 -DCMAKE_INSTALL_RPATH=/tmp/fc1/lib -S . -B build

cmake --build build

cmake --install build

        示例的cmake构建参数设置了以下内容:一,构建类型为Release,即开启-O3和-DNDEBUG;二,安装路径设置为/tmp/fc1;三,设置安装后的可执行程序和共享对象库使用/tmp/fc1/lib为rpath;四,CMake使用当前路径的CMakeLists.txt;五,构建产物存放在当前路径下的build目录里。

        CMAKE_INSTALL_RPATH设置的路径只影响安装后的目录中的文件的rpath,示例的构建产物中可执行文件和共享对象库的rpath还是默认的不变。

如何修改rpath为相对路径呢,一些实用技巧

        如果把rpath设置成绝对路径会导致安装后移动目录或重命名目录会无法执行程序,这时可以在编译时配置rpath带上${ORIGIN}。rpath中的${ORIGIN}可以理解为可执行程序或者共享对象库所在的目录名,例如/my/bin/a.out使用了libb.so,a.out的rpath是${ORIGIN}/../lib,那么执行a.out时Linux会尝试从/my/bin/../lib目录下寻找所需的libb.so。这样寻找共享对象库的路径就和命令行当前路径无关,而且也不需要在编译时设置绝对路径了。

        示例:

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/fc4 -DCMAKE_INSTALL_RPATH=\\\${ORIGIN}/../lib -S . -B build

cmake --build build

cmake --install build

你可能感兴趣的:(IT技术相关,cmake,c++)