What does gcc -lnsl this flag do? - gcc

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.

Related

what do the symbols 'Wl,-R' and '-Wl,./lib' mean in makefile?

Here is an example of makefile:
LINKFLAGS += -L./lib -lqn -Wl,-R -Wl,./lib
What exactly are the symbols '-Wl,-R' and '-Wl,./lib'?
The symbols in question have no particular meaning to make. They are just text as far as it is concerned, so their meaning depends on how they are used.
If the name "LINKFLAGS" is to be taken as indicative, however, then these will be included among the command-line arguments to link commands make runs (but this is still a question of parts of the makefile that are not in evidence). Such flags are not standardized, so the meaning is still somewhat in question.
If you happen to be using the GNU toolchain then the -Wl option to gcc and g++ assists in passing arguments through to the underlying linker, which would be consistent with the apparent intention. Appearing together as you show them, and supposing that ./lib is a directory, the effect on the GNU linker is equivalent to using its -rpath option and specifying ./lib. That would be a somewhat odd thing to do, but not altogether senseless.
Those are options for the linker (or the link step done by the compiler). You can find in the man page of gcc.
-Wl,option
Pass option as an option to the linker. If option contains commas, it is
split into multiple options at the commas. You can use this syntax to pass
an argument to the option. For example, -Wl,-Map,output.map passes
-Map output.map to the linker. When using the GNU linker, you can also get
the same effect with -Wl,-Map=output.map.
So, it is equivalent to pass the options -Rand .lib to the linker. The man page of ld stats than -R .lib is equivalent to -rpath=.lib
-rpath=dir
Add a directory to the runtime library search path. This is used when linking
an ELF executable with shared objects. All -rpath arguments are concatenated
and passed to the runtime linker, which uses them to locate shared objects at
runtime. The -rpath option is also used when locating shared objects which are
needed by shared objects explicitly included in the link; see the description
of the -rpath-link option. If -rpath is not used when linking an ELF executable,
the contents of the environment variable "LD_RUN_PATH" will be used if it is
defined.
gcc documentation indicates that -Wl is used to pass options to the linker.
gnu ld documentation and ld.so man page indicate that -R does. In summary, registering in the executable a path where shared libraries are searched when the executable is launched. The information about --enable-new-dtags and --disable-new-dtags may be also useful in understanding what happens.
The use of ./lib as argument of -R is odd, $ORIGIN is probably what is desired. Thus, with the various escape mechanisms needed,
LINKFLAGS += -L./lib -lqn -Wl,-R '-Wl,$$ORIGIN/lib'

When i should use ld instead of gcc?

I want to know when i should use ld linker instead off gcc. I just wrote a simply hello world in c++, of course i include iostream library. If i want make a binary file with gcc i just use:
g++ hello hello.cpp
and i've got my binary file.
Later i try to use ld linker. To get object file i use:
g++ -c hello.cpp. Ok that was easy, but the link command was horrible long:
ld -o hello.out hello.o \
-L /usr/lib/gcc/x86_64-linux-gnu/4.8.4/ \
/usr/lib/gcc/x86_64-linux-gnu/4.8.4/crtbegin.o \
/usr/lib/gcc/x86_64-linux-gnu/4.8.4/crtend.o \
/usr/lib/x86_64-linux-gnu/crti.o \
/usr/lib/x86_64-linux-gnu/crtn.o \
/usr/lib/x86_64-linux-gnu/crt1.o \
-dynamic-linker /lib64/ld-linux-x86-64.so.2 -lstdc++ -lc
I know fact that gcc uses the ld.
Using gcc is better in all cases or just in most cases? Please, tell me somethink about cases where ld linker has advantage.
As you mentioned, gcc merely acts as a front-end to ld at link time; it passes all the linker directives (options, default/system libraries, etc..), and makes sure everything fits together nicely by taking care of all these toolchain-specific details for you.
I believe it's best to consider the GNU toolchain as a whole, tightly integrated environment (as anyone with an experience of building toolchains for some exotic embedded platforms with, say, dietlibc integration will probably agree).
Unless you have some very specific platform integration requirements, or have reasons not to use gcc, I can hardly think of any advantage of invoking ld directly for linking. Any extra linker-specific option you may require could easily be specified with the -Wl, prefix on the gcc command line (if not already available as a plain gcc option).
It is mostly a matter of taste: you would use ld directly when the command-lines are simpler than using gcc. That would be when you are just using the linker to manipulate a small number of shared objects, e.g., to create a shared library with few dependencies.
Because you can pass options to ld via the -Wl option, often people will recommend just using gcc to manage the command-line.

How to customize the meaning of the "-l" flag for 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.

How does the linker know which archives to link together?

Suppose that I'm compiling a simple Hello World program with GCC.
When run with gcc -v hello-world.c, we could get the last line from the output which generates the ELF binary:
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.5.3/collect2 --eh-frame-hdr -m
elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/crtbegin.o
-L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/lib
-L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../.. /tmp/ccRykv97.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crtn.o
From this output we could see that some objects like crtbegin.o and crtend.o are being linked together. But how does the linker know that these files should be linked togeter?
A separate but similar question is that, if I don't want to use the standard C library, when given a directory of object files that contain the definitions of these functions, how to know the files that are needed to pass to the linker, so that it won't complain about unknown symbols?
we could get the last line from the output which generates the ELF binary
That in fact isn't the actual command that generates the ELF binary. collect in turn invokes ld, and that command generates the binary.
how does the linker know that these files should be linked
It doesn't. GCC told it (by supplying them on command line).
GCC has a compiled-in specs file, which is a domain-specific language little program, that tells GCC what arguments it should supply to the linker.
You can examine the built-in specs with gcc -dumpspecs. You will see that the program is actually quite complicated, and that crtbegin.o is only used when -static and -pie or -shared are not. The -shared implies crtbeginS.o, and -static implies crtbeginT.o.
if I don't want to use the standard C library
Use -nostdlib flag in that case.
given a directory of object files that contain the definitions of these functions, how to know the files that are needed to pass to the linker
The ones that define functions that you use. This might help.

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.

Resources