簡體   English   中英

ldd說編譯完成后找不到庫

[英]ldd says library isn't found by compile completes successfully

我正在嘗試編譯項目。 它編譯成功。 我的make命令以狀態代碼0退出,並且沒有顯示錯誤。

但是,該項目不起作用,當我運行ldd -d <file>它顯示我有兩個未找到的庫。

>ldd -d output_file.so
    linux-gate.so.1 =>  (0xf77e0000)
    libvstdlib_srv.so => not found
    libtier0_srv.so => not found
    libm.so.6 => /lib/libm.so.6 (0xf7760000)
    libdl.so.2 => /lib/libdl.so.2 (0xf775b000)
    libc.so.6 => /lib/libc.so.6 (0xf75a9000)
    /lib/ld-linux.so.2 (0x46e4a000)
undefined symbol: pfVectorNormalize     (output_file.so)
undefined symbol: _Z12VectorAnglesRK6VectorR6QAngle     (output_file.so)
undefined symbol: pfSqrt       (output_file.so)
undefined symbol: __cxa_guard_acquire   (output_file.so)
undefined symbol: __cxa_guard_release   (output_file.so)
undefined symbol: _Z6ConMsgPKcz (output_file.so)
undefined symbol: Warning      (output_file.so)
undefined symbol: __dynamic_cast        (output_file.so)
undefined symbol: _Z11ConColorMsgRK5ColorPKcz   (output_file.so)
undefined symbol: Error (output_file.so)
undefined symbol: AssertValidStringPtr  (output_file.so)
undefined symbol: _AssertValidWritePtr  (output_file.so)
undefined symbol: _AssertValidReadPtr   (output_file.so)
undefined symbol: _ZTVN10__cxxabiv121__vmi_class_type_infoE     (output_file.so)
undefined symbol: _ZTVN10__cxxabiv120__si_class_type_infoE      (output_file.so)
undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE (output_file.so)
undefined symbol: __gxx_personality_v0  (output_file.so)

這兩個庫設置為指向文件實際位置的符號鏈接:

...
lrwxrwxrwx 1 Andy Andy    62 May  2 12:30 libtier0_srv.so -> /home/dev/sdks/hl2sdk-ob-valve/lib/linux/libtier0_srv.so
lrwxrwxrwx 1 Andy Andy    64 May  2 12:30 libvstdlib_srv.so -> /home/dev/sdks/hl2sdk-ob-valve/lib/linux/libvstdlib_srv.so
-rw-r--r-- 1 Andy Andy  5444 May  2 11:53 Makefile
...

正在運行的gcc命令是

gcc -I/home/dev/sdks/hl2sdk-ob-valve/public/game/server -I. -I.. -ICEntity -Isdk -I/home/dev/project1/hl2sdk-ob-valve/public -I/home/dev/sdks/hl2sdk-ob-valve/public/engine -I/home/dev/sdks/hl2sdk-ob-valve/public/tier0 -I/home/dev/sdks/hl2sdk-ob-valve/public/tier1 -I/home/dev/sdks/hl2sdk-ob-valve/public/mathlib -I/home/dev/project1/mmsource-central/core -I/home/dev/project1/mmsource-central/core/sourcehook -I/home/dev/project1/sourcemod-central/public -I/home/dev/project1/sourcemod-central/public/sourcepawn -I/home/dev/project1/sourcemod-central/core project1_output/sdk/smsdk_ext.o project1_output/extension.o project1_output/CTrackingProjectile.o project1_output/CSentryRocket.o project1_output/CProjectileRocket.o project1_output/CProjectileArrow.o project1_output/CProjectileFlare.o project1_output/CProjectilePipe.o project1_output/CProjectileSyringe.o project1_output/CEntity/CEntity.o project1_output/CEntity/CEntityManager.o project1_output/CEntity/CPlayer.o /home/dev/project1/hl2sdk-ob-valve/lib/linux/tier1_i486.a libvstdlib_srv.so libtier0_srv.so -m32 -lm -ldl -static-libgcc -shared -o project1_output/output_file.so

我的問題是:1。)為什么這兩個庫沒有找到,即使它們是符號鏈接的? 2.)未定義的符號是mathlib包的一部分,它包含在gcc命令中。 -I/home/dev/sdks/hl2sdk-ob-valve/public/mathlib為什么這些是未定義的,盡管被包括在內?

c++不是我選擇的語言,我對Makefile有足夠的了解是危險的,但並不是真的要解決任何問題,所以如果這些信息不夠,我會道歉。 我可以根據需要提供更多。

我偶然發現了這個問題,遇到了同樣的問題,但卻有了不同的解決方案。

事實上,使用LD_LIBRARY_PATH會起作用。 如果它是在您的構建環境中進行自己的測試,那很好,但除了像這樣的情況之外,您應該盡量避免它。 這是一篇比我更了解它的人的文章,為什么LD_LIBRARY_PATH是壞的:

http://xahlee.info/UnixResource_dir/_/ldpath.html

發生的事情是,從設置LD_LIBRARY_PATH工作的事實可以看出,在運行時,您的程序找不到共享庫libtier0_srv.so 您應該將目錄添加到運行時庫搜索路徑,而不是全局設置所有程序的變量以查看/home/dev/sdks/hl2sdk-ob-valve/lib/linux/ first。 您可以通過傳遞選項來完成此操作

-rpath /home/dev/sdks/hl2sdk-ob-valve/lib/linux/

ld ,鏈接器。 您可以通過添加選項,使用您發布的gcc命令執行此操作

-Wl,-rpath,/home/dev/sdks/hl2sdk-ob-valve/lib/linux/

告訴gcc將上面的選項傳遞給ld

庫文件是共享對象,這意味着它們在運行時才會被解析。 為了讓ldd找到它們(假設Linux或其他Unix變體),你需要將庫的路徑添加到LD_LIBRARY_PATH(還有另一個可以使用的路徑env,但我現在想不到它)然后ldd應該能夠找到這個庫。

正如@ diverscuba23所提到的,您需要將庫所在的路徑添加到LD_LIBRARY_PATH 一個簡單而非永久的方法是在運行程序時指定它:

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./yourProgram

在這種情況下,庫需要位於運行程序的同一目錄中。

更普遍:

LD_LIBRARY_PATH=<PATH_TO_YOUR_LIBRARY>:$LD_LIBRARY_PATH ./yourProgram

您的輸出文件是* .so,一個共享對象庫文件; 引用了另一個共享庫中的符號但未導入(靜態鏈接)。
- 使用nm查看符號(已定義或未定義)
ldd將搜索ldconfig系統緩存,並且/etc/ld.so.conf通知搜索位置 - 您可以使用此功能添加庫路徑(例如:/ opt / valve / lib)以與所有用戶共享
- 您的編譯命令包括主目錄中的共享庫歸檔。
---- ldd通常不會搜索主目錄,使用LD_LIBRARY_PATH
------但是你必須列出目錄的完整路徑
你說你'包含'mathlib,我看這是-I(對於頭文件)
- 但庫目錄是-L $ MY_PATH / mathlib / lib和-l vstdlib_srv鏈接它
----你包含了庫而不是鏈接它 - 在C / C ++中,include的含義與其他語言不同:use / require / import / include
----這聲明了符號,類型和參數列表; 但不是實施
-I為* .h,*。hh,* .hpp提供路徑; 這是用於聲明符號的文本文件
-L提供了查找庫的路徑(以及鏈接exec的靜態庫)
-l鏈接包含實現的庫
-rpath為libs提供鏈接到exec的運行時路徑,並將其編譯到exec中
----這會綁定應用程序及其庫位置(例如-rpath ../lib,當應用程序位於bin中時)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM