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的问题 的相关文章

随机推荐

  • python在windows下获取cpu、硬盘、bios、主板序列号

    此处使用的是wmi库 xff0c 可以去google里面搜索 python wmi import os sys import time import wmi zlib def get cpu info tmpdict 61 tmpdict
  • gcc中调试代码常用的宏

    红色是比较常用的 宏 意义 FILE 本文件名 LINE 本行位于该文件的第几行 FUNCTION 函数名 PRETTY FUNCTION c语言中和同上 xff0c C 43 43 中稍有区别 VA ARGS 格式化输出 VA ARGS
  • Qt基础学习(5)-----抽屉效果之QToolBox

    cpp view plain copy print mydialog h ifndef MYDIALOG H define MYDIALOG H include lt QDialog gt class QToolBox class MyDi
  • linux下c语言抓包库libpcap

    安装命令 xff1a sudo apt get install libpcap dev 由于自己还没仔细研究过 xff0c 暂时也只是想在这里留个记录 xff0c 方便以后需要时使用 下面是百度百科里的例子 include lt pcap
  • scons简易手册

    在编译大程序时免不了要写个makefile来管理 xff0c 但是makefile的规则对于大多数人来说都还太复杂了 于是我找到了autotools工具 xff0c 尽管方便了一些 xff0c 但是还是不够傻瓜 目前scons是我用过最傻瓜
  • Round-Robin负载均衡算法及其实现原理

    第一次在pjsip协议栈中了解到这个实习负载均衡的机制 于是网上查了下资料 xff0c 下面的介绍应该可以很容易理解 轮询调度算法 Round Robin Scheduling 轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服
  • tipc协议详解

    TIPC协议和实现解析 1 TIPC简介TIPC是爱立信公司提出的一种透明进程间通信协议 主要适用于高可用 HAL 和动态集群环境 该软件当前主要由风河 windriver 公司在维护 主要支持Linux Solaris 和 VxWorks
  • python循环方法总结

    1 for循环 语法 xff1a for x in range xff08 100 xff09 补充 xff1a rang xff08 100 xff09 xff1a 数据范围0 99 range xff08 1 xff0c 100 xff
  • Ftp 线程池方式 解决多线程问题

    FTP 线程池 方式 解决多线程问题 1 pom xml中添加依赖 lt ftp gt lt dependency gt lt groupId gt commons net lt groupId gt lt artifactId gt co
  • cannot connect to X server localhost:10.0

    使用SSH连接服务器时 xff0c 打开图形界面 xff0c 若报错 xff1a cannot connect to X server localhost 10 0 可以通过如下设置 xff0c 显示图形界面 xff1a export DI
  • 【VPS + ORB-SLAM2】多人使用手机协同操作调研思考

    1 ORB SLAM3 43 深度学习开源调研 ORB SLAM3 with Docker xff1a https github com petrikvladimir orbslam3 docker 特点 xff1a ORB SLAM3 w
  • 最极致Windows仿Mac2.0【win11可用】——30分钟完成(W001)

    本文原创 禁止转载 2021年12月26日2 0 更新兼容性及bug修复 加图 2022年6月 更改邮箱 2022年12月 投放下载链接 2023年4月16日 更新链接 添加联系方式 喜欢的点个赞再拿走啊啊啊 不看消息 有问题加QQ群 群号
  • 简单介绍阿里内部工具——Arthas

    在阿里巴巴内部 xff0c 有很多自研工具供开发者使用 xff0c 其中有一款工具 xff0c 是几乎每个Java开发都使用过的工具 xff0c 那就是Arthas xff0c 这是一款Java诊断工具 xff0c 是一款牛逼带闪电的工具
  • 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 在写文档
  • 如何优雅的退出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