我一直在使用这个脚本为ARM构建一个GCC交叉编译器 https://gist.github.com/kmhofmann/eea6f7286ddf1b5b3180,以便我可以为Raspberry Pi 2编译程序。
脚本本身很大程度上基于Jeff Preshing的GCC交叉编译器脚本(另见他的博客文章http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/),我基本上只交换了几个版本号(将所有版本号都提到了最新版本。)
我可以提出一个非常简单的程序,但是我的主机上已经无法链接(x86_64,Ubuntu 15.04)。
// main.cpp
#include <iostream>
#include <future>
int main()
{
auto getNumber = [](){ return 42; };
auto f = std::async(getNumber);
std::cout << "number = " << f.get() << "\n";
}
我正在使用CMake / Make构建它,我的CMakeLists.txt看起来如下
cmake_minimum_required(VERSION 2.8)
project(pitest)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}
-std=c++14 -static-libgcc -static-libstdc++")
add_executable(pitest main.cpp)
target_compile_options(pitest PRIVATE
-O2 -ffast-math -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
并致电
CC=~/cross/install/bin/arm-linux-gnueabihf-gcc \
CXX=~/cross/install/bin/arm-linux-gnueabihf-g++ \
AR=~/cross/install/bin/arm-linux-gnueabihf-ar \
cmake .. && make
而不是链接的可执行文件,我得到了一堆丑陋的链接器错误:
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_Deferred_state<std::_Bind_simple<main::{lambda()#1} ()>, int>::_M_complete_async()':
main.cpp:(.text+0x264): undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_notify_all(unsigned int*)'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_Deferred_state<std::_Bind_simple<main::{lambda()#1} ()>, int>::~_Deferred_state()':
main.cpp:(.text+0x2e8): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_Async_state_impl<std::_Bind_simple<main::{lambda()#1} ()>, int>::~_Async_state_impl()':
main.cpp:(.text+0x3a4): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::_Sp_counted_ptr_inplace<std::__future_base::_Deferred_state<std::_Bind_simple<main::{lambda()#1} ()>, int>, std::allocator<std::_Bind_simple<main::{lambda()#1} ()> >, (__gnu_cxx::_Lock_policy)2>::_M_dispose()':
main.cpp:(.text+0x47c): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_Deferred_state<std::_Bind_simple<main::{lambda()#1} ()>, int>::~_Deferred_state()':
main.cpp:(.text+0x528): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::_Sp_counted_ptr_inplace<std::__future_base::_Async_state_impl<std::_Bind_simple<main::{lambda()#1} ()>, int>, std::allocator<std::_Bind_simple<main::{lambda()#1} ()> >, (__gnu_cxx::_Lock_policy)2>::_M_dispose()':
main.cpp:(.text+0x5f0): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o:main.cpp:(.text+0x6d0): more undefined references to `std::__future_base::_Result_base::~_Result_base()' follow
CMakeFiles/pitest.dir/main.cpp.o: In function `std::thread::_Impl<std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<main::{lambda()#1} ()>, int>::_Async_state_impl(main::{lambda()#1} (&&)())::{lambda()#1} ()> >::_M_run()':
main.cpp:(.text+0xb8c): undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_notify_all(unsigned int*)'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_Result<int>::~_Result()':
main.cpp:(.text._ZNSt13__future_base7_ResultIiED2Ev[_ZNSt13__future_base7_ResultIiED5Ev]+0x10): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_Result<int>::~_Result()':
main.cpp:(.text._ZNSt13__future_base7_ResultIiED0Ev[_ZNSt13__future_base7_ResultIiED5Ev]+0x10): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_Result<int>::_M_destroy()':
main.cpp:(.text._ZNSt13__future_base7_ResultIiE10_M_destroyEv[_ZNSt13__future_base7_ResultIiE10_M_destroyEv]+0x30): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__exception_ptr::exception_ptr std::make_exception_ptr<std::future_error>(std::future_error)':
main.cpp:(.text._ZSt18make_exception_ptrISt12future_errorENSt15__exception_ptr13exception_ptrET_[_ZSt18make_exception_ptrISt12future_errorENSt15__exception_ptr13exception_ptrET_]+0x58): undefined reference to `std::current_exception()'
CMakeFiles/pitest.dir/main.cpp.o: In function `std::__future_base::_State_baseV2::_M_break_promise(std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>)':
main.cpp:(.text._ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE[_ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE]+0x120): undefined reference to `std::__exception_ptr::exception_ptr::swap(std::__exception_ptr::exception_ptr&)'
main.cpp:(.text._ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE[_ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE]+0x128): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
main.cpp:(.text._ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE[_ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE]+0x130): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
main.cpp:(.text._ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE[_ZNSt13__future_base13_State_baseV216_M_break_promiseESt10unique_ptrINS_12_Result_baseENS2_8_DeleterEE]+0x178): undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_notify_all(unsigned int*)'
CMakeFiles/pitest.dir/main.cpp.o: In function `main':
main.cpp:(.text.startup+0x50): undefined reference to `std::__future_base::_Result_base::_Result_base()'
main.cpp:(.text.startup+0x178): undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_wait_until(unsigned int*, unsigned int, bool, std::chrono::duration<long long, std::ratio<1ll, 1ll> >, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> >)'
main.cpp:(.text.startup+0x1b8): undefined reference to `std::__exception_ptr::operator==(std::__exception_ptr::exception_ptr const&, std::__exception_ptr::exception_ptr const&)'
main.cpp:(.text.startup+0x1c4): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
main.cpp:(.text.startup+0x2f4): undefined reference to `std::__exception_ptr::exception_ptr::exception_ptr(std::__exception_ptr::exception_ptr const&)'
main.cpp:(.text.startup+0x2fc): undefined reference to `std::rethrow_exception(std::__exception_ptr::exception_ptr)'
main.cpp:(.text.startup+0x304): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
CMakeFiles/pitest.dir/main.cpp.o:(.rodata._ZTINSt13__future_base7_ResultIiEE[_ZTINSt13__future_base7_ResultIiEE]+0x8): undefined reference to `typeinfo for std::__future_base::_Result_base'
collect2: error: ld returned 1 exit status
CMakeFiles/pitest.dir/build.make:85: recipe for target 'pitest' failed
make[2]: *** [pitest] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/pitest.dir/all' failed
make[1]: *** [CMakeFiles/pitest.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2
据我所知,这些符号应该是libstdc ++的一部分。它与GCC一起编译,GCC本身是使用上面的交叉编译器脚本构建的。
我已经静态链接了libgcc和libstdc ++;否则我会在目标设备上遇到动态符号加载问题(因为Raspbian发行版附带了旧版本的这些问题。)
完整的链接器输出(在上述错误之前)如下:
>>> /home/michael/cross/install/bin/arm-linux-gnueabihf-g++ -v -std=c++14 -static-libgcc -static-libstdc++ CMakeFiles/pitest.dir/main.cpp.o -o pitest -rdynamic
Using built-in specs.
COLLECT_GCC=/home/michael/cross/install/bin/arm-linux-gnueabihf-g++
COLLECT_LTO_WRAPPER=/home/michael/cross/install/libexec/gcc/arm-linux-gnueabihf/5.2.0/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../gcc-5.2.0/configure --prefix=/home/michael/cross/install --target=arm-linux-gnueabihf --enable-languages=c,c++ --with-float=hard --disable-multilib --disable-werror
Thread model: posix
gcc version 5.2.0 (GCC)
COMPILER_PATH=/home/michael/cross/install/libexec/gcc/arm-linux-gnueabihf/5.2.0/:/home/michael/cross/install/libexec/gcc/arm-linux-gnueabihf/5.2.0/:/home/michael/cross/install/libexec/gcc/arm-linux-gnueabihf/:/home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/:/home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/:/home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/../../../../arm-linux-gnueabihf/bin/
LIBRARY_PATH=/home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/:/home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/../../../../arm-linux-gnueabihf/lib/
COLLECT_GCC_OPTIONS='-v' '-std=c++14' '-static-libgcc' '-o' 'pitest' '-rdynamic' '-mfloat-abi=hard' '-mtls-dialect=gnu'
/home/michael/cross/install/libexec/gcc/arm-linux-gnueabihf/5.2.0/collect2 -plugin /home/michael/cross/install/libexec/gcc/arm-linux-gnueabihf/5.2.0/liblto_plugin.so -plugin-opt=/home/michael/cross/install/libexec/gcc/arm-linux-gnueabihf/5.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/cc4qImrb.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh --eh-frame-hdr -export-dynamic -dynamic-linker /lib/ld-linux-armhf.so.3 -X -m armelf_linux_eabi -o pitest /home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/../../../../arm-linux-gnueabihf/lib/crt1.o /home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/../../../../arm-linux-gnueabihf/lib/crti.o /home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/crtbegin.o -L/home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0 -L/home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/../../../../arm-linux-gnueabihf/lib CMakeFiles/pitest.dir/main.cpp.o -Bstatic -lstdc++ -Bdynamic -lm -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/crtend.o /home/michael/cross/install/lib/gcc/arm-linux-gnueabihf/5.2.0/../../../../arm-linux-gnueabihf/lib/crtn.o
我错过了什么?