convert -l, -L on C++ linker line to full paths - c++

I have in my make file a list of libraries to link into the executable formatted as follows:
LIBRARIES=-L/usr/lib -lmail
and I want to use it to fill out a makefile dependency list so that the executable will re-link any time one of the linked libraries changes.
I expect that I will need to translate the linker line into full paths for each library and then specify them as dependencies like so
$(EXEC_NAME) : /usr/lib/libmail.so
Is there a utility that will translate the search paths and lib names into full paths? or is there a better way to specify the makefile dependencies?

Related

Using -L and -l flags vs giving library file as input

What's the difference between writing:
g++ test.cc -L/my/dir/ -lname
and
g++ test.cc /my/dir/libname.so ?
Are both correct?
The things that I can think of:
First one is cross platform, g++ from MINGW will look for DLL's
In the second one we explicitly specify we want dynamic linking
The difference is that
g++ test.cc -L/my/dir/ -lname
may succeed even if /my/dir/libname.so does not exist:
It can find libname.so from a system library directory (usually /lib, /usr/lib).
It can find libname.a, and do static linking.
Furthermore, it allows you to link to multiple libraries from the same directory without repeating the parent directory.
The first method looks into /my/dir directory for the library file at link time. However only a short library name libname.so (or whatever it finds according to OS) is written into the image. When the program starts, it will look for the library in some library path, i.e. LD_LIBRARY_PATH on linux. Now you can relocate the executable and the library into different new places and set a correct search path after relocation.
The second method writes the full path of the library into the image: /my/dir/libname.so. When the program starts, it will look for this particular path to get the library. This makes the image non-relocatable, unless the same library path exists in the new environment. The effect is similar to the '-rpath' method.

Link with self-compiled static libraries with cmake

I try to write some tests for project. If I need some project files I write include_directories statement and all will be included. In case of need of some manually compiled static libraries I try to set target_link_libraries.
If I set absolute path then all links ok, but for task I need another way to link another libraries, because the relative path to libraries gives undefined references.
In this case everything works fine:
target_link_libraries(ConsoleDumperTest GTest::GTest GTest::Main PocoFoundation PocoUtil PocoNet ${YAML_LIBRARIES})
target_link_libraries(ConsoleDumperTest /home/yrusinov/projects/build-fleetd-2-Desktop-dbg/protocols/libprotocols.a)
target_link_libraries(ConsoleDumperTest /home/yrusinov/projects/build-fleetd-2-Desktop-dbg/consumers/libconsumers.a)
target_link_libraries(ConsoleDumperTest /home/yrusinov/projects/build-fleetd-2-Desktop-dbg/consumers/Console/libconsole.a)
but if I do:
target_link_libraries(ConsoleDumperTest GTest::GTest GTest::Main PocoFoundation PocoUtil PocoNet ${YAML_LIBRARIES})
target_link_libraries(ConsoleDumperTest ../../../protocols/libprotocols.a)
target_link_libraries(ConsoleDumperTest ../../../consumers/libconsumers.a)
target_link_libraries(ConsoleDumperTest ../../../consumers/Console/libconsole.a)
I receive undefined references, despite of libraries contains in there directories. Which way I have to set path to link libraries?
According to documentation, target_link_libraries is not expected to work with relative paths: you should use either an absolute path, or a library name.
By knowing relative path, it is easy to construct absolute path in CMake. E.g., assuming you know relative path to the current source directory (the directory contained currently executed CMakeLists.txt), use CMAKE_CURRENT_SOURCE_DIR variable:
target_link_libraries(ConsoleDumperTest
${CMAKE_CURRENT_SOURCE_DIR}/../../../protocols/libprotocols.a
)
CMake's link_directories(...) command provides this:
link_directories(directory1 directory2 ...)
Specify the paths in which the linker should search for libraries. The command will apply only to targets created after it is called. Relative paths given to this command are interpreted as relative to the current source directory, see CMP0015.
Note also that, if these library dependencies are defined within the same CMake project, using add_library(target_name ...), you may specify the target name instead of the binary name within target_link_libraries.

OMake bin directory

I am trying to have omake build stuff in my bin directory. I tried
LIB = ../bin/mylib
.DEFAULT: $(OCamlLibrary $(LIB), $(FILES))
But only the .a and .cmxa end up in bin, all the .cmx .cmi and .o end up in src. What am I doing wrong?
Nothing wrong. OMake's built-in OCaml related rules compile each module and produce its objects (.cmo, .cmi, .cmx and .o) in the same directory of the source code.
$(OCamlLibrary $(LIB), $(FILES)) function link these module objects and produce library files $(LIB).cma, $(LIB).cmxa and $(LIB).a, just like you have seen.
If you want to change the destination directory of object files, you have to fix the build rules for OCaml. They are defined in OCaml.om found in OMake's library directory, but I have to say that this is very challenging.

In which order does the linker process the library directories?

It is possible that more than one instance of the library exists in the search path during compilation. In what order will linker process directories included in the search path? The platform in question is Sun OS.
The directories are searched in the order in which they are specified on the command line. Directories specified on the command line are searched before the default directories. All -L options apply to all -l options, regardless of the order in which the options appear. LD_LIBRARY_PATH may also be used to supplement the library search path. The directory search stops at the first directory containing the matching library.
LD_LIBRARY_PATH is tricky though:
LD_LIBRARY_PATH
A list of directories in which to search for libraries specified with
the -l option. Multiple directories
are separated by a colon. In the most
general case, it will contain two
directory lists separated by a
semicolon:
dirlist1; dirlist2
If ld is called with any number of occurrences of -L, as in:
ld . . . -Lpath1 . . . -Lpathn . . .
then the search path ordering is:
dirlist1 path1 . . . pathn dirlist2 LIBPATH
When the list of directories does not contain a semicolon, it is
interpreted as dirlist2.
LD_LIBRARY_PATH is also used to specify library search directories to
the runtime linker. That is, if
LD_LIBRARY_PATH exists in the
environment, the runtime linker will
search the directories named in it,
before its default directory, for
shared objects to be linked with the
program at execution.
Please read more about it here.

Linking libraries (C++)

Using MinGW through Eclipse for C/C++, and attempting to get GLUT (OpenGL Utility Toolkit) working on it, but I suspect it's a simple problem.
Attempts to build result in:
g++ -LC:\Documents and Settings\C\workspace\GLUTtest\Debug -LC:\Tools\MinGW\include\GL -LC:\Tools\MinGW\include -oGLUTtest.exe main.o -lglut32.lib
C:\Tools\MinGW\bin..\lib\gcc\mingw32\3.4.5........\mingw32\bin\ld.exe: cannot find -lglut32.lib
I have glut32.lib in the workspace directory, C:\Documents and Settings\C\workspace\GLUTtest. Here are the options as given by eclipse:
-L"C:\Documents and Settings\C\workspace\GLUTtest" -L"C:\Documents and Settings\C\workspace\GLUTtest\Debug" -L"C:\Documents and Settings\C\workspace\GLUTtest\GL" -L"C:\Tools\MinGW\include\GL" -L"C:\Tools\MinGW\include"
Any idea why it isn't picking up the library?
Seems your trying to pass include directories as link directories. Find the directory that contains glut32.lib and add a link-directory parameter (-L) with the directory you find.
Let's say you have a library file named libxxx.a, libxxx.so or xxx.lib. When linking, you should put the parameter as -lxxx
And second, sometimes you have to put library path with ( -L/path/to/lib/dir )
Your are passing "C:\Tools\MinGW\include\GL -LC:\Tools\MinGW\include" as your linking directory ( -L ) which seems to be your include path. so pass your include directory in include path which will appear with -I option and just check that whether your linking path is present in the list given with -L options, if not then add it in the list otherwise it will say undefined references.