Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error linking webrtc-native due to undefined reference to methods having std::string

i am trying to build webrtc version 62 , using the following

1.git checkout -b branch62 refs/remotes/branch-heads/62
2.gn gen out_release_62/x64/Debug --args="rtc_include_tests=false rtc_use_h264=false use_rtti=true is_component_build=false enable_iterator_debugging=false enable_nacl=false target_os=\"linux\" target_cpu=\"x64\" is_debug=true"
3.ninja -C out_release_62/x64/Debug

i am linking to libwebrtc.a and libwebrtc_common.a

but wherever i try to use RTC_CHECK_EQ or RTC_DCHECK_LT i get the the following error

undefined reference to `rtc::FatalMessage::FatalMessage(char const*, int, std::string*)'

and

out_release_62/include/webrtc/rtc_base/checks.h:176: undefined reference to `std::string* rtc::MakeCheckOpString<int, int>(int const&, int const&, char const*)'
./src/testwebrtc.o: In function `rtc::CheckLtImpl(int, int, char const*)':

i had no issue with build branch head 60 , i tried linking to librtc_base.a and librtc_base_approved.a but no luck. A sample program that produces this error is

#include <iostream>
#include <string>
#include <webrtc/rtc_base/checks.h>
#include <webrtc/rtc_base/ssladapter.h>
#include <webrtc/rtc_base/logging.h>
#include <webrtc/api/peerconnectioninterface.h>
using namespace std;

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    std::string type;
    std::string sdp;
    webrtc::SdpParseError error;
    webrtc::CreateSessionDescription(type,sdp,&error);
    RTC_DCHECK(5);
    RTC_CHECK_EQ(1,6);
    RTC_DCHECK_LT(1,4);
    return 0;
}

gcc verison 6.3 linker

g++ -L/home/test/webrtc-checkout-ankur/src/out_release_62/x64/Debug -o "testwebrtc"  ./src/testwebrtc.o   -lwebrtc -lwebrtc_common -lpthread -lm -ldl

this is the error that is returned

./src/testwebrtc.o: In function `main':
/home/test/workspace/testwebrtc/Debug/../src/testwebrtc.cpp:22: undefined reference to `webrtc::CreateSessionDescription(std::string const&, std::string const&, webrtc::SdpParseError*)'
/home/test/workspace/testwebrtc/Debug/../src/testwebrtc.cpp:24: undefined reference to `rtc::FatalMessage::FatalMessage(char const*, int, std::string*)'
/home/test/workspace/testwebrtc/Debug/../src/testwebrtc.cpp:25: undefined reference to `rtc::FatalMessage::FatalMessage(char const*, int, std::string*)'
./src/testwebrtc.o: In function `rtc::CheckEqImpl(int, int, char const*)':
makefile:45: recipe for target 'testwebrtc' failed
/home/test/webrtc-checkout-ankur/src/out_release_62/include/webrtc/rtc_base/checks.h:176: undefined reference to `std::string* rtc::MakeCheckOpString<int, int>(int const&, int const&, char const*)'
./src/testwebrtc.o: In function `rtc::CheckLtImpl(int, int, char const*)':
/home/test/webrtc-checkout-ankur/src/out_release_62/include/webrtc/rtc_base/checks.h:179: undefined reference to `std::string* rtc::MakeCheckOpString<int, int>(int const&, int const&, char const*)'
collect2: error: ld returned 1 exit status

From my observation any function/method that has std::string in it is showing this behaviour. _GLIBCXX_USE_CXX11_ABI=0 has been set, and -std=c++0x , this build is done on an ubuntu 16.04 system.

running nm on the built library i get

find -iname '.a' -exec nm -A -C {} \; | grep 'T rtc::FatalMessage::FatalMessage('

./Debug/obj/webrtc/rtc_base/librtc_base_approved.a:checks.o:00000000000001a0 T rtc::FatalMessage::FatalMessage(char const*, int)
./Debug/obj/webrtc/rtc_base/librtc_base_approved.a:checks.o:00000000000005e0 T rtc::FatalMessage::FatalMessage(char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
./Debug/obj/webrtc/rtc_base/librtc_base_approved.a:checks.o:00000000000001a0 T rtc::FatalMessage::FatalMessage(char const*, int)
./Debug/obj/webrtc/rtc_base/librtc_base_approved.a:checks.o:00000000000005e0 T rtc::FatalMessage::FatalMessage(char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
./Debug/obj/webrtc/libwebrtc.a:checks.o:00000000000001a0 T rtc::FatalMessage::FatalMessage(char const*, int)
./Debug/obj/webrtc/libwebrtc.a:checks.o:00000000000005e0 T rtc::FatalMessage::FatalMessage(char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
./Debug/obj/webrtc/libwebrtc.a:checks.o:00000000000001a0 T rtc::FatalMessage::FatalMessage(char const*, int)
./Debug/obj/webrtc/libwebrtc.a:checks.o:00000000000005e0 T rtc::FatalMessage::FatalMessage(char const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)

and

find -iname '.a' -exec nm -A -C {} \; | grep 'CreateSessionDescription('

./Debug/obj/webrtc/pc/libpeerconnection.a:jsepsessiondescription.o:0000000000000000 T webrtc::CreateSessionDescription(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, webrtc::SdpParseError*)
./Debug/obj/webrtc/libwebrtc.a:jsepsessiondescription.o:0000000000000000 T webrtc::CreateSessionDescription(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, webrtc::SdpParseError*)

please help

like image 224
Ankur Avatar asked Nov 17 '17 10:11

Ankur


1 Answers

you have a standard lib mismatch: on one hand you use std::string, on the other hand you use std::__1::basic_string

in other words: on one hand you use libc++ on the other hand you use libstdc++

You need to use clang and pass

-stdlib=libstdc++

to the compiler command line.

__1 signifies that we are using the libc++ llvm-clang library, which is the default for webrtc builds

__1 is the inlined namespace that libc++ uses,

so as to solve this particular issue, we should either use libc++ instead of libstdc++ in our application when we link to libwebrtc,

or

build webrtc to use libstdc++, to let gn know that we intend to use libstdc++, we pass use_custom_libcxx=false and use_custom_libcxx_for_host=false as args

like image 168
Dr. Alex Gouaillard Avatar answered Nov 14 '22 19:11

Dr. Alex Gouaillard