diff --git a/eng/Subsets.props b/eng/Subsets.props
index 14b2d3eedab02a..549b541d80a2c0 100644
--- a/eng/Subsets.props
+++ b/eng/Subsets.props
@@ -163,7 +163,7 @@
clr.nativeprereqs+clr.iltools+clr.runtime+clr.native+clr.aot+clr.nativeaotlibs+clr.nativeaotruntime+clr.crossarchtools
- $(AllSubsetsExpansion)+clr.paltests+clr.paltestlist+clr.hosts+clr.jit+clr.alljits+clr.alljitscommunity+clr.spmi+clr.corelib+clr.nativecorelib+clr.tools+clr.toolstests+clr.packages
+ $(AllSubsetsExpansion)+clr.paltests+clr.paltestlist+clr.hosts+clr.jit+clr.alljits+clr.alljitscommunity+clr.spmi+clr.corelib+clr.nativecorelib+clr.tools+clr.toolstests+clr.r2rtests+clr.packages
$(AllSubsetsExpansion)+linuxdac+alpinedac
$(AllSubsetsExpansion)+mono.runtime+provision.emsdk+mono.aotcross+mono.corelib+mono.manifests+mono.packages+mono.tools+mono.wasmruntime+mono.wasiruntime+mono.wasmworkload+mono.mscordbi+mono.workloads
$(AllSubsetsExpansion)+tools.illink+tools.cdac+tools.illinktests+tools.cdactests+tools.cdacdumptests
@@ -227,6 +227,7 @@
+
@@ -508,14 +509,17 @@
Test="true" Category="clr" Condition="'$(DotNetBuildSourceOnly)' != 'true' and '$(NativeAotSupported)' == 'true'"/>
-
+
+
+
+
<_CDacToolsBuilt Condition="'$(_CDacToolsBuilt)' != 'true'">true
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 130f23b0a097d4..5dfa9e699e1aa9 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -223,6 +223,7 @@ extends:
eq(variables['wasmDarcDependenciesChanged'], true),
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true),
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_coreclr_runtimetests.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(variables['isRollingBuild'], true))
- template: /eng/pipelines/common/platform-matrix.yml
@@ -882,6 +883,53 @@ extends:
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true),
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_cdac.containsChange'], true),
eq(variables['isRollingBuild'], true))
+
+ - template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ buildConfig: checked
+ platforms:
+ - linux_x64
+ jobParameters:
+ dependsOn:
+ - build_browser_wasm_linux_checked_CoreCLR_ReleaseLibraries
+ - build_linux_arm_checked_CoreCLR_ReleaseLibraries
+ - build_linux_x64_checked_CoreCLR_ReleaseLibraries
+ timeoutInMinutes: 120
+ nameSuffix: CLR_R2R_Tests
+ buildArgs: -s clr.r2rtests -lc Release -c $(_BuildConfig) -test /p:RequireTargetArchRuntimePack=true
+ enablePublishTestResults: true
+ testResultsFormat: 'xunit'
+ preBuildSteps:
+ - template: /eng/pipelines/common/download-artifact-step.yml
+ parameters:
+ artifactName: CoreCLR_ReleaseLibraries_BuildArtifacts_browser_wasm_linux_Checked
+ artifactFileName: CoreCLR_ReleaseLibraries_BuildArtifacts_browser_wasm_linux_Checked$(archiveExtension)
+ unpackFolder: $(Build.SourcesDirectory)/artifacts/bin
+ cleanUnpackFolder: false
+ overwriteExistingFiles: true
+ displayName: Download browser-wasm artifacts
+ - template: /eng/pipelines/common/download-artifact-step.yml
+ parameters:
+ artifactName: CoreCLR_ReleaseLibraries_BuildArtifacts_linux_arm_Checked
+ artifactFileName: CoreCLR_ReleaseLibraries_BuildArtifacts_linux_arm_Checked$(archiveExtension)
+ unpackFolder: $(Build.SourcesDirectory)/artifacts/bin
+ cleanUnpackFolder: false
+ overwriteExistingFiles: true
+ displayName: Download linux-arm artifacts
+ - template: /eng/pipelines/common/download-artifact-step.yml
+ parameters:
+ artifactName: CoreCLR_ReleaseLibraries_BuildArtifacts_linux_x64_Checked
+ artifactFileName: CoreCLR_ReleaseLibraries_BuildArtifacts_linux_x64_Checked$(archiveExtension)
+ unpackFolder: $(Build.SourcesDirectory)/artifacts/bin
+ cleanUnpackFolder: false
+ overwriteExistingFiles: true
+ displayName: Download linux-x64 artifacts
+ condition: >-
+ or(
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
+ eq(variables['isRollingBuild'], true))
+
#
# Build CrossDacs
#
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj
index e3f0ab6ea0cd15..17373e0c6f8457 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj
@@ -4,14 +4,10 @@
ILCompiler.ReadyToRun.Tests
$(NetCoreAppToolCurrent)
enable
- false
true
- x64;x86
- AnyCPU
- linux-x64;win-x64;osx-x64
- Debug;Release;Checked
true
-notrait category=failing
+ false
@@ -19,92 +15,98 @@
+
+
+
+
+
+
-
-
- CopyAllJitLibrariesToAotCompilerOutput=true
- Configuration=$(CoreCLRConfiguration);CopyAllJitLibrariesToAotCompilerOutput=true
+
+ Configuration=$(CoreCLRConfiguration);CopyAllJitLibrariesToAotCompilerOutput=true
-
- <_BuildJitsCrossArch Condition="'$(CrossBuild)' == 'true' or '$(BuildArchitecture)' != '$(TargetArchitecture)' or '$(HostOS)' != '$(TargetOS)' or '$(EnableNativeSanitizers)' != ''">true
- <_BuildJitsProperties>ClrAllJitsSubset=true;ClrWasmJitSubset=true;Configuration=$(CoreCLRConfiguration)
- <_BuildJitsProperties Condition="!$([MSBuild]::IsOsPlatform(Windows))">$(_BuildJitsProperties);Ninja=true
- <_BuildJitsProperties Condition="'$(_BuildJitsCrossArch)' == 'true'">$(_BuildJitsProperties);HostArchitecture=$(BuildArchitecture);HostCrossOS=$(HostOS);CrossBuild=false;BuildSubdirectory=$(BuildArchitecture);CMakeArgs=$(CMakeArgs) -DCLR_CROSS_COMPONENTS_BUILD=1;PgoInstrument=false;NoPgoOptimize=true
+ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'microsoft.netcore.app.runtime.browser-wasm'))
+ $([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', '$(LibrariesConfiguration)', 'runtimes', 'browser-wasm', 'lib', '$(NetCoreAppCurrent)'))
+ $([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', '$(LibrariesConfiguration)', 'runtimes', 'browser-wasm', 'native'))
+ $([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', 'Release', 'runtimes', 'browser-wasm', 'lib', '$(NetCoreAppCurrent)'))
+ $([MSBuild]::NormalizeDirectory('$(WasmRuntimePackRoot)', 'Release', 'runtimes', 'browser-wasm', 'native'))
+
+ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'microsoft.netcore.app.runtime.$(TargetOS)-arm'))
+ $([MSBuild]::NormalizeDirectory('$(ArmRuntimePackRoot)', '$(LibrariesConfiguration)', 'runtimes', '$(TargetOS)-arm', 'lib', '$(NetCoreAppCurrent)'))
+ $([MSBuild]::NormalizeDirectory('$(ArmRuntimePackRoot)', '$(LibrariesConfiguration)', 'runtimes', '$(TargetOS)-arm', 'native'))
+ $([MSBuild]::NormalizeDirectory('$(ArmRuntimePackRoot)', 'Release', 'runtimes', '$(TargetOS)-arm', 'lib', '$(NetCoreAppCurrent)'))
+ $([MSBuild]::NormalizeDirectory('$(ArmRuntimePackRoot)', 'Release', 'runtimes', '$(TargetOS)-arm', 'native'))
-
-
-
-
- <_WasmJitCrossHostArchSubdir Condition="'$(_BuildJitsCrossArch)' == 'true'">$(BuildArchitecture)/
- <_WasmJitFileName>$(HostLibPrefix)clrjit_universal_wasm_$(BuildArchitecture)$(HostLibSuffix)
- <_WasmJitSourcePath>$(CoreCLRArtifactsPath)$(_WasmJitCrossHostArchSubdir)$(_WasmJitFileName)
- <_Crossgen2InbuildPublishDir>$(CoreCLRArtifactsPath)$(BuildArchitecture)/crossgen2/
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
-
-
-
- $(CoreCLRArtifactsPath)/$(BuildArchitecture)/crossgen2
-
-
- $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)
-
-
- $(MicrosoftNetCoreAppRuntimePackNativeDir)
-
-
- $(MicrosoftNetCoreAppRefPackRefDir)
-
-
- $(CoreCLRArtifactsPath)
-
-
- $(TargetArchitecture)
-
-
- $(TargetOS)
-
-
- $(CoreCLRConfiguration)
-
-
+
+
+ @(Crossgen2InbuildOutputItems->WithMetadataValue('Filename', 'crossgen2')->WithMetadataValue('Extension', '$(ExeSuffix)')->'%(RootDir)%(Directory)')
+
+
+ $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)
+
+
+ $(MicrosoftNetCoreAppRuntimePackNativeDir)
+
+
+
+ $(RequireTargetArchRuntimePack)
+
+
+
+ $(WasmRuntimePackDir)
+
+
+ $(WasmRuntimePackNativeDir)
+
+
+
+ $(ArmRuntimePackDir)
+
+
+ $(ArmRuntimePackNativeDir)
+
+
+
+
+ $(CoreCLRConfiguration)
+
+
+
+
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/R2RTestSuites.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/R2RTestSuites.cs
index 09e98fcc6a088b..1223c2f30db233 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/R2RTestSuites.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/R2RTestSuites.cs
@@ -77,13 +77,10 @@ public void WasmWebcilModule()
new(nameof(WasmWebcilModule), [new CrossgenAssembly(wasmWebcilModule)])
{
OutputFileExtension = ".wasm",
- AdditionalArgs =
- {
- "--targetarch",
- "wasm",
- "--targetos",
- "browser",
- },
+ // Reference the real browser-wasm framework assemblies when they are available
+ // (e.g. the wasm tools-test job downloads them); otherwise the runner falls back
+ // to host references so this test still runs everywhere.
+ TargetRid = TargetRid.BrowserWasm,
Validate = Validate,
},
]));
@@ -235,7 +232,7 @@ static void Validate(ReadyToRunReader reader)
}
}
- [Fact]
+ [ConditionalFact(typeof(TestPaths), nameof(TestPaths.ArmOnHostOSSupported))]
public void ArmThumbBitRelocationTargets()
{
var inlineableLib = new CompiledAssembly
@@ -259,7 +256,7 @@ public void ArmThumbBitRelocationTargets()
new CrossgenAssembly(inlineableLib) { Kind = Crossgen2InputKind.Reference },
])
{
- Options = [Crossgen2Option.TargetArchArm],
+ TargetRid = TargetRid.HostArm,
Validate = Validate,
},
]));
@@ -272,7 +269,7 @@ static void Validate(ReadyToRunReader reader)
}
// JitStressProcedureSplitting is only available in Debug/Checked JIT builds.
- [ConditionalFact(typeof(TestPaths), nameof(TestPaths.IsNotReleaseCoreCLR))]
+ [ConditionalFact(typeof(TestPaths), nameof(TestPaths.IsNotReleaseCoreCLR), nameof(TestPaths.ArmOnHostOSSupported))]
public void ArmThumbBitHotColdRuntimeFunctions()
{
var hotColdSplitting = new CompiledAssembly
@@ -286,9 +283,9 @@ public void ArmThumbBitHotColdRuntimeFunctions()
[
new(nameof(ArmThumbBitHotColdRuntimeFunctions), [new CrossgenAssembly(hotColdSplitting)])
{
+ TargetRid = TargetRid.HostArm,
Options =
[
- Crossgen2Option.TargetArchArm,
Crossgen2Option.Optimize,
Crossgen2Option.HotColdSplitting,
],
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RDriver.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RDriver.cs
index a359f7bfa45d05..24341440e31f35 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RDriver.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RDriver.cs
@@ -18,6 +18,13 @@ internal enum Crossgen2AssemblyOption
CrossModuleOptimization,
}
+internal enum CoreLibTargetArchitecture
+{
+ Host,
+ Arm32,
+ Wasm
+}
+
internal enum Crossgen2InputKind
{
InputAssembly,
@@ -32,7 +39,6 @@ internal enum Crossgen2Option
InputBubble,
HotColdSplitting,
Optimize,
- TargetArchArm,
StripILBodies,
}
@@ -59,7 +65,6 @@ internal static class Crossgen2OptionsExtensions
Crossgen2Option.InputBubble => $"--input-bubble",
Crossgen2Option.HotColdSplitting => $"--hot-cold-splitting",
Crossgen2Option.Optimize => $"--optimize",
- Crossgen2Option.TargetArchArm => $"--targetarch:arm",
Crossgen2Option.StripILBodies => $"--strip-il-bodies",
_ => throw new ArgumentOutOfRangeException(nameof(kind)),
};
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RResultChecker.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RResultChecker.cs
index 33b4ed1d743516..f7f11d6f5c5369 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RResultChecker.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RResultChecker.cs
@@ -1194,11 +1194,15 @@ public static bool MethodILIsPresent(string msilFilePath, string declaringType,
///
internal sealed class SimpleAssemblyResolver : IAssemblyResolver
{
- private readonly TestPaths _paths;
+ private readonly Dictionary _assemblyPaths;
- public SimpleAssemblyResolver(TestPaths paths)
+ public SimpleAssemblyResolver(IEnumerable referencePaths)
{
- _paths = paths;
+ _assemblyPaths = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ foreach (string referencePath in referencePaths)
+ {
+ _assemblyPaths[Path.GetFileNameWithoutExtension(referencePath)] = referencePath;
+ }
}
public IAssemblyMetadata? FindAssembly(MetadataReader metadataReader, AssemblyReferenceHandle assemblyReferenceHandle, string parentFile)
@@ -1217,10 +1221,12 @@ public SimpleAssemblyResolver(TestPaths paths)
string candidate = Path.Combine(dir, simpleName + ".dll");
if (!File.Exists(candidate))
- candidate = Path.Combine(_paths.RuntimePackDir, simpleName + ".dll");
+ {
+ if (!_assemblyPaths.TryGetValue(simpleName, out string? referencePath) || referencePath is null)
+ return null;
- if (!File.Exists(candidate))
- return null;
+ candidate = referencePath;
+ }
return new SimpleAssemblyMetadata(candidate);
}
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestCaseCompiler.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestCaseCompiler.cs
index 7bd12c8887fe59..476ac89c09ce6e 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestCaseCompiler.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestCaseCompiler.cs
@@ -19,26 +19,13 @@ internal sealed class R2RTestCaseCompiler
{
private readonly List _frameworkReferences;
- public R2RTestCaseCompiler(TestPaths paths)
+ public R2RTestCaseCompiler(List references)
{
_frameworkReferences = new List();
- // Add reference assemblies from the ref pack (needed for Roslyn compilation)
- string refPackDir = paths.RefPackDir;
- if (Directory.Exists(refPackDir))
+ foreach (string refPath in references)
{
- foreach (string refPath in Directory.EnumerateFiles(refPackDir, "*.dll"))
- {
- _frameworkReferences.Add(MetadataReference.CreateFromFile(refPath));
- }
- }
- else
- {
- // Fallback to runtime pack implementation assemblies
- foreach (string refPath in paths.GetFrameworkReferencePaths())
- {
- _frameworkReferences.Add(MetadataReference.CreateFromFile(refPath));
- }
+ _frameworkReferences.Add(MetadataReference.CreateFromFile(refPath));
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestRunner.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestRunner.cs
index c6a2e26649671e..ce88a5bff97241 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestRunner.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestRunner.cs
@@ -11,6 +11,13 @@
namespace ILCompiler.ReadyToRun.Tests.TestCasesRunner;
+enum TargetRid
+{
+ Host,
+ HostArm,
+ BrowserWasm
+}
+
///
/// Describes an assembly compiled by Roslyn as part of a test case.
///
@@ -94,6 +101,8 @@ internal sealed class CrossgenCompilation(string name, List as
///
public Action? Validate { get; init; }
+ public TargetRid TargetRid { get; init; } = TargetRid.Host;
+
public string Name => name;
public bool IsComposite => Options.Contains(Crossgen2Option.Composite);
@@ -205,10 +214,24 @@ public void Run(R2RTestCase testCase)
// Step 2: Run each crossgen2 compilation and validate
var driver = new R2RDriver(_output, _paths);
- var refPaths = BuildReferencePaths();
+ List hostRefPaths = BuildReferencePaths(CoreLibTargetArchitecture.Host);
+ List? wasmRefPaths = null;
+ List? armRefPaths = null;
foreach(var compilation in testCase.Compilations)
{
+ List refPaths = hostRefPaths;
+ if (compilation.TargetRid == TargetRid.BrowserWasm)
+ {
+ wasmRefPaths ??= BuildReferencePaths(CoreLibTargetArchitecture.Wasm);
+ refPaths = wasmRefPaths;
+ }
+ else if (compilation.TargetRid == TargetRid.HostArm)
+ {
+ armRefPaths ??= BuildReferencePaths(CoreLibTargetArchitecture.Arm32);
+ refPaths = armRefPaths;
+ }
+
string outputPath = RunCrossgenCompilation(
testCase.Name, compilation, driver, compilation.FilePath, refPaths, assemblyPaths);
@@ -216,7 +239,7 @@ public void Run(R2RTestCase testCase)
{
Assert.True(File.Exists(outputPath), $"R2R image not found: {outputPath}");
_output.WriteLine($" Validating R2R image: {outputPath}");
- var reader = new ReadyToRunReader(new SimpleAssemblyResolver(_paths), outputPath);
+ var reader = new ReadyToRunReader(new SimpleAssemblyResolver(refPaths), outputPath);
compilation.Validate(reader);
}
}
@@ -234,9 +257,11 @@ public void Run(R2RTestCase testCase)
private Dictionary CompileAllAssemblies(
IEnumerable assemblies)
{
- var compiler = new R2RTestCaseCompiler(_paths);
var paths = new Dictionary();
+ // Tests shouldn't require a platform-specific runtime/ref pack for Roslyn compilation
+ var defaultReferences = BuildReferencePaths(CoreLibTargetArchitecture.Host);
+ var compiler = new R2RTestCaseCompiler(defaultReferences);
foreach (var asm in assemblies)
{
var sources = asm.SourceResourceNames
@@ -252,7 +277,7 @@ private Dictionary CompileAllAssemblies(
additionalReferences: asm.References.Select(r => r.FilePath).ToList(),
features: asm.Features.Count > 0 ? asm.Features : null);
paths[asm.AssemblyName] = ilPath;
- _output.WriteLine($" Roslyn compiled '{asm.AssemblyName}' -> {ilPath}");
+ _output.WriteLine($"Roslyn compiled '{asm.AssemblyName}' -> {ilPath}");
}
return paths;
@@ -307,6 +332,14 @@ private static string RunCrossgenCompilation(
foreach (var option in compilation.Options)
args.Add(option.ToArg());
+ args.AddRange(compilation.TargetRid switch
+ {
+ TargetRid.Host => [],
+ TargetRid.HostArm => ["--targetarch", "arm"],
+ TargetRid.BrowserWasm => ["--targetos", "browser", "--targetarch", "wasm"],
+ _ => throw new InvalidOperationException($"Unknown target RID: {compilation.TargetRid}")
+ });
+
// Caller-supplied raw args (for options that take values, e.g. --determinism-stress=N)
args.AddRange(compilation.AdditionalArgs);
@@ -335,33 +368,46 @@ private static void AddRefArgs(List args, List refPaths)
}
}
- private List BuildReferencePaths()
+ ///
+ /// Runtime packs are used as references for both Roslyn compilation and crossgen2 compilation. This method builds the reference paths for both.
+ ///
+ private List BuildReferencePaths(CoreLibTargetArchitecture coreLibArch)
{
- var paths = new List();
-
- paths.Add(Path.Combine(_paths.RuntimePackDir, "*.dll"));
-
- // SPCL lives in the runtime pack native/ dir in full builds (placed by
- // externals.csproj BinPlace during libs.pretest). In partial CI builds
- // that skip libs.pretest, the runtime pack layout may not exist, but the
- // CoreCLR artifacts directory always has SPCL after clr.nativecorelib.
- string spcl = Path.Combine(_paths.RuntimePackNativeDir, "System.Private.CoreLib.dll");
- if (!File.Exists(spcl))
+ List paths;
+ (string runtimePackDir, string runtimePackNativeDir) = coreLibArch switch
{
- string fallback = Path.Combine(_paths.CoreCLRArtifactsDir, "System.Private.CoreLib.dll");
- if (File.Exists(fallback))
+ CoreLibTargetArchitecture.Host => (_paths.RuntimePackDir, _paths.RuntimePackNativeDir),
+ CoreLibTargetArchitecture.Arm32 => (_paths.ArmRuntimePackDir, _paths.ArmRuntimePackNativeDir),
+ CoreLibTargetArchitecture.Wasm => (_paths.WasmRuntimePackDir, _paths.WasmRuntimePackNativeDir),
+ _ => throw new InvalidOperationException($"Unknown CoreLibTargetArchitecture: {coreLibArch}")
+ };
+ if (!RuntimePackPathsAreValid(runtimePackDir, runtimePackNativeDir))
+ {
+ if (_paths.RequireTargetArchRuntimePack)
{
- _output.WriteLine($"[R2RTestRunner] SPCL not found at '{spcl}'; using CoreCLR artifacts fallback '{fallback}'");
- spcl = fallback;
+ throw new InvalidOperationException($"Required runtime pack for {coreLibArch} not found: {runtimePackDir} or {runtimePackNativeDir}");
+ }
+ else
+ {
+ _output.WriteLine($"Warning: Required runtime pack for {coreLibArch} not found: {runtimePackDir} or {runtimePackNativeDir}. Falling back to host references.");
+ (runtimePackDir, runtimePackNativeDir) = (_paths.RuntimePackDir, _paths.RuntimePackNativeDir);
}
}
- Assert.True(File.Exists(spcl),
- $"System.Private.CoreLib.dll not found at '{spcl}'. " +
- $"Searched RuntimePackNativeDir='{_paths.RuntimePackNativeDir}' and " +
- $"CoreCLRArtifactsDir='{_paths.CoreCLRArtifactsDir}'");
- paths.Add(spcl);
+ string coreLibPath = Path.Combine(runtimePackNativeDir, "System.Private.CoreLib.dll");
+ Assert.True(File.Exists(coreLibPath), $"System.Private.CoreLib.dll not found: {coreLibPath}");
+ Assert.True(Directory.Exists(runtimePackDir), $"Runtime pack directory not found: {runtimePackDir}");
+
+ paths = [
+ ..Directory.GetFiles(runtimePackDir, "*.dll"),
+ coreLibPath
+ ];
return paths;
+
+ bool RuntimePackPathsAreValid(string runtimePackDir, string runtimePackNativeDir)
+ {
+ return Directory.Exists(runtimePackDir) && File.Exists(Path.Combine(runtimePackNativeDir, "System.Private.CoreLib.dll"));
+ }
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs
index be18b5ff9aeb91..f6bff9fe1b2305 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
@@ -29,76 +28,13 @@ private static string GetRequiredConfig(string key)
?? throw new InvalidOperationException($"Missing RuntimeHostConfigurationOption '{key}'. Was the project built with the correct properties?");
}
- ///
- /// Tries to find an existing directory by swapping the build configuration path segment
- /// (Debug, Release, Checked) in the path. Returns the first match, or the original
- /// path if no fallback exists.
- ///
- private string ProbeConfigFallback(string dir)
- {
- if (Directory.Exists(dir))
- return dir;
-
- foreach (string fallbackConfig in new[] { "Release", "Checked", "Debug" })
- {
- string fallback = Regex.Replace(
- dir, @"(?<=[/\\])(Debug|Release|Checked)(?=[/\\])", fallbackConfig);
- if (fallback != dir && Directory.Exists(fallback))
- {
- _output.WriteLine($"[TestPaths] '{dir}' not found; falling back to '{fallback}'");
- return fallback;
- }
- }
-
- return dir;
- }
-
- ///
- /// Like but for paths where the configuration name
- /// is embedded in a dot-delimited segment (e.g. linux.x64.Checked).
- ///
- private string ProbeDottedConfigFallback(string dir)
- {
- if (Directory.Exists(dir))
- return dir;
-
- foreach (string fallbackConfig in new[] { "Checked", "Release", "Debug" })
- {
- string fallback = Regex.Replace(
- dir, @"\.(Debug|Release|Checked)([/\\])", $".{fallbackConfig}$2");
- if (fallback != dir && Directory.Exists(fallback))
- {
- _output.WriteLine($"[TestPaths] '{dir}' not found; falling back to '{fallback}'");
- return fallback;
- }
- }
-
- return dir;
- }
-
///
/// Path to the crossgen2 output directory (contains the self-contained crossgen2 executable and clrjit).
/// e.g. artifacts/bin/coreclr/linux.x64.Checked/x64/crossgen2/
- /// Falls back to Checked or Release if the configured path doesn't exist.
///
- public string Crossgen2Dir
- {
- get
- {
- string dir = GetRequiredConfig("R2RTest.Crossgen2Dir");
- if (!File.Exists(Path.Combine(dir, Crossgen2ExeName)))
- {
- string fallback = ProbeDottedConfigFallback(dir);
- if (File.Exists(Path.Combine(fallback, Crossgen2ExeName)))
- return fallback;
- }
+ public string Crossgen2Dir => GetRequiredConfig("R2RTest.Crossgen2Dir");
- return dir;
- }
- }
-
- private static string Crossgen2ExeName =>
- RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "crossgen2.exe" : "crossgen2";
+ private static string Crossgen2ExeName => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "crossgen2.exe" : "crossgen2";
///
/// Path to the self-contained crossgen2 executable (from crossgen2_inbuild).
@@ -106,97 +42,38 @@ public string Crossgen2Dir
public string Crossgen2Exe => Path.Combine(Crossgen2Dir, Crossgen2ExeName);
///
- /// Path to the runtime pack managed assemblies directory.
- /// e.g. artifacts/bin/microsoft.netcore.app.runtime.linux-x64/Release/runtimes/linux-x64/lib/net11.0/
- /// Falls back to a different build configuration if the path doesn't exist.
+ /// Path to the host runtime pack managed assemblies directory.
///
- public string RuntimePackDir
- {
- get
- {
- string dir = GetRequiredConfig("R2RTest.RuntimePackDir");
- return ProbeConfigFallback(dir);
- }
- }
+ public string RuntimePackDir => GetRequiredConfig("R2RTest.RuntimePackDir");
///
- /// Path to the runtime pack native directory (contains System.Private.CoreLib.dll and native runtime).
- /// e.g. artifacts/bin/microsoft.netcore.app.runtime.linux-x64/Release/runtimes/linux-x64/native/
- /// Falls back to a different build configuration if the path doesn't exist.
+ /// Path to the host runtime pack native directory.
///
- public string RuntimePackNativeDir
- {
- get
- {
- string dir = GetRequiredConfig("R2RTest.RuntimePackNativeDir");
- return ProbeConfigFallback(dir);
- }
- }
+ public string RuntimePackNativeDir => GetRequiredConfig("R2RTest.RuntimePackNativeDir");
///
- /// Path to the CoreCLR artifacts directory (contains native bits like corerun).
- /// e.g. artifacts/bin/coreclr/linux.x64.Checked/
- /// Falls back to Checked or Release if the configured path doesn't exist.
+ /// Path to the browser-wasm runtime pack managed assemblies directory.
+ /// When present, the wasm crossgen2 compilation references these real browser-wasm
+ /// framework assemblies instead of the host runtime pack.
///
- public string CoreCLRArtifactsDir
- {
- get
- {
- string dir = GetRequiredConfig("R2RTest.CoreCLRArtifactsDir");
- return ProbeDottedConfigFallback(dir);
- }
- }
-
- public static string TargetArchitecture => GetRequiredConfig("R2RTest.TargetArchitecture");
- public static string TargetOS => GetRequiredConfig("R2RTest.TargetOS");
- public static string CoreCLRConfiguration => GetRequiredConfig("R2RTest.CoreCLRConfiguration");
- public static bool IsReleaseCoreCLR => string.Equals(CoreCLRConfiguration, "Release", StringComparison.OrdinalIgnoreCase);
- public static bool IsNotReleaseCoreCLR => !IsReleaseCoreCLR;
+ public string WasmRuntimePackDir => GetRequiredConfig("R2RTest.WasmRuntimePackDir");
///
- /// Path to the reference assembly pack (for Roslyn compilation).
- /// e.g. artifacts/bin/microsoft.netcore.app.ref/ref/net11.0/
+ /// Path to the browser-wasm runtime pack native directory (contains the wasm
+ /// System.Private.CoreLib.dll).
///
- public string RefPackDir
- {
- get
- {
- string dir = GetRequiredConfig("R2RTest.RefPackDir");
- if (!Directory.Exists(dir))
- {
- // Try the artifacts/bin/ref/net* fallback
- string artifactsBin = Path.GetFullPath(Path.Combine(CoreCLRArtifactsDir, "..", ".."));
- string refDir = Path.Combine(artifactsBin, "ref");
- if (Directory.Exists(refDir))
- {
- foreach (string subDir in Directory.GetDirectories(refDir, "net*"))
- {
- if (File.Exists(Path.Combine(subDir, "System.Runtime.dll")))
- {
- _output.WriteLine($"[TestPaths] '{dir}' not found; falling back to '{subDir}'");
- return subDir;
- }
- }
- }
- }
+ public string WasmRuntimePackNativeDir => GetRequiredConfig("R2RTest.WasmRuntimePackNativeDir");
- return dir;
- }
- }
+ public string ArmRuntimePackDir => GetRequiredConfig("R2RTest.ArmRuntimePackDir");
+ public string ArmRuntimePackNativeDir => GetRequiredConfig("R2RTest.ArmRuntimePackNativeDir");
- ///
- /// Returns the target triple string for crossgen2 (e.g. "linux-x64").
- ///
- public static string TargetTriple => $"{TargetOS.ToLowerInvariant()}-{TargetArchitecture.ToLowerInvariant()}";
-
- ///
- /// Returns all framework reference assembly paths (*.dll in the runtime pack).
- ///
- public IEnumerable GetFrameworkReferencePaths()
- {
- if (!Directory.Exists(RuntimePackDir))
- throw new DirectoryNotFoundException($"Runtime pack directory not found: {RuntimePackDir}");
+ public bool RequireTargetArchRuntimePack => string.Equals(
+ GetRequiredConfig("R2RTest.RequireTargetArchRuntimePack"),
+ bool.TrueString,
+ StringComparison.OrdinalIgnoreCase);
- return Directory.EnumerateFiles(RuntimePackDir, "*.dll");
- }
+ public static string CoreCLRConfiguration => GetRequiredConfig("R2RTest.CoreCLRConfiguration");
+ public static bool IsReleaseCoreCLR => string.Equals(CoreCLRConfiguration, "Release", StringComparison.OrdinalIgnoreCase);
+ public static bool IsNotReleaseCoreCLR => !IsReleaseCoreCLR;
+ public static bool ArmOnHostOSSupported => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
}
diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj
index 45a5d877f608a9..063aa3124cd217 100644
--- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj
+++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj
@@ -14,8 +14,6 @@
NetCore.SharedFramework
true
true
-
- true