Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,60 @@ public async Task GetJitCodegen_WithProperty_ShouldReturnAssemblyCode()
"Output should contain method or class name");
}

// https://github.com/JetBrains/dotnet-disassembler-plugin/issues/13
// dotnet build ignores MSBuild properties in platform-conditional PropertyGroups
[Test]
public async Task GetJitCodegen_WithPlatformConditionalProperties_ShouldBuildSuccessfully()
{
// Arrange
var arch = RuntimePlatformUtils.GetCurrentArch();

File.WriteAllText(_testProjectFile, $@"
<Project Sdk=""Microsoft.NET.Sdk"">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<UseAppHost>false</UseAppHost>
<Configurations>Release;Debug</Configurations>
<Platforms>{arch}</Platforms>
</PropertyGroup>
<PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Debug|{arch}' "">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Release|{arch}' "">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>");

var programFile = Path.Combine(_testProjectDir, "Program.cs");
File.WriteAllText(programFile, @"
using System;

public class TestClass
{
public static void Main()
{
Console.WriteLine(Add(2, 3));
}

public static unsafe int Add(int a, int b)
{
int result = a + b;
int* p = &result;
return *p;
}
}");

var projectContext = CreateProjectContext(platform: arch);
var config = new JitDisasmConfiguration();

// Act
var result = await _jitCodegenProvider.GetJitCodegenAsync(_addMethodTarget, projectContext, config, CancellationToken.None);

// Assert
Assert.True(result.Succeed, $"Error: {result.FailValue?.Code}\nDetails: {result.FailValue?.Details}");
}

[Test]
public async Task GetJitCodegen_WithMissingMethod_ShouldReturnEmptyOrMinimalOutput()
{
Expand All @@ -305,7 +359,7 @@ public async Task GetJitCodegen_WithMissingMethod_ShouldReturnEmptyOrMinimalOutp
"Expected empty or minimal output for missing method");
}

private JitDisasmProjectContext CreateProjectContext([CanBeNull] JitDisasmTargetFramework tfm = null)
private JitDisasmProjectContext CreateProjectContext([CanBeNull] JitDisasmTargetFramework tfm = null, [CanBeNull] string platform = null)
{
var projectRoot = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "..", "..", ".."));
var dotnetCmd = Path.Combine(projectRoot, "dotnet.cmd");
Expand All @@ -325,6 +379,7 @@ private JitDisasmProjectContext CreateProjectContext([CanBeNull] JitDisasmTarget
ProjectFilePath: _testProjectFile,
ProjectDirectory: _testProjectDir,
AssemblyName: "TestProject",
DotNetCliExePath: dotnetExe);
DotNetCliExePath: dotnetExe,
Platform: platform);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public async Task<Result<JitCodeGenResult, Error>> GetJitCodegenAsync(DisasmTarg
? ""
: $"-f {tfm}";

string platformPart = GetPlatformArg(projectContext);

// Some things can't be set in CLI e.g. appending to DefineConstants
var tmpProps = Path.GetTempFileName() + ".props";
File.WriteAllText(tmpProps, $"""
Expand All @@ -81,7 +83,7 @@ public async Task<Result<JitCodeGenResult, Error>> GetJitCodegenAsync(DisasmTarg
logger.LogInformation("Running dotnet publish for reload");

string dotnetPublishArgs =
$"publish {tfmPart} -r {runtimeId} -c Release -o \"{resultOutDir}\" --self-contained true /p:PublishTrimmed=false /p:PublishSingleFile=false /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\" /p:WarningLevel=0 /p:TreatWarningsAsErrors=false -v:q";
$"publish {tfmPart} -r {runtimeId} -c Release -o \"{resultOutDir}\" --self-contained true {platformPart} /p:PublishTrimmed=false /p:PublishSingleFile=false /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\" /p:WarningLevel=0 /p:TreatWarningsAsErrors=false -v:q";

publishResult = await ProcessUtils.RunProcessAsync(dotnetCliExePath, dotnetPublishArgs, null, projectDirPath,
LogProcessOutput, cancellationToken: cancellationToken);
Expand All @@ -98,6 +100,7 @@ public async Task<Result<JitCodeGenResult, Error>> GetJitCodegenAsync(DisasmTarg
}

string dotnetBuildArgs = $"build {tfmPart} -c Release -o \"{resultOutDir}\" --no-self-contained " +
$"{platformPart} " +
"/p:RuntimeIdentifier=\"\" " +
"/p:RuntimeIdentifiers=\"\" " +
"/p:WarningLevel=0 " +
Expand Down Expand Up @@ -364,7 +367,9 @@ private async Task<Result<JitCodeGenResult, Error>> GetJitCodegenInternalAsync(D
else if (configuration.IsNonCustomNativeAotMode())
{
logger.LogDebug("Compiling for NativeAOT (.NET 8.0+ is required) ...");


string platformPart = GetPlatformArg(projectContext);

// For non-custom NativeAOT we need to use dotnet publish + with custom IlcArgs
// namely, we need to re-direct jit's output to a file (JitStdOutFile).

Expand Down Expand Up @@ -410,7 +415,7 @@ private async Task<Result<JitCodeGenResult, Error>> GetJitCodegenInternalAsync(D
// NOTE: CustomBeforeDirectoryBuildProps is probably not a good idea to overwrite, but we need to pass IlcArgs somehow
string dotnetPublishArgs =
$"publish {tfmPart} -r {runtimeId} -c Release" +
$" /p:PublishAot=true /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\"" +
$" {platformPart} /p:PublishAot=true /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\"" +
$" /p:WarningLevel=0 /p:TreatWarningsAsErrors=false -v:q";

var publishResult = await ProcessUtils.RunProcessAsync(dotnetCliExePath, dotnetPublishArgs, null,
Expand Down Expand Up @@ -571,6 +576,9 @@ private async Task<Result<JitCodeGenResult, Error>> GetJitCodegenInternalAsync(D
}
}

private static string GetPlatformArg(JitDisasmProjectContext projectContext) =>
string.IsNullOrEmpty(projectContext.Platform) ? "" : $"/p:Platform=\"{projectContext.Platform}\"";

private void LogProcessOutput(bool isError, string message)
{
if (isError)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public record JitDisasmProjectContext(
string ProjectFilePath,
string ProjectDirectory,
[CanBeNull] string AssemblyName,
string DotNetCliExePath)
string DotNetCliExePath,
[CanBeNull] string Platform = null)
{
public Result<JitDisasmProjectContext, Error> Validate()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using JetBrains.Application.Threading;
using JetBrains.ProjectModel;
using JetBrains.ProjectModel.MSBuild;
using JetBrains.ProjectModel.Properties;
using JetBrains.ReSharper.Feature.Services.Protocol;
using JetBrains.Rider.Model;
using JetBrains.Util;
Expand All @@ -19,6 +21,7 @@ public static JitDisasmProjectContext Create(IProject project)
var outputDirectory = tfmId != null ? project.GetOutputDirectory(tfmId) : null;
var assemblyName = tfmId != null ? project.GetOutputAssemblyName(tfmId) : null;
var dotNetCliExePath = GetDotNetCliExePath(solution);
var platform = project.GetUniqueRequestedProjectProperty(MSBuildProjectUtil.PlatformTargetProperty);

return new JitDisasmProjectContext(
Sdk: sdk,
Expand All @@ -27,7 +30,8 @@ public static JitDisasmProjectContext Create(IProject project)
ProjectFilePath: project.ProjectFileLocation?.FullPath,
ProjectDirectory: project.Location?.FullPath,
AssemblyName: assemblyName,
DotNetCliExePath: dotNetCliExePath);
DotNetCliExePath: dotNetCliExePath,
Platform: platform);
});
}

Expand Down
Loading