Skip to content

Commit b134fa2

Browse files
Implement resource lookup in satellite assemblies (#86689)
Fixes #86651. This was implemented in .NET Native so we just need to resurface it from the compiler. Note that this is not full support for satellite assemblies (in the assembly binder, etc.) that never existed and nobody ever asked for and I don't even know what it entails.
1 parent 182591a commit b134fa2

File tree

12 files changed

+53
-11
lines changed

12 files changed

+53
-11
lines changed

src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
DependsOnTargets="$(IlcDynamicBuildPropertyDependencies)">
66
<ItemGroup>
77
<IlcReference Include="@(_ManagedResolvedAssembliesToPublish)" />
8+
<IlcSatelliteAssembly Include="@(_SatelliteAssembliesToPublish)" />
9+
<IlcSatelliteAssembly Include="@(IntermediateSatelliteAssembliesWithTargetPath)" />
810
</ItemGroup>
911
</Target>
1012

@@ -82,6 +84,7 @@
8284
FrameworkAssemblies="@(FrameworkAssemblies)">
8385

8486
<Output TaskParameter="ManagedAssemblies" ItemName="_ManagedResolvedAssembliesToPublish" />
87+
<Output TaskParameter="SatelliteAssemblies" ItemName="_SatelliteAssembliesToPublish" />
8588
<Output TaskParameter="AssembliesToSkipPublish" ItemName="_AssembliesToSkipPublish" />
8689
</ComputeManagedAssembliesToCompileToNative>
8790

src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ The .NET Foundation licenses this file to you under the MIT license.
194194
<IlcArg Include="@(IlcCompileInput)" />
195195
<IlcArg Include="-o:$(NativeIntermediateOutputPath)%(ManagedBinary.Filename)$(IlcOutputFileExt)" />
196196
<IlcArg Include="@(IlcReference->'-r:%(Identity)')" />
197+
<IlcArg Include="@(IlcSatelliteAssembly->'--satellite:%(Identity)')" />
197198
<IlcArg Include="@(MibcFile->'--mibc:%(Identity)')" />
198199
<IlcArg Condition="$(IlcGenerateMetadataLog) == 'true'" Include="--metadatalog:$(NativeIntermediateOutputPath)%(ManagedBinary.Filename).metadata.csv" />
199200
<IlcArg Condition="$(_targetOS) != ''" Include="--targetos:$(_targetOS)" />
@@ -262,7 +263,7 @@ The .NET Foundation licenses this file to you under the MIT license.
262263
</Target>
263264

264265
<Target Name="IlcCompile"
265-
Inputs="@(IlcCompileInput);@(IlcReference);@(RdXmlFile);%(ManagedBinary.IlcRspFile)"
266+
Inputs="@(IlcCompileInput);@(IlcReference);@(IlcSatelliteAssembly);@(RdXmlFile);%(ManagedBinary.IlcRspFile)"
266267
Outputs="%(ManagedBinary.IlcOutputFile)"
267268
DependsOnTargets="WriteIlcRspFileForCompilation;$(IlcCompileDependsOn)">
268269
<Message Text="Generating native code" Importance="high" />

src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ public ITaskItem[] ManagedAssemblies
8080
set;
8181
}
8282

83+
[Output]
84+
public ITaskItem[] SatelliteAssemblies
85+
{
86+
get;
87+
set;
88+
}
89+
8390
[Output]
8491
public ITaskItem[] AssembliesToSkipPublish
8592
{
@@ -91,6 +98,7 @@ public override bool Execute()
9198
{
9299
var list = new List<ITaskItem>();
93100
var assembliesToSkipPublish = new List<ITaskItem>();
101+
var satelliteAssemblies = new List<ITaskItem>();
94102
var nativeAotFrameworkAssembliesToUse = new HashSet<string>();
95103

96104
foreach (ITaskItem taskItem in SdkAssemblies)
@@ -164,11 +172,16 @@ public override bool Execute()
164172
string culture = moduleMetadataReader.GetString(moduleMetadataReader.GetAssemblyDefinition().Culture);
165173

166174
assembliesToSkipPublish.Add(taskItem);
175+
176+
// Split satellite assemblies from normal assemblies
167177
if (culture == "" || culture.Equals("neutral", StringComparison.OrdinalIgnoreCase))
168178
{
169-
// NativeAOT doesn't consume resource assemblies yet so skip them
170179
list.Add(taskItem);
171180
}
181+
else
182+
{
183+
satelliteAssemblies.Add(taskItem);
184+
}
172185
}
173186
}
174187
}
@@ -180,6 +193,7 @@ public override bool Execute()
180193

181194
ManagedAssemblies = list.ToArray();
182195
AssembliesToSkipPublish = assembliesToSkipPublish.ToArray();
196+
SatelliteAssemblies = satelliteAssemblies.ToArray();
183197

184198
return true;
185199
}

src/coreclr/tools/aot/ILCompiler.Compiler.Tests/DependencyGraphTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void TestDependencyGraphInvariants(EcmaMethod method)
7373
new FullyBlockedMetadataBlockingPolicy(), new FullyBlockedManifestResourceBlockingPolicy(),
7474
null, new NoStackTraceEmissionPolicy(), new NoDynamicInvokeThunkGenerationPolicy(),
7575
new ILLink.Shared.TrimAnalysis.FlowAnnotations(Logger.Null, ilProvider, compilerGeneratedState), UsageBasedMetadataGenerationOptions.None,
76-
default, Logger.Null, Array.Empty<KeyValuePair<string, bool>>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>());
76+
default, Logger.Null, Array.Empty<KeyValuePair<string, bool>>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>());
7777

7878
CompilationBuilder builder = new RyuJitCompilationBuilder(context, compilationGroup)
7979
.UseILProvider(ilProvider);

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
4444
dependencies.Add(factory.ReflectedMethod(entrypoint), "Reflectable entrypoint");
4545
}
4646

47-
CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, (EcmaAssembly)_module);
47+
EcmaAssembly ecmaAssembly = (EcmaAssembly)_module;
48+
49+
CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ecmaAssembly);
50+
51+
foreach (EcmaModule satelliteModule in ((UsageBasedMetadataManager)factory.MetadataManager).GetSatelliteAssemblies(ecmaAssembly))
52+
{
53+
dependencies.Add(factory.ModuleMetadata(satelliteModule), "Satellite assembly");
54+
}
4855

4956
return dependencies;
5057
}

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ private static (string AttributeName, DiagnosticId Id)[] _requiresAttributeMisma
6363

6464
private readonly HashSet<string> _rootEntireAssembliesModules;
6565
private readonly HashSet<string> _trimmedAssemblies;
66+
private readonly List<string> _satelliteAssemblyFiles;
6667

6768
internal FlowAnnotations FlowAnnotations { get; }
6869

@@ -83,7 +84,8 @@ public UsageBasedMetadataManager(
8384
IEnumerable<KeyValuePair<string, bool>> featureSwitchValues,
8485
IEnumerable<string> rootEntireAssembliesModules,
8586
IEnumerable<string> additionalRootedAssemblies,
86-
IEnumerable<string> trimmedAssemblies)
87+
IEnumerable<string> trimmedAssemblies,
88+
IEnumerable<string> satelliteAssemblyFilePaths)
8789
: base(typeSystemContext, blockingPolicy, resourceBlockingPolicy, logFile, stackTracePolicy, invokeThunkGenerationPolicy, options)
8890
{
8991
_compilationModuleGroup = group;
@@ -98,6 +100,20 @@ public UsageBasedMetadataManager(
98100
_rootEntireAssembliesModules = new HashSet<string>(rootEntireAssembliesModules);
99101
_rootEntireAssembliesModules.UnionWith(additionalRootedAssemblies);
100102
_trimmedAssemblies = new HashSet<string>(trimmedAssemblies);
103+
_satelliteAssemblyFiles = new List<string>(satelliteAssemblyFilePaths);
104+
}
105+
106+
public IEnumerable<EcmaModule> GetSatelliteAssemblies(EcmaAssembly module)
107+
{
108+
string expectedSimpleName = module.GetName().Name + ".resources";
109+
foreach (string filePath in _satelliteAssemblyFiles)
110+
{
111+
string simpleName = Path.GetFileNameWithoutExtension(filePath);
112+
if (simpleName == expectedSimpleName)
113+
{
114+
yield return _typeSystemContext.GetMetadataOnlyModuleFromPath(filePath);
115+
}
116+
}
101117
}
102118

103119
protected override void Graph_NewMarkedNode(DependencyNodeCore<NodeFactory> obj)

src/coreclr/tools/aot/ILCompiler/ILCompiler.props

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
<ServerGarbageCollection>true</ServerGarbageCollection>
1616
<TieredCompilation>false</TieredCompilation>
1717
<EventSourceSupport>true</EventSourceSupport>
18-
<InvariantGlobalization>true</InvariantGlobalization>
1918
<OptimizationPreference>Speed</OptimizationPreference>
2019
</PropertyGroup>
2120

src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ internal sealed class ILCompilerRootCommand : RootCommand
2828
new(new[] { "--optimize-time", "--Ot" }, "Enable optimizations, favor code speed");
2929
public Option<string[]> MibcFilePaths { get; } =
3030
new(new[] { "--mibc", "-m" }, Array.Empty<string>, "Mibc file(s) for profile guided optimization");
31+
public Option<string[]> SatelliteFilePaths { get; } =
32+
new(new[] { "--satellite" }, Array.Empty<string>, "Satellite assemblies associated with inputs/references");
3133
public Option<bool> EnableDebugInfo { get; } =
3234
new(new[] { "--debug", "-g" }, "Emit debugging information");
3335
public Option<bool> UseDwarf5 { get; } =
@@ -173,6 +175,7 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler")
173175
AddOption(OptimizeSpace);
174176
AddOption(OptimizeTime);
175177
AddOption(MibcFilePaths);
178+
AddOption(SatelliteFilePaths);
176179
AddOption(EnableDebugInfo);
177180
AddOption(UseDwarf5);
178181
AddOption(NativeLib);

src/coreclr/tools/aot/ILCompiler/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,8 @@ public int Run()
391391
featureSwitches,
392392
Get(_command.ConditionallyRootedAssemblies),
393393
rootedAssemblies,
394-
Get(_command.TrimmedAssemblies));
394+
Get(_command.TrimmedAssemblies),
395+
Get(_command.SatelliteFilePaths));
395396

396397
InteropStateManager interopStateManager = new InteropStateManager(typeSystemContext.GeneratedAssembly);
397398
InteropStubManager interopStubManager = new UsageBasedInteropStubManager(interopStateManager, pinvokePolicy, logger);

src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ public ILScanResults Trim (ILCompilerOptions options, ILogWriter logWriter)
111111
Array.Empty<KeyValuePair<string, bool>> (),
112112
Array.Empty<string> (),
113113
options.AdditionalRootAssemblies.ToArray (),
114-
options.TrimAssemblies.ToArray ());
114+
options.TrimAssemblies.ToArray (),
115+
Array.Empty<string> ());
115116

116117
PInvokeILEmitterConfiguration pinvokePolicy = new ILCompilerTestPInvokePolicy ();
117118
InteropStateManager interopStateManager = new InteropStateManager (typeSystemContext.GeneratedAssembly);

0 commit comments

Comments
 (0)