[英]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.