Skip to content

Commit

Permalink
Run illink out of process (#477)
Browse files Browse the repository at this point in the history
* Run illink out-of-process by implementing ToolTask

* Publish illink with runtimeconfig.json and deps.json

* Ensure that publish workaround runs after runtime files exist

The workaround for dotnet/sdk#1675 must run
after GenerateBuildDependencyFile and
GenerateBuildRuntimeConfigurationFiles to ensure that the deps.json
and runtimeconfig.json files exist at that time.

* Avoid string concatenation when using StringBuilder
  • Loading branch information
sbomer authored and marek-safar committed Mar 8, 2019
1 parent 2e4b687 commit ddf99d8
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/ILLink.Tasks/ILLink.Tasks.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
<file src="ILLink.Tasks.targets" target="build" />
<file src="ILLink.CrossGen.targets" target="build" />
<file src="netcoreapp2.0/**/*.dll" target="tools" />
<file src="netcoreapp2.0/**/*.json" target="tools" />
</files>
</package>
90 changes: 61 additions & 29 deletions src/ILLink.Tasks/LinkTask.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Reflection;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace ILLink.Tasks
{
public class ILLink : Task
public class ILLink : ToolTask
{
/// <summary>
/// Paths to the assembly files that should be considered as
Expand Down Expand Up @@ -70,30 +72,63 @@ public class ILLink : Task
/// </summary>
public bool DumpDependencies { get; set; }

public override bool Execute ()

private static string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH";

private string _dotnetPath;

private string DotNetPath
{
string [] args = GenerateCommandLineCommands ();
var argsString = String.Join (" ", args);
Log.LogMessageFromText ($"illink {argsString}", MessageImportance.Normal);
var logger = new AdapterLogger (Log);
int ret = Mono.Linker.Driver.Execute (args, logger);
return ret == 0;
get
{
if (!String.IsNullOrEmpty (_dotnetPath))
{
return _dotnetPath;
}
_dotnetPath = Environment.GetEnvironmentVariable (DotNetHostPathEnvironmentName);
if (String.IsNullOrEmpty (_dotnetPath))
{
throw new InvalidOperationException ($"{DotNetHostPathEnvironmentName} is not set");
}
return _dotnetPath;
}
}


/// ToolTask implementation

protected override string ToolName => Path.GetFileName (DotNetPath);

protected override string GenerateFullPathToTool () => DotNetPath;

private string _illinkPath = "";

public string ILLinkPath {
get {
if (!String.IsNullOrEmpty (_illinkPath))
{
return _illinkPath;
}
var taskDirectory = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
_illinkPath = Path.Combine (taskDirectory, "illink.dll");
return _illinkPath;
}
set => _illinkPath = value;
}

string [] GenerateCommandLineCommands ()
protected override string GenerateCommandLineCommands ()
{
var args = new List<string> ();
var args = new StringBuilder ();
args.Append (ILLinkPath);

if (RootDescriptorFiles != null) {
foreach (var rootFile in RootDescriptorFiles) {
args.Add ("-x");
args.Add (rootFile.ItemSpec);
args.Append (" -x ").Append (rootFile.ItemSpec);
}
}

foreach (var assemblyItem in RootAssemblyNames) {
args.Add ("-a");
args.Add (assemblyItem.ItemSpec);
args.Append (" -a ").Append (assemblyItem.ItemSpec);
}

HashSet<string> directories = new HashSet<string> ();
Expand All @@ -102,42 +137,39 @@ string [] GenerateCommandLineCommands ()
var dir = Path.GetDirectoryName (assemblyPath);
if (!directories.Contains (dir)) {
directories.Add (dir);
args.Add ("-d");
args.Add (dir);
args.Append (" -d ").Append (dir);
}

string action = assembly.GetMetadata ("action");
if ((action != null) && (action.Length > 0)) {
args.Add ("-p");
args.Add (action);
args.Add (Path.GetFileNameWithoutExtension (assemblyPath));
args.Append (" -p ");
args.Append (action);
args.Append (" ").Append (Path.GetFileNameWithoutExtension (assemblyPath));
}
}

if (OutputDirectory != null) {
args.Add ("-out");
args.Add (OutputDirectory.ItemSpec);
args.Append (" -out ").Append (OutputDirectory.ItemSpec);
}

if (ClearInitLocals) {
args.Add ("-s");
args.Append (" -s ");
// Version of ILLink.CustomSteps is passed as a workaround for msbuild issue #3016
args.Add ("ILLink.CustomSteps.ClearInitLocalsStep,ILLink.CustomSteps,Version=0.0.0.0:OutputStep");
args.Append ("LLink.CustomSteps.ClearInitLocalsStep,ILLink.CustomSteps,Version=0.0.0.0:OutputStep");
if ((ClearInitLocalsAssemblies != null) && (ClearInitLocalsAssemblies.Length > 0)) {
args.Add ("-m");
args.Add ("ClearInitLocalsAssemblies");
args.Add (ClearInitLocalsAssemblies);
args.Append (" -m ClearInitLocalsAssemblies ");
args.Append (ClearInitLocalsAssemblies);
}
}

if (ExtraArgs != null) {
args.AddRange (ExtraArgs.Split (' '));
args.Append (" ").Append (ExtraArgs);
}

if (DumpDependencies)
args.Add ("--dump-dependencies");
args.Append (" --dump-dependencies");

return args.ToArray ();
return args.ToString ();
}

}
Expand Down
16 changes: 15 additions & 1 deletion src/linker/ILLink.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,21 @@
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyName>illink</AssemblyName>
<OutputType>Library</OutputType>
<!-- OutputType is Exe in Mono.Linker.csproj, but it needs to be set before importing SDK targets. -->
<OutputType>Exe</OutputType>
</PropertyGroup>

<!-- When publishing illink as a dependency of ILLink.Tasks, we want
to include files needed to run it as an application in the
publish output. See https://github.com/dotnet/sdk/issues/1675. -->
<Target Name="AddRuntimeDependenciesToContent"
BeforeTargets="GetCopyToOutputDirectoryItems"
DependsOnTargets="GenerateBuildDependencyFile;GenerateBuildRuntimeConfigurationFiles"
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
<ItemGroup>
<ContentWithTargetPath Include="$(ProjectDepsFilePath)" CopyToOutputDirectory="PreserveNewest" TargetPath="$(ProjectDepsFileName)" />
<ContentWithTargetPath Include="$(ProjectRuntimeConfigFilePath)" CopyToOutputDirectory="PreserveNewest" TargetPath="$(ProjectRuntimeConfigFileName)" />
</ItemGroup>
</Target>

</Project>

0 comments on commit ddf99d8

Please sign in to comment.