Standard lib path of g++. And how to add new ones - gcc

I want to use gtest but execution tells me
./netTest: error while loading shared libraries: libgtest.so.0:
cannot open shared object file: No such file or directory
What are standard paths in that gcc linker looks for libs
What is standard path of Debian to store libs
How do I add libpaths to g++ (-L flag correct?)
Note on 2: I ask because the libs of gtest are in /usr/local/libs/ but in there is just python and gtest. All other libs are in /usr/lib/. Hence i guess the gtest installer made something wrong.

PS. Perhaps you could just instal the Debian libgtest-dev package (if there's one).
What are standard paths in that gcc linker looks for libs
You can see it with gcc -v -x c /dev/null -o /dev/null 2>&1 | grep LIBRARY_PATH
What is standard path of Debian to store libs
Perhaps you meant where the dynamic loader will look for shared libraries.
Check /etc/ld.so.conf and/or files in /etc/ld.so.conf.d/.
How do I add libpaths to g++ (-L flag correct?)
You can use the --rpath option to ld. However, I would suggest using it only during development and not in deployment.
You can also set LD_LIBRARY_PATH to the location of your libgtest.so.0.

The answer to the preceeding problem. gTest does not use precompiled libs anymore.
Use of precompiled libgtest Not Recommended
-------------------------------------------
The Google C++ Testing Framework uses conditional compilation for some
things. Because of the C++ "One Definition Rule", gtest must be
compiled with exactly the same flags as your C++ code under test.
Because this is hard to manage, upstream no longer recommends using
precompiled libraries [1].
-- Steve M. Robbins , Sat, 21 Apr 2012 17:00:56 -0500
Well doesnt surprise me anymore why I did not find the library in Wheezy :)

Related

Modify default library search dirs that gcc passes to ld

I want to force new GCC 12 on my old debian (that only has GCC 6 by default) to use fresh libstdc++ headers with new header-only features, but link with old stdlibc++,gcc_s (and other system/compiler libs used by GCC6) to keep binary compatibility with native runtime of old debian (so that users of old GCC6 can link with my binaries without having GCC12).
Of course I know that some functionality in the old runtime will be missing, and ABI is also different, but I guess I can fight with that. Afterall RedHat seems to be using similar scheme for their devtoolset packages (they try to link missing functionality of new runtime statically to your binary if these symbols are not found in native old runtime)
So far I am stuck with -L arguments that GCC is passing to ld.
Here is complete output of /usr/local/gcc12/bin/x86_64-linux-gnu-gcc-12 main.cpp -Wl,-v -v command for simple hello-world main.cpp:
https://pastebin.com/JhYSfg4x
The question: Where does GCC take all these -L paths from, and how do I remove/modify them? I don't want to accidentally link with new version of libraries that were built with GCC12:
-L/usr/lib/gcc/x86_64-linux-gnu -L/usr/local/gcc12/lib/gcc/x86_64-linux-gnu/12 -L/usr/local/gcc12/lib/gcc/x86_64-linux-gnu/12/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc -L/usr/local/gcc12/lib/gcc/x86_64-linux-gnu/12/../../.. /tmp/ccXfhCs4.o
System ld.conf does not mention any paths to /usr/local/gcc12 folder.
-nostdlib and -nodefaultlibs are removing some standard -l flags, but they are not doing anything to -L flags.
Update: I ended up just removing all *.a, .so, *.la files from include, lib and lib64 folders of gcc12, and I also added -L path to native libraries. This way I am sure gcc12 can't pickup one of its libraries for li nking. Not sure if this is good solution, but it works.

remove search paths from arm-linux-gnueabihf-g++ while cross compiling with sysroot

I want to cross compile my c++ program for an arm beaglebone. Compilation and linking works, but the binary is linked to the wrong version of libstdc++ and execution fails with
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.21' not found
On my host I have:
strings /usr/lib/gcc-cross/arm-linux-gnueabihf/5/libstdc++.so | grep GLIBCXX_3
...
GLIBCXX_3.4.20
GLIBCXX_3.4.21
An image of the beaglebone is mounted on ~/bbsysroot:
strings ~/bbsysroot/usr/lib/arm-linux-gnueabihf/libstdc++.so.6 | grep GLIBCXX_3
...
GLIBCXX_3.4.20
So, clearly, there is a version mismatch. That version mismatch is hard to avoid, since the host system is a different distribution.
The compilation command starts with
/usr/bin/arm-linux-gnueabihf-g++ -mfloat-abi=hard --sysroot=/home/user/bbsysroot
so I'm supplying the sysroot of the beaglebone to the compiler. I want that it looks for the libs in there and only in there. But
/usr/bin/arm-linux-gnueabihf-g++ --sysroot=/home/user/bbsysroot -print-search-dirs | grep libraries | sed 's/:/\n/g'
libraries
=/usr/lib/gcc-cross/arm-linux-gnueabihf/5/
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/lib/arm-linux-gnueabihf/5/
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/lib/arm-linux-gnueabihf/
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/lib/../lib/
/home/user/bbsysroot/lib/arm-linux-gnueabihf/5/
/home/user/bbsysroot/lib/arm-linux-gnueabihf/
/home/user/bbsysroot/lib/../lib/
/home/user/bbsysroot/usr/lib/arm-linux-gnueabihf/5/
/home/user/bbsysroot/usr/lib/arm-linux-gnueabihf/
/home/user/bbsysroot/usr/lib/../lib/
/usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/lib/
/home/user/bbsysroot/lib/
/home/user/bbsysroot/usr/lib/
shows, that it also looks on the host. I presume, that the host libraries have a higher priority and hence the wrong version is taken.
Is it possible to force the cross compiler to use the libraries from sysroot only? Or is that utterly wrong for some reason?
I got an answer, which might solve the problem, but i've moved on to another project since and can't test it. Though it might help others:
libstdc++ and also libgcc are actually part of the compiler and I think
that the best solution is:
use compiler version used by the BBB system (or earlier version)
upgrade those libraries on the BBB system
use '-static-libstdc++' option
You can try to use never compiler with older libgcc and libstdc++,
but I think that gcc may reference some newer functions. g++
also links libgcc dynamically by default.

Force CMake to use static libraries

[Shamelessly cross-posted from the CMake help list]
I'm trying to create binaries as statically as possible. The fortran code I've got has got X11 and quadmath as dependencies, and I've come across a number of issues (maybe each of these issues should be in a different question?):
My variables are currently
set(CMAKE_LIBRARY_PATH /usr/X11/lib /usr/X11/include/X11 ${CMAKE_LIBRARY_PATH})
find_package(X11 REQUIRED)
find_library(X11 NAMES X11.a PATHS /usr/X11/include/X11/ /usr/X11/lib)
find_library(X11_Xaw_LIB NAMES Xaw Xaw /usr/X11/include/X11/ /usr/X11/lib ${X11_LIB_SEARCH_PATH})
find_library(Xaw Xaw7 PATHS ${X11_LIB_SEARCH_PATH})
set(CMAKE_LIBRARY_PATH /usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/gcc/x86_64-linux-gnu/4.7/x32 /usr/lib/gcc/x86_64-linux-gnu/4.7/32 ${CMAKE_LIBRARY_PATH})
find_library(quadmath NAMES quadmath.a)
set(BUILD_SHARED_LIBS ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(LINK_SEARCH_START_STATIC TRUE)
set(LINK_SEARCH_END_STATIC TRUE)
set(SHARED_LIBS OFF)
set(STATIC_LIBS ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
Using these, CMake attempts to build every program statically (as expected) - however, it fails because I don't have Xaw.a - I can't find out whether this actually should exist. I have installed the latest libxaw7-dev which I was expecting to fix it. One option would be to compile the X11 libraries myself, but I don't really want to do that...
if I comment out only set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static"), then CMake compiles everything, but uses shared libraries for every program, even though I specify the location of .a X11 libraries in my find_library() calls. I was expecting CMake to use the .a files where it could and then only use shared libraries - is there a way to force this behaviour?
does anyone know yet of a fix for the bug described here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46539; whereby gfortran seemingly can't statically link libquadmath? I tried the fix using gcc but I can't get CMake to recognise the libgfortran flag:
cmake -DCMAKE_Fortran_COMPILER=gcc -DCMAKE_Fortran_FLAGS=-gfortran
results in
-- The Fortran compiler identification is unknown
-- Check for working Fortran compiler: /usr/bin/gcc
-- Check for working Fortran compiler: /usr/bin/gcc -- broken
CMake Error at /usr/share/cmake-2.8/Modules/CMakeTestFortranCompiler.cmake:54 (message):
The Fortran compiler "/usr/bin/gcc" is not able to compile a simple test program.
However, as you might have noticed, I set the location of the libquadmath.a; when I build a program which doesn't use X11 but does use quadmath when I use
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
then the program does compile successfully (running ldd reports 'not a dynamic executable') - does this mean that the bug has been fixed, or does it only work because I set the location in CMake?
I was having a similar problem. Turns out that cmake was implicitly linking against libgfortran and libquadmath. To fix this I put the following in my top level CMakeLists.txt:
unset(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES)
I could then explicitly link again the libraries using:
SET_TARGET_PROPERTIES(main_f PROPERTIES LINKER_LANGUAGE "C"
LINK_FLAGS
"/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libgfortran.a
/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libquadmath.a -lm -lgcc"
)
The static version of libgfortran is necessary because the shared library also depends on libquadmath. The added "-lm" and "-lgcc" bring in the system dynamic versions of these libraries. On a mac system, you would want to use the full path to your libm.a as well.
I guess your questions are not that much related, I don't know the answer for all of them.
For your static linking problems, since you're using GCC, you can pass multiple -static and -dynamic flags to it:
set(CMAKE_EXE_LINKER_FLAGS "-static ${STATIC_LIBS} -dynamic ${EVERYTHING ELSE} -static ${MORE_STATIC_LIBS}")
I don't know why Xaw.a isn't available on your system, probably because the package maintainer of your Linux distribution didn't really make them available.
Also, compiling everything static might make things not compatible between all distros out there and you cripple the ability for others to use improved, up-to-date libraries with your program, it might not be what you want.
If you intend to make a self-contained package of your program, it might be better just to include the shared libraries you used together, like Dropbox and many other proprietary applications do (Humble Bundle games are other example).

g++ library search failure

I have a directory structure as below:
/
|
+--- /lib
| libsomething.a
| libsomething.so
|
+----/obj
anObjFile.o
When I run the following command from within the obj directory:
g++ -L../lib -lsomething anObjFile.o
I get undefined reference errors. Apparently gcc is failing to locate libsomething.a.
But now if I delete libsomething.so and then rerun the command, linking succeeds.
As per gcc documentation -lsomething should expand to libsomething.a. Then why is presence of libsomething.so causing the library search to fail? Also, how can I resolve this problem?
I'm on Linux Mint 12 with gcc version 4.6.1.
The .so file is a dynamic library, meaning it is used each time you run your program. In that case you need to tell your OS (Mint in this case) where that dynamic library is located so your prgramm can find it at run time.
The .a file is a static library, meaning functions needed from it will be copied into your prgramm while linking. So your prgramm can run without the library file.
If nothing else is said gcc will assume you want to use the dynamic lib. If it can find a .so file it will use it instead of a .a file. If you want to tell gcc to make your programm static (use the .a file) you can add -static to your gcc call.
However the reason why the linking fails when the dynamic library is used is not clear. How did you install/build the library?

How to statically compile an SDL game on Windows

I have been trying to produce a statically linked "single binary" version of my game for windows. I want to link with sdl, sdl_image and sdl_mixer which in turn pull in a few support libraries. Unfortunately I haven't found a way to get them all to compile and link using cygwin/mingw/gcc. As far as I can tell all existing public versions are only shared libraries / dlls.
Please note that I'm not talking about licencing here. The source will be open thus the GPL/LGPLness of sdl is not relevant.
When compiling your project, you need to make just a couple changes to your makefile.
Instead of sdl-config --libs, use sdl-config --static-libs
Surround the use of the above-mentioned sdl-config --static-libs with -Wl,-Bstatic and -Wl,-Bdynamic. This tells GCC to force static linking, but only for the libraries specified between them.
If your makefile currently looks like:
SDLLIBS=`sdl-config --libs`
Change it to:
SDLLIBS=-Wl,-Bstatic `sdl-config --static-libs` -Wl,-Bdynamic
These are actually the same things you should do on Unix-like systems, but it usually doesn't cause as many errors on Unix-likes if you use the simpler -static flag to GCC, like it does on Windows.
Via this SDL mailing list post it seems that the sdl development tools ship with a sdl-config script that you can use with the --static-libs flag to determine what linker flags you need to use.
Environment: VMWare Virtual Machine with Windows 7 x64 and Equipment we Dev c + + build 7.4.2.569, complilador g+ + (tdm-1) 4.6.1
Once, SDL2-2.0.3 API installed as configuration Dev c ++ is not very clear what I've done as tradition requires command line.
The first problem is that Windows 7 appears to have changed the methodology and they go to his ball. Inventory. Ref. https://stackoverflow.com/users/464581/cheers-and-hth-alf
After the first hurdle, SDL_platform.h is that bad, it's down another, I do not remember where I downloaded, but the next does not work in the indicated version.
We must put SDL2.h ls in the directory of the executable.
D:\prg_desa\zsdl2>g++ bar.cpp main.cpp -o pepe1 -ID:\SDL2-2.0.3\i686-w64-mingw32\include\SDL2 -LD:\SDL2-2.0.3\i686-w64-mingw32\lib -lmingw32 -lSDL2main -lSDL2 -mwindow
I've finally compiled and works SDL2 testing.
That's because the SDL libs are under the LGPL-license.
If you want to static link the libs (you can do that if your recompile them. It needs some hacking into the makefiles though) you have to place your game under some compatible open source license as well.
The SDL-libs come as shared libraries because most programs that use them are closed source. The binary distribution comes in a form that most people need.
On my system (Ubuntu) I have to use the following flags:
-Wl,Bstatic -lSDL_image `sdl-config --libs` -lpng12 -lz -ltiff -ljpeg -lasound -laudio -lesd -Wl,-Bdynamic `directfb-config --libs` -lpulse-simple -lcaca -laa -ldl
That links SDL, SDL_image, and many of their dependencies as static. libdl you never want static, so making a fully-static binary that uses SDL_image is a poor idea. pulse,caca,aa, and directfb can probably be made static. I haven't got far enough to figure them out yet.

Resources