[英]Moving to different Linux build system, getting error: undefined symbol: stat
這可能只是我遷移到的構建系統的一個問題,但我將在兩個系統中包含差異以及我是如何遇到問題的。
我的舊構建系統是SLES 10機器。 gcc / cpp / g ++版本是4.1.0
我的新系統在SLES 11 SP4上,gcc / cpp / g ++版本是4.3.4。
我正在建立一個共享庫; 建立和連接新系統的工作正常。 但是,在新系統的加載時,我得到以下內容:
error ./mysharedlib.so: undefined symbol: stat
由於stat()函數包含在/usr/include/sys/stat.h中,我查看了兩個系統上的glibc。 舊:
# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.4-31.2
新的:
# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.11.3-17.95.2
我還查看了舊系統上與stat()相關的objdump輸出:
# objdump -T mysharedlib.so | grep stat
0000000000000000 D *UND* 0000000000000000 __xstat
# objdump -x mysharedlib.so | grep stat
00000000000e3f8a l F .text 0000000000000024 stat
0000000000000000 *UND* 0000000000000000 __xstat
而新系統:
# objdump -T mysharedlib.so | grep stat
0000000000000000 D *UND* 0000000000000000 stat
0000000000000000 D *UND* 0000000000000000 lstat
# objdump -x mysharedlib.so | grep stat
0000000000000000 *UND* 0000000000000000 stat
0000000000000000 *UND* 0000000000000000 lstat
這告訴我在舊系統上,stat()被定義為我實際共享對象的.text部分中的本地函數。 在新系統的mysharedlib中未定義Stat。
我確實找到了一些關於feature_test_macros的信息,並認為可以解決這個問題,所以我在stat.h之前包含了features.h並更新了我的makefile來定義_XOPEN_SOURCE:
cc -D_XOPEN_SOURCE=500
這並沒有解決問題。
我也嘗試在我的ld標志中添加“-lc”以在libc中鏈接。 這似乎應該可以工作,因為這是定義stat()的地方(我認為),但事實並非如此。
此時,我發現了這個StackOverflow問題:
所以當我在調用stat()的文件上調用g ++時,我嘗試將-O添加到我的makefile中。 這似乎解決了這個問題。 我可能對解析符號知之甚少; 然而,這對我來說似乎有些黑客攻擊。 我離開基地了嗎? 如果沒有,解決新系統上的加載時間錯誤的正確方法是什么?
您遇到的問題很可能是使用ld
構建共享庫的結果。 在UNIX系統上的用戶級別的代碼不應該使用ld
直接。 您應該使用編譯器驅動程序(在您的情況下為g++
)來執行鏈接。
例:
// t.c
#include <sys/stat.h>
void fn(const char *p)
{
struct stat st;
stat(p, &st);
}
gcc -fPIC -c t.c
ld -shared -o t.so t.o
nm t.so | grep stat
U stat ## problem: this library is not linked correctly
與正確鏈接的庫比較:
gcc -shared -o t.so t.o
nm t.so | grep stat
0000000000000700 t stat
0000000000000700 t __stat
U __xstat@@GLIBC_2.2.5
要找到上述本地stat
符號的來源,您可以這樣做:
gcc -shared -o t.so t.o -Wl,-y,stat
t.o: reference to stat
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(stat.oS): definition of stat
最后, U stat
隨着優化而消失的原因:
gcc -E t.c | grep -A2 ' stat '
extern int stat (const char *__restrict __file,
struct stat *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
gcc -E t.c -O | grep -A2 ' stat '
__attribute__ ((__nothrow__ , __leaf__)) stat (const char *__path, struct stat *__statbuf)
{
return __xstat (1, __path, __statbuf);
這是正確的:根據優化級別,您將獲得不同的預處理源。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.