66 throw new ArgumentNullException(nameof(options));
68 using var w =
new StringWriter();
70 if (options.
Output is not
null)
71 w.WriteLine($
"-out \"{options.Output}\"");
74 w.WriteLine($
"-assembly \"{options.Assembly}\"");
76 if (options.
Version is not
null)
77 w.WriteLine($
"-version {options.Version}");
79 if (options.
Target is not
null)
84 w.WriteLine($
"-target library");
87 w.WriteLine($
"-target exe");
90 w.WriteLine($
"-target winexe");
93 w.WriteLine($
"-target module");
99 w.WriteLine($
"-platform {options.Platform.ToString().ToLowerInvariant()}");
101 if (options.
KeyFile is not
null)
102 w.WriteLine($
"-keyfile \"{options.KeyFile}\"");
104 if (options.
Key is not
null)
105 w.WriteLine($
"-key {options.Key}");
108 w.WriteLine(
"-delay");
111 foreach (var reference
in options.References)
112 w.WriteLine($
"-reference \"{reference}\"");
114 if (options.Recurse is not
null)
115 foreach (var recurse
in options.Recurse)
116 w.WriteLine($
"-recurse \"{recurse}\"");
118 if (options.Exclude is not
null)
119 w.WriteLine($
"-exclude \"{options.Exclude}\"");
121 if (options.FileVersion is not
null)
122 w.WriteLine($
"-fileversion {options.FileVersion}");
124 if (options.Win32Icon is not
null)
125 w.WriteLine($
"-win32icon {options.Win32Icon}");
127 if (options.Win32Manifest is not
null)
128 w.WriteLine($
"-win32manifest {options.Win32Manifest}");
130 if (options.Resources is not
null)
131 foreach (var resource
in options.Resources)
132 w.WriteLine($
"-resource \"{resource.ResourcePath}={resource.FilePath}\"");
134 if (options.ExternalResources is not
null)
135 foreach (var resource
in options.ExternalResources)
136 w.WriteLine($
"-externalresource \"{resource.ResourcePath}={resource.FilePath}\"");
138 if (options.CompressResources)
139 w.WriteLine(
"-compressresources");
142 w.WriteLine(
"-debug portable");
144 w.WriteLine(
"-debug embedded");
146 if (options.NoAutoSerialization)
147 w.WriteLine(
"-noautoserialization");
149 if (options.NoGlobbing)
150 w.WriteLine(
"-noglobbing");
153 w.WriteLine(
"-nojni");
155 if (options.Optimize)
156 w.WriteLine(
"-optimize");
158 if (options.OptFields)
159 w.WriteLine(
"-opt:fields");
161 if (options.RemoveAssertions)
162 w.WriteLine(
"-removeassertions");
164 if (options.StrictFinalFieldSemantics)
165 w.WriteLine(
"-strictfinalfieldsemantics");
167 if (options.NoWarn is not
null)
169 if (options.NoWarn.Count == 0)
170 w.WriteLine(
"-nowarn");
172 w.WriteLine($
"-nowarn {string.Join(",
", options.NoWarn)}");
175 if (options.WarningsAsErrors is not
null)
177 if (options.WarningsAsErrors.Count == 0)
178 w.WriteLine(
"-warnaserror");
180 w.WriteLine($
"-warnaserror {string.Join(",
", options.WarningsAsErrors)}");
183 if (options.Main is not
null)
184 w.WriteLine($
"-main {options.Main}");
186 if (options.SrcPath is not
null)
187 w.WriteLine($
"-srcpath {options.SrcPath}");
189 if (options.Apartment is not
null)
190 w.WriteLine($
"-apartment {options.Apartment}");
192 if (options.SetProperties is not
null)
193 foreach (var kvp
in options.SetProperties)
194 w.WriteLine($
"-D \"{kvp.Key}={kvp.Value}\"");
196 if (options.NoStackTraceInfo)
197 w.WriteLine(
"-nostacktraceinfo");
199 if (options.PrivatePackages is not
null)
200 foreach (var i
in options.PrivatePackages)
201 w.WriteLine($
"-privatepackage {i}");
203 if (options.ClassLoader is not
null)
204 w.WriteLine($
"-classloader {options.ClassLoader}");
206 if (options.SharedClassLoader)
207 w.WriteLine(
"-sharedclassloader");
209 if (options.BaseAddress is not
null)
210 w.WriteLine($
"-baseaddress {options.BaseAddress}");
212 if (options.FileAlign is not
null)
213 w.WriteLine($
"-filealign {options.FileAlign}");
215 if (options.NoPeerCrossReference)
216 w.WriteLine(
"-nopeercrossreference");
218 if (options.NoStdLib)
219 w.WriteLine(
"-nostdlib");
221 if (options.Lib is not
null)
222 foreach (var i
in options.Lib)
223 w.WriteLine($
"-lib \"{i}\"");
225 if (options.HighEntropyVA)
226 w.WriteLine(
"-highentropyva");
229 w.WriteLine(
"-static");
231 if (options.AssemblyAttributes is not
null)
232 foreach (var i
in options.AssemblyAttributes)
233 w.WriteLine($
"-assemblyattributes \"{i}\"");
235 if (options.Runtime is not
null)
236 w.WriteLine($
"-runtime \"{options.Runtime}\"");
238 if (options.WarningLevel is not
null)
239 w.WriteLine($
"-w{options.WarningLevel}");
241 if (options.NoParameterReflection)
242 w.WriteLine($
"-noparameterreflection");
244 if (options.Remap is not
null)
245 w.WriteLine($
"-remap \"{options.Remap}\"");
247 w.WriteLine($
"-log json,file=stderr");
249 if (options.Input !=
null)
250 foreach (var i
in options.Input)
254 var response =
string.IsNullOrWhiteSpace(options.ResponseFile) ==
false ? Path.GetFullPath(options.ResponseFile) : Path.GetTempFileName();
257 var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken,
new CancellationToken());
261 if (options.Timeout != Timeout.Infinite)
262 ctk = CancellationTokenSource.CreateLinkedTokenSource(ctk,
new CancellationTokenSource(options.Timeout).Token).Token;
267 Directory.CreateDirectory(Path.GetDirectoryName(response) ??
throw new InvalidOperationException());
268 File.WriteAllText(response, w.ToString());
273 if (exe is
null || File.Exists(exe) ==
false)
274 throw new FileNotFoundException($
"Could not locate tool at '{exe}'.");
277 if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
280 if (exe.EndsWith(
".exe"))
290 var psx = Mono.Unix.UnixFileSystemInfo.GetFileSystemEntry(exe);
291 if (psx.FileAccessPermissions.HasFlag(Mono.Unix.FileAccessPermissions.UserExecute) ==
false)
292 psx.FileAccessPermissions |= Mono.Unix.FileAccessPermissions.UserExecute;
296 throw new IkvmToolException($
"Could not set user executable bit on '{exe}'.", e);
302 var args =
new List<string>();
303 args.Add($
"@{response}");
309 cli = Cli.Wrap(wrap);
316 cli = cli.WithWorkingDirectory(Environment.CurrentDirectory);
319 cli = cli.WithArguments(args);
320 cli = cli.WithValidation(CommandResultValidation.None);
329 using var pid = cli.ExecuteAsync(ctk);
332 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
336 if (pid.Task.IsCompleted ==
false)
358 if (options.ResponseFile ==
null && response !=
null && File.Exists(response))
362 File.Delete(response);