[英]Is libc++ coroutine's suspend_always::await_suspend supposed to be “exported” to c++experimental.lib?
I've got this error when compile coroutine against libc++ that I built 针对我构建的libc ++编译协程时出现此错误
"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
Before that, I've built libc++ using -DLIBCXX_ENABLE_SHARED=YES
-DLIBCXX_ENABLE_STATIC=NO
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=YES
在此之前,我已经使用-DLIBCXX_ENABLE_SHARED=YES
-DLIBCXX_ENABLE_STATIC=NO
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=YES
构建了libc ++
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
So I tried nm c++.lib
and nm c++experimental.lib
. 所以我尝试了nm c++.lib
和nm c++experimental.lib
。 I found no trace of suspend_always
. 我没有发现suspend_always
。
It seems suspend_always::await_suspend
is missing in the dll. dll中似乎缺少suspend_always::await_suspend
。 So I delve in some c++ macro. 因此,我研究了一些c ++宏。
In C:/libcxx-master/CMakeLists.txt
, there is _LIBCPP_BUILDING_LIBRARY
defined. 在C:/libcxx-master/CMakeLists.txt
,定义了_LIBCPP_BUILDING_LIBRARY
。
add_definitions(-D_LIBCPP_BUILDING_LIBRARY)
In C:/libcxx-master/include/__config
, we have 在C:/libcxx-master/include/__config
,我们有
#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
I'm in _WIN32
so we have _LIBCPP_OBJECT_FORMAT_COFF
well defined
. 我在_WIN32
所以我们_LIBCPP_OBJECT_FORMAT_COFF
很好defined
。
Further downward, we have 进一步向下,我们有
#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)
This means when we are building libc++, _LIBCPP_TYPE_VIS
becomes __declspec(dllexport)
. 这意味着当我们构建libc ++时, _LIBCPP_TYPE_VIS
变为__declspec(dllexport)
。 So we can export concrete types to DLL 因此我们可以将具体类型导出到DLL
When we compile code, _LIBCPP_TYPE_VIS
becomes __declspec(dllimport)
. 当我们编译代码时, _LIBCPP_TYPE_VIS
变成__declspec(dllimport)
。 So we can import concrete types from DLL 因此我们可以从DLL导入具体类型
And experimental/coroutine
file includes experimental/__config
which includes __config
and contains this struct suspend_always
definition 而且experimental/coroutine
文件包括experimental/__config
,其中包括__config
并包含此struct suspend_always
定义
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 {}
};
So when we build libc++, we have struct __declspec(dllexport) suspend_always
. 因此,当我们构建libc ++时,我们就有了struct __declspec(dllexport) suspend_always
。 When we compile, we have struct __declspec(dllimport) suspend_always
编译时,我们具有struct __declspec(dllimport) suspend_always
I even tried hardcoding struct __declspec(dllexport) suspend_always
when building libc++
, the result is still the same. 在构建libc++
,我什至尝试对struct __declspec(dllexport) suspend_always
硬编码,结果仍然相同。
Then I came across an idea. 然后我想到了一个主意。 I create libcxx-master/src/experimental/coroutine
and just make it #include <experimental/coroutine>
. 我创建了libcxx-master/src/experimental/coroutine
然后将其设置为#include <experimental/coroutine>
。 Rebuild libc++.dll
and it turns out that working fine this time. 重建libc++.dll
,事实证明这次工作正常。
My question is whether struct suspend_always
(and suspend_never
) is really supposed to be exported to c++experimental.lib
? 我的问题是,是否真的应该将struct suspend_always
(和suspend_never
)导出到c++experimental.lib
?
Where can I report this to the implementors? 我在哪里可以向实施者报告?
Seems like a bug. 好像是个错误。 It should be fixed in r358551. 它应该在r358551中修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.