Boost regex: Undefined references when linking - c++

Until some weeks ago, using the boost_regex library I used to compile a C++ file test.cpp using the following command.
g++-4.9 -Wall -O3 -march=native -flto -DNDEBUG -o test \
--std=c++14 test.cpp -lboost_regex -pthread
The compilation was working perfectly. But at some point, I needed to upgrade my OS (more precisely, it was Ubuntu 14.04, now it is Ubuntu 16.04).
I kept my local folders with my data, and I also installed the Boost library again in the new system, including boost_regex.
The Boost version in the new system is 1.58, unfortunately I cannot know which Boost version I was using before because it is now deleted.
I try to compile again the same file in the new system, with the same command as above, and the linker says it cannot find two functions called maybe_assign and construct_init. If I replace the -o test option with just -c (i.e. without linking) then the program is compiled without errors.
More precisely, when I try to do linking I get the following errors (they were extremely long, I hade to shorten using ... dots).
In function `boost::re_detail::perl_matcher<...>::match_match()':
undefined reference to `boost::match_results<...>::maybe_assign(boost::match_results<...> const&)'
In function `bool boost::regex_search<...>(...)':
undefined reference to `boost::re_detail::perl_matcher<...>::construct_init(...)'
In function `boost::re_detail::perl_matcher<...>::match_prefix()':
undefined reference to `boost::match_results<...>::maybe_assign(boost::match_results<...> const&)'
collect2: error: ld returned 1 exit status
I really don't know how this is possible, the libraries seem perfectly installed, nothing seems missing, and the compilation was working with a previous OS installation (then I guess older libraries).
At these point my only guess could be that Boost authors removed such functions? (maybe they are obsolete?). But I didn't find any trace of this on internet. If this is the case, how can I know the boost versions in which such functions are available?
Am I doing any mistake? Do you have any suggestions to investigate about this?

TL;DR use gcc5.
Ununtu 16.04 comes with gcc5 by default. Every C++ library in it is compiled with that compiler.
Now there was an incompatible C++ ABI change between gcc4 and gcc5. It made binaries built from C++ sources with gcc4 incompatible by default with binaries built with gcc5. This incompatibility often manifests itself as a bunch of undefined symbols that reference std::string and/or std::list.
The standard library comes built with a dual ABI to support objects built with older compilers. Other libraries like boost, hovever, don't.

Related

How to resolve 'std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream()#GLIBCXX_3.4.26' error?

I would like to use the GiNaC library within a Code::Blocks C++ project, but encounter the following errors during project build:
../../ginac/lib/libginac.so: undefined reference to `std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream()#GLIBCXX_3.4.26'
../../ginac/lib/libginac.so: undefined reference to `std::__throw_bad_array_new_length()#GLIBCXX_3.4.29'
collect2: error: ld returned 1 exit status
I assume the errors have something to do with incompatibility between the g++ compiler version and the stdc++ library version, but I don't know how to resolve this issue due to lack of experience.
Since I'm on a cluster and don't have root permissions, I installed the necessary prerequisite libraries GMP-6.2.1 and CLN-1.3.6 and of course GiNaC itself GiNaC-1.8.5 with the following commands into a non-default location PATH_TO_XXX, where XXX is GMP, CLN and GiNaC, respectively:
LDFLAGS="-lstdc++" ./configure --prefix=PATH_TO_XXX
make
make check
make install prefix=PATH_TO_XXX
For GMP --enable-cxx option was added to configure. For CLN --with-gmp=PATH_TO_GMP option was added to configure. The resulting build log gives the following entry before the errors:
g++ -L../../ginac/lib -L../../ginac/cln/lib -L../../ginac/cln/gmp/lib -L../../../../../../../../lib64 -o bin/Release/LB_COL_jetInSquareDuct_solver obj/Release/Control.o obj/Release/GridCoupling.o obj/Release/Lattice.o obj/Release/main.o obj/Release/Node.o -O2 -s -lstdc++ -lcln -lgmp -lgmpxx /lib64/libstdc++.so.6 /lib64/libgomp.so.1 ../../ginac/lib/libginac.so ../../ginac/cln/lib/libcln.so ../../ginac/cln/gmp/lib/libgmp.so ../../ginac/cln/gmp/lib/libgmpxx.so
I am grateful for any helpful input.
Regards
This error is probably the result of the std::string ABI break from GCC 5.1, 2015: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
You can set a macro with -D_GLIBCXX_USE_CXX11_ABI=0 to get the old ABI back.
It's probably not something you control, but the ABI break happened 8 years ago, this just shouldn't still be a problem in 2023. Your cluster is going to go bankrupt if it accumulates any more technical debt like that.
I was able to solve the problem. It simply arose from using different compiler versions when compiling GMP, CLN and GiNaC libraries (compiled with gcc 12.2.0) and the Code::Blocks project itself (compiled with gcc 7.1.0), which can be found in the project settings under "Settings -> Compiler -> Toolchain executables". By adding a new compiler with the correct version there, it then appears in the project build options for selection.

Can't link against static library with Mingw on Linux

I have installed the GMP library and try to cross-compile with mingw-w64-posix.
My Library is in /usr/local/lib.
My compile command looks like the following:
x86_64-w64-mingw32-g++-posix src/factorial.cpp -o bin/factorial.win.o -I/usr/local/include -L/usr/local/lib -lgmp -lgmpxx
It throws an undefined reference error:
(I can remove the whole block from -L...., same error. Seems like the library doesnt link for some reason)
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3_[_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3_]+0x27): undefined reference to `__gmpz_mul'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_l[_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_l]+0x26): undefined reference to `__gmpz_mul_si'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_E7init_siEl[_ZN10__gmp_exprIA1_12__mpz_structS1_E7init_siEl]+0x1a): undefined reference to `__gmpz_init_set_si'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_EC1EOS2_[_ZN10__gmp_exprIA1_12__mpz_structS1_EC1EOS2_]+0x2e): undefined reference to `__gmpz_init'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_ED1Ev[_ZN10__gmp_exprIA1_12__mpz_structS1_ED1Ev]+0x14): undefined reference to `__gmpz_clear'
collect2: error: ld returned 1 exit status
However if i change my compiler to g++ instead everything works fine.
OK -
The link errors (__gmpz_init, __gmpz_clear, etc.) are GMP "internals". They're supposed to come from libgmp, the C-language base library.
The code that's referencing them (.text$ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3[ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3], etc.) is "name mangled" C++.
I suspect the problem is that your "gmpxx" library was built with a different C++ compiler, that has a different "name mangling" convention than MinGW.
SOLUTION:
Download the complete libGMP source (e.g. from https://gmplib.org/, and rebuild EVERYTHING (including libgmpxx) with your libmingw-w64-posix++ C++ cross-compiler.
ADDENDUM:
I downloaded gmp-6.2.1 source, and found __gmpz_clear here:
gmp-6.2.1\gmp-h.in
#define mpz_clear __gmpz_clear
__GMP_DECLSPEC void mpz_clear (mpz_ptr);
"gmp-h.in" is a template used by the project's "autoconf", to generate the libGMP source files for the specified target environment.
Which, in turn, means:
The project you started out with (in your original question) wasn't configured for MinGW
... and ...
You didn't run "configure" correctly when you tried building from source.
SUGGESTION:
Try building libGMP from source again. DELETE everything, re-extract from the libGMP tarball, and carefully follow the INSTALL instructions:
./configure
make
make check <= VERY IMPORTANT!!
make install
I'm curious about your build environment (Windows? Linux?), compiler (exact MinGW version) and target (if you're building on a Windows workstation, do you want to run your GMP app as a Windows .exe)?

undefined reference to `log2f#GLIBC_2.27' undefined reference to `logf#GLIBC_2.27'

I'am trying to a run a sample code from pardiso website but end up with this error.
I installed the lapack package from http://www.netlib.org/lapack/
gcc pardiso_sym.c -L /home/sree/ -lpardiso600-GNU800-X86-64 -llapack -lgfortran -fopenmp -lm -ldl
error:
/home/sree//libpardiso600-GNU800-X86-64.so: undefined reference to `log2f#GLIBC_2.27'
/home/sree//libpardiso600-GNU800-X86-64.so: undefined reference to `logf#GLIBC_2.27'
collect2: error: ld returned 1 exit status
I know this question is quite old but anyway:
First of all - the error you are getting is a linker error and is seems like it cannot resolve a reference to a function defined in glibc.
The version given here for glibc (the GNU C library) is 2.27.
I would now suspect that the version used by GCC when trying to compile pardiso_sym.c was lower than the specified version of glibc - thus the error.
You can find a nice thread about checking the version of glibc used by different gcc compilers here.
That said - different gcc compilers might use different versions of glibc for linking. You could now either specifically try and link a proper version of glibc (like described here) or - probably more feasible - try and update your glibc version.
The described pardiso packages were also compiled with gcc 8.0 but there is a pardiso version available compiled using the gcc 7.2. Both versions also link agains different glibc versions and it might already be feasible to use libpardiso600-GNU720-X86-64.so.
In addition I'd also use a gcc version that is higher equal than the one used to compile pardiso so you might want to upgrade gcc too.
Edit:
Originally Pardiso 6.0 (and, for that matter also 6.2) was deployed as either libpardiso600-GNU720-X86-64.so or libpardiso600-GNU800-X86-64.so both available under its Download-Link.
As promised, here comes the summary of what I learned:
The Pardiso library (like all shared libraries) remembers which glibc version was used when it was compiled. Occasionally glibc may be older on your system than what Pardiso expects, leading to the link errors described by OP. You can check the version of your glibc by running ldd --version.
I applied for a free time-limited academic license, that gave me a personal download link. As #Flusslauf pointed out, one has the choice of 2 versions for the Linux 64-bit platform. As of today (2021-03-03) the two versions available to me were: libpardiso600-GNU720-X86-64.so (note: GNU720 and not GNU729, but that's a minor difference) and libpardiso600-GNU800-X86-64.so. The latter didn't work for me for the reasons explained above. So I compiled one of the little example programs from the Pardiso website in the directory containing the former Pardiso library as follows:
cd /path/to/pardiso
gcc pardiso_sym.c -L/usr/lib64 -L. -lpardiso600-GNU720-X86-64 \
-llapack -lblas -fopenmp -lpthread -lm -ldl -o psym
export LD_LIBRARY_PATH=/path/to/pardiso:${LD_LIBRARY_PATH}
export OMP_NUM_THREADS=2
export PARDISOLICMESSAGE=1
./psym
The -L/usr/lib64 was necessary to find LAPACK and BLAS on the machine I used. The -L. tells GCC to look for the Pardiso library in the current directory (/path/to/pardiso where I compiled the test program). After compilation, add to LD_LIBRARY_PATH the Pardiso library location, ask for 2 OpenMP threads and silence the Pardiso license message.
Oh, one last thing: don't forget to copy your license file to your home directory! :-)

Static linking to libcrypto++, with g++

I am trying to compile a program on my system with Debian Wheezy and g++4.7. I want it to be able to run on another system with Debian Squeeze (and no recent g++). I can't compile the program on the Squeeze, because I use certain C++11 features the old g++ does not support, as well as a new Boost version and libcrypto++9.
As far as I understand the usual way to get around this problem is to static link the libraries not supported at the other system, in my case libstdc, boost and crypto++.
My (linking) compiler call right now is
g++-4.7 .obj/btcmirco.o -Wl,-Bstatic -lboost_program_options -lboost_system -lcrypto++ -Wl,-Bdynamic -lcurl -static-libgcc -std=c++11 -o MyProgram
However I seem to have missed something, because it throws a lot of undefined reference errors. It works fine if I dynamic link to crypto++ (and only static link libstdc and boost).
Can anyone tell me whats wrong, or if there is a fundamental error in my approach?
The linker errors I get are (shorted):
`.text._ZN8CryptoPP22BufferedTransformationD2Ev' referenced in section `.text._ZN8CryptoPP22BufferedTransformationD1Ev[_ZN8CryptoPP22BufferedTransformationD1Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o): defined in discarded section `.text._ZN8CryptoPP22BufferedTransformationD2Ev[_ZN8CryptoPP22BufferedTransformationD5Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o)
`.text._ZN8CryptoPP25MessageAuthenticationCodeD2Ev' referenced in section `.text._ZN8CryptoPP25MessageAuthenticationCodeD1Ev[_ZN8CryptoPP25MessageAuthenticationCodeD1Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o): defined in discarded section `.text._ZN8CryptoPP25MessageAuthenticationCodeD2Ev[_ZN8CryptoPP25MessageAuthenticationCodeD5Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o)
I experienced the same problem and this has to do with the fact that you are trying to mix code generated by g++-4.7 (your program) with code generated by a previous version of g++ (cryptopp library).
The reason behind this is that when you execute compile the library executing make command, it uses the default version of g++ set up for your system, usually the one that comes with the OS.
In order to solve the issue what you should do is compile cryptopp library with g++-4.7.
For that, compile the library by executing make CXX=g++-4.7. The resulting static library shouldn't give you the error when being linked with your code.

MinGW linker error: winsock

I am using MinGW compiler on Windows to compile my C++ application with sockets. My command for linking looks like:
g++.exe -Wall -Wno-long-long -pedantic -lwsock32 -o dist/Windows/piskvorky { there are a lot of object files }
and I have also tried
g++.exe -Wall -Wno-long-long -pedantic -lws2_32 -o dist/Windows/piskvorky { there are a lot of object files }
but in both case I get this error:
build/Windows/MinGW-Windows/src/utils/tcpunit.o:tcpunit.cpp:(.text+0x33): undefined reference to `closesocket#4'
build/Windows/MinGW-Windows/src/utils/tcpunit.o:tcpunit.cpp:(.text+0xd0): undefined reference to `send#16'
build/Windows/MinGW-Windows/src/utils/tcpunit.o:tcpunit.cpp:(.text+0x1ee): undefined reference to `recv#16'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x184): undefined reference to `WSAStartup#8'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x1a5): undefined reference to `closesocket#4'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x1cb): undefined reference to `closesocket#4'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x1d3): undefined reference to `WSACleanup#0'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x6fe): undefined reference to `bind#12'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x724): undefined reference to `listen#8'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x7f0): undefined reference to `gethostbyaddr#12'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x83c): undefined reference to `socket#12'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x86f): undefined reference to `htons#4'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x8b5): undefined reference to `connect#12'
build/Windows/MinGW-Windows/src/utils/tcpdevice.o:tcpdevice.cpp:(.text+0x9c6): undefined reference to `accept#12'
Do you have any ideas where the problem can be, please?
Put the -lws2_32 AFTER the list of object files - GCC searches libraries and object files in the order they appear on the command line.
Just to help the other viewers out there:
gcc hello.c -o hello.o -lws2_32
With MinGW on eclipse:
Menu >> Project >> Properties >> C/C++ Build >> Settings: Register "Tool Settings" - MinGW C Linker - Miscellaneous: Lower Part "other objects"
Add: "D:\Programmierung\mingw\lib\libwsock32.a" for example. No other entries for libwsock32.a on any other properties required, especially not in Library-entries. Also no flags relating to this Lib.
In:
Menu - Project - Properties - c/c++Build - Settings: Register "Tool Settings" - MinGW C++ Linker - Miscellaneous: Lower Part "other objects"
Add: libwsock32.a from bin folder of MinGW.
Greetings I just went through the problem above....
So here are some observations first off....
I know you are refering to MinGw, but you may need cygwin to get around this, I don't know mingw that well, I know cygwin better. But I know that they are cousins of each other.
Cygwin comes with the precompiled boost libraries, but who knows of which version they are. I'm sure it's possible to check, but who has time to do that right? I do not link against cygwin boost libraries, or the mingw boost libraries, I built boost from scratch using gcc on windows (cygwin). The compile did fine.
At the time of this writing boost is on version 1.47.0 I beleive.
Already that fact that cygwin uses version (x?) and boost is 1.47.0 could be a major issue. Make you know what you are using in the way of boost.
I was using code developed on boost 1.42, and had related linker errors. The code compiled, headers were found, etc..etc... but then I got the undefined reference to WSA etc...etc...opensocket this, close socket that, etc....
So, apparantly boost, in order to do network sockets, requires a platform library, in which was found in the form of ws2_32 for windows, and socket for linux for sure.
So if you are properly using boost, and including the correct boost system libraries, you may also need an OS specific library to access some resources (networking in this case).
Linker errors dissappear after that. It's probably obvious to boost veterans what's going on here, but I was unable to find a clear answer via google.