Repository: dotnet/runtime
File: src/coreclr/tools/aot/ILCompiler/Program.cs (C#)

Code before:
                    {
                        // Skip adding UnmanagedEntryPointsRootProvider for modules that have been already registered as an input module
                        continue;
                    }
                    EcmaModule module = typeSystemContext.GetModuleForSimpleName(unmanagedEntryPointsAssembly);
                    compilationRoots.Add(new UnmanagedEntryPointsRootProvider(module, hidden));
                }

                foreach (var rdXmlFilePath in Get(_command.RdXmlFilePaths))
                {
                    compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath));
                }

                foreach (var linkTrimFilePath in Get(_command.LinkTrimFilePaths))
                {
                    if (!File.Exists(linkTrimFilePath))
                        throw new CommandLineException($"'{linkTrimFilePath}' doesn't exist");
                    compilationRoots.Add(new ILCompiler.DependencyAnalysis.TrimmingDescriptorNode(linkTrimFilePath));
                }

                // Get TypeMappingEntryAssembly from runtime knobs if specified
                string typeMappingEntryAssembly = null;
                foreach (var runtimeKnob in runtimeKnobs)
                {
                    var knobAndValue = runtimeKnob.Split('=', 2);
                    if (knobAndValue.Length == 2 && knobAndValue[0] == "System.Runtime.InteropServices.TypeMappingEntryAssembly")
                    {
                        typeMappingEntryAssembly = knobAndValue[1];
                        break;
                    }
                }
                if (typeMappingEntryAssembly is not null)
                {
                    var typeMapEntryAssembly = (EcmaAssembly)typeSystemContext.ResolveAssembly(AssemblyNameInfo.Parse(typeMappingEntryAssembly), throwIfNotFound: true);
                    typeMapManager = new UsageBasedTypeMapManager(TypeMapMetadata.CreateFromAssembly(typeMapEntryAssembly, typeSystemContext));
                }
                else if (entrypointModule is { Assembly: EcmaAssembly entryAssembly })
                {
                    // Fall back to entryassembly if not specified
                    typeMapManager = new UsageBasedTypeMapManager(TypeMapMetadata.CreateFromAssembly(entryAssembly, typeSystemContext));
                }
            }

            // Root whatever assemblies were specified on the command line
            string[] rootedAssemblies = Get(_command.RootedAssemblies);
            foreach (var rootedAssembly in rootedAssemblies)
            {
                EcmaModule module = typeSystemContext.GetModuleForSimpleName(rootedAssembly);

                // We only root the module type. The rest will fall out because we treat rootedAssemblies
                // same as conditionally rooted ones and here we're fulfilling the condition ("something is used").

Review comment (suggestion):
Would it be cleaner to introduce a first class command line switch for this populated from the `TypeMapEntryAssembly` property (the approach in https://github.com/dotnet/runtime/issues/121138#issuecomment-3459953860)

Code after:
                    {
                        // Skip adding UnmanagedEntryPointsRootProvider for modules that have been already registered as an input module
                        continue;
                    }
                    EcmaModule module = typeSystemContext.GetModuleForSimpleName(unmanagedEntryPointsAssembly);
                    compilationRoots.Add(new UnmanagedEntryPointsRootProvider(module, hidden));
                }

                foreach (var rdXmlFilePath in Get(_command.RdXmlFilePaths))
                {
                    compilationRoots.Add(new RdXmlRootProvider(typeSystemContext, rdXmlFilePath));
                }

                foreach (var linkTrimFilePath in Get(_command.LinkTrimFilePaths))
                {
                    if (!File.Exists(linkTrimFilePath))
                        throw new CommandLineException($"'{linkTrimFilePath}' doesn't exist");
                    compilationRoots.Add(new ILCompiler.DependencyAnalysis.TrimmingDescriptorNode(linkTrimFilePath));
                }

                // Get TypeMappingEntryAssembly from command-line option if specified
                string typeMappingEntryAssembly = Get(_command.TypeMapEntryAssembly);
                if (typeMappingEntryAssembly is not null)
                {
                    var typeMapEntryAssembly = (EcmaAssembly)typeSystemContext.ResolveAssembly(AssemblyNameInfo.Parse(typeMappingEntryAssembly), throwIfNotFound: true);
                    typeMapManager = new UsageBasedTypeMapManager(TypeMapMetadata.CreateFromAssembly(typeMapEntryAssembly, typeSystemContext));
                }
                else if (entrypointModule is { Assembly: EcmaAssembly entryAssembly })
                {
                    // Fall back to entryassembly if not specified
                    typeMapManager = new UsageBasedTypeMapManager(TypeMapMetadata.CreateFromAssembly(entryAssembly, typeSystemContext));
                }
            }

            // Root whatever assemblies were specified on the command line
            string[] rootedAssemblies = Get(_command.RootedAssemblies);
            foreach (var rootedAssembly in rootedAssemblies)
            {
                EcmaModule module = typeSystemContext.GetModuleForSimpleName(rootedAssembly);

                // We only root the module type. The rest will fall out because we treat rootedAssemblies
                // same as conditionally rooted ones and here we're fulfilling the condition ("something is used").
                compilationRoots.Add(
                    new GenericRootProvider<ModuleDesc>(module,
                    (ModuleDesc module, IRootingServiceProvider rooter) => rooter.AddReflectionRoot(module.GetGlobalModuleType(), "Command line root")));
            }

            // Unless explicitly opted in at the command line, we enable scanner for retail builds by default.
            // We also don't do this for multifile because scanner doesn't simulate inlining (this would be
            // fixable by using a CompilationGroup for the scanner that has a bigger worldview, but
            // let's cross that bridge when we get there).