Предполагается ли, что libc ++ сопрограмма suspend_always :: await_suspend "экспортируется" в c ++ экспериментальный .lib? - PullRequest
0 голосов
/ 16 апреля 2019

Я получаю эту ошибку при компиляции сопрограммы с 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

До этого я собирал libc ++ с использованием -DLIBCXX_ENABLE_SHARED=YES -DLIBCXX_ENABLE_STATIC=NO -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=YES

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++.lib и nm c++experimental.lib.Я не нашел никаких следов suspend_always.

Кажется, suspend_always::await_suspend отсутствует в DLL.Итак, я углубляюсь в некоторый макрос на С ++.

В C:/libcxx-master/CMakeLists.txt определено _LIBCPP_BUILDING_LIBRARY.

add_definitions(-D_LIBCPP_BUILDING_LIBRARY)

В 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

Я нахожусь в _WIN32, поэтому у нас есть _LIBCPP_OBJECT_FORMAT_COFF хорошо defined.Далее вниз у нас есть

#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 определение

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_alwayssuspend_never) действительно должны бытьэкспортируется в c++experimental.lib?

Где я могу сообщить об этом разработчикам?

1 Ответ

1 голос
/ 17 апреля 2019

Похоже, ошибка.Это должно быть исправлено в r358551.

...