動態庫的麻煩之處在於 - 若是你的程序使用了成百上千個動態庫,你的程序在運行時如何找到這些動態庫? html
通常有三個方法:網絡
1、設置LD_LIBRARY_PATHapp
export LD_LIBRARY_PATH="/path/to/lib"
直接手工設是不可能完成的任務,由於你也知道有不少path (多不是問題,問題時你得知道這些path),因此通常須要在由編譯系統來自動產生這些path,並放到一個runscript中:工具
#set path export LD_LIBRARY_PATH=/path/to/lib1 export LD_LIBRARY_PATH=/path/to/lib2:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=/path/to/lib3:$LD_LIBRARY_PATH # ... export LD_LIBRARY_PATH=/path/to/lib100:$LD_LIBRARY_PATH # run app /path/to/myapp
2、設置rpathpost
rpath設置能夠在編譯時:ui
g++ -Wl,-rpath,/path/to/lib ... or ld -rpath /path/to/lib ...
rpath應該能夠是-L一致,因此能夠在編譯系統中作些工做自動產生rpath,premake目前(4.4beta)還不支持,但能夠比較簡單的作個擴展支持:(同時也展示了premake的靈活性)spa
origin_libdirs = libdirs function libdirs(dirs) origin_libdirs(dirs) if type(dirs) == 'string' then dirs = { dirs } end for _, dir in ipairs(dirs) do linkoptions('-Wl,-rpath,' .. dir) end end
將libdirs都做爲rpath編譯到binary中去。code
能夠經過readelf查看htm
readelf -d binary
而cmake則提供了比較好內建支持,有選項能夠選擇是否加入rpath。blog
可是,你編譯時的rpath並不表明就是你最終生產環境中的rpath,考慮一下continuous delivery中的一個狀況:
該項目有一個shared library和一個binary,在CI的build agent上編譯產生,因此指向shared library的rpath是一個指向build agent上local的path,這些artifacts會被上傳到artifact repository,而後在發佈時被部署到生產環境中,此時該rpath一定是錯誤 --- 運行失敗。
此時須要postprocess來修改rpath,有個叫作patchelf的工具:
patchelf --set-rpath /path/to/production/lib
一樣,怎麼改rpath不是重點,重點是有哪些rpath,改爲什麼樣 - 這些須要在build system在編譯過程當中收集。
還能夠去掉不須要的rpath:
patchelf --shrink-rpath program
3、拷貝或者symbolic link
Windows下通常直接把全部dll打包放一塊兒 - 與app同一目錄,連PATH都不用設。
Linux下咱們能夠把全部的library都symblic link到同一目錄下,PATH只要設一個便可 - 這個在網絡環境下尤爲有用,以前這篇文章也講到過。