簡體   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?

我已經安裝在/ 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時失敗。所以對於符號。

$ 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:根據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

包含文件搜索路徑由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文件恢復到其初始狀態(即如果之前不存在則刪除它)。

這可能是使用黃金鏈接器的症狀,至少在某些版本中,黃金鏈接器不搜索/usr/local/lib 嘗試刪除binutils-gold包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM