0

I have a static library test1.a built on linux. When I am trying to link against it, the linker throws undefined reference errors:

CMakeFiles/Testserver.dir/src/audio/TestEncoderFactory.cpp.o: In function TestEncoderFactory::GetSupportedEncoders(): TestH264BypassedEncoder.cpp:(.text._ZN10H264BypassedEncoderC2ERKN7cricket10VideoCodecERNS_14TestClientE+0x191): undefined reference to absl::EqualsIgnoreCase(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >)

TestEncoderFactory.cpp:(.text._ZN10TestEncoderFactory20GetSupportedEncodersEv+0x20b): undefined reference to `test::SdpAudioFormat::SdpAudioFormat(std::basic_string_view<char, std::char_traits >, int, unsigned long, std::map<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits, std::allocator > const, std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > >&&)'

But then I created a sample program using the same line of code leading to linker errors as shown below and when I build it by linking against the same test.a the executable is building perfectly fine:

#include <string>
#include <rtc_base/logging.h>
#include <rtc_base/checks.h>
#include <iostream>
#include <absl/strings/match.h>
#include <memory>

using namespace std;

int main() {

cout << "testing\n";

RTC_CHECK(absl::EqualsIgnoreCase("", ""));

//RTC_LOG(INFO) << "Testing libwebrtc linking";

bool res = absl::EqualsIgnoreCase("ab", "");
cout << res;

cout << "\nending";

}

I built above using g++ -I./include -I./include/third_party/abseil-cpp test.cpp -L./lib -ltest1 -o final_ex the executable final_ex builds successfully.

The other program is a bigger one(and is private and thus can't share) and trying to link against test1.a and other are .so as mentioned in the command below:

/usr/bin/g++ -pthread -g -rdynamic CMakeFiles/testServer.dir/src/Main.cpp.o testxyz.cpp.o -o bin/testServer -L<lib_loc> -Wl,-rpath,<path....> -static-libstdc++ -static-libgcc -ltest1 -lprotobuf -lgio-2.0 -lgobject-2.0 -lglib-2.0 -ljson-glib-1.0 -lffmpeg -lX11 -ldl

I also checked many different questions on Stackoverflow but couldn't fix the issue. Can linking against static and dynamic libs be the cause behind the issue?

Fix

As question is closed so adding the fix details in question itself.

One important detail I forgot to mention was I used cxx_std_17 to build my code. Also I was not aware that the static lib test1.a was built using cxx_std_14. Once I got to know this I used cxx_std_14 and all the linker errors were resolved.

I didn't think about it earlier as I was of the understanding that it's safe to link C++17 and C++14 as mentioned in answer to this stackoverflow question. But found the hard way that it may not be the case.

Yug Singh
  • 3,112
  • 5
  • 27
  • 52
  • So where is the `cmake` file where this issue is happening? – Waqar Jul 13 '20 at 13:20
  • @Waqar I was using CMake earlier but now using the g++ command directly. Edited the question also. – Yug Singh Jul 13 '20 at 13:22
  • move the `-L ....` before `-o bin/....` – Waqar Jul 13 '20 at 13:24
  • @Waqar I tried as you suggested but still getting the linker errors – Yug Singh Jul 13 '20 at 13:30
  • `-pthread` should be `-lpthread` and why put that in the start but the rest in the end? – Waqar Jul 13 '20 at 13:41
  • I was just trying different things mentioned in other SO posts. So just posted the final command I am using. But I have tried using -lpthread also as you mentioned but none helped. – Yug Singh Jul 13 '20 at 13:52
  • @Waqar no, -pthread should absolutely not be -lpthread, never ever. – n. m. could be an AI Jul 13 '20 at 13:54
  • @n.'pronouns'm. can you share why? – Waqar Jul 13 '20 at 13:56
  • You need to link to abseil libraries. The fact that your little test program can get away with it means absolutely nothing. – n. m. could be an AI Jul 13 '20 at 13:56
  • @Waqar https://stackoverflow.com/questions/23250863/difference-between-pthread-and-lpthread-while-compiling – Thomas Sablik Jul 13 '20 at 13:58
  • @n.'pronouns'm. the static test1.a has been built with abseil libraries. I can see the abseil-cpp .o files and corresponding symbols when I do `nm test1.a`. Also that's the reason I am able to use `absl::EqualsIgnoreCase("ab", "");` in my test program also which is then linked against `test1.a`. – Yug Singh Jul 13 '20 at 13:58
  • 2
    @Waqar `man gcc` says "-pthread \[...] You should use this option consistently for both compilation and linking". That's a good enough reason for me. – n. m. could be an AI Jul 13 '20 at 13:59
  • @n.'pronouns'm. Great! thanks. Never realized this until now. – Waqar Jul 13 '20 at 14:02
  • What source file or library has the undefined reference? – n. m. could be an AI Jul 13 '20 at 14:02
  • The errors are in the executable `testServer` which I am trying to build by linking against `test1.a` and other `*.so` – Yug Singh Jul 13 '20 at 14:04
  • Please post the *entire* compiler message. A compiler message never starts with "undefined reference". There should be something before these words, namely the source or object file name and the library name. – n. m. could be an AI Jul 13 '20 at 14:08
  • @n.'pronouns'm. I have updated the error message. – Yug Singh Jul 13 '20 at 14:12
  • You need to move `-ltest1` down the link line and place it after all libraries that might need it. In addition, `nm` your libraries. If you see a reference to __cxx11, then you are a victim of the dual libstdc++ ABI fiasco and you probably need to upgrade your system or downgrade your compiler. – n. m. could be an AI Jul 13 '20 at 14:21
  • @n.'pronouns'm. the libtest1.a is not required by any library mentioned after it. So moving it down the line didn't help. One thing was that If I move it after -ldl I get the error: `libtest1.a(latebindingsymboltable_linux.o): undefined reference to symbol 'dlclose@@GLIBC_2.2.5' /home/yugander/SpiderPorkClientWebCommon/src/SpiderPorkClientWebCommon/server/lib/pipewire/lib/libdl.so: error adding symbols: DSO missing from command line` – Yug Singh Jul 13 '20 at 14:39
  • Also there are other linker errors which I didn't posted which have reference to `__cxx11`: ::SdpAudioFormat(std::basic_string_view >, int, unsigned long, std::map, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::less, std::allocator > >, std::allocator, std::allocator > const, std::__cxx11::basic_string – Yug Singh Jul 13 '20 at 14:41
  • Does this also indicate issue of dual libstdc++ ABI u mentioned? – Yug Singh Jul 13 '20 at 14:41
  • OK so this is not a link order issue but a dual ABI issue. I fixed the dupe. Basically some but not all of your code is compiled with `-D_GLIBCXX_USE_CXX11_ABI=0` (or by an ancient gcc). Don't do that. – n. m. could be an AI Jul 13 '20 at 14:46
  • if you think that the duplicates don't answer your question, tell me and I'll reopen – n. m. could be an AI Jul 13 '20 at 14:52
  • @n.'pronouns'm. I did try with -D_GLIBCXX_USE_CXX11_ABI=0 to fix the ABI issue as mentioned in the tagged question. But the issue remained. Lateron I figured out that failure was because of `cxx_std_17` and once I changed it to `cxx_std_14` all linker errors were resolved. I never knew that cxx_std_17 and 14 are incompatible. – Yug Singh Jul 15 '20 at 18:14

0 Answers0