swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.04k stars 10.32k forks source link

WinSDK import fails with Windows SDK 10.0.17763.0 #73502

Open SlugFiller opened 2 months ago

SlugFiller commented 2 months ago

Description

Caused by #70195.

Produces such error messages as:

C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um/xaudio2fx.h:29:1: error: unknown type name 'class'
class __declspec(uuid("4FC3B166-972A-40CF-BC37-7DB03DB2FBA3")) AudioVolumeMeter;
^

or

C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um/xaudio2fx.h:265:8: error: unknown type name 'bool'
    ,  bool sevenDotOneReverb = true
       ^

I don't know which version of xaudio29fx.h is a C header. But the one obtainable via winget install --id=Microsoft.WindowsSDK.10.0.17763 -e or choco install windows-sdk-10-version-1809-all is very clearly a C++ header.

If this version of the Windows SDK is intentionally unsupported, then the documentation should include instructions for installing a supported version.

Reproduction

import WinSDK

Expected behavior

Should build without errors

Environment

Swift version 5.10 (swift-5.10-RELEASE) Target: x86_64-unknown-windows-msvc

Additional information

No response

compnerd commented 2 months ago

CC: @STREGA

STREGA commented 2 months ago

I have not yet had a chance to do my own XAudio implementation.

Looks like xaudio2.h is okay for C but xaudio2fx.h is C++ only.

XAudio2FX appears to contain a small number of pre made nodes. It could probably be its own C++ only module.

For reference: This was the example that made me believe C should be doable. The example doesn't use the fx header.

SlugFiller commented 2 months ago

I actually have issues with xaudio.h too. Sample:

<module-includes>:39:10: note: in file included from <module-includes>:39:
#include "xaudio2.h"
         ^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um/xaudio2.h:61:26: error: uuid' attribute is not supported in C
    interface __declspec(uuid("2B02E3CF-2E0B-4ec3-BE45-1B2A3FE7210D")) IXAudio2;
                         ^
<module-includes>:39:10: note: in file included from <module-includes>:39:
#include "xaudio2.h"
         ^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um/xaudio2.h:1202:1: error: expected identifier or '('
XAUDIO2_STDAPI XAudio2CreateWithVersionInfo(_Outptr_ IXAudio2** ppXAudio2,
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um/xaudio2.h:1198:35: note: expanded from macro 'XAUDIO2_STDAPI'
    #define XAUDIO2_STDAPI extern "C" __declspec(dllimport) HRESULT __stdcall
                                  ^
<module-includes>:39:10: note: in file included from <module-includes>:39:
#include "xaudio2.h"
         ^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um/xaudio2.h:1216:36: error: use of undeclared identifier 'nullptr'
    static HMODULE s_dllInstance = nullptr;
                                   ^

Doesn't seem to be C-compatible.

Reverting #70195 seems to fix this cleanly. I wonder what the disadvantages are.

STREGA commented 1 month ago

Reverting #70195 seems to fix this cleanly. I wonder what the disadvantages are.

The only real disadvantage is the C++ interop mode is all or nothing. When it's enabled it causes all C targets to be compiled with C++. Not all C targets can be compiled in C++ so it's not always a choice.

When a module is marked C++ only, as XAudio2 was, the related headers can't ever be imported, even with a custom target, because the module has already reserved the header. So essentially it's impossible to use XAudio2 without your entire project also using C++ interop when the module is marked C++ only.

I actually have issues with xaudio.h too.

Hmmm. That looks pretty definitive. Sorry you ran into this, I simply haven't had time to test this properly. I was really hoping C would work as evidence made it seem possible. But Microsoft does explicitly say XAudio2 is C++ only, so I think reverting is the right way to go. Even if the C did work right now, it could change at any time breaking projects.

SlugFiller commented 1 month ago

Hmm, but in that case, since the module is auto-imported as part of WinSDK, doesn't that mean that every non-trivial Windows-targeting project will necessarily be forced into C++ mode? At the very least, my project wasn't actually using XAudio2 (I was merely trying to get HWND), and still hit that header.

If this is a potential issue, then it might be worthwhile to separate XAudio2 from the rest of WinSDK.

STREGA commented 1 month ago

Hmm, but in that case, since the module is auto-imported as part of WinSDK, doesn't that mean that every non-trivial Windows-targeting project will necessarily be forced into C++ mode?

Modules are a complicated feature and I'm not an expert, but essentially yes, that's what it means. It's very annoying. But it only seems to happen if you import the parent module (DirectX). I don't think it will happen just by importing WinSDK from what I remember.

I submitted a pull request to revert the module requirement for now. Figuring out how to fix the C++ interop requirement would be another issue, but at least for Swift 6 the build error should not be a problem.