I have installed in /usr/ the distribution provided version of SQLite - version 3.4.2. I have installed in /usr/local/ SQLite version 3.7.4.
/usr/include/sqlite3.h defines SQLITE_VERSION_NUMBER as 3004002
/usr/local/include/sqlite3.h defines SQLITE_VERSION_NUMBER as 3007004
Version 3007004 has the function sqlite3_initialize(), version 3004002 does not.
$ 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 -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.
$ 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. Why?
Edit 1: As suggested by 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 looks for headers requested with #include " file " first in the directory containing the current file, then in the directories as specified by -iquote options, then in the same places it would have looked for a header requested with angle brackets.
gcc -I adds include directory of header files.
c "). GCC uses a separate linker program (called ld.exe ) to perform the linking.
The include file search path is defined by gcc, but the library search path is encoded into ld, which is from a separate project; 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; you can get the path to the latter using
gcc -print-libgcc-file-name
If there is no specs file there, create one using
gcc -dumpspecs >specs
and verify that gcc is reading it, by calling
gcc -v
Look for a line containing %{L*}
, and add -L/usr/local/lib
behind it (separated by spaces). Gcc will then pass this argument following any -L options from the command line to ld when linking.
In order to restore the defaults, just revert the specs file to its initial state (i.e. delete it if it didn't exist before).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With