再談CMake與RPATH


   之前寫過一篇<探討CMake中關於RPATH的使用>,只要針對的方面是在編譯生成之后(不包括安裝的make install)如何去除RPATH的問題。今天給大家主要介紹一下如何讓CMake在用install命令之后如何保持RPATH。

   我先來簡單介紹下CMake關於RPATH的機制,在之前文章中介紹過,如果你沒有顯示指定CMAKE_SKIP_RPATH,CMAKE_BUILD_WITH_INSTALL_RPATH,CMAKE_SKIP_BUILD_RAPTH,CMAKE_SKIP_INSTALL_RPATH的話,默認CMake在幫你編譯之后,如果你使用了相關動態庫,它會在相應的executable中增加你相關生成動態庫的路徑,這樣當你每次去執行的時候你不需要每次都LD_LIBRARY_PATH就可以正常運行。這個時候你可以用一下

readelf -d myexe

你可以看到,當前myexe中的RPATH字段有一個Library rpath,其中指定了你生成相應動態庫target的目標路徑。當然你也可以通過

ldd -r myexe

來查看當前executable已經尋找到了哪些動態庫。當然你可以因此做一個小實驗,就是移動相關shared_lib庫的路徑,這個時候你再去運行myexe,你就會發現它已經找不到相關的動態庫了,因為目前的RPATH都是寫的絕對路徑,所以如果你只是移動exe而不是lib,則沒有任何問題。

    再來說一下make install下CMake是如何處理RPATH的。CMake為了方便用戶的安裝,默認在make install之后會自動remove刪除掉相關的RPATH,這個時候你再去查看exe的RPATH,已經發現沒有這個字段了。因此,當每次make install之后,我們進入到安裝路徑下執行相關exe的時候,就會發現此時的exe已經找不到相關的庫路徑了,因為它的RPATH已經被CMake給去除了。

    那么,如何讓CMake能夠在install的過程中寫入相關RPATH並且該RPATH不能使當初build的時候的RPATH呢?答案就是CMAKE_INSTALL_RPATH這個全局變量和INSTALL_RPATH這個target屬性。下面舉一下簡單的例子。

    大家都知道,CMake在安裝的過程會有一個和configure一樣的安裝路徑,CMAKE_INSTALL_PREFIX(configure下是--prefix,當然也可以用shell下的全局變量DESTDIR),這個時候它會把你的安裝文件安裝到你prefix下的相對路徑下,因此當我們希望在make install的時候,比如當前的share_lib在lib目錄下,我們希望安裝之后的RPATH可以自動找到它,我們就可以這么寫

set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)

需要注意的是,這個變量是全局變量,意味着你所有的target的RPATH都會在install的時候被寫成這個(包括myexe和不需要RPATH的share_lib),有沒有簡單的針對某個target呢,聰明的你應該已經想到了

set_target_properties(myexe PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

這樣就可以保證只針對當前的target進行make install的時候RPATH的寫入了。

    以上就是對前面一篇CMake與RPATH的補充,希望你會喜歡 : )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM