什么是RPATH
rpath全稱是run-time search path
。Linux下所有elf格式的文件都包含它,特別是可執行文件。它規定了可執行文件在尋找.so
文件時的第一優先位置。
另外,elf文件中還規定了runpath。它與rpath相同,只是優先級低一些。
搜索.so
的優先級順序
- RPATH: 寫在elf文件中
- LD_LIBRARY_PATH: 環境變量
- RUNPATH: 寫在elf文件中
-
ldconfig
的緩存: 配置/etc/ld.conf*
可改變 - 默認的
/lib
,/usr/lib
可以看到,RPATH與RUNPATH中間隔着LD_LIBRARY_PATH。為了讓用戶可以通過修改LD_LIBRARY_PATH來指定.so
文件,大多數編譯器都將輸出的RPATH留空,並用RUNPATH代替RPATH。
查看RPATH
對於任意的elf文件,可以使用$ readelf -d xxx | grep 'R*PATH'
來查看。
結果有兩類,一個是RPATH,另一個是RUNPATH。前文也說了,一般情況下,RPATH為空,而RUNPATH不為空。
RPATH中有個特殊的標識符$ORIGIN
。這個標識符代表elf文件自身所在的目錄。當希望使用相對位置尋找.so
文件,就需要利用$ORIGIN
設置RPATH。多個路徑之間使用冒號:
隔開。
設置RPATH
在gcc中,設置RPATH的辦法很簡單,就是設置linker的rpath選項:$ gcc -Wl,-rpath,/your/rpath/ test.cpp
如果需要設置$ORIGIN
:$ gcc -Wl,-rpath,'$ORIGIN/lib' test.cpp
。
注意,雖然選項里寫着RPATH,但它設置的還是RUNPATH。原因在前文有交代。
在CMake中,事情則有些不同。由於CMake需要包攬軟件安裝的事宜,因此CMake使用兩個變量來控制RPATH:INSTALL_RPATH
和BUILD_RPATH
。
設置的辦法是:
SET_TARGET_PROPERTIES(target
PROPERTIES INSTALL_RPATH "$ORIGIN;/another/run/path")
注意,在CMake中,多個RPATH使用分號隔開,而不是冒號。這是估計是因為冒號在CMake語法中有其他用途