How to customize the meaning of the "-l" flag for GCC? - gcc

I have problems with GCC and I would like to use the -l flags in a customized way.
I would like to specify the search path for the correspondant libfoo specified by -lfoo , I also would like to override any internal search path in GCC, i don't want GCC to use any random lib that can solve the symbols, I only want GCC to compile with a really specific lib when -l is specified.
I know that there are utils such as pkg-config but my problem is more gcc-centric because i'm focusing on having more control on the compilation steps.

There is an undocumented syntax for specifying an absolute lib path to gcc:
$ gcc -o test test.c -l:/usr/lib/libfoo.so #(note the colon)
See here: https://code.ros.org/lurker/message/20130119.001059.fad11362.de.html
A more standard way to do this would simply be:
$ gcc -o test test.c /usr/lib/libfoo.so
Really, the only reason to use the -l: syntax is if you have a conflicting library of the same name in your search path and you can't change the search path.

Related

What does gcc -lnsl this flag do?

Sorry for noobie question but I could not understand this .. what does gcc -lnsl flag do .
I tried searching over internet also read about rpc.
This flag tells gcc to link the binary with nsl library. To be more clear, the line gcc -lnsl could be rewritten to more verbose equivalent gcc -l nsl. See man gcc:
-llibrary
-l library
Search the library named library when linking. (The second
alternative with the library as a separate argument is only for
POSIX compliance and is not recommended.)
The -l option is passed directly to the linker by GCC. Refer to
your linker documentation for exact details. The general
description below applies to the GNU linker.
The linker searches a standard list of directories for the
library. The directories searched include several standard
system directories plus any that you specify with -L.

GCC linked static library failed

I tried to use gcc command to link a static library, but it didn't work.
If you want to use the -l flag command to link your application like so:
gcc t.c -L. -lt1.a -o t
Then your .a archive needs to have a filename of libt1.a not just t1.a.
When using -lsome_name to link in a library, the linker will look for a file named libsomename.so or libsomename.a
If you do not want to rename your .a archive, you can also just do
gcc t.c t1.a -o t
also, in the future please don't post an image of your code or commands, just copy paste it as text into your post
Libraries in POSIX environments (like Linux and OSX) are usually named in the pattern lib<name of library>.a. When you link with the library you either use the -l option and only use <name of library> and the linker will automatically add the lib prefix and .a suffix. Or you don't use the -l option and istead give the whole file-name verbatime.
Since you don't use the standard naming scheme for the libraries, you can't use the -l option and instead have to explicitly use the library file, similar to
$ gcc ... t1.a
If you want to use the -l option you have to name your library libt1.a and only use t1 when linking:
$ gcc ... -L. -lt1

Force solib dependency to have relative path of non-standard named shared library under a directory using gcc

I have an issue regarding the linking of a shared library with a non-standard naming convention under several directories. I need the generated executable to search for the shared library within the executables current location, but cannot find a command line parameter to force this behavior.
To demonstrate this behavior all that is required is a shared library that is under a directory.
gcc -shared mylib.c -o some/dir/mylib.so
gcc main.c -o main -Lsome/dir -l:mylib.so
The executable main gives the following ldd output:
ldd main
some/dir/mylib.so (0xf76e2000)
The output that I require is:
ldd main
mylib.so => some/dir/mylib.so (0xf7700000)
This output can be created if the library is named conventionally as libmylib.so rather than mylib.so like so:
mv some/dir/mylib.so some/dir/libmylib.so
gcc main.c -o main -Lsome/dir -lmylib
This also drops the path some/dir in the ldd listing as required.
I have investigated the use of rpath, and command line options for both the ld and gcc but I am unable to find a satisfactory solution. The strict requirements of a non-standard name and directory structure cannot be changed easily in this case.
My question is how can I force the dependency of the library to be relative to the current directory rather than absolute as in the second ldd through gcc command line options.
Thank you for your time, I hope I have explained the problem reasonably.
Jon.
Try to add soname in your shared library:
$ gcc -shared mylib.c -o some/dir/mylib.so -Wl,-soname=mylib.so
$ gcc main.c -o main -Lsome/dir -l:mylib.so
$ LD_LIBRARY_PATH=some/dir:$LD_LIBRARY_PATH ldd main
mylib.so => some/dir/mylib.so (0x00007fa7a4fd6000)
There's a magic variable you can pass to rpath to do this: $ORIGIN. See man ld.so for details.
I think in your case, the command should look like this (untested):
gcc main.c -o main -Lsome/dir -lmylib -Wl,-rpath,'$ORIGIN/some/path'
Note that you mustn't let the shell expand $ORIGIN as a shell variable.
BTW, this was the first Google hit for "rpath relative".

rpath=$ORIGIN not having desired effect?

I've got a binary "CeeloPartyServer" that needs to find libFoundation.so at runtime, on a FreeBSD machine. They're both in the same directory. I compile (on another platform, using a cross compiler) CeeloPartyServer using linker flag -rpath=$ORIGIN.
> readelf -d CeeloPartyServer |grep -i rpath
0x0000000f (RPATH) Library rpath: [$ORIGIN]
> ls
CeeloPartyServer Contents Foundation.framework libFoundation.so
> ./CeeloPartyServer
/libexec/ld-elf.so.1: Shared object "libFoundation.so" not found, required by "CeeloPartyServer"
Why isn't it finding the library when I try to run it?
My exact linker line is: -lm -lmysql -rpath=$ORIGIN.
I am pretty sure I don't have to escape $ or anything like that since my readelf analysis does in fact show that library rpath is set to $ORIGIN. What am I missing?
I'm assuming you are using gcc and binutils.
If you do
readelf -d CeeloPartyServer | grep ORIGIN
You should get back the RPATH line you found above, but you should also see some entries about flags. The following is from a library that I built.
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../lib]
0x000000000000001e (FLAGS) ORIGIN
0x000000006ffffffb (FLAGS_1) Flags: ORIGIN
If you aren't seeing some sort of FLAGS entries, you probably haven't told the linker to mark the object as requiring origin processing. With binutils ld, you do this by passing the -z origin flag.
I'm guessing you are using gcc to drive the link though, so in that case you will need to pass flag through the compiler by adding -Wl,-z,origin to your gcc link line.
Depending on how many layers this flag passes through before the linker sees it, you may need to use $$ORIGIN or even \$$ORIGIN. You will know that you have it right when readelf shows an RPATH header that looks like $ORIGIN/../lib or similar. The extra $ and the backslash are just to prevent the $ from being processed by other tools in the chain.
\$\ORIGIN if you are using chrpath and \$\$ORIGIN if you are providing directly in LDFLAGS
using ldd CeeloPartyServer to check the dependency .so is starting with ./ or not. (e.g. libFoundation.so and ./libFoundation.so)
For common situation it should be libFoundation.so and without the prefix ./
if ./ prefix is necessary for some uncommon case, make sure the CWD is the same folder with libFoundation.so, and the $ORIGIN would be invalid.
=======
For example:
g++ --shared -Wl,--rpath="\$ORIGIN" ./libFoundation.so -o lib2.so
would got a library lib2.so with ./libFoundation.so
g++ --shared -Wl,--rpath="\$ORIGIN" libFoundation.so -o lib2.so
would got libFoundation.so instead.

Including libraries while compilation

to include say gstreamer libraries we need to use
-lgstreamer-0.10
but if i want to manually specify the complete path.. which in this case is
/usr/bin/gstreamer-0.10
how can i do that
i tried doing the following, but this give me following errors:
-L/usr/lib/gstreamer-0.10
-L defines the search path so:
-L/usr/lib -lgstreamer-0.10
Note that if you don't use the expected style of library name ('lib' prefix - library name - '.a' suffix) the -L doesn't work. Instead, just include the entire name of the library at the end of your compile line in the makefile.
cc -o tst tst.o /usr/lib/gstreamer-0.10

Resources