How do I prevent hard coded library path dependencies in my executables created with gcc ?

Posted on 2004-04-22
Last Modified: 2012-05-04
My make file links the executable with shared libraries.  I have set the library search path with the "-L..\lib\x86_64".  The resultant executable then has hard coded dependency to ..\lib\x86_64 which I do not want.  When program loads, I want LD_LIBRARY_PATH to determine which shared library to link with - I do not want it hard coded.

Below is my make file for tgoctest executable.  Along with a "strings" output which proves that the executable is hard wired to a specific path.

PROJ = tgoctest
CC = gcc
LINK = gcc

#default configuation - this should be speciifed when using this makefile
#default platform - this should be specified when using this makefile
TGPLATFORM:=$(shell arch)

LIBS_EXT = -lpthread -lncurses
CFLAGSDEBUG = -g  -D "_DEBUG" -D "UNIX" -D "LINUX" -I ../include
LFLAGSDEBUG = -g -L../lib/$(TGPLATFORM) -ltgoc -ltgjpeg
CFLAGSRELEASE = -O -D "UNIX" -D "LINUX" -I ../include
LFLAGSRELEASE = -L../lib/$(TGPLATFORM) -ltgoc -ltgjpeg

TGOCTEST_DEP = ../include/tgocosdp.h \

all:    checkconfig $(OBJDIR)/$(PROJ)

        @if [[ ! -d $(OBJDIR) ]]; then \
                mkdir $(OBJDIR); \

"tgoctestlinux.mak" 50L, 1116C                      

tyohe@suse64:/yam/tg/source/tgoctest> strings x86_64/tgoctest | grep lib
Zlib Compile Flags =0x%x
Set Zlib compression level
Question by:tomatoyohe
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4

Expert Comment

ID: 10892028
strings is not the right way of testing.

Use ldd.

Using -L does not hardcode library paths. -R has to be used for this. So, it's not a problem of where your libs are at compile time. If they are somewhere in the LD_LIBRARY_PATH at exec time, they will be used.


Author Comment

ID: 10892324
Thanks for your insight, however it is not quite on target.  ldd shows where the libraries will be loaded from if you were to execute the program and it uses LD_LIBRARY_PATH to help determine this.  When I try to load the executable, it fails even if LD_LIBRARY_PATH is set to a directory where the shared libraries reside.  The strings command shows that the shared libraries must reside in ..\lib\x8_64 relative to the current directory.

The following illustrates this.

tyohe@suse64:~/test> set | grep LD_LIBRARY_PATH
tyohe@suse64:~/test> ls -l junk
total 404
-rwxr-xr-x  1 tyohe users 176803 2004-04-22 14:36 libtgjpeg.a
-rwxr-xr-x  1 tyohe users 230689 2004-04-22 14:36 libtgoc.a
tyohe@suse64:~/test> ls -l
total 200
drwxr-xr-x  2 tyohe users    112 2004-04-22 14:37 junk
-rwxr-xr-x  1 tyohe users 203259 2004-04-22 14:36 tgoctest
tyohe@suse64:~/test> ./tgoctest
./tgoctest: error while loading shared libraries: ../lib/x86_64/libtgoc.a: cannot open shared object file: No such file or directory
tyohe@suse64:~/test> pwd

Previous investigation led me to this article 
 which indicates that ldd does not show hardcoded references - only what would be chosen by dynamic linker.

Expert Comment

ID: 10892669
Oh no !!!

This is totally normal. The libraries you have here are "static libraries". I did not notice it in the first place.

in fact, a ".a" file is an archive file that contains ".o" files.

If you want to link with shared libraries, you have to use the following :

gcc -shared -Xlinker -x -o myobj1.o myobj1.o

Then, link against these.

And, I'm sorry, but ldd is completely on topic. It will show you what will actually be used by the dynamic loader. So, it allows you to see that the libraries are correctly loaded.

A short example :

serval:/tmp # cat test.c
doit() {
  printf("test\n") ;

serval:/tmp # cat test2.c
extern doit() ;

main() {

  doit() ;


serval:/tmp # gcc -c test.c
serval:/tmp # gcc -shared -Xlinker -x -o test.o
serval:/tmp # gcc test2.c -o test2 -L/tmp -ltest

serval:/tmp # ls -al test*
-rw-r--r--    1 root     root           32 Apr 22 21:15 test.c
-rw-r--r--    1 root     root          760 Apr 22 21:22 test.o
-rwxr-xr-x    1 root     root         8466 Apr 22 21:22 test2
-rw-r--r--    1 root     root           41 Apr 22 21:16 test2.c

serval:/tmp # mkdir foo
serval:/tmp # cd foo/
serval:/tmp/foo # ldd ../test2 => not found => /lib/i686/ (0x40032000)
        /lib/ => /lib/ (0x40000000)

serval:/tmp/foo # export LD_LIBRARY_PATH=/tmp
serval:/tmp/foo # ldd ../test2 => /tmp/ (0x4001a000) => /lib/i686/ (0x40034000)
        /lib/ => /lib/ (0x40000000)

serval:/tmp/foo # ../test2

See ?
The Orion Papers

Are you interested in becoming an AWS Certified Solutions Architect?

Discover a new interactive way of training for the exam.


Expert Comment

ID: 10892684
Oh. And, yes. ldd only shows what's used.
But you don't care about static references if your dynamic linker is able to find the libraries where you want them to be.

Expert Comment

ID: 10892752
Sorry. One more.

Works on Linux, but not on all systems.

serval:/tmp # unset LD_LIBRARY_PATH
serval:/tmp # gcc test2.c -o test2 -Wl,-rpath,/tmp -L/tmp -ltest
serval:/tmp # cd foo/
serval:/tmp/foo # ldd ../test2 => /tmp/ (0x4001a000) => /lib/i686/ (0x40034000)
        /lib/ => /lib/ (0x40000000)

Some systems (like Solaris) use the '-R' option to the compiler.

These differences is the reason why most big projects make use of libtool. libtool standardizes the calls to the compiler/linker and adapt to the actual system's options.

Author Comment

ID: 10892860
As far as I know, libtgoc.a is not a static library but a shared library.  When I built it, I thought I specified it to be shared.  Here is pertinent part of the make file:

PROJ = libtgoc.a

CC = gcc
LINK = gcc

#default configuation - this should be speciifed when using this makefile
#default platform - this should be specified when using this makefile
TGPLATFORM:=$(shell arch)


CFLAGSDEBUG = -g -fPIC -D "_DEBUG" -D "UNIX" -D "LINUX" -I ../include
LFLAGSDEBUG = -shared -fPIC -Wl,-Bsymbolic -ldl

CFLAGSRELEASE = -fPIC -O3 -D "UNIX" -D "LINUX" -I ../include
LFLAGSRELEASE = -shared -fPIC -Wl,-Bsymbolic -ldl

LIBS_EXT =  -l m -l c -l pthread

Author Comment

ID: 10892931
Furthermore, objdump utility indicates that the library is dynamic (not static).

tyohe@suse64:~/test/junk> objdump -f libtgoc.a

libtgoc.a:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
start address 0x0000000000007470

Accepted Solution

Alf666 earned 250 total points
ID: 10893848
Ok. Just a naming convention problem then. It should be named .so and not .a. (I'm not sure if it makes a difference, but you might want to try).

Can you show me the output of ldd on tgoctest ?

Author Comment

ID: 10894064
Well after simply renaming the ".a" files to ".so" files the hard coded paths are now removed from the executable!  Thank you.

tyohe@suse64:/yam/tg/source/tgoctest> strings x86_64/tgoctest | grep lib

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question