简体   繁体   English

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

[英]GCC looks for headers in /usr/local/include when compiling, but not for libraries in /usr/local/lib when linking. Why?

I have installed in /usr/ the distribution provided version of SQLite - version 3.4.2. 我已经安装在/ usr /分发提供的SQLite版本 - 版本3.4.2。 I have installed in /usr/local/ SQLite version 3.7.4. 我已经安装在/ usr / local / SQLite版本3.7.4中。

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

Version 3007004 has the function sqlite3_initialize(), version 3004002 does not. 版本3007004具有sqlite3_initialize()函数,版本3004002没有。

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

When I compile the following example program: 当我编译以下示例程序时:

#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;
}

When compiled and linked (with gcc 4.2.4) like this the preprocessor finds the sqlite3.h header for version 3.7.4 in /usr/local/include/, but the linker fails as it's looking in /usr/lib/libsqlite3.so for the symbols. 当像这样编译和链接(使用gcc 4.2.4)时,预处理器在/ usr / local / include /中找到版本3.7.4的sqlite3.h头,但是链接器在查找/ usr / lib / libsqlite3时失败。所以对于符号。

$ 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

Of course I can specify the lib directory and it links the correct version of the library. 当然我可以指定lib目录,它链接正确的库版本。

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

It seems by default gcc looks in /usr/local/include/ before /usr/include/ for headers, but not for libraries when linking. 默认情况下,gcc在/ usr / local / include / before / usr / include / for headers中查找,但在链接时不在库中查找。 Why? 为什么?

Edit 1: As suggested by Tim Post: 编辑1:根据Tim Post的建议:

$ 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

The include file search path is defined by gcc , but the library search path is encoded into ld , which is from a separate project; 包含文件搜索路径由gcc定义,但库搜索路径编码为ld ,它来自单独的项目; these are not necessarily synchronized. 这些不一定是同步的。

One thing you could do is patch the specs file, which, if it exists, can be found in the same directory as libgcc ; 您可以做的一件事是修补specs文件,如果它存在,可以在与libgcc相同的目录中找到; you can get the path to the latter using 你可以使用后者获得后者的路径

gcc -print-libgcc-file-name

If there is no specs file there, create one using 如果那里没有specs文件,请使用创建一个

gcc -dumpspecs >specs

and verify that gcc is reading it, by calling 并通过调用验证gcc是否正在读取它

gcc -v

Look for a line containing %{L*} , and add -L/usr/local/lib behind it (separated by spaces). 查找包含%{L*} ,并在其后面添加-L/usr/local/lib (以空格分隔)。 Gcc will then pass this argument following any -L options from the command line to ld when linking. 然后,Gcc将在链接时将命令行中的任何-L选项传递给ld

In order to restore the defaults, just revert the specs file to its initial state (ie delete it if it didn't exist before). 要恢复默认值,只需将specs文件恢复到其初始状态(即如果之前不存在则删除它)。

This may be symptom of using the gold linker, which does not search /usr/local/lib , at least in some versions. 这可能是使用黄金链接器的症状,至少在某些版本中,黄金链接器不搜索/usr/local/lib Try removing the package binutils-gold . 尝试删除binutils-gold包。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当它们不在 /usr/local/lib 中时,链接到 gslcblas 库的正确标志是什么? - What are the correct flags for linking to gslcblas libraries when they are not in /usr/local/lib? Xcode 7.1无法从/ usr / local / lib库链接 - Xcode 7.1 not linking from /usr/local/lib library 将文件添加到 /usr/local/include - Adding files to /usr/local/include 为什么在文件夹“/ lib”和“/ usr / lib”中链接库(如pthread)? - Why link libraries (like pthread) when they are in the right folder “/lib” and “/usr/lib”? 未找到 /usr/local/lib 中的共享库 - Shared library in /usr/local/lib not found MPICH:MPICC ld:找不到文件:/usr/local/lib/gcc/4.9/libgfortran.3.dylib用于架构x86_64 - MPICH: MPICC ld: file not found: /usr/local/lib/gcc/4.9/libgfortran.3.dylib for architecture x86_64 如何使cc查看/ usr / local / include的头文件 - How to make cc look into /usr/local/include for header files 将库安装在/ usr / include中时,如何使它的“通用标头”工作? - How to make “common headers” for a library work when it's installed in /usr/include? 从 /usr/lib 或 /usr/local/lib 通过 cmake 链接到二进制文件的最文明/现代的方式是什么? - What's the most civil/modern way to get a library from /usr/lib or /usr/local/lib linked to a binary via cmake? KLEE:错误:加载文件 /usr/local/lib/klee/runtime/klee-uclibc.bca 失败:记录无效 - KLEE: ERROR: Loading file /usr/local/lib/klee/runtime/klee-uclibc.bca failed: Invalid record
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM