Tuesday, August 25, 2009

Setting search paths

A common problem when compiling a program using library header files is the error:

FILE.h: No such file or directory 

This occurs if a header file is not present in the standard include file directories used by gcc. A similar problem can occur for libraries:

/usr/bin/ld: cannot find library 

This happens if a library used for linking is not present in the standard library directories used by gcc.

By default, gcc searches the following directories for header files:

/usr/local/include/ /usr/include/ 

and the following directories for libraries:

/usr/local/lib/ /usr/lib/ 

The list of directories for header files is often referred to as the include path, and the list of directories for libraries as the library search path or link path.

The directories on these paths are searched in order, from first to last in the two lists above.(7) For example, a header file found in ‘/usr/local/include’ takes precedence over a file with the same name in ‘/usr/include’. Similarly, a library found in ‘/usr/local/lib’ takes precedence over a library with the same name in‘/usr/lib’.

When additional libraries are installed in other directories it is necessary to extend the search paths, in order for the libraries to be found. The compiler options -I and-L add new directories to the beginning of the include path and library search path respectively.

The following example program uses a library that might be installed as an additional package on a system--the GNU Database Management Library (GDBM). The GDBM Library stores key-value pairs in a DBM file, a type of data file which allows values to be stored and indexed by a key (an arbitrary sequence of characters). Here is the example program ‘dbmain.c’, which creates a DBM file containing a key ‘testkey’ with the value ‘testvalue’:

#include  #include   int main (void) {   GDBM_FILE dbf;   datum key = { "testkey", 7 };     /* key, length */   datum value = { "testvalue", 9 }; /* value, length */    printf ("Storing key-value pair... ");   dbf = gdbm_open ("test", 0, GDBM_NEWDB, 0644, 0);   gdbm_store (dbf, key, value, GDBM_INSERT);   gdbm_close (dbf);   printf ("done.\n");   return 0; } 

The program uses the header file ‘gdbm.h’ and the library ‘libgdbm.a’. If the library has been installed in the default location of ‘/usr/local/lib’, with the header file in‘/usr/local/include’, then the program can be compiled with the following simple command:

$ gcc -Wall dbmain.c -lgdbm 

Both these directories are part of the default gcc include and link paths.

However, if GDBM has been installed in a different location, trying to compile the program will give the following error:

$ gcc -Wall dbmain.c -lgdbm     dbmain.c:1: gdbm.h: No such file or directory 

For example, if version 1.8.3 of the GDBM package is installed under the directory ‘/opt/gdbm-1.8.3’ the location of the header file would be,

/opt/gdbm-1.8.3/include/gdbm.h 

which is not part of the default gcc include path. Adding the appropriate directory to the include path with the command-line option -I allows the program to be compiled, but not linked:

$ gcc -Wall -I/opt/gdbm-1.8.3/include dbmain.c -lgdbm  /usr/bin/ld: cannot find -lgdbm collect2: ld returned 1 exit status 

The directory containing the library is still missing from the link path. It can be added to the link path using the following option:

-L/opt/gdbm-1.8.3/lib/ 

The following command line allows the program to be compiled and linked:

$ gcc -Wall -I/opt/gdbm-1.8.3/include     -L/opt/gdbm-1.8.3/lib dbmain.c -lgdbm 

This produces the final executable linked to the GDBM library. Before seeing how to run this executable we will take a brief look at the environment variables that affect the -I and -L options.

Note that you should never place the absolute paths of header files in #include statements in your source code, as this will prevent the program from compiling on other systems. The -I option or the INCLUDE_PATH variable described below should always be used to set the include path for header files.

No comments:

Post a Comment