Sometimes an administrator must install source code packages that include DLLs (Dynamic Link Libraries), also known as shared object (or SO) files. While not normally a problem, occasionally some source code will refuse to compile because of minor problems with the DLLs. As an administrator you should be able to correct such minor problems without (paying for) a software developer's help.
The main issues are:
If a compile of some source code fails due to a missing library,
first make sure the library is really missing.
For example, the bsdtar
source code package includes
a required DLL, “libarchive
”.
However, building this package fails because the build process
attempts to build the program (“bsdtar
”) before
building and installing the DLL it needs
(“libarchive
”).
In this case the fix was easy: cd
to the
libarchive
build directory, and issue the required
make
and make install
steps
manually.
Once finished building libarchive
, a restart of the
bsdtar
build succeeded.
If the missing DLL is not part of the current source
package (or tar-ball), check the included README
,
INSTALL
,
and other documentation to see if this is discussed.
Query your package management system to see if the library is
part of some package that you may need to refresh.
Search various repositories on the Internet to see if the missing
library is available as part of some other package you can install.
If you can't locate the file, make sure the package you are trying to install is designed to work on your (type of) system!
If you do locate the DLL on your system but the compiler can't find it, there are some likely causes:
mylib.so.1.2.3
”,
you should have the following symlinks to that DLL:
mylib.so mylib.so.1 mylib.so.1.2
(The link with no version number is used by compilers, but usually
installed from a separate package
“somelib-devel
”.)
root
installed the DLL and the
umask
was set to say “027
”, then
other users may not have permission to use the
DLLs.
This is fixable easily with chmod
.
lib.so.2
”, you probably have that version
installed now.
Now if you install some other software that requires specifically
lib.so.1
, you won't be able to build (or use) it.
The fix in this case is to have both versions installed.
But make sure all the symlinks are correct, and that
lib.so
symlink refers to the latest version and not
some earlier one.
In order to have two different versions of some library available, so some applications can use one version while other applications use a different version, the symbols (function, data, ... names) in the DLLs must be tagged with a version number. Not all systems support that. For example, Red Hat Linux and variants such as Fedora don't, while Debian Linux and variants such as Ubuntu do. Of course, you can rebuild the kernel on a Red Hat type system and the DLL tools, and use multiple versions there too.
ld.so
(or ld-linux.so
) isn't
configured to look in that location.
In that case you need to edit /etc/ld.so.conf*
to make
sure the correct location is used, and/or run
“ldconfig
” to rebuild the cache.
LD_LIBRARY_PATH
environment
variable, so every non-standard location where DLLs
are to be found must be listed on the command line using the
“-Ldir
” option.
The fix here is to edit the Makefile
and change the
compiler options to also look in the required directory.
Look near the top of the makefile and try to spot where the
compiler options are defined, by looking for lines containing other
“-Ldir
” compiler options.
Now edit that line (or add a new one) that includes the missing
“-Ldir
” option.
Here is a simple demo of a “Hello, World!” C program.
This demo contains the source code for a DLL named
“libhello.so.1
”.
(The actual library file name is
“libhello.so.1.0.0
”.)
First you must build this and install it.
For this demo, no root access is required.
We will install the DLL in a non-standard location, namely
“~/lib
”.
Once the DLL is built you can then build the
application that uses the DLL, named
“libhello_test
”.
This can then be installed in your ~/bin
directory.
/* libhello - source to demo shared library use. * Shared libraries have a "major" version and a * "minor" version (and sometimes a "release" version * number as well). Different major numbers indicate * (possibly) incompatible versions; if the major * number is the same than the minor number indicates * compatible bug fixes. Our current version is * "libhello.1.0.0". * * BUILD DIRECTIONS: * gcc -fPIC -shared -Wl,-soname,libhello.so.1 \ * -o libhello.so.1.0.0 libhello.c * * INSTALL DIRECTIONS: * Copy the libhello.so.1.0.0 to a standard directory * such as /usr/lib (or if system is configured for it, * /usr/local/lib). * Run "ldconfig" to create the various symlinks required. * * * OR * * * Put the libhello.so.1.0.0 anywhere, say ~/lib, and then: * Run "ldconfig -nv ~/lib" (or whatever dir you used). * (Note for security reasons LD_LIBRARY_PATH is ignored when * running SUID programs!) * * In either case ldconfig doesn't create a full set of symlinks. * Make sure you manually create any missing ones: * cd ~/lib * ln -s libhello.so.1.0.0 libhello.so.1.0 * ln -s libhello.so.1.0 libhello.so.1 * ln -s libhello.so.1 libhello.so * * Written 7/2005 by Wayne Pollock, Tampa Florida USA. */ #include "libhello.h" #include <stdio.h> /* ELF shared libraries can have many functions and even * global variables. Here is one demo function: */ void say_hello ( char* s ) { printf( "Hello, %s!\n", s ); } /* When a shared library is loaded, two special function * are used: _init when the library is loaded and _fini * when it is unloaded (typically when the process exits). * If you don't have either one defined, the system will * create a default "do nothing" version for you! void _init () { printf( "%s\n", "Library libhello.so initializing!" ); } void _fini (); { printf( "%s\n", "Library libhello.so unloading!" ); } */
/* libhello.h - header for libhello.so.1.0.0 demo program * * Written 7/2005 by Wayne Pollock, Tampa Florida USA. */ /* ELF shared libraries can have many functions and even * global variables. Here is one demo function: */ void say_hello ( char* str ); /* When a shared library is loaded, two special function * are used: _init when the library is loaded and _fini * when it is unloaded (typically when the process exits). * If you don't have either one defined, the system will * create a default "do nothing" version for you! void _init (); void _fini (); */
/* libhello_test - A sample application that * uses the demo shared library "~/lib/libhello.so.1.0.0". * * COMPILE DIRECTIONS: * Make sure libhello.so* is in a standard directory, or * use the gcc command line argument "-L<dir>". * Also make sure libhello.h is in a standard include directory * (such as the current directory) or add "-I<dir>": * * gcc -Wall -L~/lib -o libhello_test libhello_test.c -lhello * * If this fails to work make sure the library is chmod a+rx, * and that all needed symlinks are there. (Note ldconfig -nv dir * doesn't create all required links.) * * Written 7/2005 by Wayne Pollock, Tampa Florida USA. */ #include "libhello.h" int main ( void ) { say_hello( "World" ); return 0; }
If a DLL is installed in a non-standard location,
even if some application that uses it builds successfully it
may not run!
This is because the compiler uses command-line arguments
(“-Ldir
”) to locate DLLs
at compile time, but at run time only the standard locations are
checked.
To fix you can tell the program where to look for such
DLLs by setting the LD_LIBRARY_PATH
environment variable.
However this is awkward as every program will use this
setting, so other applications may break.
An alternative is to hard-code the absolute pathname to the
DLL(s) in the application binary.
This can be done by adding a compiler option of
“-W1,-rpath=path-to-DLL
”
to the command line when building the application.
If you later move the DLLs to a standard location
you will have to rebuild the application without this extra option.
The gcc
commands used to compile C programs include
options to tell the compiler where to look for
header files (dot-h files).
If the compile fails because some header file couldn't be located,
first make sure you read the README
,
INSTALL
, and other documentation before proceeding
with any trouble-shooting steps!
If the is no mention of the problem in the documentation,
you should see if you can locate the file yourself.
Often it will be in the same directory (or a sub-directory) of
the program you are attempting to build.
If not, use locate
or find
to determine
the file's location.
Now see if the gcc
command that generated the
“not found” error lists that directory on the command line
with the “-Idirectory
” option.
If not, you have found the problem!
You can fix the problem in two ways:
edit the C source code file and repair the faulty
“#include "path-to-file.h"
” line;
or edit the “Makefile
” to make sure the correct
directory is used with gcc
.
In the latter case look near the top of the makefile to locate
the line(s) where the compiler options are defined, and
change or just add the required directory.
(That is, look for the other
“...-Idir
...”
lines, and add in a new one or replace the old bad one.)
If the file doesn't appear to be on your system, check the website home of the software and see if you can find a more recent source package or tar-ball then the one you're using. Check for notes, postings, mailing list archives, FAQs, or other information about your problem. Don't hesitate to use any of the Internet resources you have learned!