首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >libc++ coroutine的suspend_always::await_suspend应该被“输出”到c++experimental.lib吗?

libc++ coroutine的suspend_always::await_suspend应该被“输出”到c++experimental.lib吗?
EN

Stack Overflow用户
提问于 2019-04-16 08:52:42
回答 1查看 490关注 0票数 0

在针对我构建的libc++编译coroutine时,我得到了这个错误

代码语言:javascript
复制
"C:\\Program Files\\LLVM\\bin\\lld-link" ... c++.lib c++experimental.lib ...
lld-link: error: undefined symbol: __declspec(dllimport) public: void __cdecl std::experimental::coroutines_v1::suspend_always::await_suspend(class std::experimental::coroutines_v1::coroutine_handle<void>) const

在此之前,我使用libc++ -DLIBCXX_ENABLE_SHARED=YES -DLIBCXX_ENABLE_STATIC=NO -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=YES构建了

代码语言:javascript
复制
set LIB=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.20.27508\lib\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\um\x64
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM="C:/Program Files (x86)/Ninja/ninja.exe" -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER="C:/Program Files/LLVM/bin/clang-cl.exe" -DCMAKE_C_FLAGS="-fms-compatibility-version=19.20.27508 --target=x86_64-pc-windows-msvc19.20.27508" -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang-cl.exe" -DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.20.27508 --target=x86_64-pc-windows-msvc19.20.27508" -DCMAKE_C_LINK_EXECUTABLE="C:/Program Files/LLVM/bin/lld-link.exe" -DCMAKE_CXX_LINK_EXECUTABLE="C:/Program Files/LLVM/bin/lld-link.exe" -DLLVM_PATH="C:/Program Files/LLVM" -DLIBCXX_ENABLE_SHARED=YES -DLIBCXX_ENABLE_STATIC=NO -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=YES "C:/libcxx-master"
ninja -j 2

所以我尝试了nm c++.libnm c++experimental.lib。我没有发现suspend_always的踪迹。

在dll中似乎缺少suspend_always::await_suspend。因此,我深入研究了一些c++宏。

C:/libcxx-master/CMakeLists.txt中,定义了_LIBCPP_BUILDING_LIBRARY

代码语言:javascript
复制
add_definitions(-D_LIBCPP_BUILDING_LIBRARY)

C:/libcxx-master/include/__config,我们有

代码语言:javascript
复制
#if defined(__ELF__)
#  define _LIBCPP_OBJECT_FORMAT_ELF   1
#elif defined(__MACH__)
#  define _LIBCPP_OBJECT_FORMAT_MACHO 1
#elif defined(_WIN32)
#  define _LIBCPP_OBJECT_FORMAT_COFF  1
#elif defined(__wasm__)
#  define _LIBCPP_OBJECT_FORMAT_WASM  1
#else
#  error Unknown object file format
#endif

我在_WIN32所以我们有_LIBCPP_OBJECT_FORMAT_COFF well defined

再往下看,我们

代码语言:javascript
复制
#if defined(_LIBCPP_OBJECT_FORMAT_COFF)

#ifdef _DLL
#  define _LIBCPP_CRT_FUNC __declspec(dllimport)
#else
#  define _LIBCPP_CRT_FUNC
#endif

#if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
#  define _LIBCPP_DLL_VIS
#  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
#  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
#  define _LIBCPP_OVERRIDABLE_FUNC_VIS
#  define _LIBCPP_EXPORTED_FROM_ABI
#elif defined(_LIBCPP_BUILDING_LIBRARY)
#  define _LIBCPP_DLL_VIS __declspec(dllexport)
#  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS
#  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS
#  define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS
#  define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport)
#else
#  define _LIBCPP_DLL_VIS __declspec(dllimport)
#  define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS
#  define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
#  define _LIBCPP_OVERRIDABLE_FUNC_VIS
#  define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport)
#endif

#define _LIBCPP_TYPE_VIS            _LIBCPP_DLL_VIS
#define _LIBCPP_FUNC_VIS            _LIBCPP_DLL_VIS
#define _LIBCPP_EXCEPTION_ABI       _LIBCPP_DLL_VIS
#define _LIBCPP_HIDDEN
#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
#define _LIBCPP_TEMPLATE_VIS
#define _LIBCPP_ENUM_VIS

#endif // defined(_LIBCPP_OBJECT_FORMAT_COFF)

这意味着当我们构建libc++时,_LIBCPP_TYPE_VIS变成了__declspec(dllexport)。这样我们就可以将具体类型导出到DLL。

当我们编译代码时,_LIBCPP_TYPE_VIS变成了__declspec(dllimport)。所以我们可以从DLL中导入具体类型。

experimental/coroutine文件包括experimental/__config,其中包含__config并包含此struct suspend_always定义。

代码语言:javascript
复制
struct _LIBCPP_TYPE_VIS suspend_always {
  _LIBCPP_INLINE_VISIBILITY
  bool await_ready() const _NOEXCEPT { return false; }
  _LIBCPP_INLINE_VISIBILITY
  void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
  _LIBCPP_INLINE_VISIBILITY
  void await_resume() const _NOEXCEPT {}
};

因此,当我们构建libc++时,我们就有了struct __declspec(dllexport) suspend_always。当我们编译时,我们有struct __declspec(dllimport) suspend_always

我甚至在构建struct __declspec(dllexport) suspend_always时尝试过硬编码libc++,结果仍然一样。

然后我想到了一个主意。我创建了libcxx-master/src/experimental/coroutine并使其成为#include <experimental/coroutine>。重新构建libc++.dll,这一次的效果很好。

我的问题是struct suspend_always (和suspend_never)是否真的是应该输出到c++experimental.lib

我在哪里可以向实现者报告这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-17 04:29:55

好像是个虫子。它应该用r358551来修复。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55704187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档