Skip to content

Commit

Permalink
Dllimport generator build and test fixes (dotnet#59658)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky authored Oct 6, 2021
1 parent d81945e commit 2dff7cd
Show file tree
Hide file tree
Showing 21 changed files with 206 additions and 26 deletions.
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
<XunitPerformanceApiPackageVersion>1.0.0-beta-build0015</XunitPerformanceApiPackageVersion>
<MicrosoftDiagnosticsToolsRuntimeClientVersion>1.0.4-preview6.19326.1</MicrosoftDiagnosticsToolsRuntimeClientVersion>
<MicrosoftDiagnosticsNETCoreClientVersion>0.2.61701</MicrosoftDiagnosticsNETCoreClientVersion>
<DNNEVersion>1.0.23</DNNEVersion>
<DNNEVersion>1.0.26</DNNEVersion>
<!--
These are used as reference assemblies only, so they must not take a ProdCon/source-build
version. Insert "RefOnly" to avoid assignment via PVP.
Expand Down
10 changes: 5 additions & 5 deletions eng/generators.targets
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
<ItemGroup Condition="'@(EnabledGenerators)' != ''
and @(EnabledGenerators->AnyHaveMetadataValue('Identity', 'DllImportGenerator'))
and '$(IncludeDllImportGeneratorSources)' == 'true'">
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.InteropServices/gen/DllImportGenerator/DllImportGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<Compile Include="$(LibrariesProjectRoot)Common/src/System/Runtime/InteropServices/GeneratedDllImportAttribute.cs" />
<Compile Include="$(LibrariesProjectRoot)Common/src/System/Runtime/InteropServices/GeneratedMarshallingAttribute.cs" />
<Compile Include="$(LibrariesProjectRoot)Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.InteropServices\gen\DllImportGenerator\DllImportGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<Compile Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\GeneratedDllImportAttribute.cs" />
<Compile Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\GeneratedMarshallingAttribute.cs" />
<Compile Include="$(LibrariesProjectRoot)Common\src\System\Runtime\InteropServices\ArrayMarshaller.cs" />
</ItemGroup>

<Target Name="ConfigureGenerators"
Expand All @@ -59,7 +59,7 @@
<DefineConstants>$(DefineConstants);DLLIMPORTGENERATOR_INTERNALUNSAFE</DefineConstants>
</PropertyGroup>

<MSBuild Projects="$(LibrariesProjectRoot)System.Runtime.InteropServices/gen/DllImportGenerator/DllImportGenerator.csproj"
<MSBuild Projects="$(LibrariesProjectRoot)System.Runtime.InteropServices\gen\DllImportGenerator\DllImportGenerator.csproj"
RemoveProperties="TargetFramework">
<Output TaskParameter="TargetOutputs" PropertyName="DllImportGeneratorOutputPath" />
</MSBuild>
Expand Down
21 changes: 21 additions & 0 deletions eng/native/output-toolchain-info.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Output the toolchain information required to create a command line that builds with the right rootfs as XML

set (ADDED_COMPILE_OPTIONS)
if (CMAKE_SCRIPT_MODE_FILE)
# add_compile_options and add_definitions can't be used in scripts,
# so override the implementations to append to a local property
macro(add_compile_options)
list(APPEND ADDED_COMPILE_OPTIONS ${ARGV})
endmacro()
macro(add_definitions)
list(APPEND ADDED_COMPILE_OPTIONS ${ARGV})
endmacro()
endif()

include(${CMAKE_CURRENT_LIST_DIR}/../common/cross/toolchain.cmake)

message("<toolchain-info>")
message("<target-triple>${TOOLCHAIN}</target-triple>")
message("<linker-args>${CMAKE_SHARED_LINKER_FLAGS_INIT}</linker-args>")
message("<compiler-args>${ADDED_COMPILE_OPTIONS}</compiler-args>")
message("</toolchain-info>")
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ internal static partial class Interop
{
internal static partial class Kernel32
{
#if DLLIMPORTGENERATOR_ENABLED
[GeneratedDllImport(Libraries.Kernel32, SetLastError = true)]
internal static partial bool CloseHandle(IntPtr handle);
#else
#pragma warning disable DLLIMPORTGENANALYZER015 // Use 'GeneratedDllImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time
// Disabled since CloseHandle is a QCall in some scenarios and DllImportGenerator doesn't support QCalls.
[DllImport(Libraries.Kernel32, SetLastError = true)]
internal static extern bool CloseHandle(IntPtr handle);
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,18 @@ internal static partial class Kernel32
private const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
private const int ERROR_INSUFFICIENT_BUFFER = 0x7A;

#if DLLIMPORTGENERATOR_ENABLED
[GeneratedDllImport(Libraries.Kernel32, EntryPoint = "FormatMessageW", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static unsafe partial int FormatMessage(
#else
#pragma warning disable DLLIMPORTGENANALYZER015 // Use 'GeneratedDllImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time
// Disabled since FormatMessage is a QCall in some scenarios and DllImportGenerator doesn't support QCalls.
[DllImport(Libraries.Kernel32, EntryPoint = "FormatMessageW", BestFitMapping = true, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
private static extern unsafe int FormatMessage(
#endif
int dwFlags,
IntPtr lpSource,
uint dwMessageId,
int dwLanguageId,
void* lpBuffer,
int nSize,
IntPtr arguments);
#pragma warning restore DLLIMPORTGENANALYZER015

/// <summary>
/// Returns a string message for the specified Win32 error code.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ internal static partial class Kernel32
internal static partial uint GetFullPathNameW(
#else
[DllImport(Libraries.Kernel32, BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
internal static extern uint GetFullPathNameW(
#endif
internal static extern uint GetFullPathNameW(
ref char lpFileName,
uint nBufferLength,
ref char lpBuffer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ internal static partial class Kernel32
internal static partial uint GetLongPathNameW(
#else
[DllImport(Libraries.Kernel32, BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
internal static extern uint GetLongPathNameW(
#endif
internal static extern uint GetLongPathNameW(
ref char lpszShortPath,
ref char lpszLongPath,
uint cchBuffer);

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<EnableDllImportGenerator>true</EnableDllImportGenerator>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
<EnableDllImportGenerator>true</EnableDllImportGenerator>
<!-- file locking can't be disabled on Windows -->
<TargetFrameworks>$(NetCoreAppCurrent)-Unix</TargetFrameworks>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-OSX</TargetFrameworks>
<EnableDllImportGenerator>true</EnableDllImportGenerator>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit;

// We build the libraries tests in CI once per target OS+Arch+Configuration, but we share it between runtime test runs.
// As a result, we need to exclude the Mono run here since we build the tests once for CoreCLR and Mono for desktop test runs.
// We should switch this to another mechanism in the future so we don't submit a work item of this assembly that skips every test
// for Mono-on-Desktop-Platforms test runs.
[assembly:ActiveIssue("https://github.com/dotnet/runtime/issues/59815", TestRuntimes.Mono)]
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
<IsPackable>false</IsPackable>
<LangVersion>Preview</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ partial class NativeExportsNE
{
public partial class FunctionPointer
{
[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "invoke_callback_after_gc")]
[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "invoke_managed_callback_after_gc")]
public static unsafe partial void InvokeAfterGC(delegate* <void> cb);

[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "invoke_callback_after_gc")]
Expand All @@ -22,7 +22,7 @@ public partial class FunctionPointer
[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "invoke_callback_after_gc")]
public static unsafe partial void InvokeAfterGC(delegate* unmanaged[Stdcall]<void> cb);

[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "invoke_callback_blittable_args")]
[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "invoke_managed_callback_blittable_args")]
public static unsafe partial int InvokeWithBlittableArgument(delegate* <int, int, int> cb, int a, int b);

[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "invoke_callback_blittable_args")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks>
<IsPackable>false</IsPackable>
<LangVersion>Preview</LangVersion>
<Nullable>enable</Nullable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,31 @@ public static void InvokeCallbackAfterGCCollect(delegate* unmanaged<void> fptr)
fptr();
}

[UnmanagedCallersOnly(EntryPoint = "invoke_managed_callback_after_gc")]
public static void InvokeManagedCallbackAfterGCCollect(void* fptr)
{
// We are at the mercy of the GC to verify our delegate has been retain
// across the native function call. This is a best effort validation.
for (int i = 0; i < 5; ++i)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}

// If the corresponding Delegate was collected, the runtime will rudely abort.
((delegate*<void>)fptr)();
}

[UnmanagedCallersOnly(EntryPoint = "invoke_callback_blittable_args")]
public static int InvokeCallbackWithBlittableArgument(delegate* unmanaged<int, int, int> fptr, int a, int b)
{
return fptr(a, b);
}

[UnmanagedCallersOnly(EntryPoint = "invoke_managed_callback_blittable_args")]
public static int InvokeManagedCallbackWithBlittableArgument(void* fptr, int a, int b)
{
return ((delegate*<int, int, int>)fptr)(a, b);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
<EnableDynamicLoading>true</EnableDynamicLoading>
<DnneAddGeneratedBinaryToProject>true</DnneAddGeneratedBinaryToProject>
<DnneGenRollForward>Major</DnneGenRollForward>
<!-- To integrate with DNNE's architecture calculation, we need to set the RID for this project. -->
<RuntimeIdentifier>$(OutputRid)</RuntimeIdentifier>
<AppHostRuntimeIdentifier>$(OutputRid)</AppHostRuntimeIdentifier>
</PropertyGroup>

<ItemGroup>
Expand All @@ -17,4 +20,97 @@
<ProjectReference Include="..\SharedTypes\SharedTypes.csproj" />
</ItemGroup>

<Target Name="GetLinuxCrossBuildArgumentsForDNNE"
Condition="'$(CrossBuild)' == 'true' and (
'$(TargetOS)' == 'Linux' or
'$(TargetOS)' == 'NetBSD' or
'$(TargetOS)' == 'FreeBSD' or
'$(TargetOS)' == 'illumos' or
'$(TargetOS)' == 'Solaris')">
<PropertyGroup>
<NativeCompiler>$(Compiler)</NativeCompiler>
<NativeCompiler Condition="'$(NativeCompiler)' == ''">clang</NativeCompiler>
</PropertyGroup>

<Exec Command="bash -c 'source &quot;$(RepositoryEngineeringDir)/common/native/init-compiler.sh&quot; &quot;$(RepositoryEngineeringDir)/common/native&quot; $(TargetArchitecture) $(NativeCompiler) &amp;&amp; echo $CC '"
EchoOff="true"
ConsoleToMsBuild="true"
StandardOutputImportance="Low">
<Output TaskParameter="ConsoleOutput" PropertyName="DnneCompilerCommand" />
</Exec>
<Exec Command="cmake -P &quot;$(RepositoryEngineeringDir)/native/output-toolchain-info.cmake&quot;"
EchoOff="true"
ConsoleToMsBuild="true"
StandardOutputImportance="Low"
EnvironmentVariables="TARGET_BUILD_ARCH=$(TargetArchitecture)">
<Output TaskParameter="ConsoleOutput" PropertyName="CrossTargetXml" />
</Exec>

<XmlPeek XmlContent="$(CrossTargetXml)" Query="toolchain-info/target-triple/text()">
<Output TaskParameter="Result" PropertyName="TargetTriple" />
</XmlPeek>
<XmlPeek XmlContent="$(CrossTargetXml)" Query="toolchain-info/linker-args/text()">
<Output TaskParameter="Result" PropertyName="DnneLinkerUserFlags" />
</XmlPeek>
<XmlPeek XmlContent="$(CrossTargetXml)" Query="toolchain-info/compiler-args/text()">
<Output TaskParameter="Result" PropertyName="DnneCompilerUserFlags" />
</XmlPeek>

<PropertyGroup>
<CommonToolchainArgs>--target=$(TargetTriple) --gcc-toolchain=$(ROOTFS_DIR)/usr --sysroot=$(ROOTFS_DIR)</CommonToolchainArgs>
<DnneLinkerUserFlags>$(CommonToolchainArgs) $(DnneLinkerUserFlags.Replace(';',' '))</DnneLinkerUserFlags>
<DnneCompilerUserFlags>$(CommonToolchainArgs) $(DnneCompilerUserFlags.Replace(';',' '))</DnneCompilerUserFlags>
</PropertyGroup>
</Target>

<Target Name="GetAppleCrossBuildArgumentsForDNNE"
Condition="'$(TargetOS)' == 'OSX' or
'$(TargetOS)' == 'MacCatalyst' or
'$(TargetOS)' == 'iOS' or
'$(TargetOS)' == 'iOSSimulator' or
'$(TargetOS)' == 'tvOS' or
'$(TargetOS)' == 'tvOSSimulator'">
<PropertyGroup Condition=" '$(TargetOS)' == 'MacCatalyst'">
<TargetTriple Condition="'$(TargetArchitecture)' == 'arm64'">arm64-apple-ios14.2-macabi</TargetTriple>
<TargetTriple Condition="'$(TargetArchitecture)' == 'x64'">x86_64-apple-ios13.5-macabi</TargetTriple>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetOS)' == 'OSX'">
<TargetTriple Condition="'$(TargetArchitecture)' == 'arm64'">arm64-apple-macos11</TargetTriple>
<TargetTriple Condition="'$(TargetArchitecture)' == 'x64'">x86_64-apple-macos10.13</TargetTriple>
<XCodeSdkName>macosx</XCodeSdkName>
</PropertyGroup>

<Error Condition="'$(TargetTriple)' == ''" Text="A target triple was not specified for the native components build. Update the 'GetAppleCrossBuildArgumentsForDNNE' target to specify a triple." />
<Error Condition="'$(XCodeSdkName)' == ''" Text="The name of the XCode SDK for the target platform, as passed to xcrun to locate the sdk, must be specified." />

<!-- xcrun is used to locate the XCode SDKs and tools within them. See the xcrun manpage for usage information. -->
<Exec Command="xcrun --sdk $(XCodeSdkName) --show-sdk-path"
EchoOff="true"
ConsoleToMsBuild="true"
StandardOutputImportance="Low">
<Output TaskParameter="ConsoleOutput" PropertyName="SysRootIncludePath" />
</Exec>

<Exec Command="xcrun --sdk $(XCodeSdkName) --find clang"
EchoOff="true"
ConsoleToMsBuild="true"
StandardOutputImportance="Low">
<Output TaskParameter="ConsoleOutput" PropertyName="DnneCompilerCommand" />
</Exec>

<PropertyGroup>
<DnneLinkerUserFlags>-target $(TargetTriple)</DnneLinkerUserFlags>
<DnneCompilerUserFlags>-isysroot &quot;$(SysRootIncludePath)&quot; -target $(TargetTriple)</DnneCompilerUserFlags>
</PropertyGroup>
</Target>

<Target Name="GetBuildArgumentsForDNNE"
DependsOnTargets="ResolveFrameworkReferences;
GetLinuxCrossBuildArgumentsForDNNE;
GetAppleCrossBuildArgumentsForDNNE"
BeforeTargets="DnneBuildNativeExports">
<PropertyGroup>
<DnneNetHostDir>$([System.IO.Path]::GetDirectoryName('$(AppHostSourcePath)'))</DnneNetHostDir>
</PropertyGroup>
</Target>
</Project>
15 changes: 15 additions & 0 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Transactions.Local\tests\System.Transactions.Local.Tests.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetsMobile)' == 'true'">
<!-- DllImportGenerator runtime tests depend on DNNE, which does not support mobile platforms. -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\DllImportGenerator.Tests\DllImportGenerator.Tests.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'arm'">
<!-- DllImportGenerator runtime tests depend on DNNE, which does not support Windows ARM32 as we don't officially support it. -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\DllImportGenerator.Tests\DllImportGenerator.Tests.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'FreeBSD'">
<!-- DllImportGenerator runtime tests build depends pulling down a pre-built nethost binary, which is not available for FreeBSD. -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\DllImportGenerator.Tests\DllImportGenerator.Tests.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'Windows' and '$(RuntimeFlavor)' == 'Mono' and '$(RunDisabledMonoTestsOnWindows)' != 'true'">
<!-- Issue: https://github.com/dotnet/runtime/issues/53281 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Net.WebSockets.Client\tests\System.Net.WebSockets.Client.Tests.csproj" />
Expand Down
8 changes: 8 additions & 0 deletions src/samples/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props, $(MSBuildThisFileDirectory)..))" />

<PropertyGroup>
<EnableDefaultItems>true</EnableDefaultItems>
<UseLocalTargetingRuntimePack>true</UseLocalTargetingRuntimePack>
</PropertyGroup>
</Project>
5 changes: 5 additions & 0 deletions src/samples/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>
<Import Project="$(RepositoryEngineeringDir)targetingpacks.targets" />

<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets, $(MSBuildThisFileDirectory)..))" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.InteropServices/gen/DllImportGenerator/DllImportGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.InteropServices\tests\Ancillary.Interop\Ancillary.Interop.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.InteropServices\tests\TestAssets\NativeExports\NativeExports.csproj" />
</ItemGroup>
Expand Down
11 changes: 7 additions & 4 deletions src/samples/DllImportGeneratorSample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;

namespace Demo
{
partial class NativeExportsNE
internal static partial class NativeExportsNE
{
public const string NativeExportsNE_Binary = "Microsoft.Interop.Tests." + nameof(NativeExportsNE);

Expand All @@ -17,9 +20,9 @@ partial class NativeExportsNE
public static partial void Sum(int a, ref int b);
}

class Program
internal static class Program
{
static void Main(string[] args)
public static void Main(string[] args)
{
int a = 12;
int b = 13;
Expand Down

0 comments on commit 2dff7cd

Please sign in to comment.