LD_LIBRARY_PATH is ignored by GCC - c

according to docs, GCC looks paths in LD_LIBRARY_PATH for linking shared library BUT it seems in my case it is ignored!
echo $LD_LIBRARY_PATH -->:/home/mehrdad/usr/lib (so LD_LIBRARY_PATH is set currectly)
i have libfoo.so in "/home/mehrdad/usr/lib" BUT :
gcc main.c -lfoo returns error :
/usr/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status
so what is the problem??? is LD_LIBRARY_PATH deprecated???!
but i can successfully link with explicit command :
gcc main.c -L/home/mehrdad/usr/lib -lfoo
and also I can successfully execute the a.out by just:
./a.out
it seems LD_LIBRARY_PATH is respected by OS library loader BUT NOT GCC!
my environment :
OS : CentOs 7
compiler : gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)

I was wrong! thanks to Alexandre C and David Schwartz!
LD_LIBRARY_PATH is only for loader(runtime).
LIBRARY_PATH is what I need according to the docs:
The value of LIBRARY_PATH is a colon-separated list of directories,
much like PATH. When configured as a native compiler, GCC tries the
directories thus specified when searching for special linker files, if
it cannot find them using GCC_EXEC_PREFIX. Linking using GCC also uses
these directories when searching for ordinary libraries for the -l
option (but directories specified with -L come first).

Related

why can my gcc command not have -static parameter

I usually use gcc to compile my C program, it works ok, but when I tried to compile static library with -static parameter it always failed.
Although I tried some solutions on google, but it still didn't get fixed.
My command is as follows:
gcc mycode.c -static -L . -lurl -lcap -o mycode
The error message is:
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
but when I remove -static it works very well.
GCC's -static linkage option directs the linker to ignore shared libraries
during the linkage. So it must find static versions of all the libraries required
by the linkage, including those that are linked by default, such as libc.
You have not installed the static version of libc (which would be /usr/lib/???/libc.a), so:
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
libc.a is installed by the libc development package. The name of the libc
development package and how to install it depends on your distro. E.g. On Debian
or Ubuntu, the package to install is libc6-dev; on Fedora it is glibc-develop.
But before you go to do that, hang on a tick. You said:
I tried to compile static library with -static parameter it always failed.
gcc mycode.c -static -L . -lurl -lcap -o mycode
That sounds rather as if you just wanted to link your program with one or both
static libraries liburl.a, libcap.a, located in ./, and thought you should
do it by passing -static to the linkage.
There is no need to pass -static to link your program with ./liburl.a and/or
./libcap.a. The options:
-L . -lurl -lcap
will direct the linker to search in ./ for either of the files liburl.so (shared library)
or liburl.a (static library) and if it finds one or other of them it will link your
program with that library. If it finds both of them in ./, then it will choose the
shared library liburl.so. So unless you have ./liburl.so as well as ./liburl.a
then:
-L . -lurl
by itself will link your program against ./liburl.a.
And likewise for -lcap. No need for -static. The default shared library libc.so
will be linked automatically. The linker has no problem at all linking your program
with some static libraries and some shared ones. That is what is already happening
with your successful linkage:
gcc mycode.c -L . -lurl -lcap -o mycode
assuming that liburl.a and libcap.a are the only candidates for resolving
-lurl and -lcap in ./.
And even if you do have both ./liburl.a and ./liburl.so - and/or ./libcap.a and ./libcap.so - there is still no
need for a solution as drastic as a fully static linkage. You can just explicitly
tell the linker to find a particular static library if that's what you want, like:
gcc mycode.c -L . -l:liburl.a -l:libcap.a -o mycode

LIBRARY_PATH environment variable not being used / read with gcc

My LIBRARY_PATH variable is exported, but I still have to pass the -L option to gcc in order to link to my library.
If I understand the GCC documentation correctly 3.20 Environment Variables Affecting GCC, the LIBRARY_PATH environment variable should be looked so that I only have to specify the -l option.
When I run
gcc -Wall cog.c -L$HOME/lib -lutil
the program is compiled, and I get an a.out as expected.
If I run
gcc -Wall cog.c -lutil
I get an undefined reference error.
As far as I can tell, I've properly exported the environment variable.
cassiopeia~> export LIBRARY_PATH=$HOME/lib
cassiopeia~> ls $LIBRARY_PATH
libutil.a
Any clues?
For what it's worth, I'm using Fedora 23 64bit and gcc version 5.3.1 20160406 (Red Hat 5.3.1-6).
Your distro probably is multilib-enabled. If this is the case, all path strings to libraries are expanded with the architecture for this machine (typically 32-bit or 64-bit). So, if you specify
$HOME/lib
as your search path, multilib might expand it to
$HOME/lib/x86_64-linux/4.6
or
$HOME/lib/x86_32-linux/4.6
You can check if this is the case by invoking gcc once using
gcc --print-search-dirs
This makes gcc respond with all search paths in use for config and libraries.

a linker issue when learning static library [duplicate]

When I try to build the following program:
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
On OS X 10.6.4, with the following flags:
gcc -static -o blah blah.c
It returns this:
ld: library not found for -lcrt0.o
collect2: ld returned 1 exit status
Has anyone else encountered this, or is it something that noone else has been affected with yet? Any fixes?
Thanks
This won’t work. From the man page for gcc:
This option will not work on Mac OS X unless all libraries (including libgcc.a) have also been compiled with -static. Since neither a static version of libSystem.dylib nor crt0.o are provided, this option is not useful to most people.
Per Nate's answer, a completely static application is apparently not possible - see also man ld:
-static Produces a mach-o file that does not use the dyld. Only used building the kernel.
The problem in linking with static libraries is that, if both a static and a dynamic version of a library are found in the same directory, the dynamic version will be taken in preference. Three ways of avoiding this are:
Do not attempt to find them via the -L and -l options; instead, specify the full paths, to the libraries you want to use, on the compiler or linker command line.
$ g++ -Wall -Werror -o hi /usr/local/lib/libboost_unit_test_framework.a hi.cpp
Create a separate directory, containing symbolic links to the static libraries, use the -L option to have this directory searched first, and use the -l option to specify the libraries you want to use.
$ g++ -Wall -Werror -L ./staticBoostLib -l boost_unit_test_framework -o hi hi.cpp
Instead of creating a link of the same name in a different directory, create a link of a different name in the same directory, and specify that name in a -l argument.
$ g++ -Wall -Werror -l boost_unit_test_framework_static -o hi hi.cpp
You may also try LLVM LLD linker - I did prebuilt version for my two major OSes - https://github.com/VerKnowSys/Sofin-llds
This one allows me to link for exmple: "Qemu" properly - which is impossible with ld preinstalled by Apple.
And last one is - to build GCC yourself with libstdc++ (don't).

GCC math.h in fedora v/s Ubuntu

I am using sin function in one of my c program.
The program runs prefectly on fedora machine but ginving reference issue in ubuntu machine
I have compile it using -lm like following:
gcc -lm kepler.c -o a.out --working on fedora, but not on ubuntu
gcc kepler.c -lm -o a.out --Working on both, fedora and ubuntu
/tmp/ccshH33a.o: In function `kepler':
/tmp/28/kepler.c:7: undefined reference to `sin'
collect2: error: ld returned 1 exit status
So can any one explains about the position of -lm, and why its working on fedora machine for both cases?
Thanks in Adavance.
gcc like all common compilers internally launches different programs : at least a compiler and a linker. -lm option is intended for linker, as is -o a.out. BTW,-o a.outis just a no-op sincea.outis the default name when-o` option is absent.
Why -lm before kernel.c may fail : as explained in the answer to the question referenced by Cornstalks in comment, linker processes its arguments left to right, so dependant libraries must come after modules calling them
Why could it succeed on fedora : object modules will always be included in the executable program, so it can makes sense to always put them first in the argument list passed to the linker, of for the linker to process them first
Why did it work on Fedora and not on Ubuntu : I assume it is not same version of gcc, and the one on Fedora is more tolerant.
Anyway, the correct way is to always put dependant libraries after the modules (or other libraries) calling them.

Cannot find -lagent when compiling c source code (incompatible library)

With gcc in ubuntu I used this command to compile my source code:
gcc 1.c -L. -lagent -lm -lpthread -o 1
but I got this error:
/usr/bin/ld: skipping incompatible ./libagent.so when searching for -lagent
/usr/bin/ld: cannot find -lagent
collect2: ld returned 1 exit status
How can I solve this?
The linker is telling you that the file ./libagent.so exists, but isn't in the appropriate format.
It could be an empty file, or built for 32-bit instead of 64-bit, or it could be a symlink pointing to the wrong version.
Let's look at your command line parameters first.
gcc 1.c -L. -lagent -lm -lpthread -o 1
You call the compiler gcc with the input source code of 1.c and then you specify an additional (link) library path to include the current directory (.) -L.. Then you tell it to link against the agent and pthread libraries, where shared (dynamic) libraries have the default name format of libNAME.so where NAME is replaced with the name. Static libraries have the default file extension .a (from the term archive). Then you specify the output (executable in this case) to be the file 1 (digit one, not the letter 'ell').
/usr/bin/ld: skipping incompatible ./libagent.so when searching for -lagent
This is the linker (ld) telling you that the file ./libagent.so (it found presumably in the current directory) is not a valid shared library format as it was expecting. This could be for a different machine architecture (x86-64, ARMle, PowerPC, MIPS) or a incompatible library format (I don't know if library files, .so, have any COFF or ELF or PE dependencies or not). Or simply otherwise empty or corrupted (e.g. interrupted output due to errors compiling / linking).
So you normally want to not include your current directory in your linker's search path, unless you have the copy of the library that you have not yet installed (typically to /usr/lib/ or /usr/local/lib/), such as you wrote the library and wish to link test programs to it before you install it.
Debian and Unbuntu-oriented part of the answer:
Normally you want to install shared library's runtime component (often named something like libagent) and the associated development files (most often at least a header file and hopefully a manpage) in the format libagent-dev. RPM based Linux systems use libagent-devel style naming conventions (from memory). So sudo aptitude install libagent-dev should do the trick if that is the package's name.

Resources