Reputation: 6725
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
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
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