Chris Watts
Chris Watts

Reputation: 6725

Unable to use std::chrono with std::future - GLIBCXX_3.4.19 not found

I'm trying to use std::future::wait_for(std::chrono::duration) in my application (in fact, I don't want to wait at all which makes this more frustrating, as you'll see), but in using anything from std::chrono, I am unable to run the application after cross-compiling it for my BeagleBone Black:

/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.19' not found

Until I add the following lines to my code, this project compiles and runs great with an older version of GLIBCXX, but just to be able to check if a future's value is ready without blocking, I suddenly need all these newer libraries:

if (myFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
    return true;

The BeagleBone Black comes with GLIBCXX_3.4.17 from GCC 4.6.3 - I've checked the C++ headers on the system, and as I suspected, all the functionality I need from the chrono library is there. So why does it ask for version 3.4.19?

I tried updating and upgrading Debian with sudo apt-get upgrade in the hopes that the newer libraries would be added. This had no effect. Besides, I would really like to be able to run on the stock image.

So I tried statically linking libstdc++ with -static-libstdc++ added to my LD flags. Now I'm apparently missing GLIBC-2.7 which can't be fixed in the same way with -static-libgcc

I'm out of ideas.

Upvotes: 2

Views: 2815

Answers (2)

Titonus
Titonus

Reputation: 11

It works the ".symver" change, but it will break your std::chrono timers and dates if you compile it with >= GCC 4.8, because std::chrono ABI had changes. It will run with systems like Ubuntu 12.04 (GCC 4.6.3) but date & time will not be showed correctly.

Upvotes: 1

Chris Watts
Chris Watts

Reputation: 6725

I was able to compile with a previous version of the function that required 3.4.19 by following steps in another answer.

Firstly, I checked what was needed from 3.4.19:

$ objdump -T myapp | grep "GLIBCXX_3.4.19"
00000000      DF *UND*  00000000  GLIBCXX_3.4.19 _ZNSt6chrono3_V212system_clock3nowEv

Then I searched for the same symbol in the library I have

$ objdump -T /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 | grep "_ZNSt6chrono3_V212system_clock3nowEv"

But this returned nothing. On a hunch, I tried finding just 'chrono' instead

$ objdump -T /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 | grep "chrono"
00080828 g    DF .text  0000002a  GLIBCXX_3.4.11 _ZNSt6chrono12system_clock3nowEv
0008ae38 g    DO .rodata    00000001  GLIBCXX_3.4.11 _ZNSt6chrono12system_clock12is_monotonicE

Bingo. While it's not an exact match, it looked good enough for me. I added an assembly directive to my source file to update the linkage for the requested symbol.

__asm__(".symver _ZNSt6chrono3_V212system_clock3nowEv,_ZNSt6chrono12system_clock3nowEv@GLIBCXX_3.4.11");

While it now compiles and runs, I am unable to say for sure that this substitution works as I have other hurdles to get around however I think I'd be safe in saying it's a solution.

Upvotes: 2

Related Questions