2011-01-25 4 views
9

私は、SQLiteのバージョン3.4.2を提供する/ usr/distributionにインストールしました。 私は/ usr/local/SQLiteバージョン3.7.4にインストールしました。 3004002
/usr/local/include/sqlite3.hは3007004GCCは、コンパイル時に/ usr/local/includeのヘッダーを探しますが、リンク時に/ usr/local/libのライブラリは探しません。どうして?

版3007004としてSQLITE_VERSION_NUMBERを定義するよう

/usr/include/sqlite3.hはSQLITE_VERSION_NUMBERを定義バージョン3004002にはない、()関数sqlite3_initializeを有しています。

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

Iは、次の例のプログラムのコンパイル時:

#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で)コンパイルおよびリンクする場合、プリプロセッサは、バージョン3.7.4用sqlite3.hヘッダを発見/ usr/local/include /にありますが、リンカはシンボルの/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 
$ 

リンク時には/ usr /含める/ヘッダのではなく、ライブラリのための/は/ usr/localには/の前に含ま見えるデフォルトのgccでいるようです。どうして?

編集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 

答えて

8

インクルードファイルの検索パスを含めるにはGCCによって定義されていますが、ライブラリの検索パスは、別のプロジェクトからであるLD、にエンコードされ;これらは必ずしも同期されるとは限りません。あなたができる

ことの一つは、それが存在する場合は、のlibgcc と同じディレクトリに見つけることができ、スペックファイルを、パッチです。あなたは何スペックファイルが存在しない場合は、

gcc -print-libgcc-file-name 

を使用して、後者へのパスを取得

gcc -dumpspecs >specs 

を使用して作成し、gccが

gcc -v 
を呼び出すことによって、それを読んでいることを確認することができます

%{L*}が含まれている行を探し、その後に(空白で区切って)-L/usr/local/libを追加します。 GCCは、リンク時にコマンドラインから-Lオプションの後にこの引数をldに渡します。

デフォルトを復元するには、スペックファイルを元の状態に戻してください(以前に存在しなかった場合は削除してください)。

+1

ライブラリパスは 'ld'にコード化されているだけでなく、' ld'コマンドラインで 'gcc'によって明示的に指定されています(' ld'にもコード化されています)。単に 'strace'を使って見てください。 –

0

これは少なくとも一部のバージョンでは/usr/local/libを検索しない金リンカーを使用した場合の症状です。パッケージbinutils-goldを取り外してみてください。

+0

-1ははるかに良いリンカーである金を取り除くことが最善の提案ではないためです。 –

+0

次に、より良い提案は何ですか?すべてのコマンドラインに明示的な '-L/usr/local/lib'を追加しますか?小規模なプロジェクトでは、この問題を除いて基本的に 'gold'と' ld'の違いはありません。 –

+0

-1は、検索パスに関してgoldとldの間に違いがないためです。リンク時ライブラリ検索パスはgccから来ます。 –