diff --git a/.github/skills/add-dotnet-aot-command/SKILL.md b/.github/skills/add-dotnet-aot-command/SKILL.md index 407e33542267..196a86203cdb 100644 --- a/.github/skills/add-dotnet-aot-command/SKILL.md +++ b/.github/skills/add-dotnet-aot-command/SKILL.md @@ -65,7 +65,7 @@ but inside that process the BCL "where am I" APIs do **not** point there: So deriving an SDK-relative path (`MSBuild.dll`, `Sdks/`, `DotnetTools/`, targets) from `AppContext.BaseDirectory` or a dll path is **wrong** in the AOT bubble. Instead: -- **In-repo:** read `SdkPaths.SdkDirectory` (in `Microsoft.DotNet.Cli.Utils`), which resolves the +- **In-repo:** read `SdkPaths.SdkDirectory` (in `Microsoft.DotNet.Cli.CoreUtils`), which resolves the `Microsoft.DotNet.Sdk.Root` AppContext value -> SDK assembly directory -> `AppContext.BaseDirectory` (once, cached). - `NativeEntryPoint.ExecuteCore` resolves the SDK directory once (host `sdk_dir`, else self-locating the diff --git a/src/Cli/Microsoft.DotNet.Cli.CoreUtils/DotnetFiles.cs b/src/Cli/Microsoft.DotNet.Cli.CoreUtils/DotnetFiles.cs index 85adda5135bb..caa1ef453696 100644 --- a/src/Cli/Microsoft.DotNet.Cli.CoreUtils/DotnetFiles.cs +++ b/src/Cli/Microsoft.DotNet.Cli.CoreUtils/DotnetFiles.cs @@ -9,15 +9,13 @@ namespace Microsoft.DotNet.Cli.Utils; public static class DotnetFiles { - private static string SdkRootFolder => AppContext.BaseDirectory; - private static readonly Lazy s_versionFileObject = new(() => new DotnetVersionFile(VersionFile)); /// /// The SDK ships with a .version file that stores the commit information and SDK version /// - public static string VersionFile => Path.GetFullPath(Path.Combine(SdkRootFolder, ".version")); + public static string VersionFile => Path.GetFullPath(Path.Combine(SdkPaths.SdkDirectory, ".version")); public static DotnetVersionFile VersionFileObject => s_versionFileObject.Value; } diff --git a/src/Cli/Microsoft.DotNet.Cli.CoreUtils/Microsoft.DotNet.Cli.CoreUtils.csproj b/src/Cli/Microsoft.DotNet.Cli.CoreUtils/Microsoft.DotNet.Cli.CoreUtils.csproj index 7ca17824ecb9..38d86a0eeb32 100644 --- a/src/Cli/Microsoft.DotNet.Cli.CoreUtils/Microsoft.DotNet.Cli.CoreUtils.csproj +++ b/src/Cli/Microsoft.DotNet.Cli.CoreUtils/Microsoft.DotNet.Cli.CoreUtils.csproj @@ -6,4 +6,10 @@ enable MicrosoftAspNetCore + + + + + + diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/SdkPaths.cs b/src/Cli/Microsoft.DotNet.Cli.CoreUtils/SdkPaths.cs similarity index 95% rename from src/Cli/Microsoft.DotNet.Cli.Utils/SdkPaths.cs rename to src/Cli/Microsoft.DotNet.Cli.CoreUtils/SdkPaths.cs index 4f8cdc066860..25695c68a6e1 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/SdkPaths.cs +++ b/src/Cli/Microsoft.DotNet.Cli.CoreUtils/SdkPaths.cs @@ -19,7 +19,7 @@ namespace Microsoft.DotNet.Cli.Utils; /// /// Under the Native AOT CLI (dotnet-aot loaded directly by the muxer) the BCL location APIs do /// NOT point at the versioned SDK directory: and -/// resolve to the install root (the muxer's own +/// Environment.ProcessPath resolve to the install root (the muxer's own /// directory) and Assembly.Location is empty. The AOT entry point therefore publishes the /// resolved SDK directory as the Microsoft.DotNet.Sdk.Root AppContext value, which this helper /// reads first. Code that needs an SDK-relative path (MSBuild, tasks, tools, forwarders) should use @@ -66,7 +66,7 @@ internal static string ResolveSdkDirectory() return sdkRoot; } - // The SDK assemblies ship in the versioned SDK directory, so the location of this assembly is that + // CoreUtils ships in the versioned SDK directory, so the location of this assembly is that // directory for the JIT-compiled managed CLI. Under a single-file / NativeAOT deployment // Assembly.Location is empty (which is what the IL3000 analyzer flags); fall through to // AppContext.BaseDirectory in that case - the AOT bridge sets the AppContext value (preferred above). diff --git a/test/dotnet-aot.Tests/AotIntegrationTests.cs b/test/dotnet-aot.Tests/AotIntegrationTests.cs index 904a34b88aba..b1e5a5fc1ca4 100644 --- a/test/dotnet-aot.Tests/AotIntegrationTests.cs +++ b/test/dotnet-aot.Tests/AotIntegrationTests.cs @@ -165,7 +165,12 @@ private void RunSeparatedLayoutBasePathTest(bool selfLocate) Directory.CreateDirectory(sdkSubDir); try { + // These are synthetic sentinel values; only their end-to-end appearance in --version matters. + const string expectedVersion = "11.0.100-preview.7.12345.67"; File.Copy(aotSource, Path.Combine(sdkSubDir, aotLib)); + File.WriteAllLines( + Path.Combine(sdkSubDir, ".version"), + ["0123456789abcdef", expectedVersion]); var env = new Dictionary { ["DOTNET_AOT_SDK_DIR"] = sdkSubDir }; if (selfLocate) @@ -189,6 +194,10 @@ private void RunSeparatedLayoutBasePathTest(bool selfLocate) Assert.IsTrue(basePathReferencesSdkDir, $"--info Base Path did not reference the resolved SDK directory '{sdkSubDir}'. Output:\n{stdout}"); + + var (versionExitCode, versionOutput, _) = RunDn(["--version"], enableAot: true, extraEnv: env); + Assert.AreEqual(0, versionExitCode); + Assert.AreEqual(expectedVersion, versionOutput.Trim()); } finally {