I'm trying to compile a shared library for systems that don't have a libstdc++ new enough to run it, which means I need to statically link libstdc++ into the library. I'm trying to link directly to libstdc++.a (-Wl,-Bstatic -L/path/to/lib64 -lstdc++), but I'm getting an error that seems to indicate that my libstdc++.a wasn't linked with PIC:
/usr/bin/ld: lib64/libstdc++.a(compatibility.o): relocation R_X86_64_32 against `typeinfo for __cxxabiv1::__forced_unwind' can not be used when making a shared object; recompile with -fPIC
lib64/libstdc++.a: could not read symbols: Bad value
I tried recompiling GCC with CFLAGS="-fPIC" and CXXFLAGS="-fPIC", but that didn't seem to do anything.
Help?
The idea is to pass --with-pic option to the configure. GCC build is a very complex beast with multiple stages, so simply passing a CFLAGS variable may not work as intended.
Reading GCC configure documentation. I used this flag --enable-host-shared when building GCC as it said in the description:
Specify that the host code should be built into position-independent
machine code (with -fPIC), allowing it to be used within shared
libraries, but yielding a slightly slower compiler.
Related
I use c++11, but also some libraries that are not configured for it, and need some type conversion. In particular I need a way to convert std::__cxx11::string to regular std::string, but googling I can't find a way to do this and putting (string) in front does not work.
If I do not convert I get linker errors like this:
undefined reference to `H5::CompType::insertMember(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, H5::DataType const&) const'
Is it possible that you are using GCC 5?
If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.
Source: GCC 5 Release Notes/Dual ABI
Defining the following macro before including any standard library headers should fix your problem: #define _GLIBCXX_USE_CXX11_ABI 0
If you can recompile all incompatible libs you use, do it with compiler option
-D_GLIBCXX_USE_CXX11_ABI=1
and then rebuild your project. If you can't do so, add to your project's makefile compiler option
-D_GLIBCXX_USE_CXX11_ABI=0
The define
#define _GLIBCXX_USE_CXX11_ABI 0/1
is also good but you probably need to add it to all your files while compiler option do it for all files at once.
When I had similar issue it's happened because my lib was build using clang++, and it's linked to libstdc++.so by default on my system. While app binary was build using clang and linked with -lc++ option.
Easiest way to check dependencies is to perform ldd libName.so
To fix it you should use the same library on in app and library.
Easiest way. Build library using clang++ and compile app using clang++. Without extra linking options on both steps. Default stdlib will be used.
Build library with -stdlib=c++ and compile app with -lc++. In this case both library and app will use libc++.so.
Build library without extra options and link binary to -lstdc++. In this case both library and app will use libstdc++.so.
Answers here mostly focus on short way to fix it, but if that does not help, I'll give some steps to check, that helped me (Linux only):
If the linker errors happen when linking other libraries, build those libs with debug symbols ("-g" GCC flag)
List the symbols in the library and grep the symbols that linker complains about (enter the commands in command line):
nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout
If you got the method signature, proceed to the next step, if you got no symbols instead, mostlikely you stripped off all the symbols from the library and that is why linker can't find them when linking the library. Rebuild the library without stripping ALL the symbols, you can strip debug (strip -S option) symbols if you need.
Use a c++ demangler to understand the method signature, for example, this one
Compare the method signature in the library that you just got with the one you are using in code (check header file as well), if they are different, use the proper header or the proper library or whatever other way you now know to fix it
I got this, the only way I found to fix this was to update all of mingw-64 (I did this using pacman on msys2 for your information).
For me -D_GLIBCXX_USE_CXX11_ABI=0 didn't help.
It works after I linked to C++ libs version instead of gnustl.
I had a similar issue recently while trying to link with the pre-built binaries of hdf5 version 1.10.5 on Ubuntu 16.04. None of the solutions suggested here worked for me, and I was using g++ version 9.1. I found that the best solution is to build the hdf5 library from source. Do not use the pre-built binaries since these were built using gcc 4.9! Instead, download the source code archives from the hdf website for your particular distribution and build the library. It is very easy.
You will also need the compression libraries zlib and szip from here and here, respectively, if you do not already have them on your system.
In my case, I was having a similar problem:
/usr/bin/ld: Bank.cpp:(.text+0x19c): undefined reference to 'Account::SetBank(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' collect2: error: ld returned 1 exit status
After some researches, I realized that the problem was being generated by the way that Visual Studio Code was compiling the Bank.cpp file. So, to solve that, I just prompted the follow command in order to compile the c++ file sucessful:
g++ Bank.cpp Account.cpp -o Bank
With the command above, It was able to linkage correctly the Header, Implementations and Main c++ files.
OBS: My g++ version: 9.3.0 on Ubuntu 20.04
I've encountered similar problems
It turns out my project was using gcc 7 and g++ 9 and tried to link together object files compiled by those two and it all messed up.
Make sure you use the same compiler versions in all your project.
I use c++11, but also some libraries that are not configured for it, and need some type conversion. In particular I need a way to convert std::__cxx11::string to regular std::string, but googling I can't find a way to do this and putting (string) in front does not work.
If I do not convert I get linker errors like this:
undefined reference to `H5::CompType::insertMember(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, H5::DataType const&) const'
Is it possible that you are using GCC 5?
If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.
Source: GCC 5 Release Notes/Dual ABI
Defining the following macro before including any standard library headers should fix your problem: #define _GLIBCXX_USE_CXX11_ABI 0
If you can recompile all incompatible libs you use, do it with compiler option
-D_GLIBCXX_USE_CXX11_ABI=1
and then rebuild your project. If you can't do so, add to your project's makefile compiler option
-D_GLIBCXX_USE_CXX11_ABI=0
The define
#define _GLIBCXX_USE_CXX11_ABI 0/1
is also good but you probably need to add it to all your files while compiler option do it for all files at once.
When I had similar issue it's happened because my lib was build using clang++, and it's linked to libstdc++.so by default on my system. While app binary was build using clang and linked with -lc++ option.
Easiest way to check dependencies is to perform ldd libName.so
To fix it you should use the same library on in app and library.
Easiest way. Build library using clang++ and compile app using clang++. Without extra linking options on both steps. Default stdlib will be used.
Build library with -stdlib=c++ and compile app with -lc++. In this case both library and app will use libc++.so.
Build library without extra options and link binary to -lstdc++. In this case both library and app will use libstdc++.so.
Answers here mostly focus on short way to fix it, but if that does not help, I'll give some steps to check, that helped me (Linux only):
If the linker errors happen when linking other libraries, build those libs with debug symbols ("-g" GCC flag)
List the symbols in the library and grep the symbols that linker complains about (enter the commands in command line):
nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout
If you got the method signature, proceed to the next step, if you got no symbols instead, mostlikely you stripped off all the symbols from the library and that is why linker can't find them when linking the library. Rebuild the library without stripping ALL the symbols, you can strip debug (strip -S option) symbols if you need.
Use a c++ demangler to understand the method signature, for example, this one
Compare the method signature in the library that you just got with the one you are using in code (check header file as well), if they are different, use the proper header or the proper library or whatever other way you now know to fix it
I got this, the only way I found to fix this was to update all of mingw-64 (I did this using pacman on msys2 for your information).
For me -D_GLIBCXX_USE_CXX11_ABI=0 didn't help.
It works after I linked to C++ libs version instead of gnustl.
I had a similar issue recently while trying to link with the pre-built binaries of hdf5 version 1.10.5 on Ubuntu 16.04. None of the solutions suggested here worked for me, and I was using g++ version 9.1. I found that the best solution is to build the hdf5 library from source. Do not use the pre-built binaries since these were built using gcc 4.9! Instead, download the source code archives from the hdf website for your particular distribution and build the library. It is very easy.
You will also need the compression libraries zlib and szip from here and here, respectively, if you do not already have them on your system.
In my case, I was having a similar problem:
/usr/bin/ld: Bank.cpp:(.text+0x19c): undefined reference to 'Account::SetBank(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' collect2: error: ld returned 1 exit status
After some researches, I realized that the problem was being generated by the way that Visual Studio Code was compiling the Bank.cpp file. So, to solve that, I just prompted the follow command in order to compile the c++ file sucessful:
g++ Bank.cpp Account.cpp -o Bank
With the command above, It was able to linkage correctly the Header, Implementations and Main c++ files.
OBS: My g++ version: 9.3.0 on Ubuntu 20.04
I've encountered similar problems
It turns out my project was using gcc 7 and g++ 9 and tried to link together object files compiled by those two and it all messed up.
Make sure you use the same compiler versions in all your project.
I am attempting to compile an OpenGl application that uses SDL2 and GLEW in such a way that it will run on any version of Linux it may find itself -- not just where it was originally compiled. To do this, I have tried several things none of which work.
I have tried directly linking to .a files produced by running make in the extracted root directory of GLEW and SDL from each library's website download. This produces the following errors:
/usr/bin/ld: /opt/SDL2-2.0.4/build/.libs/libSDL2.a(SDL_syssem.o): undefined reference to symbol 'sem_getvalue##GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
I have tried building as I do with dynamically linked libraries, which works fine except for the cross-platform capabilities, (with pkg-config --libs sdl2 and pkg-config --libs glew) but adding -static, at which point I get the following errors:
/usr/bin/ld: cannot find -lGLEW
/usr/bin/ld: cannot find -lGL
When I change the previous scenario to point to my statically compiled GLEW libraries, I get undefined reference errors to OpenGl functions along with undefined reference errors like the following from many SDL functions. Adding -lGL does not change anything.
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_UnloadObject_REAL':
When I try using pkg-config --libs --static <library name> for all libraries, I get the following error:
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/bin/ld: cannot find -lasound
/usr/bin/ld: cannot find -lpulse-simple
/usr/bin/ld: cannot find -lpulse
/usr/bin/ld: cannot find -lsndio
/usr/bin/ld: cannot find -lwayland-egl
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libwayland-cursor.a(libwayland_cursor_la-xcursor.o): In function `XcursorImagesDestroy':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libXcursor.a(file.o):(.text+0x7d0): first defined here
/usr/bin/ld: cannot find -lGLEW
/usr/bin/ld: cannot find -lGL
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(xim_trans.o): In function `_XimXTransSocketINETConnect':
collect2: error: ld returned 1 exit status
NOTE: All of the output above is from the command g++ -o /path/to/outputExecutable <list of object files>.o <libraries as described above>
NOTE: I do not think this question is a duplicate of any other question on the Stack Exchange network because I have been trying to figure this out for about one and a half months and I have seen a very large number of these questions and tried everything in them, thus, even if the symptoms are the same the underlying problem is different.
NOTE: This is a closed-source application so dynamic linking is not an option for it requires distributing the source code to allow users to build the binaries on their own systems.
NOTE: I am currently trying to get this to compile with Linux via g++, but, I do intend to use mingw to distribute this application for Windows as well. Any advice that works there is preferable to Linux only advice, but, I can ask another question if I can't figure out that part from what will end up here.
NOTE: I am using Ubuntu 16.04 LTS x64 to compile.
Thank you in advance for even getting this far in this question. Sorry for the wall of text, but, I wanted to provide as much information as possible. I look forward to any answers!
Older Loki games did full static linking. Probably not worth it anymore, and far more difficult if you use external libraries.
Libraries are often not self-sufficient, requiring other libraries, .... Dynamic library have dependency information built-in, but static library is just an archive of .o files - it may depend on something but there is no special section that describes what extra libraries should be used. Your first error says that libSDL2.a uses symbol sem_getvalue##GLIBC_2.2.5 (sem_getvalue function, marked with glibc version) that cannot be resolved - most likely because you didn't add -lpthread to your linker flags. (libSDL.so depends on some version of pthrtead among other things - that's why you don't need to manually link with it if you don't use it directly).
GLEW should have no problems with static linking. You need to be more specific on errors you're getting. Maybe you got your libraries order wrong and linker cannot resolve GL functions. Need to see actual linking line and some 'undefined reference' errors to be more specific.
pkg-config's --static flag should give you dependencies list (e.g. -lpthread should be in the output of sdl2-config --static-libs among many others), but it does not by itself produce static linking with given library. To request static linking, there are -static gcc flag that generates static executable (hard!) and -Bstatic linker flag to use static version for all libraries specified after it (so that way you can use some static libraries and some dynamic). -Bdynamic is a counterpart, asking to use dynamic libraries. E.g. to use static SDL and GLEW but dynamic GL linking line should be something like (if you use gcc to link, not ld directly) gcc ${OBJECT_FILES} -Wl,-Bstatic -lSDL2 -lGLEW -Wl,-Bdynamic -lGL -lpthread -ldl -lm <everything else SDL2 requires - query with sdl2-config>.
Your /usr/bin/ld: cannot find -lasound lines may have two reasons - static linking or related to the fact that you don't have development libraries installed (e.g. libasound2-dev, libpulse-dev, ... - at least they called that on debian, it is unlikely ubuntu have different names). 'User' libraries usually contains e.g. libasound.so.2 but linker will not find this library as it have a version in it. Development package contains headers and symlink libasound.so -> libasound.so.2 - that way linker knows what to use. If you use it indirectly via SDL2 - you don't need that, shared SDL2 already have a link to versioned library.
However there may be little point in doing so at all. You can distribute requred shared libraries with your software and use them either via rpath or LD_LIBRARY_PATH environment variable (maya, steam, etc... - almost everyone doing these this days). Moreover, even with static SDL2 end user can override SDL2 with their own (this is a feature intentionally implemented in SDL2). If there is a bug (or just very different environment) and your software is no longer gets updates - there is a chance that problem may be fixed by just replacing shared libraries. Would you really mind people running your program on wayland or mir if your original SDL2 had only X11 support?
in such a way that it will run on any version of Linux it may find itself -- not just where it was originally compiled is far more complicated, and honestly almost unrealistic (unless you have quite small program and use only very limited set of libraries with a good forward/backward compatibility - but even then it may be hard). One of big problems is glibc; usually it is a good idea to use lowest possible version of glibc to compile your program.
To sum it up, it is possible, but it does not help much.
DMD 2.60 on Ubuntu 12.04 ...
I want to create a static binary, so that I can run it in an ages old environment.
dmd doesn't have '-static' flag.
I tried passing '-static' flag to the linker with "dmd -L-static ..." - get error message
/usr/bin/ld: cannot find -lgcc_s
Compiling C code with "gcc -static ..." works fine.
Is it something I miss ?
Thanks !
It doesn't currently work if you use dmd to link due to how it passes the linker flags to the linker. You need to build everything with -c to generate object files and then link those manually with either gcc or ld.
I should point out though that in general, statically linking glibc is considered to be a bad idea. It may very well work and be the correct solution in your case, but it definitely has potential issues (I don't remember the details though). So, you probably shouldn't do it unless you actually need to.
I've been trying to move a project over from Xcode to Linux (Ubuntu x86 for now, but hopefully the statically-linked executable will run on an x86 CentOS machine? I hope I hope?). I have the whole project compiling but it fails at the linking stage-- it's giving me undefined references for all functions defined by IPP. This is probably something really small and silly but I've been beating my head over this for a couple days now and I can't get it to work.
Here's the compile statement (I also have a makefile that's generating the same errors):
g++ -static
/opt/intel/ipp/6.0.1.071/ia32/lib/libippiemerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippimerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippsemerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippsmerged.a
/opt/intel/ipp/6.0.1.071/ia32/lib/libippcore.a
-pthread -I /opt/intel/ipp/6.0.1.071/ia32/include
-I tools/include -o main main.cpp pick_peak.cpp
get_starting_segments.cpp
get_segment_timing_differences.cpp
recast_and_normalize_wave_file.cpp
rhythm_score.cpp pitch_score.cpp
pitch_curve.cpp
tools/source/LocalBuffer.cpp
tools/source/wave.cpp distance.cpp
...and here is the beginning of the long list of linker errors:
./main.o: In function `main':
main.cpp:(.text+0x13f): undefined reference to `ippsMalloc_16s'
main.cpp:(.text+0x166): undefined reference to `ippsMalloc_32f'
main.cpp:(.text+0x213): undefined reference to `ippsMalloc_16s'
Any ideas? FWIW, these are the IPP dependencies in my Xcode project that builds, links, and runs without a problem: "-lippiemerged",
"-lippimerged",
"-lippsemerged",
"-lippsmerged",
"-lippcore",
Thanks!
Your linking problem is likely due to the fact that your link line is completely backwards: archive libraries should follow source and object files on command line, not precede them. To understand why the order matters, read this.
Also note that on Linux statically linked executables are significantly less portable than dynamically linked ones. In general, if you link system libraries dynamically on an older Linux system, it will work on all newer systems (I use ancient RedHat 6.2, and I haven't seen a system on which my executable will not run). This is not true for completely static executables; they may crash in all kinds of "interesting" ways when moved to a system with a different libc from the one against which they were linked.
I had problems with linking code with the v 6 of the ipp; using the v11 version of the compiler (with the included updates to the ipp) mysteriously fixed them. Granted, that was with a windows platform, but I was getting 8u versions of functions to compile and no 32f versions, despite both being listed as valid in the documentation.