---此文章同步自我的CSDN博客---
##一.**運行時**動態庫:not found 今天在使用linux編寫c/c++程序時,需要用到第三方的動態庫文件。剛開始編譯完后,運行提示找不到動態庫文件.我就使用了ldd命令查看了一下,發現是有一個庫文件顯示"not found”,如下圖所示;
對於庫文件未找到,因為編譯、鏈接都沒有問題,那就是運行鏈接動態庫時找不到動態庫了。對於運行鏈接動態庫時找不到動態庫的方法,最基本的解決方法就兩種:
第一種方法:找到缺少的動態庫(由於編譯和鏈接時候的使用到了這個動態庫,所以很容易找得到),將其加到/lib,/usr/lib中的一個文件夾下,這幾個文件夾是系統默認的搜索路徑。將庫文件放置在其中,運行時就可以搜索到了。
第二種方法:設置臨時增加鏈接動態庫的路徑;使用
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:《your_lib_path》
比如我的libpaho-mqtt3cs.so.1在/home/mqtt/MQTT-c/lib目錄下,那我使用的是:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/mqtt/MQTT-c/lib
這種方法設置的是臨時的,系統重啟之后就沒了。當然也可以設置為持久的,這里就不過多講述。
還有一種方法是不常用的,更改配置文件:
第三種方法:/etc/ld.so.cache中緩存了動態庫路徑,可以通過修改配置文件/etc/ld.so.conf中指定的動態庫搜索路徑,然后執行ldconfig命令來改變。
不過,我又想了一下,感覺這幾種方法都不適合我現在的情況,這些都是事后補救的方法。首先,我不可能每次需要用到一個第三方的動態庫的時候都要往幾個系統默認的文件夾里面扔,這會導致這幾個文件夾越來越大,越來越亂;再者,我也不想每次都設置臨時動態庫搜索路徑,每個程序這么做的話得設置多少次啊,而且也導致文件夾變多,總歸不好;而更改配置我就更不推薦了,會導致配置文件越來越亂。
我又google了一下,找到了一個命令,適合我目前的情況:指定程序運行時會在指定文件下尋找第三方的動態庫。
-第四種方法:在鏈接時語句后面添加如下命令:
-Wl,-rpath=《my_thirdparty_lib_path》
對比一下添加前后的Makefile語句。not found時的語句:

更改之后的語句:

我們來看看更改之后的編譯結果:

可以看到,我的libpaho-mqtt3cs.so.1從我在文章開頭時的【not found】變成了有來源了,而綠色部分的路徑就是我剛剛Makefile中的-Wl,-rpath=之后的路徑。
二.介紹-Wl,-rpath=
因為今天是-Wl,-rpath解決了我的問題,而且發現網上搜到的資料不夠詳細,我在這里就介紹一下這個方法。
-Wl,-rpath=《your_lib_dir》是為程序添加一個運行時庫文件搜索路徑的命令,在使用gcc編譯鏈接時添加即可。
其中,有兩個單獨的部分-Wl和-rpath組成。
-Wl
這個是gcc的參數,表示編譯器將后面的參數傳遞給鏈接器ld。
請注意此處的W是大寫的。
-rpath
使用man ld命令查看手冊,找到了-rpath的講解:
Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime. The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the -rpath-link option. If -rpath is not used when linking an ELF executable, the contents of the environment variable "LD_RUN_PATH" will be used if it is defined.
大體就以下這幾個意思:
1. 添加一個文件夾作為運行時庫的搜索路徑。在將ELF可執行文件與共享對象鏈接時使用此選項;
2. 在鏈接時,一些動態庫明確的鏈接了其他動態庫, 則-rpath選項也可用於定位這些鏈接的動態庫(沒太理解這個);
3. 在運行鏈接時,會優先搜索-rpath的路徑,再去搜索LD_RUN_PATH的路徑。
至此,該命令也算是能夠完成我對程序的需求了。即通過-Wl,-rpath=《lib_path》可添加文件夾作為動態庫搜索路徑,並記錄在程序ELF可執行程序中。我們調用程序時回去我們寫入的目錄中查找我們的第三方庫文件。
總結
后續我又查了一下,這四種方法的優先順序:四->二->三->一。而我介紹的第四種命令是我認為在程序中應該多用的。
---[來自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78736291)---
