[wasm] Build target fixes (#12418)
[mono-project.git] / sdks / wasm / sdk / Mono.WebAssembly.Build / WasmLinkAssemblies.cs
blobd796687a9a2847b78e94290a92b47369f65191e3
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 //
3 // Licensed under the MIT license.
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Text;
9 using Microsoft.Build.Framework;
10 using Microsoft.Build.Utilities;
12 namespace Mono.WebAssembly.Build
14 public class WasmLinkAssemblies : ToolTask
16 /// <summary>
17 /// The root application assembly.
18 /// </summary>
19 [Required]
20 public ITaskItem[] RootAssembly { get; set; }
22 /// <summary>
23 /// Any additional assemblies to be considered by the linker.
24 /// </summary>
25 public ITaskItem[] Assemblies { get; set; }
27 /// <summary>
28 /// The directory containing the framework assemblies.
29 /// </summary>
30 [Required]
31 public string FrameworkDir { get; set; }
33 /// <summary>
34 /// The directory into which to output the linked assemblies.
35 /// </summary>
36 [Required]
37 public string OutputDir { get; set; }
39 /// <summary>
40 /// Controls which kinds of assemblies are linked.
41 /// </summary>
42 // HACK: for some reason MSBuild doesn't like us typing this as an enum
43 public string LinkMode { get; set; }
45 /// <summary>
46 /// Semicolon separated list of assembly names that should not be linked.
47 /// </summary>
48 public string LinkSkip { get; set; }
50 /// <summary>
51 /// Whether to include debug information
52 /// </summary>
53 public bool Debug { get; set; }
55 /// <summary>
56 /// Internationalization code pages to be supported
57 /// </summary>
58 public string I18n { get; set; }
60 protected override string ToolName => "monolinker";
62 protected override string GenerateFullPathToTool ()
64 var dir = Path.GetDirectoryName (GetType ().Assembly.Location);
65 // Check if coming from nuget or local
66 var toolsPath = Path.Combine (Path.GetDirectoryName( dir ), "tools", "monolinker.exe");
67 if (File.Exists(toolsPath))
68 return toolsPath;
69 else
70 return Path.Combine (dir, "monolinker.exe");
73 protected override bool ValidateParameters ()
75 if (string.IsNullOrEmpty (OutputDir)) {
76 Log.LogError ("OutputDir is required");
77 return false;
80 if (string.IsNullOrEmpty (FrameworkDir)) {
81 Log.LogError ("FrameworkDir is required");
82 return false;
85 WasmLinkMode linkme;
86 if (!Enum.TryParse<WasmLinkMode>(LinkMode, out linkme)) {
87 Log.LogError ("LinkMode is invalid.");
88 return false;
92 return base.ValidateParameters ();
95 protected override string GenerateCommandLineCommands ()
97 var sb = new StringBuilder ();
99 sb.Append (" --verbose");
101 string coremode, usermode;
103 switch ((WasmLinkMode)Enum.Parse (typeof (WasmLinkMode), LinkMode)) {
104 case WasmLinkMode.SdkOnly:
105 coremode = "link";
106 usermode = "copy";
107 break;
108 case WasmLinkMode.Full:
109 coremode = "link";
110 usermode = "link";
111 break;
112 default:
113 coremode = "copyused";
114 usermode = "copy";
115 break;
118 sb.AppendFormat (" -c {0} -u {1}", coremode, usermode);
120 //the linker doesn't consider these core by default
121 sb.AppendFormat (" -p {0} netstandard -p {0} WebAssembly.Bindings -p {0} WebAssembly.Net.Http", coremode);
123 if (!string.IsNullOrEmpty (LinkSkip)) {
124 var skips = LinkSkip.Split (new[] { ';', ',', ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
125 foreach (var s in skips) {
126 sb.AppendFormat (" -p \"{0}\" copy", s);
130 sb.AppendFormat (" -out \"{0}\"", OutputDir);
131 sb.AppendFormat (" -d \"{0}\"", FrameworkDir);
132 sb.AppendFormat (" -d \"{0}\"", Path.Combine(FrameworkDir, "Facades"));
133 sb.AppendFormat (" -b {0} -v {0}", Debug);
135 sb.AppendFormat (" -a \"{0}\"", RootAssembly[0].GetMetadata("FullPath"));
137 //we'll normally have to check most of the because the SDK references most framework asm by default
138 //so let's enumerate upfront
139 var frameworkAssemblies = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
140 foreach (var f in Directory.EnumerateFiles (FrameworkDir)) {
141 frameworkAssemblies.Add (Path.GetFileNameWithoutExtension (f));
143 foreach (var f in Directory.EnumerateFiles (Path.Combine (FrameworkDir, "Facades"))) {
144 frameworkAssemblies.Add (Path.GetFileNameWithoutExtension (f));
147 //add references for non-framework assemblies
148 if (Assemblies != null) {
149 foreach (var asm in Assemblies) {
151 var p = asm.GetMetadata ("FullPath");
152 if (frameworkAssemblies.Contains(Path.GetFileNameWithoutExtension(p))) {
153 continue;
156 sb.AppendFormat (" -r \"{0}\"", p);
160 if (string.IsNullOrEmpty (I18n)) {
161 sb.Append (" -l none");
162 } else {
163 var vals = I18n.Split (new[] { ',', ';', ' ', '\r', '\n', '\t' });
164 sb.AppendFormat (" -l {0}", string.Join(",", vals));
167 return sb.ToString ();
171 public enum WasmLinkMode
173 None,
174 SdkOnly,
175 Full