errors linking clang-built executable with g++-v6-built boost library - c++

I have a boost regex library built myself with g++ version 6.3.1 on Fedora Linux.
Then I have my own library using the boost regex, built with clang++ 4.0 as shared object.
Building this works fine.
At last I have an executable which links to my library and this produces the following error:
undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform[abi:cxx11](char const*, char const*) const'
Building and linking with g++ only works correctly.
Can this be solved with some commandline argument to clang++?

As nobody seems to have a solution for this, I compiled boost a second time with
./b2 toolset=clang
and now my problems are gone.

Related

linking libphonenumber/C++

I am trying to statically link my project to a fresh libphonenumber/cpp build (release 8.12.56), and get lots of linker errors involving abseil. Here are the first two:
/usr/bin/ld: ../libphonenumber/cpp/build/libphonenumber.a(phonenumberutil.cc.o): in function `absl::lts_20220623::hash_internal::MixingHashState::MixingHashState()':
phonenumberutil.cc:(.text._ZN4absl12lts_2022062313hash_internal15MixingHashStateC2Ev[_ZN4absl12lts_2022062313hash_internal15MixingHashStateC5Ev]+0xb): undefined reference to `absl::lts_20220623::hash_internal::MixingHashState::kSeed'
/usr/bin/ld: ../libphonenumber/cpp/build/libphonenumber.a(phonenumberutil.cc.o): in function `absl::lts_20220623::hash_internal::MixingHashState::CombineContiguousImpl(unsigned long, unsigned char const*, unsigned long, std::integral_constant<int, 8>)':
phonenumberutil.cc:(.text._ZN4absl12lts_2022062313hash_internal15MixingHashState21CombineContiguousImplEmPKhmSt17integral_constantIiLi8EE[_ZN4absl12lts_2022062313hash_internal15MixingHashState21CombineContiguousImplEmPKhmSt17integral_constantIiLi8EE]+0x56): undefined reference to `absl::lts_20220623::hash_internal::MixingHashState::CombineLargeContiguousImpl64(unsigned long, unsigned char const*, unsigned long)'
Somewhat similarly named functions do appear in libphonenumber.a, but apparently they do not match. libphonenumber_test runs successfully.
The last version of libphonenumber to successfully link with my project is 8.12.39.
My build environment is out-of-the-box debian buster with a the required libraries (as specified in the README) and default-jre-headless installed. I tried compiling with C++11 and C++17 standard. I also tried a few intermediate versions of libphonenumber, with no success.
g++ version: g++ (Debian 8.3.0-6) 8.3.0
cmake version: cmake version 3.13.4

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)?

boost.regex fails to link with MinGW and GCC compiler

On Windows 10 I installed MinGW, and use Eclipse to write C++ programs together with Boost libraries 1.71.0 (for example boost/algorithm/string.hpp).
I can successfully create the executable using boost::replace_all(doc, "#", "_"); in my source code.
The compiler is GCC version 8.2.0
As I also want use the Boost.regex library I built the Boost libraries suffing following commands commands in a Command Prompt window
bootstrap.bat
.\b2 --prefix=C:\Users\makkun\Documents\boost_1_71_0\build install
I then changed to the Boost root directory and invoked b2 as follows:
b2 --build-dir=C:\Users\makkun\Documents\boost_1_71_0\build toolset=gcc --build-type=complete stage
The directory C:\Users\makkun\Documents\boost_1_71_0\stage\lib was created and I can see the regex related files
libboost_regex-mgw82-mt-d-x32-1_71.a
libboost_regex-mgw82-mt-d-x32-1_71.dll.a
libboost_regex-mgw82-mt-sd-x32-1_71.a
libboost_regex-mgw82-mt-s-x32-1_71.a
libboost_regex-mgw82-mt-x32-1_71.a
libboost_regex-mgw82-mt-x32-1_71.dll.a
libboost_regex-mgw82-mt-d-x32-1_71.dll
libboost_regex-mgw82-mt-x32-1_71.dll
In Eclipse I added in MinGW C++ Linker > Libraries > Library search path (-L) the library folder "C:\Users\makkun\Documents\boost_1_71_0\stage\lib"
In my source code I have
#include <boost/regex.hpp>
...
boost::regex e("(\\d{4}[- ]){3}\\d{4}");
The compilation is OK, but the linking with command
g++ "-LC:\\Users\\makkun\\Documents\\boost_1_71_0\\stage\\lib" "-LC:\\Users\\makkun\\Documents\\boost_1_71_0\\libs" -o LastDoc.exe "src\\LastDoc.o"
fails with 46 errors of the type undefined reference to:
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: src\LastDoc.o: in function `ZN5boost16re_detail_10710027cpp_regex_traits_char_layerIcEC2ERKNS0_21cpp_regex_traits_baseIcEE':
C:/Users/makkun/Documents/boost_1_71_0/boost/regex/v4/cpp_regex_traits.hpp:370: undefined reference to `boost::re_detail_107100::cpp_regex_traits_char_layer<char>::init()'
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: src\LastDoc.o: in function `ZN5boost16re_detail_10710011raw_storage6extendEj':
C:/Users/makkun/Documents/boost_1_71_0/boost/regex/v4/regex_raw_buffer.hpp:131: undefined reference to `boost::re_detail_107100::raw_storage::resize(unsigned int)
...'
I also tried to add in MinGW C++ Linker > Libraries > Libraries (-l) string "boost-regex" but the linker does find it
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: cannot find -lboost_regex
Can anybody suggest where the problem is, please?

Boost regex: Undefined references when linking

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.

strange mingw linker errors with boost?

I've been working on this for a while now, and can't seem to make sense of the situation - partly bceause I don't fully understand what's going on (which is why I came here).
I'm doing a sort of boost hello world as follows:
#include <boost/thread/thread.hpp>
#include <cstdio>
void helloworld() {
std::printf("HELLO FROM A BOOST THREAD!");
}
int main(int argc, char **argv) {
boost::thread t(&helloworld);
t.join();
}
This is on Windows. I stored the Boost directory in C:\Boost. I ran bootstrap and bjam, and now have a stage/lib folder that contains all the .lib files. The lib files relating to the boost/thread library are:
libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib
Now I compile:
g++ -c main.cpp -I/Boost
that line works fine, I get main.o. Then:
g++ -o test.exe main.o -L/Boost/stage/lib -llibboost_thread-vc100-mt
And that's where the trouble happens. First of all, If I didn't type the -l argument the way I did, MinGW couldn't even find the file. Meaning, if I tried:
-lboost_thread-vc100-mt
instead of the way I typed it above (and how I thought it should be done), ld would exit with no such file. Anyway, this is now the output I'm getting from that line:
main.o:main.cpp:(.text+0x47): undefined reference to `_imp___ZN5boost6thread4joinEv'
main.o:main.cpp:(.text+0x55): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text+0x70): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text$_ZN5boost6threadC1IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE[boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type)]+0x23): undefined reference to `_imp___ZN5boost6thread12start_threadEv'
collect2: ld returned 1 exit status
Now somewhere in there, I can tell that these are apparently the functions I'm supposed to be getting from boost/thread, and apparently it does find the lib file, so why isn't it linking correctly?
Thank you very much for any help!
EDIT:
I've rebuilt boost using the bjam "stage" option
bjam toolset=gcc stage
Now, after the build completes, I'm left with a stage/lib folder with .a files, as is to be expected. These are the boost/thread related libraries:
libboost_thread-mgw45-mt-1_46_1.a
libboost_thread-mgw45-mt-d-1_46_1.a
However, linking as follows:
g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1
outputs the exact same errors. Also tried:
g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1 -static
I'm at a loss, still.
Solved the problem. Boost's headers are configured to be dynamically linked, but the dynamic libraries (dll's) are not built unless you specify:
--build-type=complete
when invoking bjam. After that, copy the appropriate dll to your application directory, but still use the
-L/BOOST_DIR/stage/lib -lname
when linking.
This set of library files:
libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib
are for the Visual Studio 2010 compiler. They won't work with GCC. If you want to use gcc/MinGW, you'll need to download/build a set of boost libraries for that compiler. Alternatively you can install VS 2010 and use that compiler (the free VC++ 2010 Express version should work fine if cost is an issue).
You can get a MinGW distribution with Boost already in the package from http://nuwen.net/mingw.html (32-bit target only, I believe).
To answer about getting the errors with using the MinGW libs:
The _imp_ prefixes on the symbols is an indication that g++ is looking to link to a a dll/shared library. The .lib file you have are for static libraries (which is what also what I get when doing a straightforward bjam build of the libraries). If you look in boost/thread/detail/config.hpp you'll see that for Win32 builds it defaults to building against a DLL library unless the MSVC or Intel compiler is being used.
I'm not even sure exactly how to build the DLL libraries - I'll have to look it up. In the meantime, you can use the following command to build your example such that it'll link against the static library. The BOOST_THREAD_USE_LIB macro build the .cpp file such that it'll expect to link against the static library:
g++ -I/Boost -DBOOST_THREAD_USE_LIB -c main.cpp