xmake经验总结1:解决c++ future/promise抛出std::system_error的问题

2023-05-16

1 背景

1.1 场景

编译器gcc 9.4
运行系统Ubuntu 20.04.4 LTS
xmake: v2.6.7
场景:其大致场景是使用c++的future/promise功能,类似如下示意代码:

#include <iostream>
#include <future>

using namespace std;

int main(int argc, char** argv)
{
    std::promise<int> p;
    p.set_value(42);
    auto f = p.get_future();
    int res = f.get();
    std::cout << "future got value: " << res << std::endl;
    return 0;
}

默认xmake文件如下:

add_rules("mode.debug", "mode.release")

target("explicit_stdc++")
    set_kind("binary")
    add_files("src/*.cpp")

编译运行以及执行结果如下:

gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake
checking for platform ... linux     
checking for architecture ... x86_64
[ 25%]: ccache compiling.release src/main.cpp
[ 50%]: linking.release explicit_stdc++
[100%]: build ok!
gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake run
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1

编译出来的执行文件的链接库如下所示:

$ ldd build/linux/x86_64/release/explicit_stdc++ 
        linux-vdso.so.1 (0x00007ffe29fbd000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f26b8abf000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f26b8aa4000)  
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f26b88b2000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f26b8763000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f26b8cb4000)

网上关于这部分的信息几乎是没有,经过一番查找,然后才开始了如下尝试,并最终找到对应的解决方案。

2 问题及现象的原因

根本原因:从c++11开始的future/promise 等于多线程编程相关的标准接口在Linux下的gcc环境下,其底层实现是需要依赖pthread相关接口的,因此需要在xmake脚本中添加相应的库依赖。

3 尝试

3.1 直接添加pthread

既然是因为c++多线程编程相关功能的底层实现在Linux下的gcc环境是依赖的pthread相关接口, 而如前面所示,原始的xmake中并未显示地添加pthread库,那么直接在xmake添加pthread 库。其xmake脚本如下所示:

add_rules("mode.debug", "mode.release")

target("explicit_stdc++")
    set_kind("binary")
    add_syslinks("pthread")
    add_files("src/*.cpp")

但是从编译以及ldd的结果来看,其并未为在链接库里面新增pthread库,并且运行仍然会出错。

gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ cat xmake.lua 
add_rules("mode.debug", "mode.release")

target("explicit_stdc++")
    set_kind("binary")
    add_syslinks("pthread")
    add_files("src/*.cpp")


gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake
[ 25%]: ccache compiling.release src/main.cpp
[ 50%]: linking.release explicit_stdc++
[100%]: build ok!

.../xmake_test/explicit_stdc++$ ldd build/linux/x86_64/release/explicit_stdc++
        linux-vdso.so.1 (0x00007fff7d3b0000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8d9e680000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8d9e665000)  
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8d9e473000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8d9e324000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8d9e875000)
gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake run
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1

3.2 更改ld

对于这个问题,一开始笔者也是百思不得其解,折腾了半天,无奈之下,尝试将xmake的构建过程显示出来看看到底是什么情况:

gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake -vvv
[ 25%]: ccache compiling.release src/main.cpp
/usr/bin/gcc -c -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -o build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o src/main.cpp
[ 50%]: linking.release explicit_stdc++
/usr/bin/g++ -o build/linux/x86_64/release/explicit_stdc++ build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o -m64 -s -lpthread
[100%]: build ok!

如上,所示,其是使用g++作为“ld” 进行链接的,且在链接的参数中已经有显示地添加 -lpthread。

于是想到的另一个尝试就是修改ld,使用gcc作为链接器。xmake的资料相对来说还是太少了, 查找了一下,可以如下方式指定ld:

gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake f --ld=gcc
checking for platform ... linux     
checking for architecture ... x86_64
gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake -vvvv
checking for gcc ... /usr/bin/gcc
checking for the c++ compiler (cxx) ... gcc
checking for /usr/bin/gcc ... ok
checking for flags (-fPIC) ... ok
checking for flags (-fvisibility-inlines-hidden) ... ok
checking for flags (-O3) ... ok
checking for flags (-DNDEBUG) ... ok
[ 25%]: ccache compiling.release src/main.cpp
/usr/bin/gcc -c -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -o build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o src/main.cpp
checking for flags (-MMD -MF) ... ok
checking for flags (-fdiagnostics-color=always) ... ok
checking for flags (-fPIC) ... ok
[ 50%]: linking.release explicit_stdc++
gcc -o build/linux/x86_64/release/explicit_stdc++ build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o -m64 -s -lpthread
error: /usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::{lambda()#2}::_FUN()':
main.cpp:(.text._ZZSt9call_onceIMNSt13__future_base13_State_baseV2EFvPSt8functionIFSt10unique_ptrINS0_12_Result_baseENS4_8_DeleterEEvEEPbEJPS1_S9_SA_EEvRSt9once_flagOT_DpOT0_ENUlvE0_4_FUNEv[_ZZSt9call_onceIMNSt13__future_base13_State_baseV2EFvPSt8functionIFSt10unique_ptrINS0_12_Result_baseENS4_8_DeleterEEvEEPbEJPS1_S9_SA_EEvRSt9once_flagOT_DpOT0_ENUlvE0_4_FUNEv]+0x7): undefined reference to `std::__once_callable'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::__future_base::_State_baseV2::~_State_baseV2()':
main.cpp:(.text._ZNSt13__future_base13_State_baseV2D0Ev[_ZNSt13__future_base13_State_baseV2D5Ev]+0x2a): undefined reference to `operator delete(void*, unsigned long)'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2>::~_Sp_counted_ptr_inplace()':     
main.cpp:(.text._ZNSt23_Sp_counted_ptr_inplaceINSt13__future_base13_State_baseV2ESaIS1_ELN9__gnu_cxx12_Lock_policyE2EED0Ev[_ZNSt23_Sp_counted_ptr_inplaceINSt13__future_base13_State_baseV2ESaIS1_ELN9__gnu_cxx12_Lock_policyE2EED5Ev]+0xa): undefined reference to `operator delete(void*, unsigned long)'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::__future_base::_Result<int>::~_Result()':
main.cpp:(.text._ZNSt13__future_base7_ResultIiED2Ev[_ZNSt13__future_base7_ResultIiED5Ev]+0xf): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::__future_base::_Result<int>::~_Result()':
main.cpp:(.text._ZNSt13__future_base7_ResultIiED0Ev[_ZNSt13__future_base7_ResultIiED5Ev]+0x13): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
/usr/bin/ld: main.cpp:(.text._ZNSt13__future_base7_ResultIiED0Ev[_ZNSt13__future_base7_ResultIiED5Ev]+0x21): undefined reference to `operator delete(void*, unsigned long)'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2>::_M_destroy()':
main.cpp:(.text._ZNSt23_Sp_counted_ptr_inplaceINSt13__future_base13_State_baseV2ESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv[_ZNSt23_Sp_counted_ptr_inplaceINSt13__future_base13_State_baseV2ESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv]+0x5): undefined reference to `operator delete(void*)'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)':
main.cpp:(.text._ZNSt13__future_base13_State_baseV29_M_do_setEPSt8functionIFSt10unique_ptrINS_12_Result_baseENS3_8_DeleterEEvEEPb[_ZNSt13__future_base13_State_baseV29_M_do_setEPSt8functionIFSt10unique_ptrINS_12_Result_baseENS3_8_DeleterEEvEEPb]+0x63): undefined reference to `std::__throw_bad_function_call()'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/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]+0x26): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
/usr/bin/ld: main.cpp:(.text._ZNSt13__future_base7_ResultIiE10_M_destroyEv[_ZNSt13__future_base7_ResultIiE10_M_destroyEv]+0x34): undefined reference to `operator delete(void*, unsigned long)'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::promise<int>::~promise()':
main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x5f): undefined reference to `std::future_category()'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x91): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0xe3): undefined reference to `std::logic_error::logic_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0xf2): undefined reference to `operator delete(void*)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x106): undefined reference to `operator delete(void*)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x10d): undefined reference to `vtable for std::future_error'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x129): undefined reference to `__cxa_allocate_exception'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x137): undefined reference to `typeinfo for std::future_error'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x142): undefined reference to `__cxa_init_primary_exception'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x14d): undefined reference to `std::logic_error::logic_error(std::logic_error const&)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x170): undefined reference to `std::__exception_ptr::exception_ptr::exception_ptr(void*)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x18d): undefined reference to `std::__exception_ptr::exception_ptr::swap(std::__exception_ptr::exception_ptr&)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x195): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x19d): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x1a5): undefined reference to `std::future_error::~future_error()'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x215): undefined reference to `std::__future_base::_Result_base::~_Result_base()'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x222): undefined reference to `operator delete(void*, unsigned long)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x301): undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_notify_all(unsigned int*)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x324): undefined reference to `operator delete(void*)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x338): undefined reference to `operator delete(void*)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiED2Ev[_ZNSt7promiseIiED5Ev]+0x33d): undefined reference to `std::terminate()'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `std::promise<int>::set_value(int&&)':
main.cpp:(.text._ZNSt7promiseIiE9set_valueEOi[_ZNSt7promiseIiE9set_valueEOi]+0xe2): undefined reference to `std::__once_callable'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiE9set_valueEOi[_ZNSt7promiseIiE9set_valueEOi]+0xf6): undefined reference to `std::__once_call'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiE9set_valueEOi[_ZNSt7promiseIiE9set_valueEOi]+0x103): undefined reference to `__once_proxy'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiE9set_valueEOi[_ZNSt7promiseIiE9set_valueEOi]+0x11d): undefined reference to `std::__throw_future_error(int)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiE9set_valueEOi[_ZNSt7promiseIiE9set_valueEOi]+0x171): undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_notify_all(unsigned int*)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiE9set_valueEOi[_ZNSt7promiseIiE9set_valueEOi]+0x17f): undefined reference to `std::__throw_system_error(int)'
/usr/bin/ld: main.cpp:(.text._ZNSt7promiseIiE9set_valueEOi[_ZNSt7promiseIiE9set_valueEOi]+0x189): undefined reference to `std::__throw_future_error(int)'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `main.cold':
main.cpp:(.text.unlikely+0x4): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `main':
main.cpp:(.text.startup+0x31): undefined reference to `operator new(unsigned long)'
/usr/bin/ld: main.cpp:(.text.startup+0x86): undefined reference to `operator new(unsigned long)'
/usr/bin/ld: main.cpp:(.text.startup+0x9b): undefined reference to `std::__future_base::_Result_base::_Result_base()'
/usr/bin/ld: main.cpp:(.text.startup+0x142): undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_wait_until(unsigned int*, unsigned int, bool, std::chrono::duration<long, std::ratio<1l, 1l> >, std::chrono::duration<long, std::ratio<1l, 1000000000l> >)'/usr/bin/ld: main.cpp:(.text.startup+0x16e): undefined reference to `std::__exception_ptr::operator==(std::__exception_ptr::exception_ptr const&, std::__exception_ptr::exception_ptr const&)'
/usr/bin/ld: main.cpp:(.text.startup+0x178): undefined reference to `std::__exception_ptr::exception_ptr::~exception_ptr()'
/usr/bin/ld: main.cpp:(.text.startup+0x1b6): undefined reference to `std::cout'
/usr/bin/ld: main.cpp:(.text.startup+0x1bb): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)'
/usr/bin/ld: main.cpp:(.text.startup+0x1c5): undefined reference to `std::cout'
/usr/bin/ld: main.cpp:(.text.startup+0x1ca): undefined reference to `std::ostream::operator<<(int)'
/usr/bin/ld: main.cpp:(.text.startup+0x1d2): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
/usr/bin/ld: main.cpp:(.text.startup+0x253): undefined reference to `std::__throw_future_error(int)'
/usr/bin/ld: main.cpp:(.text.startup+0x262): undefined reference to `std::__throw_future_error(int)'
/usr/bin/ld: main.cpp:(.text.startup+0x26d): undefined reference to `std::__exception_ptr::exception_ptr::exception_ptr(std::__exception_ptr::exception_ptr const&)'
/usr/bin/ld: main.cpp:(.text.startup+0x275): undefined reference to `std::rethrow_exception(std::__exception_ptr::exception_ptr)'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o: in function `_GLOBAL__sub_I_main':
main.cpp:(.text.startup+0x2d0): undefined reference to `std::ios_base::Init::Init()'
/usr/bin/ld: main.cpp:(.text.startup+0x2d7): undefined reference to `std::ios_base::Init::~Init()'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.ro._ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE[_ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'   
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.ro._ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE[_ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.ro._ZTINSt13__future_base13_State_baseV2E[_ZTINSt13__future_base13_State_baseV2E]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.ro._ZTINSt13__future_base7_ResultIiEE[_ZTINSt13__future_base7_ResultIiEE]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.ro._ZTINSt13__future_base7_ResultIiEE[_ZTINSt13__future_base7_ResultIiEE]+0x10): undefined reference to `typeinfo for std::__future_base::_Result_base'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.ro._ZTINSt13__future_base13_State_baseV27_SetterIiOiEE[_ZTINSt13__future_base13_State_baseV27_SetterIiOiEE]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info' 
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.ro._ZTISt23_Sp_counted_ptr_inplaceINSt13__future_base13_State_baseV2ESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE[_ZTISt23_Sp_counted_ptr_inplaceINSt13__future_base13_State_baseV2ESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/usr/bin/ld: build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o:(.data.rel.local.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status

其结果如上,其根本原因是,使用gcc作为链接器,它不会默认链接c++的标准库,因此需要显示在xmake中添加,如下所示:

add_rules("mode.debug", "mode.release")

target("explicit_stdc++")
    set_kind("binary")
    add_syslinks("stdc++", "pthread")
    add_files("src/*.cpp")

其编译和运行结果,如下所示:

gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake -vvvv
checking for gcc ... /usr/bin/gcc
checking for dmd ... no
checking for ldc2 ... no
checking for gdc ... no
checking for zig ... no
checking for zig ... no
checking for gcc ... /usr/bin/gcc
checking for the c++ compiler (cxx) ... gcc
checking for /usr/bin/gcc ... ok
checking for flags (-fPIC) ... ok
checking for flags (-fvisibility-inlines-hidden) ... ok
checking for flags (-O3) ... ok
checking for flags (-DNDEBUG) ... ok
[ 25%]: ccache compiling.release src/main.cpp
/usr/bin/gcc -c -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -o build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o src/main.cpp
checking for flags (-MMD -MF) ... ok
checking for flags (-fdiagnostics-color=always) ... ok
checking for flags (-fPIC) ... ok
[ 50%]: linking.release explicit_stdc++
gcc -o build/linux/x86_64/release/explicit_stdc++ build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o -m64 -s -lstdc++ -lpthread
[100%]: build ok!
gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake run
future got value: 42

如上所示,已经解决了此问题,可以程序可以正常运行了。

Note: 此种解决方案有两个问题

  1. 需要显示地更改ld,构建过程多了xmake f xxx 这样的配置过程
  2. 不同操作系统或者运行环境,使用的c++标准库可能会有不同,因此添加的“stdc++”标准可可能需要根据情况进行灵活变更

3.3 只需显示添加sdc++库

虽然根据3.2节可以解决问题,但感觉还是有些复杂。于是乎做了一番尝试,发现其实只需要显示地添加stdc++标准库,即使使用默认的g++作为链接器,也可以正常的编译和运行。如下所示:

gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake -vvvv
checking for platform ... linux     
checking for architecture ... x86_64
checking for gcc ... /usr/bin/gcc
checking for dmd ... no
checking for ldc2 ... no
checking for gdc ... no
checking for zig ... no
checking for zig ... no
checking for gcc ... /usr/bin/gcc
checking for the c++ compiler (cxx) ... gcc
checking for /usr/bin/gcc ... ok
checking for flags (-fPIC) ... ok
checking for flags (-fvisibility-inlines-hidden) ... ok
checking for flags (-O3) ... ok
checking for flags (-DNDEBUG) ... ok
[ 25%]: ccache compiling.release src/main.cpp
/usr/bin/gcc -c -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -o build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o src/main.cpp
checking for flags (-MMD -MF) ... ok
checking for flags (-fdiagnostics-color=always) ... ok
checking for g++ ... /usr/bin/g++
checking for the linker (ld) ... g++
checking for /usr/bin/g++ ... ok    
checking for flags (-fPIC) ... ok
[ 50%]: linking.release explicit_stdc++
/usr/bin/g++ -o build/linux/x86_64/release/explicit_stdc++ build/.objs/explicit_stdc++/linux/x86_64/release/src/main.cpp.o -m64 -s -lstdc++ -lpthread
[100%]: build ok!
gw123@DESKTOP-KJUN5HL:~/workspace/temp/xmake_test/explicit_stdc++$ xmake run
future got value: 42

至此,问题解决,笔者最终也是选择的最后这种方案,只需显示地添加stdc++库和pthread库即可。 至于这其中的根本原因,笔者目前还不胜了解[捂脸]。 有知道其根本原因的大牛也希望能不吝赐教[抱拳]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

xmake经验总结1:解决c++ future/promise抛出std::system_error的问题 的相关文章

  • Gazebo仿真

    在ROS中有3个可以模拟机器人的模拟器软件 xff1a Gazebo Stage ArbotiX 就是RVIz 你可以任选一个 xff1a Gazebo是一个仿真环境 xff08 平台 xff09 xff0c 可以进行三维机器人动力学仿真等
  • [小插曲]VC学习——基于MFC的模拟时钟程序

    一 程序窗口设计步骤 xff08 1 xff09 用AppWizard生成一个名为Clock的单文档 xff08 SDI xff09 程序框架 为了简化应用程序 xff0c 在第四步时去掉Docking toolbar和Initial st
  • gazebo官网例程

    首先官网下载代码https github com ros simulation gazebo ros demos 1 创建编译工作空间 cd catkin ws src git clone https github com ros simu
  • ROS action

    Actionlib是ROS非常重要的库 xff0c 像执行各种运动的动作 xff0c 例如控制手臂去抓取一个杯子 xff0c 这个过程可能复杂而漫长 xff0c 执行过程中还可能强制中断或反馈信息 xff0c 这时Actionlib就能大展
  • opencv3 特征检测与匹配及寻找目标

    1 算法 xff1a surf特征提取算法 SURF算法是著名的尺度不变特征检测器SIFT Scale Invariant Features Transform 的高效变种 xff0c 它为每个检测到的特征定义了位置和尺度 xff0c 其中
  • 论文笔记:Beyond a Pre-Trained Object Detector:Cross-Modal Textual and Visual Context for Image Caption

    前言 这篇论文是CVPR2022的一篇文章 xff0c 代码也已经开源 这博客主要分享自己的一些理解 xff0c 详情可以去阅读原文 论文思想 这篇论文首先提出了一个问题是当前的大多数图像描述模型主要依赖预训练的图像特征和一个固定的目标检测
  • Stm32定时器中断触发AD采样

    Stm32的ADC有DMA功能这都毋庸置疑 xff0c 也是我们用的最多的 xff01 然而 xff0c 如果我们要对一个信号 xff08 比如脉搏信号 xff09 进行定时采样 xff08 也就是隔一段时间 xff0c 比如说2ms 有三
  • permission denied (publickey)问题的解决

    使用ssh key这种方式进行clone xff0c pull github上面的项目 xff0c 使用 git clone或者git pull origin master出现permission denied publickey xff0
  • 【图像识别与处理】ros下使用realsense d435获取点云

    realsense驱动安装见上篇博文 1 通过源码安装intel RealSense ROS 1 创建catkin工作空间 mkdir p catkin ws src cd catkin ws src 2 将下载的源码复制到 catkin
  • 【图像识别与处理】构建用于垃圾分类的图像分类器

    1 构建图像分类器 训练一个卷积神经网络 xff0c 用fastai库 xff08 建在PyTorch上 xff09 将图像分类为纸板 xff0c 玻璃 xff0c 金属 xff0c 纸张 xff0c 塑料或垃圾 使用了由Gary Thun
  • kitti数据集各个榜单介绍

    kitti数据集网站 下面我们分别介绍下KITTI的几项benchmark Stereo Stereo Evaluation xff08 立体评估 xff09 基于图像的立体视觉和3维重建 xff0c 从一个图像中恢复结构本质上是模糊的 x
  • 解决ubuntu20.04虚拟机无法上网的问题

    64 linux虚拟机无法正常上网 前言 刚建立好的linux虚拟机使用NAT方式可以连接外网 xff0c 系统重启几次 xff0c 系统无法上网 xff0c 这是什么问题导致的呢 xff1f 提示 xff1a 以下是本篇文章正文内容 xf
  • [Linux] 使用vim保存文件时报E45错误

    今天在使用vim为Linux系统设置静态IP时 xff0c 报了E45错误 xff1a 环境说明 系统 xff1a Ubuntu18 04 操作步骤 1 打开到静态IP配置文件 打开到netplan目录 cd etc netplan amp
  • 【C++】类和对象-继承

    目录 一 继承基本方式 1 公 共 继 承 2 保 护 继 承 3 私 有 继 承 二 继承中的对象模型 三 继承中的构造和析构顺序 四 继承中同名成员处理方式 1 成员变量的处理方式 2 成员函数的处理方式 五 继承同名静态成员处理方式
  • Pytorch param.grad.data. 出现 AttributeError: ‘NoneType‘ object has no attribute ‘data‘

    程序中有需要优化的参数未参与前向传播
  • 大白话谈谈ChatGPT:多点人工,多点智能

    对于NLP领域 xff0c 本人也是门外汉 xff0c 就是最近了看到的博文 xff0c 记录自己的一些体会 ChatGPT简介 ChatGPT的全称是 34 Conversational Generative Pre training T
  • GO如何查看变量大小和数据类型

    如何查看一个变量的大小和数据类型 如何查看一个变量的大小和数据类型 paceage main import 34 fmt 34 34 unsafe 34 var n2 int64 61 10 fmt Printf 34 n2的类型 T n2
  • GO语言百分号参数

    常用 参数 v 值的默认格式 T 值得类型的GO语法表示 t 单词true或者false b 表示为二进制 c 该值对应的unicode码值 d 表示十进制 o 表示八进制 f 有小数部分但无指数部分 q 双引号输出
  • java第八节-重复执行

    import java util Scanner public class hello public static void main String args for System out println 34 hello 34 impor
  • java基础第九节-跳转控制语句-数组

    continue用在循环中 xff0c 基于条件控制 xff0c 跳过某次循环体内容的执行 xff0c 继续下一次的执行 break用在循环中 xff0c 基于条件控制 xff0c 终止循环体内容的执行 xff0c 结束当前的整个循环 数组

随机推荐

  • JAVA基础-基本类型转换

    int 和string的相互转换 1 int转换String public static String valuesOf int i 返回int参数的字符串表示形式 xff0c 该方法是String类的方法 1 String转换int pu
  • ubuntu系统-查看系统版本信息

    cat etc issue
  • Ubuntu查看cpu使用情况

    top命令查看cpu等信息 id是 xff1a 空闲 CPU 占用的 CPU 百分比
  • Ubuntu系统查看内存信息

    free命令查看内存信息 h 选项会在数字后面加上适于可读的单位 free h total xff1a 总物理内存大小 used xff1a 内存使用量 free xff1a 剩余可用内存
  • 嘉立创打样的阻抗匹配

    一 适用条件 最好使用4层板以上 xff0c 2层做匹配没啥意义 xff0c 套用大佬的话 主要是中间层和表层的距离近 xff0c 表层和中间层的玻璃纤维厚度是0 2mm xff0c 双层板最少是0 6mm xff0c 这里的差距很大 xf
  • echo 命令总结

    echo命令的功能是在显示器上显示一段文字 xff0c 一般起到一个提示的作用 此外 xff0c 也可以直接在文件中写入要写的内容 也可以用于脚本编程时显示某一个变量的值 xff0c 或者直接输出指定的字符串 echo命令的语法是 xff1
  • Android音频子系统(十三)------audio音频测试工具

    你好 xff01 这里是风筝的博客 xff0c 欢迎和我一起交流 测试音频延时的话 xff0c 一般使用WALT来测试是最为准确的 xff0c 他是借助了外部硬件来捕获音频信号 xff0c 某宝上有卖 xff1a 就是有丢丢小贵 xff0c
  • 一位北邮信通硕士的求职历程,看看 或许有帮助

    序 xff1a 写在前面的话 这篇文章的适用对象为 xff1a 非技术类方向的同学 xff0c 如果你是技术大牛 xff0c 你可以跳过这篇文章了 如果你觉得自己不喜欢技术或者技术不适合你 xff0c 此文或许会给你些有用的东西 简单介绍一
  • [转]STM32 串口传输处理方式 FreeRTOS+队列+DMA+IDLE (二)

    紧接着上一篇文章 xff0c 如何合理处理多个串口接收大量数据 此种方法 xff0c 很厉害 xff0c 很NB xff0c 首先 xff0c 利用DMA 可节省大量CUP资源 其次 xff0c 利用IDLE空闲中断来接收位置个数的数据 最
  • [转]FreeRTOS消息队列、信号量、事件标志组、任务通知

    功能及区别列表 消息队列 xff08 需要传递消息时使用 xff09 在任务与任务间 中断和任务间传递信息 xff0c 可以数据传输 事件标志组 xff08 多个事件同步 xff0c 不需要传递消息时使用 xff09 实现任务与任务间 中断
  • ubuntu 终端打不开解决办法

    由于ubuntu自带的是python3 5 在新安装了python3 6以后 xff0c 开机突然发现无论是点击图标还是使用快捷键终端都无法打开 xff0c 解决办法如下 xff1a xff11 xff0e 按Ctrl 43 Alt 43
  • Jack server already installed in "/***/.jack-server" 异常

    xff08 1 xff09 在新增新用户后 xff0c 进行android编译 xff0c 出现如下异常 xff1a Ensure Jack server is installed and started FAILED bin bash c
  • gstreamer移植qnx(二):交叉编译glib

    一 简介 这里以glib的2 63 0版本 xff0c QNX系统的版本是 xff1a 6 6 这里是为了编译gstreamer的依赖库 xff0c 也就是说最终目标 xff0c 是将gstreamer移植到QNX6 6系统上 我选择的是g
  • repo安装与简单使用

    一 概述 当一个大的项目需要拆分成很多的子项目 xff0c 或者说一个软件系统拆分成多个子系统 每一个子项目或者子系统都对应一个git repository 这种需求在实际项目当中是很常见的 xff0c 有的可能就直接写一个shell脚本来
  • 通过qemu-img命令将raw image转换成VMware虚拟硬盘vmdk

    为了在VMware中跑QNX系统 xff0c 我需要想办法将编译BSP生成的img文件固化到VMware的虚拟硬盘中去 xff0c 之前一直找不到方法 xff0c 到渐渐的只能用很笨的方法几次中专 将生成的img文件通过win32DiskI
  • WSL2 Ubuntu安装Qt(包括QtCreator)

    最近因为需要在Linux下使用qtcreator做一些界面开发的预研和学习 xff0c 主要是因为要交叉编译Qt 但又不想再使用虚拟机了 xff0c 真的太消耗内存了 于是就想着直接使用Windows10 下面的WSL2 怎么安装WSL2这
  • 架构师成长之路工具篇(1):markdown撰写文档

    今天笔者想说的工具就是markdown xff0c 正所谓工欲善其事必先利其器 xff0c 选择高效的工具自然能提升工作效率 笔者使用的markdown工具是 xff1a typora word太重 xff0c 太复杂 xff0c 在写文档
  • Artifact xxxx:Web exploded: Error during artifact deployment. See server log........

    从Git上拉取了一个新项目到idea xff0c 结果一运行就报错 xff0c 错误下图 看大家的解决方法基本都是重新部署Tomcat Maven或者项目 xff0c 还有什么jar包冲突要删除的 xff0c 齐齐试了一遍 xff0c 并没
  • 如何优雅的退出qemu虚拟环境

    在console环境下 xff0c 先 按 ctrl 43 a xff0c 释放之后再按 x 键 既可terminate qemu 注 xff1a 1 a 和 x 均为小写 2 必须先释放ctrl 43 a 之后 再按x键
  • xmake经验总结1:解决c++ future/promise抛出std::system_error的问题

    1 背景 1 1 场景 编译器 xff1a gcc 9 4 运行系统 xff1a Ubuntu 20 04 4 LTS xmake v2 6 7 场景 xff1a 其大致场景是使用c 43 43 的future promise功能 xff0