Skip to content

Commit

Permalink
Implement resource lookup in satellite assemblies (#86689)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
MichalStrehovsky authored May 29, 2023
1 parent 182591a commit b134fa2
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
DependsOnTargets="$(IlcDynamicBuildPropertyDependencies)">
<ItemGroup>
<IlcReference Include="@(_ManagedResolvedAssembliesToPublish)" />
<IlcSatelliteAssembly Include="@(_SatelliteAssembliesToPublish)" />
<IlcSatelliteAssembly Include="@(IntermediateSatelliteAssembliesWithTargetPath)" />
</ItemGroup>
</Target>

Expand Down Expand Up @@ -82,6 +84,7 @@
FrameworkAssemblies="@(FrameworkAssemblies)">

<Output TaskParameter="ManagedAssemblies" ItemName="_ManagedResolvedAssembliesToPublish" />
<Output TaskParameter="SatelliteAssemblies" ItemName="_SatelliteAssembliesToPublish" />
<Output TaskParameter="AssembliesToSkipPublish" ItemName="_AssembliesToSkipPublish" />
</ComputeManagedAssembliesToCompileToNative>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ The .NET Foundation licenses this file to you under the MIT license.
<IlcArg Include="@(IlcCompileInput)" />
<IlcArg Include="-o:$(NativeIntermediateOutputPath)%(ManagedBinary.Filename)$(IlcOutputFileExt)" />
<IlcArg Include="@(IlcReference->'-r:%(Identity)')" />
<IlcArg Include="@(IlcSatelliteAssembly->'--satellite:%(Identity)')" />
<IlcArg Include="@(MibcFile->'--mibc:%(Identity)')" />
<IlcArg Condition="$(IlcGenerateMetadataLog) == 'true'" Include="--metadatalog:$(NativeIntermediateOutputPath)%(ManagedBinary.Filename).metadata.csv" />
<IlcArg Condition="$(_targetOS) != ''" Include="--targetos:$(_targetOS)" />
Expand Down Expand Up @@ -262,7 +263,7 @@ The .NET Foundation licenses this file to you under the MIT license.
</Target>

<Target Name="IlcCompile"
Inputs="@(IlcCompileInput);@(IlcReference);@(RdXmlFile);%(ManagedBinary.IlcRspFile)"
Inputs="@(IlcCompileInput);@(IlcReference);@(IlcSatelliteAssembly);@(RdXmlFile);%(ManagedBinary.IlcRspFile)"
Outputs="%(ManagedBinary.IlcOutputFile)"
DependsOnTargets="WriteIlcRspFileForCompilation;$(IlcCompileDependsOn)">
<Message Text="Generating native code" Importance="high" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ public ITaskItem[] ManagedAssemblies
set;
}

[Output]
public ITaskItem[] SatelliteAssemblies
{
get;
set;
}

[Output]
public ITaskItem[] AssembliesToSkipPublish
{
Expand All @@ -91,6 +98,7 @@ public override bool Execute()
{
var list = new List<ITaskItem>();
var assembliesToSkipPublish = new List<ITaskItem>();
var satelliteAssemblies = new List<ITaskItem>();
var nativeAotFrameworkAssembliesToUse = new HashSet<string>();

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

assembliesToSkipPublish.Add(taskItem);

// Split satellite assemblies from normal assemblies
if (culture == "" || culture.Equals("neutral", StringComparison.OrdinalIgnoreCase))
{
// NativeAOT doesn't consume resource assemblies yet so skip them
list.Add(taskItem);
}
else
{
satelliteAssemblies.Add(taskItem);
}
}
}
}
Expand All @@ -180,6 +193,7 @@ public override bool Execute()

ManagedAssemblies = list.ToArray();
AssembliesToSkipPublish = assembliesToSkipPublish.ToArray();
SatelliteAssemblies = satelliteAssemblies.ToArray();

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void TestDependencyGraphInvariants(EcmaMethod method)
new FullyBlockedMetadataBlockingPolicy(), new FullyBlockedManifestResourceBlockingPolicy(),
null, new NoStackTraceEmissionPolicy(), new NoDynamicInvokeThunkGenerationPolicy(),
new ILLink.Shared.TrimAnalysis.FlowAnnotations(Logger.Null, ilProvider, compilerGeneratedState), UsageBasedMetadataGenerationOptions.None,
default, Logger.Null, Array.Empty<KeyValuePair<string, bool>>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>());
default, Logger.Null, Array.Empty<KeyValuePair<string, bool>>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>());

CompilationBuilder builder = new RyuJitCompilationBuilder(context, compilationGroup)
.UseILProvider(ilProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
dependencies.Add(factory.ReflectedMethod(entrypoint), "Reflectable entrypoint");
}

CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, (EcmaAssembly)_module);
EcmaAssembly ecmaAssembly = (EcmaAssembly)_module;

CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ecmaAssembly);

foreach (EcmaModule satelliteModule in ((UsageBasedMetadataManager)factory.MetadataManager).GetSatelliteAssemblies(ecmaAssembly))
{
dependencies.Add(factory.ModuleMetadata(satelliteModule), "Satellite assembly");
}

return dependencies;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ private static (string AttributeName, DiagnosticId Id)[] _requiresAttributeMisma

private readonly HashSet<string> _rootEntireAssembliesModules;
private readonly HashSet<string> _trimmedAssemblies;
private readonly List<string> _satelliteAssemblyFiles;

internal FlowAnnotations FlowAnnotations { get; }

Expand All @@ -83,7 +84,8 @@ public UsageBasedMetadataManager(
IEnumerable<KeyValuePair<string, bool>> featureSwitchValues,
IEnumerable<string> rootEntireAssembliesModules,
IEnumerable<string> additionalRootedAssemblies,
IEnumerable<string> trimmedAssemblies)
IEnumerable<string> trimmedAssemblies,
IEnumerable<string> satelliteAssemblyFilePaths)
: base(typeSystemContext, blockingPolicy, resourceBlockingPolicy, logFile, stackTracePolicy, invokeThunkGenerationPolicy, options)
{
_compilationModuleGroup = group;
Expand All @@ -98,6 +100,20 @@ public UsageBasedMetadataManager(
_rootEntireAssembliesModules = new HashSet<string>(rootEntireAssembliesModules);
_rootEntireAssembliesModules.UnionWith(additionalRootedAssemblies);
_trimmedAssemblies = new HashSet<string>(trimmedAssemblies);
_satelliteAssemblyFiles = new List<string>(satelliteAssemblyFilePaths);
}

public IEnumerable<EcmaModule> GetSatelliteAssemblies(EcmaAssembly module)
{
string expectedSimpleName = module.GetName().Name + ".resources";
foreach (string filePath in _satelliteAssemblyFiles)
{
string simpleName = Path.GetFileNameWithoutExtension(filePath);
if (simpleName == expectedSimpleName)
{
yield return _typeSystemContext.GetMetadataOnlyModuleFromPath(filePath);
}
}
}

protected override void Graph_NewMarkedNode(DependencyNodeCore<NodeFactory> obj)
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/tools/aot/ILCompiler/ILCompiler.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>false</TieredCompilation>
<EventSourceSupport>true</EventSourceSupport>
<InvariantGlobalization>true</InvariantGlobalization>
<OptimizationPreference>Speed</OptimizationPreference>
</PropertyGroup>

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ internal sealed class ILCompilerRootCommand : RootCommand
new(new[] { "--optimize-time", "--Ot" }, "Enable optimizations, favor code speed");
public Option<string[]> MibcFilePaths { get; } =
new(new[] { "--mibc", "-m" }, Array.Empty<string>, "Mibc file(s) for profile guided optimization");
public Option<string[]> SatelliteFilePaths { get; } =
new(new[] { "--satellite" }, Array.Empty<string>, "Satellite assemblies associated with inputs/references");
public Option<bool> EnableDebugInfo { get; } =
new(new[] { "--debug", "-g" }, "Emit debugging information");
public Option<bool> UseDwarf5 { get; } =
Expand Down Expand Up @@ -173,6 +175,7 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler")
AddOption(OptimizeSpace);
AddOption(OptimizeTime);
AddOption(MibcFilePaths);
AddOption(SatelliteFilePaths);
AddOption(EnableDebugInfo);
AddOption(UseDwarf5);
AddOption(NativeLib);
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/tools/aot/ILCompiler/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ public int Run()
featureSwitches,
Get(_command.ConditionallyRootedAssemblies),
rootedAssemblies,
Get(_command.TrimmedAssemblies));
Get(_command.TrimmedAssemblies),
Get(_command.SatelliteFilePaths));

InteropStateManager interopStateManager = new InteropStateManager(typeSystemContext.GeneratedAssembly);
InteropStubManager interopStubManager = new UsageBasedInteropStubManager(interopStateManager, pinvokePolicy, logger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ public ILScanResults Trim (ILCompilerOptions options, ILogWriter logWriter)
Array.Empty<KeyValuePair<string, bool>> (),
Array.Empty<string> (),
options.AdditionalRootAssemblies.ToArray (),
options.TrimAssemblies.ToArray ());
options.TrimAssemblies.ToArray (),
Array.Empty<string> ());

PInvokeILEmitterConfiguration pinvokePolicy = new ILCompilerTestPInvokePolicy ();
InteropStateManager interopStateManager = new InteropStateManager (typeSystemContext.GeneratedAssembly);
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/tools/aot/crossgen2/crossgen2.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<Configurations>Debug;Release;Checked</Configurations>
<ServerGarbageCollection>true</ServerGarbageCollection>
<EventSourceSupport>true</EventSourceSupport>
<InvariantGlobalization>true</InvariantGlobalization>
<OptimizationPreference>Speed</OptimizationPreference>
<RunAnalyzers>false</RunAnalyzers>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ public static IEnumerable<object[]> CultureResourceData()

[Theory]
[MemberData(nameof(CultureResourceData))]
[ActiveIssue("https://github.com/dotnet/runtimelab/issues/155", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] // satellite assemblies
public static void GetString_CultureFallback(string key, string cultureName, string expectedValue)
{
Type resourceType = typeof(Resources.TestResx);
Expand All @@ -98,7 +97,6 @@ public static void GetString_CultureFallback(string key, string cultureName, str
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtimelab/issues/155", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] //satellite assemblies
public static void GetString_FromTestClassWithoutNeutralResources()
{
// This test is designed to complement the GetString_FromCulutureAndResourceType "fr" & "fr-CA" cases
Expand Down

0 comments on commit b134fa2

Please sign in to comment.