Merge pull request #8887 from rolfbjarne/dotnet-linker-generate-main
[dotnet] Generate a main function, and use it to compile the main executable.
This commit is contained in:
Коммит
53c285c097
|
@ -22,6 +22,38 @@
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- Architecture -->
|
||||||
|
<!-- If the old-style variables are set, use those -->
|
||||||
|
<PropertyGroup Condition=" '$(TargetArchitectures)' == '' ">
|
||||||
|
<TargetArchitectures Condition=" '$(_PlatformName)' == 'macOS' And '$(XamMacArch)' != '' ">$(XamMacArch)</TargetArchitectures>
|
||||||
|
<TargetArchitectures Condition=" '$(_PlatformName)' != 'macOS' And '$(MtouchArch)' != '' ">$(MtouchArch)</TargetArchitectures>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- If the old-style variables aren't set, figure it out using RuntimeIdentifier. -->
|
||||||
|
<!-- This is a variation of https://github.com/dotnet/sdk/blob/873d79d861cbd001488414b9875e53acbeaed890/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets#L68-L96 -->
|
||||||
|
<!-- This doesn't cover every single possibility (in particular it does not handle ARMv7s, either as a thin or fat option, and the same for ARMv7k), but that can be done by passing /p:TargetArchitectures=ARMv7s to msbuild -->
|
||||||
|
<PropertyGroup Condition=" '$(TargetArchitectures)' == '' And '$(_PlatformName)' == 'iOS' ">
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-arm64')) Or $(RuntimeIdentifier.Contains('-arm64-')) ">ARM64</TargetArchitectures>
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-x64')) Or $(RuntimeIdentifier.Contains('-x64-')) ">x86_64</TargetArchitectures>
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-x84')) Or $(RuntimeIdentifier.Contains('-x86-')) ">i386</TargetArchitectures>
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-arm')) Or $(RuntimeIdentifier.Contains('-arm-')) ">ARMv7</TargetArchitectures>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(TargetArchitectures)' == '' And '$(_PlatformName)' == 'tvOS' ">
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-arm64')) Or $(RuntimeIdentifier.Contains('-arm64-')) ">ARM64</TargetArchitectures>
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-x64')) Or $(RuntimeIdentifier.Contains('-x64-')) ">x86_64</TargetArchitectures>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(TargetArchitectures)' == '' And '$(_PlatformName)' == 'watchOS' ">
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-x84')) Or $(RuntimeIdentifier.Contains('-x86-')) ">i386</TargetArchitectures>
|
||||||
|
<TargetArchitectures Condition=" $(RuntimeIdentifier.EndsWith('-arm')) Or $(RuntimeIdentifier.Contains('-arm-')) ">ARM64_32</TargetArchitectures>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(TargetArchitectures)' == '' And '$(_PlatformName)' == 'macOS' ">
|
||||||
|
<TargetArchitectures Condition=" '$(RuntimeIdentifier)' == 'osx-x64' ">x86_64</TargetArchitectures>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(ComputedPlatform)' == ''">
|
||||||
|
<ComputedPlatform Condition="'$(_PlatformName)' != 'macOS' And ($(TargetArchitectures.Contains('i386')) Or $(TargetArchitectures.Contains('x86_64')))">iPhoneSimulator</ComputedPlatform>
|
||||||
|
<ComputedPlatform Condition="'$(_PlatformName)' != 'macOS' And '$(ComputedPlatform)' == ''">iPhone</ComputedPlatform>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- Declare the XI/XM framework bundled with this version of the SDK. See Microsoft.NETCoreSdk.BundledVersions.props -->
|
<!-- Declare the XI/XM framework bundled with this version of the SDK. See Microsoft.NETCoreSdk.BundledVersions.props -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- Runtime pack identifiers -->
|
<!-- Runtime pack identifiers -->
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<_XamarinTaskAssembly Condition="'$(_PlatformName)' != 'macOS'">$(_XamarinSdkRootDirectory)\tools\msbuild\iOS\Xamarin.iOS.Tasks.dll</_XamarinTaskAssembly>
|
||||||
|
<_XamarinTaskAssembly Condition="'$(_PlatformName)' == 'macOS'">$(_XamarinSdkRootDirectory)\tools\msbuild\macOS\Xamarin.Mac.Tasks.dll</_XamarinTaskAssembly>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<UsingTask TaskName="Xamarin.MacDev.Tasks.CompileNativeCode" AssemblyFile="$(_XamarinTaskAssembly)" />
|
||||||
|
<UsingTask TaskName="Xamarin.MacDev.Tasks.LinkNativeCode" AssemblyFile="$(_XamarinTaskAssembly)" />
|
||||||
|
|
||||||
<!-- Project types and how do we distinguish between them
|
<!-- Project types and how do we distinguish between them
|
||||||
|
|
||||||
OutputType Custom variable
|
OutputType Custom variable
|
||||||
|
@ -83,6 +91,9 @@
|
||||||
_CompileAppManifest;
|
_CompileAppManifest;
|
||||||
_ComputeLinkerArguments;
|
_ComputeLinkerArguments;
|
||||||
ComputeFilesToPublish;
|
ComputeFilesToPublish;
|
||||||
|
_LoadLinkerOutput;
|
||||||
|
_CompileNativeExecutable;
|
||||||
|
_LinkNativeExecutable;
|
||||||
_ComputePublishLocation;
|
_ComputePublishLocation;
|
||||||
CopyFilesToPublishDirectory;
|
CopyFilesToPublishDirectory;
|
||||||
</CreateAppBundleDependsOn>
|
</CreateAppBundleDependsOn>
|
||||||
|
@ -97,9 +108,19 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- Pass the custom options to our custom steps -->
|
<!-- Pass the custom options to our custom steps -->
|
||||||
<_CustomLinkerOptionsFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)custom-linker-options.txt'))</_CustomLinkerOptionsFile>
|
<_CustomLinkerOptionsFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)custom-linker-options.txt'))</_CustomLinkerOptionsFile>
|
||||||
|
|
||||||
|
<!-- The directory where the linker puts *.items files that will be loaded in the _LoadLinkerOutput target -->
|
||||||
|
<_LinkerItemsDirectory>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)linker-items'))</_LinkerItemsDirectory>
|
||||||
|
|
||||||
|
<!-- A temporary output directory for our linker steps -->
|
||||||
|
<_LinkerCacheDirectory>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)linker-cache'))</_LinkerCacheDirectory>
|
||||||
|
|
||||||
<_CustomLinkerOptions>
|
<_CustomLinkerOptions>
|
||||||
|
CacheDirectory=$(_LinkerCacheDirectory)
|
||||||
|
ItemsDirectory=$(_LinkerItemsDirectory)
|
||||||
Platform=$(_PlatformName)
|
Platform=$(_PlatformName)
|
||||||
PlatformAssembly=$(_PlatformAssemblyName).dll
|
PlatformAssembly=$(_PlatformAssemblyName).dll
|
||||||
|
TargetArchitectures=$(TargetArchitectures)
|
||||||
</_CustomLinkerOptions>
|
</_CustomLinkerOptions>
|
||||||
<_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --custom-data "LinkerOptionsFile=$(_CustomLinkerOptionsFile)"</_ExtraTrimmerArgs>
|
<_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --custom-data "LinkerOptionsFile=$(_CustomLinkerOptionsFile)"</_ExtraTrimmerArgs>
|
||||||
|
|
||||||
|
@ -112,12 +133,86 @@
|
||||||
<BeforeStep>LoadReferencesStep</BeforeStep>
|
<BeforeStep>LoadReferencesStep</BeforeStep>
|
||||||
<Type>Xamarin.SetupStep</Type>
|
<Type>Xamarin.SetupStep</Type>
|
||||||
</_TrimmerCustomSteps>
|
</_TrimmerCustomSteps>
|
||||||
|
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)">
|
||||||
|
<!-- At the end of the pipeline -->
|
||||||
|
<Type>Xamarin.GenerateMainStep</Type>
|
||||||
|
</_TrimmerCustomSteps>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- Create the file with our custom linker options -->
|
<!-- Create the file with our custom linker options -->
|
||||||
<WriteLinesToFile File="$(_CustomLinkerOptionsFile)" Lines="$(_CustomLinkerOptions)" Overwrite="true" />
|
<WriteLinesToFile File="$(_CustomLinkerOptionsFile)" Lines="$(_CustomLinkerOptions)" Overwrite="true" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="_LoadLinkerOutput">
|
||||||
|
<!-- Load _MainFile -->
|
||||||
|
<ReadItemsFromFile File="$(_LinkerItemsDirectory)/_MainFile.items" Condition="Exists('$(_LinkerItemsDirectory)/_MainFile.items')">
|
||||||
|
<Output TaskParameter="Items" ItemName="_MainFile" />
|
||||||
|
</ReadItemsFromFile>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- Native code -->
|
||||||
|
|
||||||
|
<Target Name="_ComputeVariables" DependsOnTargets="_GenerateBundleName">
|
||||||
|
<PropertyGroup>
|
||||||
|
<_IntermediateNativeLibraryDir>$(IntermediateOutputPath)nativelibraries/</_IntermediateNativeLibraryDir>
|
||||||
|
<_NativeExecutableName>$(_AppBundleName)</_NativeExecutableName>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="_CompileNativeExecutable"
|
||||||
|
DependsOnTargets="_DetectSdkLocations;_ComputeTargetArchitectures;_GenerateBundleName;_ComputeVariables;_GetMinimumOSVersion"
|
||||||
|
Inputs="@(_MainFile)"
|
||||||
|
Outputs="@(_MainFile -> '%(_IntermediateNativeLibraryDir)%(Filename).o')"
|
||||||
|
>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<_MainFile Update="@(_MainFile)">
|
||||||
|
<OutputFile>$(_IntermediateNativeLibraryDir)%(Filename).o</OutputFile>
|
||||||
|
</_MainFile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<MakeDir SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' == 'true'" Directories="$(_IntermediateNativeLibraryDir)" />
|
||||||
|
|
||||||
|
<CompileNativeCode
|
||||||
|
SessionId="$(BuildSessionId)"
|
||||||
|
CompileInfo="@(_MainFile)"
|
||||||
|
MinimumOSVersion="$(_MinimumOSVersion)"
|
||||||
|
SdkDevPath="$(_SdkDevPath)"
|
||||||
|
SdkIsSimulator="$(_SdkIsSimulator)"
|
||||||
|
SdkRoot="$(_SdkRoot)"
|
||||||
|
TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)"
|
||||||
|
>
|
||||||
|
<Output TaskParameter="ObjectFiles" ItemName="_NativeExecutableObjectFiles" />
|
||||||
|
</CompileNativeCode>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="_LinkNativeExecutable"
|
||||||
|
DependsOnTargets="_DetectSdkLocations;_ComputeTargetArchitectures;_GenerateBundleName;_CompileNativeExecutable;_CompileAppManifest"
|
||||||
|
Inputs="@(_NativeExecutableObjectFiles)"
|
||||||
|
Outputs="$(_IntermediateNativeLibraryDir)$(_NativeExecutableName)"
|
||||||
|
>
|
||||||
|
|
||||||
|
<LinkNativeCode
|
||||||
|
SessionId="$(BuildSessionId)"
|
||||||
|
Frameworks="@(_NativeExecutableFrameworks)"
|
||||||
|
MinimumOSVersion="$(_MinimumOSVersion)"
|
||||||
|
ObjectFiles="@(_NativeExecutableObjectFiles)"
|
||||||
|
OutputFile="$(_IntermediateNativeLibraryDir)$(_NativeExecutableName)"
|
||||||
|
SdkDevPath="$(_SdkDevPath)"
|
||||||
|
SdkIsSimulator="$(_SdkIsSimulator)"
|
||||||
|
SdkRoot="$(_SdkRoot)"
|
||||||
|
TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)"
|
||||||
|
WeakFrameworks="@(_NativeExecutableWeakFrameworks)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- Copy the executable from the intermediate directory to the .app -->
|
||||||
|
<ResolvedFileToPublish
|
||||||
|
Include="$(_IntermediateNativeLibraryDir)$(_NativeExecutableName)"
|
||||||
|
RelativePath="$([MSBuild]::MakeRelative($(MSBuildProjectDirectory)$(PublishDir),$(MSBuildProjectDirectory)$(_AppBundlePath)))\$(_NativeExecutableName)"/>
|
||||||
|
</ItemGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
<Target Name="_ComputePublishLocation" DependsOnTargets="_GenerateBundleName">
|
<Target Name="_ComputePublishLocation" DependsOnTargets="_GenerateBundleName">
|
||||||
<!-- Put .dll, .pdb, .exe and .dylib in the .app -->
|
<!-- Put .dll, .pdb, .exe and .dylib in the .app -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
|
||||||
|
using Xamarin.Utils;
|
||||||
|
|
||||||
|
namespace Xamarin.MacDev.Tasks {
|
||||||
|
public abstract class CompileNativeCodeTaskBase : XamarinTask {
|
||||||
|
|
||||||
|
#region Inputs
|
||||||
|
[Required]
|
||||||
|
public ITaskItem [] CompileInfo { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string MinimumOSVersion { get; set; }
|
||||||
|
|
||||||
|
[Output]
|
||||||
|
public ITaskItem [] ObjectFiles { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string SdkDevPath { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string SdkRoot { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public bool SdkIsSimulator { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override bool Execute ()
|
||||||
|
{
|
||||||
|
var processes = new Task<Execution> [CompileInfo.Length];
|
||||||
|
var objectFiles = new List<ITaskItem> ();
|
||||||
|
|
||||||
|
if (ObjectFiles != null)
|
||||||
|
objectFiles.AddRange (ObjectFiles);
|
||||||
|
|
||||||
|
for (var i = 0; i < CompileInfo.Length; i++) {
|
||||||
|
var info = CompileInfo [i];
|
||||||
|
var src = Path.GetFullPath (info.ItemSpec);
|
||||||
|
var arguments = new List<string> ();
|
||||||
|
|
||||||
|
arguments.Add ("clang");
|
||||||
|
|
||||||
|
arguments.Add (PlatformFrameworkHelper.GetMinimumVersionArgument (TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));
|
||||||
|
|
||||||
|
arguments.Add ("-isysroot");
|
||||||
|
arguments.Add (SdkRoot);
|
||||||
|
|
||||||
|
var args = info.GetMetadata ("Arguments");
|
||||||
|
if (!StringUtils.TryParseArguments (args, out var parsed_args, out var ex)) {
|
||||||
|
Log.LogError ("Could not parse the arguments '{0}': {1}", args, ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
arguments.AddRange (parsed_args);
|
||||||
|
|
||||||
|
var arch = info.GetMetadata ("Arch");
|
||||||
|
if (!string.IsNullOrEmpty (arch)) {
|
||||||
|
arguments.Add ("-arch");
|
||||||
|
arguments.Add (arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputFile = info.GetMetadata ("OutputFile");
|
||||||
|
if (string.IsNullOrEmpty (outputFile))
|
||||||
|
outputFile = Path.ChangeExtension (src, ".o");
|
||||||
|
outputFile = Path.GetFullPath (outputFile);
|
||||||
|
arguments.Add ("-o");
|
||||||
|
arguments.Add (outputFile);
|
||||||
|
objectFiles.Add (new TaskItem (outputFile));
|
||||||
|
|
||||||
|
arguments.Add ("-c");
|
||||||
|
arguments.Add (src);
|
||||||
|
|
||||||
|
processes [i] = ExecuteAsync ("xcrun", arguments, sdkDevPath: SdkDevPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Threading.Tasks.Task.WaitAll (processes);
|
||||||
|
|
||||||
|
ObjectFiles = objectFiles.ToArray ();
|
||||||
|
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
|
||||||
|
namespace Xamarin.MacDev.Tasks {
|
||||||
|
public abstract class LinkNativeCodeTaskBase : XamarinTask {
|
||||||
|
|
||||||
|
#region Inputs
|
||||||
|
[Required]
|
||||||
|
public string SdkDevPath { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public bool SdkIsSimulator { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string SdkRoot { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string OutputFile { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public ITaskItem [] ObjectFiles { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string MinimumOSVersion { get; set; }
|
||||||
|
|
||||||
|
public ITaskItem[] Frameworks { get; set; }
|
||||||
|
public ITaskItem [] WeakFrameworks { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override bool Execute ()
|
||||||
|
{
|
||||||
|
var arguments = new List<string> ();
|
||||||
|
arguments.Add ("clang");
|
||||||
|
|
||||||
|
arguments.Add (PlatformFrameworkHelper.GetMinimumVersionArgument (TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));
|
||||||
|
|
||||||
|
arguments.Add ("-isysroot");
|
||||||
|
arguments.Add (SdkRoot);
|
||||||
|
|
||||||
|
if (Frameworks != null) {
|
||||||
|
foreach (var fw in Frameworks) {
|
||||||
|
arguments.Add ("-framework");
|
||||||
|
arguments.Add (fw.ItemSpec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WeakFrameworks != null) {
|
||||||
|
foreach (var fw in WeakFrameworks) {
|
||||||
|
arguments.Add ("-weak_framework");
|
||||||
|
arguments.Add (fw.ItemSpec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectFiles != null)
|
||||||
|
foreach (var obj in ObjectFiles)
|
||||||
|
arguments.Add (Path.GetFullPath (obj.ItemSpec));
|
||||||
|
|
||||||
|
arguments.Add ("-o");
|
||||||
|
arguments.Add (OutputFile);
|
||||||
|
|
||||||
|
ExecuteAsync ("xcrun", arguments, sdkDevPath: SdkDevPath).Wait ();
|
||||||
|
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.Build.Framework;
|
using Microsoft.Build.Framework;
|
||||||
using Microsoft.Build.Utilities;
|
using Microsoft.Build.Utilities;
|
||||||
|
@ -89,6 +90,22 @@ namespace Xamarin.MacDev.Tasks {
|
||||||
throw new InvalidOperationException ($"Invalid platform: {Platform}");
|
throw new InvalidOperationException ($"Invalid platform: {Platform}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async System.Threading.Tasks.Task<Execution> ExecuteAsync (string fileName, IList<string> arguments, string sdkDevPath)
|
||||||
|
{
|
||||||
|
var environment = new Dictionary<string, string> () {
|
||||||
|
{ "DEVELOPER_DIR", sdkDevPath },
|
||||||
|
};
|
||||||
|
Log.LogMessage (MessageImportance.Low, $"Executing '{fileName} {StringUtils.FormatArguments (arguments)}'");
|
||||||
|
var rv = await Execution.RunAsync ("xcrun", arguments, environment: environment, mergeOutput: true);
|
||||||
|
if (rv.ExitCode != 0) {
|
||||||
|
Log.LogMessage (MessageImportance.Normal, rv.StandardOutput.ToString ());
|
||||||
|
Log.LogError ($"Executing '{fileName} {StringUtils.FormatArguments (arguments)}' failed with exit code {rv.ExitCode}. Please review build log for more information.");
|
||||||
|
} else {
|
||||||
|
Log.LogMessage (MessageImportance.Low, rv.StandardOutput.ToString ());
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Text.Json" Version="4.7.0" />
|
<PackageReference Include="System.Text.Json" Version="4.7.0" />
|
||||||
|
@ -35,6 +36,9 @@
|
||||||
<Compile Include="..\..\tools\common\TargetFramework.cs">
|
<Compile Include="..\..\tools\common\TargetFramework.cs">
|
||||||
<Link>TargetFramework.cs</Link>
|
<Link>TargetFramework.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\..\tools\common\Execution.cs">
|
||||||
|
<Link>Execution.cs</Link>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\tools\mtouch\errors.resx">
|
<None Include="..\..\tools\mtouch\errors.resx">
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace Xamarin.MacDev.Tasks {
|
||||||
|
public class CompileNativeCode : CompileNativeCodeTaskBase {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace Xamarin.MacDev.Tasks {
|
||||||
|
public class LinkNativeCode : LinkNativeCodeTaskBase {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Compat.cs: might not be ideal but it eases code sharing with existing code during the initial implementation.
|
||||||
|
|
||||||
|
namespace Xamarin.Bundler {
|
||||||
|
public class Application {
|
||||||
|
// This method is needed for ErrorHelper.tools.cs to compile.
|
||||||
|
public void LoadSymbols ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,22 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
using Mono.Linker;
|
using Mono.Linker;
|
||||||
|
|
||||||
|
using Xamarin.Bundler;
|
||||||
using Xamarin.Utils;
|
using Xamarin.Utils;
|
||||||
|
|
||||||
namespace Xamarin.Linker {
|
namespace Xamarin.Linker {
|
||||||
public class LinkerConfiguration {
|
public class LinkerConfiguration {
|
||||||
|
public List<Abi> Abis;
|
||||||
|
public string ItemsDirectory { get; private set; }
|
||||||
public ApplePlatform Platform { get; private set; }
|
public ApplePlatform Platform { get; private set; }
|
||||||
public string PlatformAssembly { get; private set; }
|
public string PlatformAssembly { get; private set; }
|
||||||
|
public string CacheDirectory { get; private set; }
|
||||||
|
|
||||||
static ConditionalWeakTable<LinkContext, LinkerConfiguration> configurations = new ConditionalWeakTable<LinkContext, LinkerConfiguration> ();
|
static ConditionalWeakTable<LinkContext, LinkerConfiguration> configurations = new ConditionalWeakTable<LinkContext, LinkerConfiguration> ();
|
||||||
|
|
||||||
|
@ -43,6 +50,12 @@ namespace Xamarin.Linker {
|
||||||
var key = line [..eq];
|
var key = line [..eq];
|
||||||
var value = line [(eq + 1)..];
|
var value = line [(eq + 1)..];
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
case "CacheDirectory":
|
||||||
|
CacheDirectory = value;
|
||||||
|
break;
|
||||||
|
case "ItemsDirectory":
|
||||||
|
ItemsDirectory = value;
|
||||||
|
break;
|
||||||
case "Platform":
|
case "Platform":
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case "iOS":
|
case "iOS":
|
||||||
|
@ -64,17 +77,54 @@ namespace Xamarin.Linker {
|
||||||
case "PlatformAssembly":
|
case "PlatformAssembly":
|
||||||
PlatformAssembly = Path.GetFileNameWithoutExtension (value);
|
PlatformAssembly = Path.GetFileNameWithoutExtension (value);
|
||||||
break;
|
break;
|
||||||
|
case "TargetArchitectures":
|
||||||
|
if (!Enum.TryParse<Abi> (value, out var arch))
|
||||||
|
throw new InvalidOperationException ($"Unknown target architectures: {value} in {linker_file}");
|
||||||
|
// Add to the list of Abis as separate entries (instead of a flags enum value), because that way it's easier to enumerate over them.
|
||||||
|
Abis = new List<Abi> ();
|
||||||
|
for (var b = 0; b < 32; b++) {
|
||||||
|
var a = (Abi) (1 << b);
|
||||||
|
if ((a & arch) == a)
|
||||||
|
Abis.Add (a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException ($"Unknown key '{key}' in {linker_file}");
|
throw new InvalidOperationException ($"Unknown key '{key}' in {linker_file}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorHelper.Platform = Platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write ()
|
public void Write ()
|
||||||
{
|
{
|
||||||
Console.WriteLine ($"LinkerConfiguration:");
|
Console.WriteLine ($"LinkerConfiguration:");
|
||||||
|
Console.WriteLine ($" ABIs: {string.Join (", ", Abis.Select (v => v.AsArchString ()))}");
|
||||||
|
Console.WriteLine ($" CacheDirectory: {CacheDirectory}");
|
||||||
|
Console.WriteLine ($" ItemsDirectory: {ItemsDirectory}");
|
||||||
Console.WriteLine ($" Platform: {Platform}");
|
Console.WriteLine ($" Platform: {Platform}");
|
||||||
Console.WriteLine ($" PlatformAssembly: {PlatformAssembly}.dll");
|
Console.WriteLine ($" PlatformAssembly: {PlatformAssembly}.dll");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WriteOutputForMSBuild (string itemName, List<MSBuildItem> items)
|
||||||
|
{
|
||||||
|
var xmlNs = XNamespace.Get ("http://schemas.microsoft.com/developer/msbuild/2003");
|
||||||
|
var elements = items.Select (item =>
|
||||||
|
new XElement (xmlNs + itemName,
|
||||||
|
new XAttribute ("Include", item.Include),
|
||||||
|
item.Metadata.Select (metadata => new XElement (xmlNs + metadata.Key, metadata.Value))));
|
||||||
|
|
||||||
|
var document = new XDocument (
|
||||||
|
new XElement (xmlNs + "Project",
|
||||||
|
new XElement (xmlNs + "ItemGroup",
|
||||||
|
elements)));
|
||||||
|
|
||||||
|
document.Save (Path.Combine (ItemsDirectory, itemName + ".items"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MSBuildItem {
|
||||||
|
public string Include;
|
||||||
|
public Dictionary<string, string> Metadata = new Dictionary<string, string> ();
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
using Mono.Linker.Steps;
|
using Mono.Linker.Steps;
|
||||||
|
|
||||||
|
using Xamarin.Bundler;
|
||||||
using Xamarin.Linker;
|
using Xamarin.Linker;
|
||||||
|
|
||||||
namespace Xamarin {
|
namespace Xamarin {
|
||||||
|
@ -13,6 +15,10 @@ namespace Xamarin {
|
||||||
// This will be replaced with something more useful later.
|
// This will be replaced with something more useful later.
|
||||||
Console.WriteLine ("Hello SetupStep");
|
Console.WriteLine ("Hello SetupStep");
|
||||||
Configuration.Write ();
|
Configuration.Write ();
|
||||||
|
|
||||||
|
ErrorHelper.Platform = Configuration.Platform;
|
||||||
|
Directory.CreateDirectory (Configuration.ItemsDirectory);
|
||||||
|
Directory.CreateDirectory (Configuration.CacheDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
using Xamarin.Linker;
|
||||||
|
|
||||||
|
namespace Xamarin {
|
||||||
|
|
||||||
|
public class GenerateMainStep : ConfigurationAwareStep {
|
||||||
|
protected override void EndProcess ()
|
||||||
|
{
|
||||||
|
base.EndProcess ();
|
||||||
|
|
||||||
|
var items = new List<MSBuildItem> ();
|
||||||
|
|
||||||
|
foreach (var abi in Configuration.Abis) {
|
||||||
|
var file = Path.Combine (Configuration.CacheDirectory, $"main.{abi.AsArchString ()}.m");
|
||||||
|
var contents = @"
|
||||||
|
int
|
||||||
|
main (int argc, char** argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
";
|
||||||
|
File.WriteAllText (file, contents);
|
||||||
|
|
||||||
|
items.Add (new MSBuildItem {
|
||||||
|
Include = file,
|
||||||
|
Metadata = {
|
||||||
|
{ "Arch", abi.AsArchString () },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Configuration.WriteOutputForMSBuild ("_MainFile", items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,13 +2,45 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<RootNamespace>dotnet_linker</RootNamespace>
|
<RootNamespace>dotnet_linker</RootNamespace>
|
||||||
|
<DefineConstants>$(DefineConstants);BUNDLER</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="XliffTasks" Version="1.0.0-beta.20154.1" />
|
||||||
<PackageReference Include="Microsoft.NET.ILLink" Version="5.0.0-preview.3.20302.1" />
|
<PackageReference Include="Microsoft.NET.ILLink" Version="5.0.0-preview.3.20302.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\common\ApplePlatform.cs">
|
<Compile Include="..\common\ApplePlatform.cs">
|
||||||
<Link>ApplePlatform.cs</Link>
|
<Link>external\ApplePlatform.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
<Compile Include="..\common\MachO.cs">
|
||||||
|
<Link>external\MachO.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\src\ObjCRuntime\ErrorHelper.cs">
|
||||||
|
<Link>external\ErrorHelper.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\common\error.cs">
|
||||||
|
<Link>external\error.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\common\ErrorHelper.tools.cs">
|
||||||
|
<Link>external\ErrorHelper.tools.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\mtouch\Errors.designer.cs">
|
||||||
|
<Link>external\Errors.designer.cs</Link>
|
||||||
|
<DependentUpon>Errors.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="external\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="..\mtouch\Errors.resx">
|
||||||
|
<Link>external\Errors.resx</Link>
|
||||||
|
<XlfSourceFormat>Resx</XlfSourceFormat>
|
||||||
|
<XlfOutputItem>EmbeddedResource</XlfOutputItem>
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Errors.Designer.cs</LastGenOutput>
|
||||||
|
<CustomToolNamespace>Xamarin.Bundler</CustomToolNamespace>
|
||||||
|
<LogicalName>Errors.mtouch.resources</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче