編譯和運行是不同的事情。:)
1)make文件包含有關如何構建應用程序的規則。所以當你編寫一條規則時:
-L/usr/local/lib -lxerces-c-3.1
你正在傳遞選項給鏈接器。 -L
選項告訴鏈接程序將其他庫(在本例中爲'/ usr/local/lib')添加到鏈接程序的搜索路徑。 -l
選項命名應該鏈接的庫。
2)當您運行可執行文件時,加載器需要找到所有需要的庫。例如,在Linux系統上,您可以使用ldd命令查看使用哪些共享庫。例如我的系統上:
ldd FEParser
linux-vdso.so.1 => (0x00007ffcdc7c9000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f835b143000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f835ae3d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f835ac27000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f835a862000)
/lib64/ld-linux-x86-64.so.2 (0x00007f835b447000)
由此看來,你可以看到一個鏈接到「=>」標記的左側庫的名稱和路徑到圖書館的權利。如果找不到圖書館,它會顯示爲丟失。
現在你的情況,你已經能夠成功地編譯和鏈接你的程序,因爲給路徑和庫名稱使用。由於裝載程序在運行時無法找到該庫,因此無法運行該程序。
您有幾種選擇在這裏:
1)您可以在一個目錄是在裝載機的搜索路徑移動圖書館。
2)您可以修改LD_LIBRARY_PATH
,這會將其他目錄添加到加載程序搜索路徑中。此外,LD_LIBRARY_PATH
中指定的目錄將傳遞給鏈接器(它將在所有-L
標誌之後附加)。你需要小心這一點,就好像你在全局設置它(例如在.bashrc
中),那麼它會影響你所做的所有編輯。你可能會也可能不想要這種行爲。
3)正如其他人已經指定,您可以使用-Wl,rpath=....
,但它已被棄用,我很少使用它。
4)如果您需要安裝在一個不尋常的位置庫,你可以添加一個創建/etc/ld.so.conf.d
包含,例如下一個文件(文件yaml.conf):
# yaml default configuration
/opt/yaml/lib
在系統啓動時,加載器讀取此目錄中的所有文件並將路徑附加到加載器路徑。如果您對此目錄進行了修改,則可以使用ldconfig
命令使加載程序重新處理/etc/ld.so.con.d
。注:我知道這適用於GNU/Linux的centOS和Ubuntu版本 - 不能在其他版本上進行權威性的說明。
我建議從你的makefile文件中添加最小的一組規則來演示這個問題,最多10行。現在,我們仍然在猜測makefile中的內容,以及是否可以提供最佳的改進。祝你好運。 – shellter
看看這個帖子:http://stackoverflow.com/questions/1904990/what-is-the-difference-between-ld-library-path-and-l-at-link-time,其中類似的問題已經回答 –
'-L'和'LD_LIBRARY_PATH'影響兩個非常*不同的(但相關的)操作。編譯時鏈接和運行時鏈接。 –