forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copy build task over from CoreRT repo (dotnet#43)
* Copy build task over from CoreRT repo At CoreRT commit b48a58e6facdda7f50f9256e0d9d6a209473132f. * Hook up ILCompiler.Build.Tasks to build Co-authored-by: dotnet-bot <dotnet-bot@microsoft.com>
- Loading branch information
1 parent
a4b2355
commit 0a59f67
Showing
5 changed files
with
555 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
...coreclr/src/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.Build.Framework; | ||
using Microsoft.Build.Utilities; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Reflection.Metadata; | ||
using System.Reflection.PortableExecutable; | ||
|
||
|
||
|
||
namespace Build.Tasks | ||
{ | ||
public class ComputeManagedAssembliesToCompileToNative : DesktopCompatibleTask | ||
{ | ||
[Required] | ||
public ITaskItem[] Assemblies | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
/// <summary> | ||
/// The CoreRT-specific System.Private.* assemblies that must be used instead of the netcoreapp2.1 versions. | ||
/// </summary> | ||
[Required] | ||
public ITaskItem[] SdkAssemblies | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
/// <summary> | ||
/// The set of AOT-specific framework assemblies we currently need to use which will replace the same-named ones | ||
/// in the app's closure. | ||
/// </summary> | ||
[Required] | ||
public ITaskItem[] FrameworkAssemblies | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
/// <summary> | ||
/// The native apphost (whose name ends up colliding with the CoreRT output binary) | ||
/// </summary> | ||
[Required] | ||
public string DotNetAppHostExecutableName | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
/// <summary> | ||
/// The CoreCLR dotnet host fixer library that can be skipped during publish | ||
/// </summary> | ||
[Required] | ||
public string DotNetHostFxrLibraryName | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
/// <summary> | ||
/// The CoreCLR dotnet host policy library that can be skipped during publish | ||
/// </summary> | ||
[Required] | ||
public string DotNetHostPolicyLibraryName | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
[Output] | ||
public ITaskItem[] ManagedAssemblies | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
[Output] | ||
public ITaskItem[] AssembliesToSkipPublish | ||
{ | ||
get; | ||
set; | ||
} | ||
|
||
public override bool Execute() | ||
{ | ||
var list = new List<ITaskItem>(); | ||
var assembliesToSkipPublish = new List<ITaskItem>(); | ||
var coreRTFrameworkAssembliesToUse = new HashSet<string>(); | ||
|
||
foreach (ITaskItem taskItem in SdkAssemblies) | ||
{ | ||
coreRTFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec)); | ||
} | ||
|
||
foreach (ITaskItem taskItem in FrameworkAssemblies) | ||
{ | ||
coreRTFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec)); | ||
} | ||
|
||
foreach (ITaskItem taskItem in Assemblies) | ||
{ | ||
// In the case of disk-based assemblies, this holds the file path | ||
string itemSpec = taskItem.ItemSpec; | ||
|
||
// Skip the native apphost (whose name ends up colliding with the CoreRT output binary) and supporting libraries | ||
if (itemSpec.EndsWith(DotNetAppHostExecutableName, StringComparison.OrdinalIgnoreCase) || itemSpec.Contains(DotNetHostFxrLibraryName) || itemSpec.Contains(DotNetHostPolicyLibraryName)) | ||
{ | ||
assembliesToSkipPublish.Add(taskItem); | ||
continue; | ||
} | ||
|
||
// Prototype aid - remove the native CoreCLR runtime pieces from the publish folder | ||
if (itemSpec.Contains("microsoft.netcore.app") && (itemSpec.Contains("\\native\\") || itemSpec.Contains("/native/"))) | ||
{ | ||
assembliesToSkipPublish.Add(taskItem); | ||
continue; | ||
} | ||
|
||
// Remove any assemblies whose implementation we want to come from CoreRT's package. | ||
// Currently that's System.Private.* SDK assemblies and a bunch of framework assemblies. | ||
if (coreRTFrameworkAssembliesToUse.Contains(Path.GetFileName(itemSpec))) | ||
{ | ||
assembliesToSkipPublish.Add(taskItem); | ||
continue; | ||
} | ||
|
||
try | ||
{ | ||
using (FileStream moduleStream = File.OpenRead(itemSpec)) | ||
using (var module = new PEReader(moduleStream)) | ||
{ | ||
if (module.HasMetadata) | ||
{ | ||
MetadataReader moduleMetadataReader = module.GetMetadataReader(); | ||
if (moduleMetadataReader.IsAssembly) | ||
{ | ||
string culture = moduleMetadataReader.GetString(moduleMetadataReader.GetAssemblyDefinition().Culture); | ||
|
||
if (culture == "" || culture.Equals("neutral", StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
// CoreRT doesn't consume resource assemblies yet so skip them | ||
assembliesToSkipPublish.Add(taskItem); | ||
list.Add(taskItem); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
catch (BadImageFormatException) | ||
{ | ||
} | ||
} | ||
|
||
ManagedAssemblies = list.ToArray(); | ||
AssembliesToSkipPublish = assembliesToSkipPublish.ToArray(); | ||
|
||
return true; | ||
} | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
src/coreclr/src/tools/aot/ILCompiler.Build.Tasks/DesktopCompatibleTask.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Reflection; | ||
|
||
using Microsoft.Build.Utilities; | ||
|
||
namespace Build.Tasks | ||
{ | ||
public abstract class DesktopCompatibleTask : Task | ||
{ | ||
static DesktopCompatibleTask() | ||
{ | ||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; | ||
} | ||
|
||
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) | ||
{ | ||
// apply any existing policy | ||
AssemblyName referenceName = new AssemblyName(AppDomain.CurrentDomain.ApplyPolicy(args.Name)); | ||
|
||
string fileName = referenceName.Name + ".dll"; | ||
string assemblyPath = null; | ||
string probingPath = null; | ||
Assembly assm = null; | ||
|
||
// look next to requesting assembly | ||
assemblyPath = args.RequestingAssembly?.Location; | ||
if (!String.IsNullOrEmpty(assemblyPath)) | ||
{ | ||
probingPath = Path.Combine(Path.GetDirectoryName(assemblyPath), fileName); | ||
Debug.WriteLine($"Considering {probingPath} based on RequestingAssembly"); | ||
if (Probe(probingPath, referenceName.Version, out assm)) | ||
{ | ||
return assm; | ||
} | ||
} | ||
|
||
// look next to the executing assembly | ||
assemblyPath = Assembly.GetExecutingAssembly().Location; | ||
if (!String.IsNullOrEmpty(assemblyPath)) | ||
{ | ||
probingPath = Path.Combine(Path.GetDirectoryName(assemblyPath), fileName); | ||
|
||
Debug.WriteLine($"Considering {probingPath} based on ExecutingAssembly"); | ||
if (Probe(probingPath, referenceName.Version, out assm)) | ||
{ | ||
return assm; | ||
} | ||
} | ||
|
||
// look in AppDomain base directory | ||
probingPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName); | ||
Debug.WriteLine($"Considering {probingPath} based on BaseDirectory"); | ||
if (Probe(probingPath, referenceName.Version, out assm)) | ||
{ | ||
return assm; | ||
} | ||
|
||
// look in current directory | ||
Debug.WriteLine($"Considering {fileName}"); | ||
if (Probe(fileName, referenceName.Version, out assm)) | ||
{ | ||
return assm; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/// <summary> | ||
/// Considers a path to load for satisfying an assembly ref and loads it | ||
/// if the file exists and version is sufficient. | ||
/// </summary> | ||
/// <param name="filePath">Path to consider for load</param> | ||
/// <param name="minimumVersion">Minimum version to consider</param> | ||
/// <param name="assembly">loaded assembly</param> | ||
/// <returns>true if assembly was loaded</returns> | ||
private static bool Probe(string filePath, Version minimumVersion, out Assembly assembly) | ||
{ | ||
if (File.Exists(filePath)) | ||
{ | ||
AssemblyName name = AssemblyName.GetAssemblyName(filePath); | ||
|
||
if (name.Version >= minimumVersion) | ||
{ | ||
assembly = Assembly.Load(name); | ||
return true; | ||
} | ||
} | ||
|
||
assembly = null; | ||
return false; | ||
} | ||
} | ||
} |
Oops, something went wrong.