GCC ищет заголовки в / usr / local / include при компиляции, но не ищет библиотеки в / usr / local / lib при компоновке. Зачем? - PullRequest
11 голосов
/ 25 января 2011

Я установил в / 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) препроцессор находит заголовок sqlite3.h для версии 3.7.4 в / 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
$

Кажется, по умолчанию gcc ищет в / usr / local / include / before / usr / include / для заголовков, но не для библиотек при компоновке. Почему?

Редактировать 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 ]

9 голосов
/ 25 января 2011

Путь поиска включаемого файла определяется 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 в его первоначальное состояние (т.е. удалите его, если он не существовал ранее).

0 голосов
/ 30 августа 2013

Это может быть признаком использования золотого компоновщика, который не выполняет поиск /usr/local/lib, по крайней мере, в некоторых версиях. Попробуйте удалить пакет binutils-gold.

...