-
Notifications
You must be signed in to change notification settings - Fork 4.6k
/
TargetInfo.cs
121 lines (106 loc) · 5.5 KB
/
TargetInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.NET.HostModel.AppHost;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace Microsoft.NET.HostModel.Bundle
{
/// <summary>
/// TargetInfo: Information about the target for which the single-file bundle is built.
///
/// Currently the TargetInfo only tracks:
/// - the target operating system
/// - the target architecture
/// - the target framework
/// - the default options for this target
/// - the assembly alignment for this target
/// </summary>
public class TargetInfo
{
public readonly OSPlatform OS;
public readonly Architecture Arch;
public readonly Version FrameworkVersion;
public readonly uint BundleMajorVersion;
public readonly BundleOptions DefaultOptions;
public readonly int AssemblyAlignment;
public TargetInfo(OSPlatform? os, Architecture? arch, Version targetFrameworkVersion)
{
OS = os ?? HostOS;
Arch = arch ?? RuntimeInformation.OSArchitecture;
FrameworkVersion = targetFrameworkVersion ?? Environment.Version;
if (FrameworkVersion.Major >= 6)
{
BundleMajorVersion = 6u;
DefaultOptions = BundleOptions.None;
}
else if (FrameworkVersion.Major == 5)
{
BundleMajorVersion = 2u;
DefaultOptions = BundleOptions.None;
}
else if (FrameworkVersion.Major == 3)
{
BundleMajorVersion = 1u;
DefaultOptions = BundleOptions.BundleAllContent;
}
else
{
throw new ArgumentException($"Invalid input: Unsupported Target Framework Version {targetFrameworkVersion}");
}
if (IsWindows)
{
// We align assemblies in the bundle at 4K - per requirements of memory mapping API (MapViewOfFile3, et al).
// This is only necessary for R2R assemblies, but we do it for all assemblies for simplicity.
AssemblyAlignment = 4096;
}
else if (Arch == Architecture.Arm64)
{
// We align assemblies in the bundle at 4K so that we can use mmap on Unix without changing the page alignment of ARM64 R2R code.
// This is only necessary for R2R assemblies, but we do it for all assemblies for simplicity.
// See https://github.com/dotnet/runtime/issues/41832.
AssemblyAlignment = 4096;
}
else
{
// Otherwise, assemblies are 64 bytes aligned, so that their sections can be memory-mapped cache aligned.
AssemblyAlignment = 64;
}
}
public bool IsNativeBinary(string filePath)
{
return IsWindows ? PEUtils.IsPEImage(filePath) : IsOSX ? MachOUtils.IsMachOImage(filePath) : ElfUtils.IsElfImage(filePath);
}
public string GetAssemblyName(string hostName)
{
// This logic to calculate assembly name from hostName should be removed (and probably moved to test helpers)
// once the SDK in the correct assembly name.
return (IsWindows ? Path.GetFileNameWithoutExtension(hostName) : hostName);
}
public override string ToString()
{
string os = IsWindows ? "win" : OS.ToString().ToLowerInvariant();
string arch = Arch.ToString().ToLowerInvariant();
return $"OS: {os} Arch: {arch} FrameworkVersion: {FrameworkVersion}";
}
private static readonly OSPlatform s_freebsdOSPlatform = OSPlatform.Create("FREEBSD");
private static OSPlatform HostOS => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? OSPlatform.Linux :
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? OSPlatform.OSX : RuntimeInformation.IsOSPlatform(s_freebsdOSPlatform) ? s_freebsdOSPlatform : OSPlatform.Windows;
public bool IsOSX => OS.Equals(OSPlatform.OSX);
public bool IsWindows => OS.Equals(OSPlatform.Windows);
// The .net core 3 apphost doesn't care about semantics of FileType -- all files are extracted at startup.
// However, the apphost checks that the FileType value is within expected bounds, so set it to the first enumeration.
public FileType TargetSpecificFileType(FileType fileType) => (BundleMajorVersion == 1) ? FileType.Unknown : fileType;
// In .net core 3.x, bundle processing happens within the AppHost.
// Therefore HostFxr and HostPolicy can be bundled within the single-file app.
// In .net 5, bundle processing happens in HostFxr and HostPolicy libraries.
// Therefore, these libraries themselves cannot be bundled into the single-file app.
// This problem is mitigated by statically linking these host components with the AppHost.
// https://github.com/dotnet/runtime/issues/32823
public bool ShouldExclude(string relativePath) =>
(FrameworkVersion.Major != 3) && (relativePath.Equals(HostFxr) || relativePath.Equals(HostPolicy));
private string HostFxr => IsWindows ? "hostfxr.dll" : IsOSX ? "libhostfxr.dylib" : "libhostfxr.so";
private string HostPolicy => IsWindows ? "hostpolicy.dll" : IsOSX ? "libhostpolicy.dylib" : "libhostpolicy.so";
}
}