GCC在编译时在/ usr / local / include中查找头文件,但在链接时不查找/ usr / local / lib中的库。为什么?

时间:2011-01-25 09:19:54

标签: c linux gcc linker header

我已经在/ usr /发行版提供了SQLite版本3.4.2。 我安装在/ usr / local / SQLite版本3.7.4。

/usr/include/sqlite3.h将SQLITE_VERSION_NUMBER定义为3004002
/usr/local/include/sqlite3.h将SQLITE_VERSION_NUMBER定义为3007004

版本3007004具有sqlite3_initialize()函数,版本3004002没有。

$ nm -D /usr/local/lib/libsqlite3.so | grep sqlite3_initialize
00018e20 T sqlite3_initialize

当我编译以下示例程序时:

#include <stdio.h>
#include <sqlite3.h>

// This should fail if including /usr/include/sqlite3.h
#if SQLITE_VERSION_NUMBER != 3007004
    #error "SQLite version is not 3.7.4"
#endif

int main() {
    printf( "%d\n", SQLITE_VERSION_NUMBER );
    sqlite3_initialize();
    return 0;
}

当像这样编译和链接(使用gcc 4.2.4)时,预处理器在/ usr / local / include /中找到版本3.7.4的sqlite3.h头文件,但链接器在查看/ usr / lib时失败/libsqlite3.so用于符号。

$ gcc -Wall test.c -o cpp -lsqlite3
/tmp/cc4iSSN6.o: In function `main':
test.c:(.text+0x26): undefined reference to `sqlite3_initialize'
test.c:(.text+0x2b): undefined reference to `sqlite3_shutdown'
collect2: ld returned 1 exit status

当然,我可以指定lib目录,并链接正确的库版本。

$ gcc -Wall test.c -o cpp -L/usr/local/lib -lsqlite3
$ ./cpp
3007004
$

默认情况下,gcc在/ usr / local / include / before / usr / include / for headers中查找,但在链接时不在库中查找。为什么呢?

编辑1:正如蒂姆·波斯特所建议的那样:

$ sudo ldconfig -n /usr/local/lib
$ ldconfig -p | grep sqlite3
    libsqlite3.so.0 (libc6) => /usr/local/lib/libsqlite3.so.0
    libsqlite3.so.0 (libc6) => /usr/lib/libsqlite3.so.0
    libsqlite3.so (libc6) => /usr/local/lib/libsqlite3.so
    libsqlite3.so (libc6) => /usr/lib/libsqlite3.so
$ gcc -Wall cpp.c -o cpp -lsqlite3
/tmp/ccwPT9o0.o: In function `main':
cpp.c:(.text+0x26): undefined reference to `sqlite3_initialize'
cpp.c:(.text+0x2b): undefined reference to `sqlite3_shutdown'
collect2: ld returned 1 exit status

2 个答案:

答案 0 :(得分:9)

包含文件搜索路径由 gcc 定义,但库搜索路径编码为 ld ,它来自一个单独的项目;这些不一定是同步的。

您可以做的一件事是修补 specs 文件,如果它存在,可以在与 libgcc 相同的目录中找到;你可以使用

获得后者的路径
gcc -print-libgcc-file-name

如果那里没有 specs 文件,请使用

创建一个
gcc -dumpspecs >specs

并通过调用

验证gcc正在读取它
gcc -v

查找包含%{L*}的行,并在其后面添加-L/usr/local/lib(以空格分隔)。然后,Gcc将在链接后将任何-L选项从命令行传递到 ld 之后传递此参数。

为了恢复默认值,只需将specs文件还原为其初始状态(即如果之前不存在则将其删除)。

答案 1 :(得分:0)

这可能是使用黄金链接器的症状,至少在某些版本中,黄金链接器不会搜索/usr/local/lib。请尝试删除包binutils-gold

相关问题