Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P/Invoke and COM definitions not generated by builds for ARM64 #494

Closed
shibayan opened this issue Jan 31, 2022 · 6 comments
Closed

P/Invoke and COM definitions not generated by builds for ARM64 #494

shibayan opened this issue Jan 31, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@shibayan
Copy link

Actual behavior

Some APIs do not seem to generate definitions even if you build with ARM64 platform instead of Any CPU. I can confirm this with IShellBrowser, IShellView and SHGetFileInfo.

Expected behavior

I expect the API definition to be generated when ARM64 is specified as well as when x64 is specified.

Repro steps

  1. NativeMethods.txt content:
IShellBrowser
IShellView
SHGetFileInfo
  1. NativeMethods.json content (if present):
  1. Any of your own code that should be shared?
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <Platforms>x64;arm64</Platforms>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.635-beta">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

</Project>

Build comand

# Succeeded
dotnet build -p:Platform=x64
# Warning
dotnet build -p:Platform=arm64

Build log

C:\Users\shibayan\Documents\cswin32test\NativeMethods.txt(1,1): warning PInvoke005: This API is only available when targeting a specific CPU architecture. AnyCPU cannot generate this API. [C:\Users\shibayan\Documents\cswin32test\cswin32test.csproj]
C:\Users\shibayan\Documents\cswin32test\NativeMethods.txt(2,1): warning PInvoke005: This API is only available when targeting a specific CPU architecture. AnyCPU cannot generate this API. [C:\Users\shibayan\Documents\cswin32test\cswin32test.csproj]
C:\Users\shibayan\Documents\cswin32test\NativeMethods.txt(3,1): warning PInvoke005: This API is only available when targeting a specific CPU architecture. AnyCPU cannot generate this API. [C:\Users\shibayan\Documents\cswin32test\cswin32test.csproj]

Context

  • CsWin32 version: 0.1.635-beta
  • Win32Metadata version (if explicitly set by project):
  • Target Framework: net6.0
  • LangVersion (if explicitly set by project):
@shibayan shibayan added the bug Something isn't working label Jan 31, 2022
@AArnott
Copy link
Member

AArnott commented Jan 31, 2022

That would be due to the metadata. I don't see an architecture-specific attribute on IShellBrowser directly, but one of its referenced types (transitively) must not be available for ARM64. Whether or not that's by design is up to the metadata team.

@AArnott AArnott transferred this issue from microsoft/CsWin32 Jan 31, 2022
@sotteson1
Copy link
Contributor

Looking at the structs, TBBUTTON has a definition for x86 and one for x64/arm64. The error message sounds like you're trying to build for AnyCpu, which it can't do because there are different definitions for 32 and 64 bits. @AArnott, am I misreading the error message? Doesn't this look like it's by design?

@AArnott
Copy link
Member

AArnott commented Jan 31, 2022

Hmm... Yes the build log does make it look like it's AnyCPU. But the build command line use is what I was reading and that makes it appears it would not be Any CPU. I'll take another look.

@AArnott AArnott transferred this issue from microsoft/win32metadata Jan 31, 2022
@AArnott
Copy link
Member

AArnott commented Feb 1, 2022

Ok, so the problem is apparent when you add -bl to your build and inspect the msbuild.binlog file. The Csc task is invoked with Platform set to AnyCPU.
It turns out that merely setting the msbuild Platform property isn't enough. The property that is passed to the compiler is PlatformTarget. If you set that at the command line, it works:

dotnet build -p:Platform=arm64 -bl -t:rebuild -p:PlatformTarget=arm64

A quick glance at the msbuild .targets files in the .NET SDK suggests that this disconnect is intended for projects to pivot based on runtime identifiers instead of platforms. If you modify your project file like this:

-    <Platforms>x64;arm64</Platforms>
+    <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>

Then building succeeds when you target a specific runtime identifier:

dotnet build -bl -t:rebuild -r win-arm64
dotnet build -bl -t:rebuild -r win-x64

I don't know why this is only required when setting platform to arm64. Your project builds fine as you expected with -p:x64. Maybe the .targets files in the SDK know how to map Platform to PlatformTarget for x86 and x64 but not arm64. @rainersigwald, do you have any idea?

@rainersigwald
Copy link
Member

@AArnott I think you're exactly right, and dotnet/sdk#15434 should be the right place to track it.

@baronfel, I think there might be room for some docs guidance about Platform/RID for .NET projects; I believe we generally prefer specifying RID and inferring Platform/PlatformTarget but I couldn't see that anywhere in the docs.

@shibayan
Copy link
Author

shibayan commented Feb 2, 2022

Thanks for the investigation.

I was able to avoid this problem for the time being by adding the following definition to csproj file.

  <PropertyGroup Condition=" '$(_PlatformWithoutConfigurationInference)' == 'ARM64' ">
    <PlatformTarget Condition=" '$(PlatformTarget)' == '' ">ARM64</PlatformTarget>
  </PropertyGroup>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants