Basic infrastructure to enable DllImportGenerator (#52486)
authorElinor Fung <elfung@microsoft.com>
Mon, 10 May 2021 19:48:18 +0000 (12:48 -0700)
committerGitHub <noreply@github.com>
Mon, 10 May 2021 19:48:18 +0000 (12:48 -0700)
Directory.Build.targets
NuGet.config
eng/Versions.props
eng/generators.targets [new file with mode: 0644]
src/libraries/Common/src/System/Runtime/InteropServices/GeneratedDllImportAttribute.cs [new file with mode: 0644]
src/libraries/Common/src/System/Runtime/InteropServices/GeneratedMarshallingAttribute.cs [new file with mode: 0644]

index e6457e6..c46b686 100644 (file)
@@ -9,6 +9,7 @@
 
   <Import Project="Sdk.targets" Sdk="Microsoft.DotNet.Arcade.Sdk" />
   <Import Project="$(RepositoryEngineeringDir)liveBuilds.targets" />
+  <Import Project="$(RepositoryEngineeringDir)generators.targets" />
   <Import Project="$(RepositoryEngineeringDir)python.targets" />
 
   <PropertyGroup>
@@ -24,7 +25,7 @@
     <InformationalVersion Condition="'$(InformationalVersion)' == '' and '$(VersionSuffix)' == ''">$(ProductVersion)</InformationalVersion>
     <InformationalVersion Condition="'$(InformationalVersion)' == '' and '$(VersionSuffix)' != ''">$(ProductVersion)-$(VersionSuffix)</InformationalVersion>
   </PropertyGroup>
-  
+
   <!-- The Default behavior in VS is to show files for the first target framework in TargetFrameworks property.
        This is required to show all the files corresponding to all target frameworks in VS. -->
   <ItemGroup Condition="'$(DefaultLanguageSourceExtension)' != '' and
index 7812fc3..d9e88a6 100644 (file)
@@ -19,6 +19,8 @@
     <add key="dotnet6-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6-transport/nuget/v3/index.json" />
     <!-- Used for the Rich Navigation indexing task -->
     <add key="richnav" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/vs-buildservices/nuget/v3/index.json" />
+    <!-- Used for DllImportGenerator -->
+    <add key="dotnet-experimental" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json" />
   </packageSources>
   <disabledPackageSources>
     <clear />
index 9d3af13..48e3667 100644 (file)
     <runtimewinx64MicrosoftNETCoreRuntimeMonoLLVMToolsVersion>9.0.1-alpha.1.21253.1</runtimewinx64MicrosoftNETCoreRuntimeMonoLLVMToolsVersion>
     <runtimeosx1012x64MicrosoftNETCoreRuntimeMonoLLVMSdkVersion>9.0.1-alpha.1.21253.1</runtimeosx1012x64MicrosoftNETCoreRuntimeMonoLLVMSdkVersion>
     <runtimeosx1012x64MicrosoftNETCoreRuntimeMonoLLVMToolsVersion>9.0.1-alpha.1.21253.1</runtimeosx1012x64MicrosoftNETCoreRuntimeMonoLLVMToolsVersion>
+    <!-- Experimental -->
+    <MicrosoftInteropDllImportGeneratorVersion>1.0.0-alpha.21258.2</MicrosoftInteropDllImportGeneratorVersion>
   </PropertyGroup>
   <!-- Override isolated build dependency versions with versions from Repo API. -->
   <Import Project="$(DotNetPackageVersionPropsPath)" Condition="'$(DotNetPackageVersionPropsPath)' != ''" />
diff --git a/eng/generators.targets b/eng/generators.targets
new file mode 100644 (file)
index 0000000..77d07da
--- /dev/null
@@ -0,0 +1,35 @@
+<Project InitialTargets="ConfigureGenerators">
+
+  <Target Name="ConfigureGenerators"
+          DependsOnTargets="ConfigureDllImportGenerator" />
+
+  <!-- Microsoft.Interop.DllImportGenerator -->
+  <Target Name="ConfigureDllImportGenerator" DependsOnTargets="EnableDllImportGeneratorForNetCoreApp">
+    <PropertyGroup Condition="'$(EnableDllImportGenerator)' == 'true'">
+        <DllImportGenerator_UseMarshalType>true</DllImportGenerator_UseMarshalType>
+    </PropertyGroup>
+    <ItemGroup Condition="'$(EnableDllImportGenerator)' == 'true' and $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">
+        <PackageReference Include="Microsoft.Interop.DllImportGenerator" Version="$(MicrosoftInteropDllImportGeneratorVersion)" PrivateAssets="all" />
+
+        <!-- For testing purposes, compile sources files with attributes directly into the project.
+            This is mimicking the case where the source generator always generates the attributes. -->
+        <Compile Include="$(LibrariesProjectRoot)Common/src/System/Runtime/InteropServices/GeneratedDllImportAttribute.cs" />
+        <Compile Include="$(LibrariesProjectRoot)Common/src/System/Runtime/InteropServices/GeneratedMarshallingAttribute.cs" />
+    </ItemGroup>
+  </Target>
+
+  <Target Name="EnableDllImportGeneratorForNetCoreApp"
+          Condition="'$(EnableDllImportGenerator)' == ''
+                        and ('$(IsNetCoreAppSrc)' == 'true' or '$(MSBuildProjectName)' == 'System.Private.CoreLib')
+                        and '$(MSBuildProjectExtension)' == '.csproj'">
+    <PropertyGroup>
+      <!-- Enable DllImportGenerator by default for System.Private.CoreLib -->
+      <EnableDllImportGenerator Condition="'$(MSBuildProjectName)' == 'System.Private.CoreLib'">true</EnableDllImportGenerator>
+
+      <!-- Enable DllImportGenerator by default for NETCoreApp libraries that reference either System.Runtime.InteropServices or System.Private.CoreLib -->
+      <EnableDllImportGenerator Condition="'@(Reference)' != '' and @(Reference->AnyHaveMetadataValue('Identity', 'System.Runtime.InteropServices'))">true</EnableDllImportGenerator>
+      <EnableDllImportGenerator Condition="'@(ProjectReference)' != '' and @(ProjectReference->AnyHaveMetadataValue('Identity', '$(CoreLibProject)'))">true</EnableDllImportGenerator>
+    </PropertyGroup>
+  </Target>
+
+</Project>
diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/GeneratedDllImportAttribute.cs b/src/libraries/Common/src/System/Runtime/InteropServices/GeneratedDllImportAttribute.cs
new file mode 100644 (file)
index 0000000..b04c9d9
--- /dev/null
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#nullable enable
+
+//
+// Types in this file are used for generated p/invokes (docs/design/features/source-generator-pinvokes.md).
+// See the DllImportGenerator experiment in https://github.com/dotnet/runtimelab.
+//
+namespace System.Runtime.InteropServices
+{
+    /// <summary>
+    /// Indicates that method will be generated at compile time and invoke into an unmanaged library entry point
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
+    internal sealed class GeneratedDllImportAttribute : Attribute
+    {
+        public bool BestFitMapping { get; set; }
+        public CallingConvention CallingConvention { get; set; }
+        public CharSet CharSet { get; set; }
+        public string? EntryPoint { get; set; }
+        public bool ExactSpelling { get; set; }
+        public bool PreserveSig { get; set; }
+        public bool SetLastError { get; set; }
+        public bool ThrowOnUnmappableChar { get; set; }
+
+        public GeneratedDllImportAttribute(string dllName)
+        {
+            this.Value = dllName;
+        }
+
+        public string Value { get; private set; }
+    }
+}
diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/GeneratedMarshallingAttribute.cs b/src/libraries/Common/src/System/Runtime/InteropServices/GeneratedMarshallingAttribute.cs
new file mode 100644 (file)
index 0000000..c66605e
--- /dev/null
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+//
+// Types in this file are used for generated p/invokes (docs/design/features/source-generator-pinvokes.md).
+// See the DllImportGenerator experiment in https://github.com/dotnet/runtimelab.
+//
+namespace System.Runtime.InteropServices
+{
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
+    internal class GeneratedMarshallingAttribute : Attribute
+    {
+    }
+
+    [AttributeUsage(AttributeTargets.Struct)]
+    internal class BlittableTypeAttribute : Attribute
+    {
+    }
+
+    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
+    internal class NativeMarshallingAttribute : Attribute
+    {
+        public NativeMarshallingAttribute(Type nativeType)
+        {
+            NativeType = nativeType;
+        }
+
+        public Type NativeType { get; }
+    }
+
+    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.Field)]
+    internal class MarshalUsingAttribute : Attribute
+    {
+        public MarshalUsingAttribute(Type nativeType)
+        {
+            NativeType = nativeType;
+        }
+
+        public Type NativeType { get; }
+    }
+}