2017-05-31 309 views
4

这可能只是我正在迁移到的构建系统的问题,但我会在两个系统中包含差异以及我如何遇到问题。转移到不同的Linux构建系统,出现错误: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 

这告诉我,在旧系统上,sta t()被定义为我实际共享对象的.text节中的本地函数。 Stat在新系统的mysharedlib中未定义。

我没有找到feature_test_macros一些信息,并认为可能会解决这个问题,所以我包括features.h stat.h前和更新我的makefile定义_XOPEN_SOURCE:

cc -D_XOPEN_SOURCE=500 

这并没有解决问题。

我也尝试添加“-lc”到我的ld标志链接在libc中。这似乎应该工作,因为这是stat()的定义(我认为),但它没有。

在这一点上,我发现这个StackOverflow的问题:

Why does -O to gcc cause "stat" to resolve?

所以,我想在调用统计文件调用g当++()加入-O到我的makefile文件。这似乎解决了这个问题。我可能对解析符号不够了解;然而,这对我来说似乎有些不合理。我在那里的基地?如果没有,解决新系统加载时间错误的正确方法是什么?

+2

你在调用'stat','fstat'或'lstat'函数的源代码模块中的#include指令是什么?它是否有'man 2 stat'中指出的那些? – Deathgrip

+0

你有没有做一个完全干净的编译,重新编译每个二进制文件? –

+0

我的包含包含man 2 stat。在重新编译每个源文件之前,我做了一次清理。 – Jetson

回答

6

您面临的问题很可能是与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 [email protected]@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); 

没错:您根据优化级别获得不同的预处理源。