Makefile -L command - makefile

If I have this line in the make file:\
libpqxx_Libs = -L/share/home/cb -lpqxx-2.6.9 -lpq
Does this indicate the compiler to use the lpqxx-2.6.9.so shared object file or does this indciate the compiler to use all the .so in the foler lpqxx-2.6.9? Or is this something else altogether?
Thanks for the help!

-L in this context is an argument to the linker, that adds the specified directory to the list of directories that the linker will search for necessary libraries, e.g. libraries that you've specified using -l.
It isn't a makefile command, even though it's usually seen in makefiles for C projects.

The -L is actually not a makefile command (as you state it in the title of your question).
What actually happens in this line is an assignment of a value to the variable libpqxx_Libs -- nothing more and nothing less. You will have to search in your makefile where that variable is used via $(libpqxx_Libs) or ${libpqxx_Libs}. That is most likely as a argument in a link command, or a compile command that includes linking.
In that context, the meaning of -L and -l can be found in, for example, the gcc man pages, which state that
-llibrary
Use the library named library when linking.
The linker searches a standard list of directories for the li-
brary, which is actually a file named `liblibrary.a'. The linker
then uses this file as if it had been specified precisely by
name.
The directories searched include several standard system direc-
tories 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'

The -l option in GCC

I have just begun reading the book Advanced Programming in Unix Environment and try to compile the first example code, just the same as in this question.
Although the problem for the compilation is solved using the command,
gcc -o myls myls.c -I SCADDRESS/include/ -L SCADDRESS/lib/ -lapue
I looked it up in the GCC manual, but what does the GCC option -lxxx mean? Where xxx stands for the base name of a header file (in this case, it's apue.h). According to the manual, xxx should be some library files, either end with .so for shared object files, or with .a for static libraries.
This is documented in ยง2.13 "Options for Linking" in the GCC manual:
-llibrary
Search the library named library when linking.
It makes a difference where in the command you write this option; the
linker searches processes libraries and object files in the order they
are specified. Thus, `foo.o -lz bar.o' searches library `z'
after file `foo.o' but before `bar.o'. If `bar.o' refers
to functions in `z', those functions may not be loaded.
The linker searches a standard list of directories for the library,
which is actually a file named `liblibrary.a'. The linker then uses this file as if it had been specified precisely by name.
The directories searched include several standard system directories
plus any that you specify with `-L'.
Normally the files found this way are library files--archive files
whose members are object files. The linker handles an archive file by
scanning through it for members which define symbols that have so far
been referenced but not defined. But if the file that is found is an
ordinary object file, it is linked in the usual fashion. The only
difference between using an `-l' option and specifying a file name is that `-l' surrounds library with `lib' and `.a'
and searches several directories.
The -l option tells GCC to link in the specified library. In this case, the library is apue, and that it happens to line up with the name of a header file is just how the apue coders designed their project.
In reality, the -l option has nothing to do with header files. Like cas says in the comments, read the man page; it'll give you much more information.

Two ways of linking to static libraries

Here are a couple of ways to use functions from a static library, built with ar (i.e. libSOMTEHING.a):
ld -o result myapp.o -Lpath/to/library -lname
ld -o result myapp.o path/to/library/libname.a
Since we omit any dynamic libraries from the command line, this should build a static executable.
What are the differences? For example, are the whole libraries linked in the executable, or just the needed functions? In the second example, does switching the places of the lib and the object file matter?
(PS: some non-GNU ld linkers require all options like -o to be before the first non-option filename, in which case they'd only accept -L... -lname before myapp.o)
In the first line, a search for a dynamic library (libname.so) occurs before the static library (libname.a) within a directory. Also, the standard lib path is also searched for libname.*, not just /path/to/library.
From "man ld"
On systems which support shared libraries, ld may also search for
files other than libnamespec.a. Specifically, on ELF and SunOS
systems, ld will search a directory for a library called
libnamespec.so before searching for one called libnamespec.a. (By
convention, a ".so" extension indicates a shared library.)
The second line forces the linker to use the static library at path/to/lib.
If there is no dynamic library built (libname.so), and the only library available is path/to/library/libname.a, then the two lines will produce the same "result" binary.

How to get only file name in preprocessor?

I am (was) using the __FILE__ and __LINE__ macros for printing diagnostic messages out of my code. This works quite well when you use GCC with make, the file is as short as you specified it on the command line. I recently switched to using CodeLite which uses fully qualified file names (at least under windows) when building. Suddenly my diagnostic output is almost not readable.
It there a way to get only the file component of the filename in the preprocessor? I can live with a non portable GCC specific solution. (I will fallback to plain __FILE__ other cases.)
Sure I can pass the contents of __FILE__ through a function and extract only the file component, but string operations was not what I had in mind for diagnostic messages that should not change runtime behavior...
NOTE: I use the filename the way GNU uses it. A Path is collection of filenames and a filename is either a relative or absolute identifier of a file. A filename can be made up of a directory component and file component.
If you are using GNU Make then you can simply pass -D BASE_FILE_NAME=\"$*.c\" in on the preprocessing stage of compilation (if you're doing them separately, or at compilation if in a single stage, which is the norm).
This depends upon the way you have your file names determined. Mine come from a list of plain file names and are prefixed with directories using functions in the makefile at a later stage.
IE, this works well for me, but your mileage may vary! :-)
A simplified version of my make "code" :
CLASSES = main.c init.c
PREPROCESSED = $(patsubst %.c,$(PPCDIR)/%.pp.c,$(CLASSES))
$(PREPROCESSED): $(PPCDIR)/%.pp.c: %.c $(ALLH)
$(GCC) $(GCCOPTS) -D BASE_FILE_NAME=\"$*\" -E $< > $#
The simply use BASE_FILE_NAME in your code as you like :-)
There is no known preprocessor macro that provides the functionality. Passing __FILE__ through a function seams like the only sensible option.
In reply to FredCooke above, you can exchange this line:
-D BASE_FILE_NAME=\"$*.c\"
With:
-D BASE_FILE_NAME=\"$(<F)\"
This will give you proper file name expansion, for .cpp as well.
As has already been mentioned in other answers, the only portable way to do this is by passing in a define from the compiler, there are however compiler spesific extensions:
Clang: __FILE_NAME__
GCC: __BASE_FILE__

Different ways to specify libraries to gcc/g++

I'd be curious to understand if there's any substantial difference in specifying libraries (both shared and static) to gcc/g++ in the two following ways (CC can be g++ or gcc)
CC -o output_executable /path/to/my/libstatic.a /path/to/my/libshared.so source1.cpp source2.cpp ... sourceN.cpp
vs
CC -o output_executable -L/path/to/my/libs -lstatic -lshared source1.cpp source2.cpp ... sourceN.cpp
I can only see a major difference being that passing directly the fully-specified library name would make for a greater control in choosing static or dynamic versions, but I suspect there's something else going on that can have side effects on how the executable is built or will behave at runtime, am I right?
Andrea.
Ok, I can answer myself basing on some experiments and a deeper reading of gcc documentation:
From gcc documentation: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
[...] The linker handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an -l option and specifying a file name is that -l surrounds library with lib' and.a' and searches several directories
This actually answers also to the related doubt about the 3rd option of directly specifying object files on the gcc command line (i.e. in that case all the code in the object files will become part of the final executable, while using archives, only the object files that are really needed will be pulled in).

Resources