libpqxx icon indicating copy to clipboard operation
libpqxx copied to clipboard

[Build failure] undefined reference to `pqxx::argument_error::argument_error`

Open Big-Iron-Cheems opened this issue 1 year ago • 6 comments

Hello, I am trying to use this library in my project with CMake (via the <pqxx/pqxx> header). Before I was using only the pq library, but after refactoring my project and adding pqxx to the mix this errror keeps happening:

====================[ Build | test_project | Debug ]===============================
/home/self/.local/share/JetBrains/Toolbox/apps/clion/bin/cmake/linux/x64/bin/cmake --build /home/self/Projects/CLionProjects/test_project/cmake-build-debug --target test_project -j 10
[6/6] Linking CXX executable /home/self/Projects/CLionProjects/test_project/bin/test_project
FAILED: /home/self/Projects/CLionProjects/test_project/bin/test_project 
: && /usr/bin/c++ -Wall -Wextra -g  CMakeFiles/test_project.dir/src/main.cpp.o CMakeFiles/test_project.dir/src/db/dbutils.cpp.o CMakeFiles/test_project.dir/src/redis/rdutils.cpp.o CMakeFiles/test_project.dir/src/models/Customer.cpp.o CMakeFiles/test_project.dir/src/models/Supplier.cpp.o CMakeFiles/test_project.dir/src/models/Transporter.cpp.o CMakeFiles/test_project.dir/src/utils.cpp.o -o /home/self/Projects/CLionProjects/test_project/bin/test_project  -lhiredis  -lpqxx  -lpq && :
/usr/bin/ld: CMakeFiles/test_project.dir/src/main.cpp.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
/usr/include/pqxx/internal/encodings.hxx:122:(.text+0x200): undefined reference to `pqxx::argument_error::argument_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
/usr/bin/ld: CMakeFiles/test_project.dir/src/db/dbutils.cpp.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
/usr/include/pqxx/internal/encodings.hxx:122:(.text+0x200): undefined reference to `pqxx::argument_error::argument_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
/usr/bin/ld: CMakeFiles/test_project.dir/src/db/dbutils.cpp.o: in function `pqxx::string_traits<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::into_buf(char*, char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
/usr/include/pqxx/internal/conversions.hxx:605:(.text._ZN4pqxx13string_traitsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE8into_bufEPcS8_RKS6_[_ZN4pqxx13string_traitsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE8into_bufEPcS8_RKS6_]+0xa2): undefined reference to `pqxx::conversion_overrun::conversion_overrun(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
/usr/bin/ld: CMakeFiles/test_project.dir/src/db/dbutils.cpp.o: in function `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > pqxx::to_string<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)':
/usr/include/pqxx/internal/conversions.hxx:1188:(.text._ZN4pqxx9to_stringISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEEES7_RKT_[_ZN4pqxx9to_stringISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEEES7_RKT_]+0xab): undefined reference to `pqxx::conversion_error::conversion_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
/usr/bin/ld: CMakeFiles/test_project.dir/src/db/dbutils.cpp.o: in function `pqxx::internal::array_string_traits<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::into_buf(char*, char*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)':
/usr/include/pqxx/internal/conversions.hxx:1034:(.text._ZN4pqxx8internal19array_string_traitsISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEE8into_bufEPcSC_RKSA_[_ZN4pqxx8internal19array_string_traitsISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEE8into_bufEPcSC_RKSA_]+0xb3): undefined reference to `pqxx::conversion_overrun::conversion_overrun(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
/usr/bin/ld: CMakeFiles/test_project.dir/src/models/Customer.cpp.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
/usr/include/pqxx/internal/encodings.hxx:122:(.text+0x200): undefined reference to `pqxx::argument_error::argument_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
/usr/bin/ld: CMakeFiles/test_project.dir/src/models/Supplier.cpp.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
/usr/include/pqxx/internal/encodings.hxx:122:(.text+0x200): undefined reference to `pqxx::argument_error::argument_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
/usr/bin/ld: CMakeFiles/test_project.dir/src/models/Transporter.cpp.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
/usr/include/pqxx/internal/encodings.hxx:122:(.text+0x200): undefined reference to `pqxx::argument_error::argument_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::source_location)'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

linking pqxx first as specified in the FAQ

target_link_libraries(test_project PRIVATE -lhiredis -lpqxx -lpq)

library versions, up to date, downloaded via pacman

extra/libpqxx          7.8.1-2	(at /usr/include/pqxx/pqxx) 
extra/postgresql-libs  16.1-5	(at /usr/include/libpq-fe.h)

building with

gcc 13.2.1-5 for Arch

Any advice? Feel free to ask for more info if this is not enough.

Big-Iron-Cheems avatar Feb 09 '24 12:02 Big-Iron-Cheems

Could it be that you're compiling libpqxx and your application with different compiler or language versions?

jtv avatar Feb 09 '24 13:02 jtv

I have not compiled libpqxx manually myself, instead I got it straight from pacman at https://archlinux.org/packages/extra/x86_64/libpqxx/. My projects are set to use C++ 23 (I tried usig C++ 20, same issue), and use my system's default compiler (never changed it myself).

Big-Iron-Cheems avatar Feb 09 '24 13:02 Big-Iron-Cheems

Ahhh, then I see what went wrong. :-(

First off: different C++ builds are not necessarily compatible with each other. Some things that can (but don't necessarily, so it's easy to rely on "luck" without even noticing) break the ability to link an application to a library (or one library to another) that was compiled differently:

  • Different compilers.
  • Different compiler versions.
  • Different C++ versions, e.g. C++17 vs. C++20.
  • Different debug options.

Any of these can "break the ABI" by producing incompatible binaries. And unfortunately none of the packaging systems seem to take this into account. They just assume that a C++ library works just like a C library — stable ABI, doesn't care how you compiled it. That whole model just doesn't work for C++ unless you give up everything that makes it C++.

To complicate things more, in libpqxx I added a feature in C++20 that made the libpqxx exception classes ABI-incompatible between C++17 and C+20, so you get these errors when you link a C++17-compiled libpqxx to a C++20-compiled application or library, or vice versa.

The fix is already committed for the upcoming 7.9.0 release, but the issue has caused a lot of trouble along the way. For now I would strongly recommend compiling libpqxx yourself.

jtv avatar Feb 09 '24 22:02 jtv

Thank you for the insight, really appreciate all this info. I'll be looking out for the upcoming release, will definitely try to build it myself in the meantime.

Big-Iron-Cheems avatar Feb 10 '24 01:02 Big-Iron-Cheems

Some blockers for the next release have cleared up in recent days, so hoping to release 7.9.0 soon, and hopefully the problem won't happen with that.

However in the grander scale, we're still stuck with the problem that all package managers encourage us to link things together that may or may not actually be compatible, because of different language versions etc.

jtv avatar Feb 10 '24 19:02 jtv

I am in the process of releasing 7.9.0 which should fix this problem.

jtv avatar Feb 18 '24 20:02 jtv

@Big-Iron-Cheems the problem should disappear as soon as Pacman updates to 7.9.0.

jtv avatar Feb 25 '24 14:02 jtv