pywinrt/python-winsdk

Fails to build with Clang in MSYS2

mimi89999 opened this issue · 7 comments

Hello,
I tried to build python-winsdk with Clang on MSYS2, but it failed with:

FAILED: CMakeFiles/_winrt.dir/cmake_pch.hxx.pch
C:\msys64\clang64\bin\c++.exe -D_winrt_EXPORTS -IC:/Users/Michel/git/python-winsdk/cppwinrt -IC:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src -isystem C:/msys64/clang64/include/python3.10 -O3 -DNDEBUG -std=gnu++20 -Winvalid-pch -fpch-instantiate-templates -Xclang -emit-pch -Xclang -include -Xclang C:/Users/Michel/git/python-winsdk/_skbuild/mingw_x86_64_clang-3.10/cmake-build/CMakeFiles/_winrt.dir/cmake_pch.hxx -x c++-header -MD -MT CMakeFiles/_winrt.dir/cmake_pch.hxx.pch -MF CMakeFiles\_winrt.dir\cmake_pch.hxx.pch.d -o CMakeFiles/_winrt.dir/cmake_pch.hxx.pch -c C:/Users/Michel/git/python-winsdk/_skbuild/mingw_x86_64_clang-3.10/cmake-build/CMakeFiles/_winrt.dir/cmake_pch.hxx.cxx
In file included from <built-in>:1:
In file included from C:/Users/Michel/git/python-winsdk/_skbuild/mingw_x86_64_clang-3.10/cmake-build/CMakeFiles/_winrt.dir/cmake_pch.hxx:5:
In file included from C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.AI.MachineLearning.Preview.h:5:
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h:802:28: error: expected a qualified name after 'typename'
    struct buffer<typename T>
                           ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h:2140:27: error: missing 'typename' prior to dependent type name 'winrt::com_array<IInspectable>::value_type'
            return sizeof(winrt::com_array<T>::value_type);
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/msys64/clang64/include/c++/v1/__memory/unique_ptr.h:714:32: note: in instantiation of member function 'py::ComArray<winrt::Windows::Foundation::IInspectable>::ValueSize' requested here
    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
                               ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h:1819:31: note: in instantiation of function template specialization 'std::make_unique<py::ComArray<winrt::Windows::Foundation::IInspectable>>' requested here
            auto array = std::make_unique<ComArray<T>>();
                              ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h:1913:30: note: in instantiation of member function 'py::converter<winrt::com_array<winrt::Windows::Foundation::IInspectable>>::convert' requested here
        return converter<T>::convert(instance);
                             ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Foundation.Collections.h:2114:24: note: in instantiation of function template specialization 'py::convert<winrt::com_array<winrt::Windows::Foundation::IInspectable>>' requested here
                return convert(items);}
                       ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Foundation.Collections.h:1870:9: note: in instantiation of member function 'py::impl::Windows::Foundation::Collections::IVectorView<winrt::Windows::Foundation::IInspectable>::seq_subscript' requested here
        IVectorView(winrt::Windows::Foundation::Collections::IVectorView<T> o) : _obj(o) {}
        ^
C:/msys64/clang64/include/c++/v1/__memory/unique_ptr.h:714:32: note: (skipping 5 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
                               ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Security.Isolation.h:33:49: note: in instantiation of function template specialization 'py::convert<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Foundation::IInspectable>>' requested here
                py::pyobj_handle py_param1{ py::convert(param1) };
                                                ^
C:/Users/Michel/git/python-winsdk/cppwinrt/winrt/Windows.Security.Isolation.h:546:9: note: in instantiation of member function 'winrt::impl::delegate<winrt::Windows::Security::Isolation::HostMessageReceivedCallback, (lambda at C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Security.Isolation.h:28:20)>::Invoke' requested here
        delegate(H&& handler) : implements_delegate<winrt::Windows::Security::Isolation::HostMessageReceivedCallback, H>(std::forward<H>(handler)) {}
        ^
C:/Users/Michel/git/python-winsdk/cppwinrt/winrt/base.h:5385:64: note: in instantiation of member function 'winrt::impl::delegate<winrt::Windows::Security::Isolation::HostMessageReceivedCallback, (lambda at C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Security.Isolation.h:28:20)>::delegate' requested here
        return { static_cast<void*>(static_cast<abi_t<T>*>(new delegate<T, H>(std::forward<H>(handler)))), take_ownership_from_abi };
                                                               ^
C:/Users/Michel/git/python-winsdk/cppwinrt/winrt/Windows.Security.Isolation.h:1630:43: note: in instantiation of function template specialization 'winrt::impl::make_delegate<winrt::Windows::Security::Isolation::HostMessageReceivedCallback, (lambda at C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Security.Isolation.h:28:20)>' requested here
        HostMessageReceivedCallback(impl::make_delegate<HostMessageReceivedCallback>(std::forward<L>(handler)))
                                          ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Security.Isolation.h:28:20: note: in instantiation of function template specialization 'winrt::Windows::Security::Isolation::HostMessageReceivedCallback::HostMessageReceivedCallback<(lambda at C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.Security.Isolation.h:28:20)>' requested here
            return [delegate = std::move(_delegate)](auto param0, auto param1)
                   ^
2 errors generated.
dlech commented

Can you give the exact steps to reproduce the problem?

I found and fixed some other errors when trying to compile with clang-cl that ships with VS2022, but did not see this error.

  1. Install MSYS2
  2. Start the MSYS2 CLANG64 env
  3. Install the required dependencies. I don't remember which ones exactly, but here is a list of packages that I have installed, that might be useful:
mingw-w64-clang-x86_64-clang
mingw-w64-clang-x86_64-cmake
mingw-w64-clang-x86_64-ninja
mingw-w64-clang-x86_64-python-scikit-build
  1. Clone the repo
  2. Apply the following changes:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 752a0c17..2dad77e8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,12 +9,14 @@ file(GLOB headers RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
     "pywinrt/${CMAKE_PROJECT_NAME}/src/*.h"
 )

-set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

-# TODO: re-enable /GL and /LTCG when we get a bigger build machine
-add_compile_options(/await /bigobj /GR- /permissive-)
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+  # TODO: re-enable /GL and /LTCG when we get a bigger build machine
+  add_compile_options(/await /bigobj /GR- /permissive-)
+endif()

 # strip suffix to allow support for prerelease version
 string(REGEX MATCH "^[0-9]\\.[0-9]+(\\.[0-9]+)?" PYTHON_BASE_VERSION ${PYTHON_VERSION_STRING})
diff --git a/setup.py b/setup.py
index 26aea3fb..3cc7175c 100644
--- a/setup.py
+++ b/setup.py
@@ -29,7 +29,7 @@ setup(
         ],
     packages=find_namespace_packages(where=("pywinrt")),
     package_dir={"": "pywinrt"},
-    cmake_args=['-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_C_COMPILER=cl', '-DCMAKE_CXX_COMPILER=cl'],
+    cmake_args=['-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_C_COMPILER=cc', '-DCMAKE_CXX_COMPILER=c++'],
     # recursive glob (**) doesn't seem to work here
     package_data={"winsdk": ["py.typed", "*.pyi", "*/*.pyi", "*/*/*.pyi", "*/*/*/*.pyi", "*/*/*/*/*.pyi"]},
 )
  1. Run python.exe setup.py build

I also tried building in MSYS2 MINGW64 with GCC and got the following errors:

FAILED: CMakeFiles/_winrt.dir/cmake_pch.hxx.gch
C:\msys64\mingw64\bin\c++.exe -D_winrt_EXPORTS -IC:/Users/Michel/git/python-winsdk/cppwinrt -IC:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src -isystem C:/msys64/mingw64/include/python3.10 -O3 -DNDEBUG -std=gnu++20 -Winvalid-pch -x c++-header -include C:/Users/Michel/git/python-winsdk/_skbuild/mingw_x86_64-3.10/cmake-build/CMakeFiles/_winrt.dir/cmake_pch.hxx -MD -MT CMakeFiles/_winrt.dir/cmake_pch.hxx.gch -MF CMakeFiles\_winrt.dir\cmake_pch.hxx.gch.d -o CMakeFiles/_winrt.dir/cmake_pch.hxx.gch -c C:/Users/Michel/git/python-winsdk/_skbuild/mingw_x86_64-3.10/cmake-build/CMakeFiles/_winrt.dir/cmake_pch.hxx.cxx
In file included from C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.AI.MachineLearning.Preview.h:5,
                 from C:/Users/Michel/git/python-winsdk/_skbuild/mingw_x86_64-3.10/cmake-build/CMakeFiles/_winrt.dir/cmake_pch.hxx:5,
                 from <command-line>:
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h: In function 'To py::as(winrt_wrapper_base*)':
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h:180:51: error: expected primary-expression before '>' token
  180 |         return wrapper->get_unknown(wrapper).as<To>();
      |                                                   ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h:180:53: error: expected primary-expression before ')' token
  180 |         return wrapper->get_unknown(wrapper).as<To>();
      |                                                     ^
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h: At global scope:
C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/pybase.h:802:29: error: template argument 1 is invalid
  802 |     struct buffer<typename T>
      |                             ^
ninja: build stopped: subcommand failed.

Thanks for fixing those errors in pywinrt. Now both Clang and GCC are failing on PyObject to void conversions:
Clang:

C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.ApplicationModel.Appointments.DataProvider.cpp:266:22: error: cannot initialize a member subobject of type 'void *' with an lvalue of type 'PyObject *(PyTypeObject *, PyObject *, PyObject *) noexcept' (aka '_object *(_typeobject *, _object *, _object *) noexcept')
        { Py_tp_new, _new_AppointmentCalendarCancelMeetingRequest },
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[and many similar]
GCC:

C:/Users/Michel/git/python-winsdk/pywinrt/winsdk/src/py.Windows.ApplicationModel.AppService.cpp:173: error: invalid conversion from 'PyObject* (*)(PyTypeObject*, PyObject*, PyObject*) noexcept' {aka '_object* (*)(_typeobject*, _object*, _object*) noexcept'} to 'void*' [-fpermissive]
  173 |         { Py_tp_new, _new_AppServiceCatalog },
      |
```
[and many similar]
dlech commented

That should already be fixed by pywinrt/pywinrt@c646dbe.

Thanks. That was indeed fixed in pywinrt.

I also have an issue with the linker complaining about duplicate symbols:

ld.lld: error: duplicate symbol: py::buffer_format<bool, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<signed char, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<unsigned char, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<short, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<unsigned short, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<int, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<unsigned int, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<long long, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<unsigned long long, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<float, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<double, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<char16_t, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<winrt::guid, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<winrt::hstring, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<winrt::Windows::Foundation::IInspectable, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<std::__1::chrono::time_point<winrt::clock, std::__1::chrono::duration<long long, std::__1::ratio<1ll, 10000000ll>>>, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<std::__1::chrono::duration<long long, std::__1::ratio<1ll, 10000000ll>>, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<winrt::Windows::Foundation::Collections::CollectionChange, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<winrt::Windows::Foundation::AsyncStatus, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: duplicate symbol: py::buffer_format<winrt::Windows::Foundation::PropertyType, void>
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt.cpp.obj
>>> defined at CMakeFiles/_winrt.dir/pywinrt/winsdk/src/_winrt_array.cpp.obj

ld.lld: error: too many errors emitted, stopping now (use --error-limit=0 to see all errors)

Closing the issue since after pywinrt/pywinrt@64d3e07 I can finally build it 😃
Thanks a lot for your help!