How to add path to gcc's search dirs? - gcc

command
gcc -print-search-dirs
returns:
install: /usr/lib/gcc/i686-linux-gnu/4.6/
programs: =/usr/lib/gcc/i686-linux-gnu/4.6/:/usr/lib/gcc/i686-linux-gnu/4.6/:/usr/lib/gcc/i686-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/4.6/:/usr/lib/gcc/i686-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/bin/i686-linux-gnu/4.6/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/bin/i386-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/bin/
libraries: =/usr/lib/gcc/i686-linux-gnu/4.6/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/lib/i686-linux-gnu/4.6/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/lib/i386-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/lib/../lib/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../i686-linux-gnu/4.6/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../lib/:/lib/i686-linux-gnu/4.6/:/lib/i386-linux-gnu/:/lib/../lib/:/usr/lib/i686-linux-gnu/4.6/:/usr/lib/i386-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../../i686-linux-gnu/lib/:/usr/lib/gcc/i686-linux-gnu/4.6/../../../:/lib/:/usr/lib/
How to add some other path to libraries section? I want to make my custom library available via flag -lmylib instead specific path.

The usual way to do this is to install th library to /usr/lib on a user's system. The only way to change the built-in specs is by using a custom specs file (not recommended!) and this also requires an additional argument.
Either install it to /usr/lib or pass the location as an argument when linking.

You can also copy the path printed as you showed, and prepend your desired path element and pass it to the -B option.

Related

How are you supposed to know what library names are

When using a tool like pkg-config (see here), how is one supposed to know what the library name should be? It is not always intuitive. DLIB, for example, doesn't work for
pkg-config --cflags dlib
pkg-config --cflags libdlib
pkg-config --cflags dlib-19.9
I usually have to issue a command like sudo ldconfig -p | grep dlib, but all that does is return libdlib.so, which also doesn't work.
How do experts tackle this problem. Do they simply know all the library names?
It is called package name what you are using as a main parameter for pkg-config, and then applying --cflags or --libs, etc one just accesses the parameters specified and evaluated from the corresponding package config file ([some_package_name].pc, a.k.a pkg-config metadata file) that was found in pkg-config search paths.
And yes, there is no rule how package name relates to library name. Typically it's either library name without lib- prefix or just the whole library name. I found the following in pkg-config guide:
A common choice is to match the library name to the .pc name.
For instance, a package installing libfoo.so would have a
corresponding libfoo.pc file containing the pkg-config metadata. This
choice is not necessary; the .pc file should simply be a unique
identifier for your library. Following the above example, foo.pc or
foolib.pc would probably work just as well.
However, you can list all available in pkg-config search paths and find out the correct names before using them in Makefile:
$ pkg-config --list-all | grep dlib

Choose right library version

I have a project which uses libibverbs. I have to compile this project on a server to run it there. The server has libibverbs installed system-wide, but unfortunately it doesn't support a feature which I need.
I decided to compile and use my own version of libibverbs, which has the corresponding feature. So I compiled the library, installed it to my home directory, and updated following environment variables: PATH, LD_LIBRARY_PATH, C_INCLUDE_PATH, LIBRARY_PATH, CPLUS_INCLUDE_PATH
Now I have to compile my project. First I call configure and it fails with following error message:
conftest.c:(.text.startup+0x7): undefined reference to `ibv_open_xrc_domain'
This is the symbol, which is missing in the system-wide version, but is present in the version I installed. First entry in LIBRARY_PATH is the path to the new libibversion, so I expected it is going to be used first, but it seems that the old version is used anyway.
Compilation command which ./configure uses, contains flag -L/libibverbs/1.1.4/lib, which points to the directory with the new library version. This flag goes just after -L/usr/lib/../lib64 which point to the directory, with system-wide libibverbs
If I put -L with new version in the end of command, the conftest compiles successfully.
To be clear following fails: https://gist.github.com/planetA/a421669269b14e69026c53f56fa45b2b
And following works:
https://gist.github.com/planetA/3b0e22bf6aca3a1c67f30bfa3666d9a8
Could you help me to enforce picking the new version of the library in a way that configure catches it?
LD_LIBRARY_PATH specifies directories to be searched, before the
defaults, for a library that is to be loaded in a process at runtime.
It does not affect the directories that are searched for a library
in order to link it at buildtime.
The linker searches for libraries in the directories that are specified
with the -Ldir option in its commandline, before it searches its
default directories. Your configure script tests whether it can find a libibverbs library in the linker's search directories that defines the function
ibv_open_xrc_domain, and fails because it cannot. The value of LD_LIBRARY_PATH does
not matter to this test.
For GNU make, the -L-options it should pass to the linker
are conventionally specified in the environment variable LDFLAGS. GNU autoconf - which
generates your configure script - follows this convention. autoconf generates
the configure script from the project's configure.ac file.
So, if your want your modified package to generate a generate a configure
script such that running ./configure will in turn generate makefiles
in which -L/my/library/version/is/here is passed to the linker then
you need to modify the project's configure.ac like:
LDFLAGS="$LDFLAGS -L/my/library/version/is/here"
and you need to do this in the configure.ac before it runs the test for
the libibverbs library. After making this change you will need to reconfigure
the package by running autoreconf in the project directrory, to regenerate
the configure script.
If you don't want to change the configure.ac like this then you can achieve the same
effect by:
./configure LDFLAGS="$LDFLAGS -L/my/library/version/is/here"
or:
export LDFLAGS="$LDFLAGS -L/my/library/version/is/here"
... # in same shell or a subshell
./configure
Then until the next time you run the configure script the project's makefiles
will pass -L/my/library/version/is/here to the linker. But the next time
you run ./configure you must remember to set LDFLAGS in the same way, or
the regenerated makefiles will revert to the default behaviour.

cmake: how to link a library which has a lib prefix on windows

On GNU/Linux the convention is to pass the name of the library (let's call it foo) to target_link_libraries without the lib prefix (otherwise it tries to link liblibfoo.so). On windows however when I'm asking to link with "foo" it tries to find "foo.lib" which does not exist, as the library is named libfoo.lib. Is there a way to instruct cmake to add the lib prefix, without resorting to yet another if(WIN32) block ?
Use command find_library for search absolute path to the library. You may specify all possible names of searched library with NAMES option:
find_library(FOO_LIBRARY NAMES foo libfoo)
Then use result of this command for link with the library:
target_link_libraries(my_exec ${FOO_LIBRARY})

How do I change GCC's default search directory for crti.o?

I'd like to specify GCC's search directory for the startfile and
endfile: crt1.o, crti.o and crtn.o. Passing -B on the command line to
the GCC driver works, but is inconvenient. How do I modify the specs
file (lib/gcc/x86_64-unknown-linux-gnu/4.9.2/specs) to specify the search path for startfile?
I tried adding the -B option to the startfile spec and got the error:
ld: unrecognized option '-B/gsc/btl/linuxbrew/lib'
I then tried adding the -B option to the cc1 spec and got the error:
cc1: error: command line option '-B/gsc/btl/linuxbrew/lib' is valid
for the driver but not for C
If it's not possible to do this via the specs file, is there an environment variable or a configure option to GCC that accomplishes the same goal?
I've installed a recent version of glibc in my home directory. Everything's working great. I've modified the specs file to link against the new version of glibc, but it's still linking against the old system version in /usr of startfile and endfile.
Here's a the unanswered question on the gcc-help mailing list. Here's a related Linuxbrew bug, gfortran is broken with stand alone Linuxbrew, and a proposed fix, gcc, binutils: link to Cellar instead of system libs.
Thanks,
Shaun
You can use an absolute path in the *startfile: and *endfile: sections in the specs file, instead of the default relative paths. This will override GCC's choice of the default location.
As per https://wiki.debian.org/Multiarch/LibraryPathOverview, gcc will look for startup files such as crt1.o in $(sysroot)/lib, so you can specify the --sysroot option when running gcc, or compile gcc with --with-sysroot.

How to specify non-default shared-library path in GCC Linux? Getting "error while loading shared libraries" when running

There is a laptop on which I have no root privilege.
onto the machine I have a library installed using configure --prefix=$HOME/.usr .
after that, I got these files in ~/.usr/lib :
libXX.so.16.0.0
libXX.so.16
libXX.so
libXX.la
libXX.a
when I compile a program that invokes one of function provided by the library with this command :
gcc XXX.c -o xxx.out -L$HOME/.usr/lib -lXX
xxx.out was generated without warning, but when I run it error like this was thrown:
./xxx.out: error while loading shared libraries: libXX.so.16: cannot open shared object file: No such file or directory , though libXX.so.16 resides there.
my clue-less assumption is that ~/.usr/lib wasn't searched when xxx.out is invoked.
but what can I do to specify path of .so , in order that xxx.out can look there for .so file?
An addition is when I feed -static to gcc, another error happens like this:
undefined reference to `function_proviced_by_the_very_librar'
It seems .so does not matter even though -L and -l are given to gcc.
what should I do to build a usable exe with that library?
For other people who has the same question as I did
I found a useful article at tldp about this.
It introduces static/shared/dynamic loaded library, as well as some example code to use them.
There are two ways to achieve that:
Use -rpath linker option:
gcc XXX.c -o xxx.out -L$HOME/.usr/lib -lXX -Wl,-rpath=/home/user/.usr/lib
Use LD_LIBRARY_PATH environment variable - put this line in your ~/.bashrc file:
export LD_LIBRARY_PATH=/home/user/.usr/lib
This will work even for a pre-generated binaries, so you can for example download some packages from the debian.org, unpack the binaries and shared libraries into your home directory, and launch them without recompiling.
For a quick test, you can also do (in bash at least):
LD_LIBRARY_PATH=/home/user/.usr/lib ./xxx.out
which has the advantage of not changing your library path for everything else.
Should it be LIBRARY_PATH instead of LD_LIBRARY_PATH.
gcc checks for LIBRARY_PATH which can be seen with -v option

Resources