xamarin-macios/tools/common/Driver.cs

1285 строки
47 KiB
C#
Исходник Обычный вид История

2016-04-21 15:57:02 +03:00
/*
* Copyright 2014 Xamarin Inc. All rights reserved.
*
* Authors:
* Rolf Bjarne Kvinge <rolf@xamarin.com>
*
*/
using System;
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
using System.Collections.Generic;
2016-04-21 15:57:02 +03:00
using System.Diagnostics;
using System.Globalization;
2016-04-21 15:57:02 +03:00
using System.IO;
using System.Linq;
using System.Text;
[mtouch] Rework how tasks are built. The previous build system kept a forward-pointing single linked list of tasks to execute: task X had a list of subsequent tasks to execute. If task X was up-to-date, it was not created (and the next tasks were directly added to the list of tasks to execute). In this world it became complicated to merge output from tasks (for instance if the output of task X and task Y should be a consumed by a single task producing a single output, since the corresponding task would end up in both X's and Y's list of subsequent tasks). Example: creating a single framework from the aot-compiled output of multiple assemblies. So I've reversed the logic: now we keep track of the final output, and then each task has a list of dependencies that must be built. This makes it trivial to create merging tasks (for the previous example, there could for instance be a CreateFrameworkTask, where its dependencies would be all the corresponding AotTasks). We also always create every task, and then each task decides when its executed whether it should do anything or not. This makes it unnecessary to 'forward- delete' files when creating tasks (say you have three tasks, A, B, C; B depends on A, and C depends on B; if A's output isn't up-to-date, it has to delete its own output if it exists, otherwise B would not detect that it would have to re-execute, because at task *creation* time, B's input hadn't changed). Additionally make it based on async/await, since much of the work happens in externel processes (and we don't need to spin up additional threads just to run external processes). This makes us have less code run on background threads, which makes any issues with thread-safety less likely.
2017-01-26 12:56:55 +03:00
using System.Threading.Tasks;
2016-04-21 15:57:02 +03:00
using Xamarin.MacDev;
2016-04-21 15:57:02 +03:00
using Xamarin.Utils;
using ObjCRuntime;
2016-04-21 15:57:02 +03:00
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
#if MTOUCH
using ProductException = Xamarin.Bundler.MonoTouchException;
#else
using ProductException=Xamarin.Bundler.MonoMacException;
#endif
2016-04-21 15:57:02 +03:00
namespace Xamarin.Bundler {
public partial class Driver {
2020-02-19 00:05:42 +03:00
public static int Main (string [] args)
{
try {
Console.OutputEncoding = new UTF8Encoding (false, false);
SetCurrentLanguage ();
return Main2 (args);
} catch (Exception e) {
ErrorHelper.Show (e);
} finally {
Watch ("Total time", 0);
}
return 0;
}
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
// Returns true if the process should exit (with a 0 exit code; failures are propagated using exceptions)
static bool ParseOptions (Application app, Mono.Options.OptionSet options, string[] args, ref Action action)
{
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
Action a = Action.None; // Need a temporary local variable, since anonymous functions can't write directly to ref/out arguments.
options.Add ("h|?|help", "Displays the help", v => a = Action.Help);
options.Add ("version", "Output version information and exit.", v => a = Action.Version);
options.Add ("v|verbose", "Specify how verbose the output should be. This can be passed multiple times to increase the verbosity.", v => Verbosity++);
options.Add ("q|quiet", "Specify how quiet the output should be. This can be passed multiple times to increase the silence.", v => Verbosity--);
options.Add ("sdkroot=", "Specify the location of Apple SDKs, default to 'xcode-select' value.", v => sdk_root = v);
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
options.Add ("target-framework=", "Specify target framework to use. Currently supported: '" + string.Join ("', '", TargetFramework.ValidFrameworks.Select ((v) => v.ToString ())) + "'.", v => SetTargetFramework (v));
options.Add ("no-xcode-version-check", "Ignores the Xcode version check.", v => { min_xcode_version = null; }, true /* This is a non-documented option. Please discuss any customers running into the xcode version check on the maciosdev@ list before giving this option out to customers. */);
options.Add ("warnaserror:", "An optional comma-separated list of warning codes that should be reported as errors (if no warnings are specified all warnings are reported as errors).", v =>
{
try {
if (!string.IsNullOrEmpty (v)) {
foreach (var code in v.Split (new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries))
ErrorHelper.SetWarningLevel (ErrorHelper.WarningLevel.Error, int.Parse (code));
} else {
ErrorHelper.SetWarningLevel (ErrorHelper.WarningLevel.Error);
}
} catch (Exception ex) {
2020-01-31 23:02:52 +03:00
ErrorHelper.Error (26, ex, Errors.MX0026, "--warnaserror", ex.Message);
}
});
options.Add ("nowarn:", "An optional comma-separated list of warning codes to ignore (if no warnings are specified all warnings are ignored).", v =>
{
try {
if (!string.IsNullOrEmpty (v)) {
foreach (var code in v.Split (new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries))
ErrorHelper.SetWarningLevel (ErrorHelper.WarningLevel.Disable, int.Parse (code));
} else {
ErrorHelper.SetWarningLevel (ErrorHelper.WarningLevel.Disable);
}
} catch (Exception ex) {
2020-01-31 23:02:52 +03:00
ErrorHelper.Error (26, ex, Errors.MX0026, "--nowarn", ex.Message);
}
});
options.Add ("coop:", "If the GC should run in cooperative mode.", v => { app.EnableCoopGC = ParseBool (v, "coop"); }, hidden: true);
options.Add ("sgen-conc", "Enable the *experimental* concurrent garbage collector.", v => { app.EnableSGenConc = true; });
options.Add ("marshal-objectivec-exceptions:", "Specify how Objective-C exceptions should be marshalled. Valid values: default, unwindmanagedcode, throwmanagedexception, abort and disable. The default depends on the target platform (on watchOS the default is 'throwmanagedexception', while on all other platforms it's 'disable').", v => {
switch (v) {
case "default":
app.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.Default;
break;
case "unwindmanaged":
case "unwindmanagedcode":
app.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.UnwindManagedCode;
break;
case "throwmanaged":
case "throwmanagedexception":
app.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.ThrowManagedException;
break;
case "abort":
app.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.Abort;
break;
case "disable":
app.MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.Disable;
break;
default:
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (26, Errors.MX0026, "--marshal-objective-exceptions", $"Invalid value: {v}. Valid values are: default, unwindmanagedcode, throwmanagedexception, abort and disable.");
}
});
options.Add ("marshal-managed-exceptions:", "Specify how managed exceptions should be marshalled. Valid values: default, unwindnativecode, throwobjectivecexception, abort and disable. The default depends on the target platform (on watchOS the default is 'throwobjectivecexception', while on all other platform it's 'disable').", v => {
switch (v) {
case "default":
app.MarshalManagedExceptions = MarshalManagedExceptionMode.Default;
break;
case "unwindnative":
case "unwindnativecode":
app.MarshalManagedExceptions = MarshalManagedExceptionMode.UnwindNativeCode;
break;
case "throwobjectivec":
case "throwobjectivecexception":
app.MarshalManagedExceptions = MarshalManagedExceptionMode.ThrowObjectiveCException;
break;
case "abort":
app.MarshalManagedExceptions = MarshalManagedExceptionMode.Abort;
break;
case "disable":
app.MarshalManagedExceptions = MarshalManagedExceptionMode.Disable;
break;
default:
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (26, Errors.MX0026, "--marshal-managed-exceptions", $"Invalid value: {v}. Valid values are: default, unwindnativecode, throwobjectivecexception, abort and disable.");
}
});
options.Add ("j|jobs=", "The level of concurrency. Default is the number of processors.", v => {
Jobs = int.Parse (v);
});
options.Add ("embeddinator", "Enables Embeddinator targetting mode.", v => {
app.Embeddinator = true;
}, true);
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162) * [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. * Refactor required symbol collection to store more information about each symbol (field, function, Objective-C class), and in general make the code more straight forward. * Implement support for generating source code that references these symbols, and do this whenever we can't ask the native linker to keep these symbols (when using bitcode). Additionally make it possible to do this manually, so that the source code can be generated for non-bitcode platforms too (which is useful if the number of symbols is enormous, in which case we might surpass the maximum command-line length). * Also make it possible to completely ignore native symbols, or ignore them on a per-symbol basis. This provides a fallback for users if we get something right and we try to preserve something that shouldn't be preserved (for instance if it doesn't exist), and the user ends up with unfixable linker errors. * Don't collect Objective-C classes unless they're in an assembly with LinkWith attributes. We don't need to preserve Objective-C classes in any other circumstances. * Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the code between them. * Remove previous workaround for bug #51710, since it's no longer needed. * Add tests. https://bugzilla.xamarin.com/show_bug.cgi?id=54417 https://bugzilla.xamarin.com/show_bug.cgi?id=51710 * [mtouch] Make sure to only keep symbols from the current app when code sharing. This fixes a build problem with the interdependent-binding-projects test when testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
options.Add ("dynamic-symbol-mode:", "Specify how dynamic symbols are treated so that they're not linked away by the native linker. Valid values: linker (pass \"-u symbol\" to the native linker), code (generate native code that uses the dynamic symbol), ignore (do nothing and hope for the best). The default is 'code' when using bitcode, and 'linker' otherwise.", (v) => {
switch (v.ToLowerInvariant ()) {
case "default":
app.SymbolMode = SymbolMode.Default;
break;
case "linker":
app.SymbolMode = SymbolMode.Linker;
break;
case "code":
app.SymbolMode = SymbolMode.Code;
break;
case "ignore":
app.SymbolMode = SymbolMode.Ignore;
break;
default:
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (26, Errors.MX0026, "--dynamic-symbol-mode", $"Invalid value: {v}. Valid values are: default, linker, code and ignore.");
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162) * [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. * Refactor required symbol collection to store more information about each symbol (field, function, Objective-C class), and in general make the code more straight forward. * Implement support for generating source code that references these symbols, and do this whenever we can't ask the native linker to keep these symbols (when using bitcode). Additionally make it possible to do this manually, so that the source code can be generated for non-bitcode platforms too (which is useful if the number of symbols is enormous, in which case we might surpass the maximum command-line length). * Also make it possible to completely ignore native symbols, or ignore them on a per-symbol basis. This provides a fallback for users if we get something right and we try to preserve something that shouldn't be preserved (for instance if it doesn't exist), and the user ends up with unfixable linker errors. * Don't collect Objective-C classes unless they're in an assembly with LinkWith attributes. We don't need to preserve Objective-C classes in any other circumstances. * Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the code between them. * Remove previous workaround for bug #51710, since it's no longer needed. * Add tests. https://bugzilla.xamarin.com/show_bug.cgi?id=54417 https://bugzilla.xamarin.com/show_bug.cgi?id=51710 * [mtouch] Make sure to only keep symbols from the current app when code sharing. This fixes a build problem with the interdependent-binding-projects test when testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
}
});
options.Add ("ignore-dynamic-symbol:", "Specify that Xamarin.iOS/Xamarin.Mac should not try to prevent the linker from removing the specified symbol.", (v) => {
app.IgnoredSymbols.Add (v);
});
options.Add ("root-assembly=", "Specifies any root assemblies. There must be at least one root assembly, usually the main executable.", (v) => {
app.RootAssemblies.Add (v);
});
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
options.Add ("optimize=", "A comma-delimited list of optimizations to enable/disable. To enable an optimization, use --optimize=[+]remove-uithread-checks. To disable an optimizations: --optimize=-remove-uithread-checks. Use '+all' to enable or '-all' disable all optimizations. Only compiler-generated code or code otherwise marked as safe to optimize will be optimized.\n" +
"Available optimizations:\n" +
" dead-code-elimination: By default always enabled (requires the linker). Removes IL instructions the linker can determine will never be executed. This is most useful in combination with the inline-* optimizations, since inlined conditions almost always also results in blocks of code that will never be executed.\n" +
" remove-uithread-checks: By default enabled for release builds (requires the linker). Remove all UI Thread checks (makes the app smaller, and slightly faster at runtime).\n" +
#if MONOTOUCH
" inline-isdirectbinding: By default enabled unless the interpreter is enabled (requires the linker). Tries to inline calls to NSObject.IsDirectBinding to load a constant value. Makes the app smaller, and slightly faster at runtime.\n" +
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
#else
" inline-isdirectbinding: By default disabled, because it may require the linker. Tries to inline calls to NSObject.IsDirectBinding to load a constant value. Makes the app smaller, and slightly faster at runtime.\n" +
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
#endif
#if MONOTOUCH
" remove-dynamic-registrar: By default enabled when the static registrar is enabled and the interpreter is not used. Removes the dynamic registrar (makes the app smaller).\n" +
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
" inline-runtime-arch: By default always enabled (requires the linker). Inlines calls to ObjCRuntime.Runtime.Arch to load a constant value. Makes the app smaller, and slightly faster at runtime.\n" +
#endif
Optimize calls to BlockLiteral.SetupBlock to inject the block signature. (#3391) * [linker] Optimize calls to BlockLiteral.SetupBlock to inject the block signature. Optimize calls to BlockLiteral.SetupBlock[Unsafe] to calculate the block signature at build time, and inject it into the call site. This makes block invocations 10-15x faster (I've added tests that asserts at least an 8x increase). It's also required in order to be able to remove the dynamic registrar code in the future (since calculating the block signature at runtime requires the dynamic registrar). * [mtouch/mmp] Add support for reporting errors/warnings that point to the code line causing the error/warning. Add support for reporting errors/warnings that point to the code line causing the error/warning by adding ErrorHelper overloads that take the exact instruction to report (previously we defaulted to the first line/instruction in a method). * [tests] Add support for asserting filename/linenumber in warning messages. * Make all methods that manually create BlockLiterals optimizable. * [tests] Create a BaseOptimizeGeneratedCodeTest test that's included in both XI's and XM's link all test. * [tests] Add link all test (for both XI and XM) to test the BlockLiteral.SetupBlock optimization. * [tests] Add mtouch/mmp tests for the BlockLiteral.SetupBlock optimization. * [tests][linker] Make the base test class abstract, so tests in the base class aren't executed twice. * [tests][linker] Don't execute linkall-only tests in linksdk. The optimization tests only apply when the test assembly is linked, and that only happens in linkall, so exclude those tests in linksdk. * [tests][mmptest] Update test according to mmp changes. Fixes these test failures: 1) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("inline-runtime-arch") The warning 'MM0132: Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' 2) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("foo") The warning 'MM0132: Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output: Message #1 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' Message #2 did not match: actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.' expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' * [tests][linker] Fix typo. Fixes this test failure: 1) SetupBlock_CustomDelegate (Linker.Shared.BaseOptimizeGeneratedCodeTest.SetupBlock_CustomDelegate) Counter Expected: 1 But was: 2 * [registrar] Minor adjustment to error message to match previous (and better) behavior. Fixes this test failure: 1) Failed : Xamarin.Registrar.GenericType_WithInvalidParameterTypes The error 'MT4136: The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' was not found in the output: Message #1 did not match: actual: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<Foundation.NSObject>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' expected: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' * [docs] mmp shows MM errors/warnings. * [docs] Improve according to reviews. * [tests] Fix merge failure causing test duplication.
2018-02-06 09:08:15 +03:00
" blockliteral-setupblock: By default enabled when using the static registrar. Optimizes calls to BlockLiteral.SetupBlock to avoid having to calculate the block signature at runtime.\n" +
" inline-intptr-size: By default enabled for builds that target a single architecture (requires the linker). Inlines calls to IntPtr.Size to load a constant value. Makes the app smaller, and slightly faster at runtime.\n" +
" inline-dynamic-registration-supported: By default always enabled (requires the linker). Optimizes calls to Runtime.DynamicRegistrationSupported to be a constant value. Makes the app smaller, and slightly faster at runtime.\n" +
#if !MONOTOUCH
" register-protocols: Remove unneeded metadata for protocol support. Makes the app smaller and reduces memory requirements. Disabled when the interpreter is used or when the static registrar is not enabled.\n" +
" trim-architectures: Remove unneeded architectures from bundled native libraries. Makes the app smaller and is required for macOS App Store submissions.\n" +
#else
" register-protocols: Remove unneeded metadata for protocol support. Makes the app smaller and reduces memory requirements. Disabled, by default, to allow dynamic code loading.\n" +
" remove-unsupported-il-for-bitcode: Remove IL that is not supported when compiling to bitcode, and replace with a NotSupportedException.\n" +
[mtouch] Add `force-rejected-types-removal` optimization (#8009) This optimization can be enabled when it's not possible to use the managed linker (e.g. **Don't link**) or when the managed linker cannot remove references to deprecated types that would cause an application to be rejected by Apple. References to the existing types will be renamed, e.g. `UIWebView` to `DeprecatedWebView`, in every assemblies. The type definition is also renamed (for validity) and all custom attributes on the types and their members will be removed. Code inside the members will be replaced with a `throw new NotSupportedException ();`. The msbuild test app `MyReleaseBuild` has been updated to test that the optimization is working as expected (device builds are slow so reusing this test has little impact in test time). Basically the test ensure that `UIWebView` is used and cannot be removed by the compiler (optimization) or the managed linker (since it's referenced). Since the optimization is enabled then we can `grep` then final `.app` directory to ensure there's no mention of `UIWebView` inside any of the files that would be submitted. The application can be run, by itself, and will turn green if OK, red if `DeprecatedWebView` can't be found (skeleton replacement for `UIWebView`) or orange if a `NotSupportedException` is thrown. Finally introspection tests have been updated to skip over the deprecated (and renamed) types. It should not be an issue right now, since this optimization is not enabled by default, but it made testing easier.
2020-03-02 17:20:29 +03:00
" force-rejected-types-removal: Forcefully remove types that are known to cause rejections when applications are submitted to Apple. This includes: `UIWebView` and related types.\n" +
#endif
"",
[mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. (#3242) * [mtouch/mmp] Give users more control over optimizations, and share more code between mtouch and mmp. 1. Add an --optimize flag to mtouch/mmp that allows users to select which optimizations to apply (or not). This makes it easier to add future optimizations, and allow users to disable any optimization that causes problems without having to disable many other features. 2. Share as much optimization code as possible between mtouch and mmp. This immediately gives a benefit to mmp, which has three new optimizations only mtouch had: NSObject.IsDirectBinding inlining, IntPtr.Size inlining and dead code elimination. This results in ~6kb of disk space saved for a linked Xamarin.Mac app: * link sdk: [Debug][1], [Release][2] * link all: [Debug][3], [Release][4] Testing also verifies that monotouchtest ([Debug][5], [Release][6]) has not changed size at all, which means that no default optimizations have changed inadvertedly. [1]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--debug [2]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-sdk-mac--release [3]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--debug [4]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#link-all-mac--release [5]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonedebug64 [6]: https://gist.github.com/rolfbjarne/6b731e3b5ca6170355662e6505c3d492#monotouchtest-iphonerelease64 * [tools] Don't enable the IsDirectBinding optimization by default for Xamarin.Mac apps, it's not safe. * Fix whitespace issues. * [doc] Document optimizations. * Officially support optimizations by adding them to the Versions.plist. * [linker] Improve IntPtr.Size inliner + dead code eliminatior and add tests. * Properly handle operands for the ldc_i4_s instruction (they're sbyte). * Fix less-than condition to actually do a less-than comparison. * Make sure to look up the bitness in the Target, not the Application, since the Application's value will be incorrect when building fat apps (both Is32Build and Is64Build will be true). * Remove unnecessary checks for the IntPtr.Size inliner: this optimization does not depend on other instructions than the IntPtr.get_Size call, so remove the checks that verify surrounding instructions. This makes the IntPtr.Size inliner kick in in more scenarios (such as the new tests). * Add tests. * [tests] Add mmp tests for optimizations. * [tests] Fix XM optimization tests. * [tests] Fix test build error.
2018-01-23 13:33:48 +03:00
(v) => {
app.Optimizations.Parse (v);
});
options.Add (new Mono.Options.ResponseFileSource ());
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
try {
app.RootAssemblies.AddRange (options.Parse (args));
} catch (ProductException) {
throw;
} catch (Exception e) {
throw ErrorHelper.CreateError (10, e, Errors.MX0010, e);
}
if (a != Action.None)
action = a;
if (action == Action.Help || args.Length == 0) {
ShowHelp (options);
return true;
} else if (action == Action.Version) {
Console.WriteLine (NAME + " {0}.{1}", Constants.Version, Constants.Revision);
return true;
}
LogArguments (args);
ValidateTargetFramework ();
return false;
}
static int Jobs;
public static int Concurrency {
get {
return Jobs == 0 ? Environment.ProcessorCount : Jobs;
}
}
static int verbose = GetDefaultVerbosity ();
[mtouch/mmp] Print assembly references in verbose mode. (#2139) * [mtouch/mmp] Print assembly references in verbose mode. Sample output: Loaded assembly 'unifiedtestapp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' from /Users/rolf/Projects/TestApp/bin/iPhoneSimulator/Debug/unifiedtestapp.exe References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065 Loaded assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/mscorlib.dll Loaded assembly 'Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/../../64bits/Xamarin.iOS.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756 References: System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756 References: System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/Mono.Security.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.Xml.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.Core.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e I believe this will make it easier to diagnose cases where something references a desktop assembly. * [mtouch/mmp] Share more code between mmp and mtouch.
2017-05-29 17:15:22 +03:00
public static int Verbosity {
get { return verbose; }
set {
verbose = value;
ErrorHelper.Verbosity = Verbosity;
}
}
static int GetDefaultVerbosity ()
{
var v = 0;
var fn = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), $".{NAME}-verbosity");
if (File.Exists (fn)) {
v = (int) new FileInfo (fn).Length;
if (v == 0)
v = 4; // this is the magic verbosity level we give everybody.
}
return v;
}
public static void Log (string value)
{
Log (0, value);
}
public static void Log (string format, params object [] args)
{
Log (0, format, args);
}
public static void Log (int min_verbosity, string value)
{
if (min_verbosity > Verbosity)
return;
Console.WriteLine (value);
}
public static void Log (int min_verbosity, string format, params object [] args)
{
if (min_verbosity > Verbosity)
return;
if (args.Length > 0)
Console.WriteLine (format, args);
else
Console.WriteLine (format);
[mtouch/mmp] Print assembly references in verbose mode. (#2139) * [mtouch/mmp] Print assembly references in verbose mode. Sample output: Loaded assembly 'unifiedtestapp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' from /Users/rolf/Projects/TestApp/bin/iPhoneSimulator/Debug/unifiedtestapp.exe References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065 Loaded assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/mscorlib.dll Loaded assembly 'Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/../../64bits/Xamarin.iOS.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756 References: System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756 References: System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/Mono.Security.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.Xml.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Loaded assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.Core.dll References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e I believe this will make it easier to diagnose cases where something references a desktop assembly. * [mtouch/mmp] Share more code between mmp and mtouch.
2017-05-29 17:15:22 +03:00
}
Add a BindingImpl attribute and use to to teach the linker look for it to search for optimizable code. (#3299) * [ObjCRuntime] Add a BindingImplAttribute. * [linker] Make ProviderToString an extension method on ICustomAttributeProvider to make it more discoverable. * [generator] Use [BindingImpl] instead of [CompilerGenerated]. The entire diff is big (89MB), so it can't be gisted. However, most of it is either removal of `using System.Runtime.CompilerServices;` or the change from `[CompilerGenerated]` to `[BindingImpl (...)]` like this: https://gist.github.com/rolfbjarne/8bfda3ed37b956d0342a1c1e9b079244 If I remove those parts of the diff, there's nothing significant left: https://gist.github.com/rolfbjarne/4156164d6bdb1376366200394eb8a091 * [linker] Teach the linker about the new [BindingImpl] attribute. In addition to the existing logic where the linker would optimize some [CompilerGenerated] code (sometimes with additional requirements), it will now also optimize all [BindingImpl (Optimizable)] code (without any additional requirements). * [tests] Add tests to make sure [BindingImpl (Optimizable)] works as expected. * [linker] Check for [BindingImpl] before [CompilerGenerated] and stop checking for [CompilerGenerated] in XAMCORE_4_0. Check for [BindingImpl] before checking for [CompilerGenerated], since the former is more common. Also stop checking for [CompilerGenerated] (at least to mean that code is optimizable) in our next non-compatible evolutionary leap (XAMCORE_4_0): * [introspection] Impl a better typo check.
2018-01-26 20:38:23 +03:00
public const bool IsXAMCORE_4_0 = false;
public static bool IsDotNet {
get { return TargetFramework.IsDotNet; }
}
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
static TargetFramework targetFramework;
2016-04-21 15:57:02 +03:00
public static TargetFramework TargetFramework {
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
get { return targetFramework; }
2016-04-21 15:57:02 +03:00
set { targetFramework = value; }
}
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
// We need to delay validating the target framework until we've parsed all the command line arguments,
// so first store it here, and then we call ValidateTargetFramework when we're done parsing the command
// line arguments.
static string target_framework;
static void SetTargetFramework (string value)
2016-04-21 15:57:02 +03:00
{
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
target_framework = value;
}
static void ValidateTargetFramework ()
{
if (string.IsNullOrEmpty (target_framework))
throw ErrorHelper.CreateError (86, Errors.MX0086 /* A target framework (--target-framework) must be specified */);
2016-04-21 15:57:02 +03:00
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
var fx = target_framework;
2016-04-21 15:57:02 +03:00
switch (fx.Trim ().ToLowerInvariant ()) {
case "xammac":
case "mobile":
case "xamarin.mac":
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
targetFramework = TargetFramework.Xamarin_Mac_2_0_Mobile;
ErrorHelper.Warning (90, Errors.MX0090, /* The target framework '{0}' is deprecated. Use '{1}' instead. */ fx, targetFramework);
return;
2016-04-21 15:57:02 +03:00
default:
TargetFramework parsedFramework;
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
if (!TargetFramework.TryParse (fx, out parsedFramework))
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (68, Errors.MX0068, fx);
2016-04-21 15:57:02 +03:00
targetFramework = parsedFramework;
break;
}
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
bool show_0090 = false;
#if MONOMAC
if (!TargetFramework.IsValidFramework (targetFramework)) {
// For historic reasons this is messy.
// If the TargetFramework we got isn't any of the one we accept, we have to do some fudging.
bool force45From40UnifiedSystemFull = false;
// Detect Classic usage, and show an error.
if (App.References.Any ((v) => Path.GetFileName (v) == "XamMac.dll"))
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
throw ErrorHelper.CreateError (143, Errors.MM0143 /* Projects using the Classic API are not supported anymore. Please migrate the project to the Unified API. */);
if (targetFramework == TargetFramework.Net_2_0
|| targetFramework == TargetFramework.Net_3_0
|| targetFramework == TargetFramework.Net_3_5
|| targetFramework == TargetFramework.Net_4_0
|| targetFramework == TargetFramework.Net_4_5) {
// .NETFramework,v2.0 => Xamarin.Mac,Version=v4.5,Profile=Full
// .NETFramework,v3.0 => Xamarin.Mac,Version=v4.5,Profile=Full
// .NETFramework,v3.5 => Xamarin.Mac,Version=v4.5,Profile=Full
// .NETFramework,v4.0 => Xamarin.Mac,Version=v4.5,Profile=Full
// .NETFramework,v4.5 => Xamarin.Mac,Version=v4.5,Profile=Full
TargetFramework = TargetFramework.Xamarin_Mac_4_5_Full;
} else if (TargetFramework.Identifier == TargetFramework.Xamarin_Mac_2_0_Mobile.Identifier
&& TargetFramework.Version == TargetFramework.Xamarin_Mac_2_0_Mobile.Version) {
// At least once instance of a TargetFramework of Xamarin.Mac,v2.0,(null) was found already. Assume any v2.0 implies a desire for Modern.
TargetFramework = TargetFramework.Xamarin_Mac_2_0_Mobile;
} else if (TargetFramework.Identifier == TargetFramework.Xamarin_Mac_4_5_Full.Identifier
&& TargetFramework.Profile == TargetFramework.Xamarin_Mac_4_5_Full.Profile) {
// Xamarin.Mac,Version=vX.Y,Profile=Full => Xamarin.Mac,Version=v4.5,Profile=Full
TargetFramework = TargetFramework.Xamarin_Mac_4_5_Full;
} else if (TargetFramework.Identifier == TargetFramework.Xamarin_Mac_4_5_System.Identifier
&& TargetFramework.Profile == TargetFramework.Xamarin_Mac_4_5_System.Profile) {
// Xamarin.Mac,Version=vX.Y,Profile=System => Xamarin.Mac,Version=v4.5,Profile=System
TargetFramework = TargetFramework.Xamarin_Mac_4_5_System;
} else {
// This is a total hack. Instead of passing in an argument, we walk the references looking for
// the "right" Xamarin.Mac and assume you are doing something
foreach (var asm in App.References) {
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
if (asm.EndsWith ("reference/full/Xamarin.Mac.dll", StringComparison.Ordinal)) {
force45From40UnifiedSystemFull = TargetFramework == TargetFramework.Net_4_0;
TargetFramework = TargetFramework.Xamarin_Mac_4_5_System;
break;
} else if (asm.EndsWith ("mono/4.5/Xamarin.Mac.dll", StringComparison.Ordinal)) {
TargetFramework = TargetFramework.Xamarin_Mac_4_5_Full;
break;
}
}
}
if (force45From40UnifiedSystemFull) {
// Xamarin.Mac Unified Full System profile requires .NET 4.5, not .NET 4.0.
FixReferences (x => x.Contains ("lib/mono/4.0"), x => x.Replace ("lib/mono/4.0", "lib/mono/4.5"));
}
show_0090 = true;
}
2016-04-21 15:57:02 +03:00
#endif
[mtouch/mmp] Improve target framework code. (#8137) * Unify target framework code between mtouch and mmp. * Simplify the code in mmp: have three possible valid target frameworks for most of code, and add special code to handle setting any other valid target frameworks to redirect to one of those three valid target frameworks (and warn if given any of those valid, but not "main", target frameworks). Any other code can then depend on the target framework having exactly one of those specific values, which means we can make IsUnified* variables convenience properties instead. * Unify a bit more of the argument parsing code between mtouch and mmp, since that made a few other things easier. * Add TargetFramework.IsValidFramework to have one validation implementation. * Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp itself, it's not really related to the target framework. * Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore. * Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years. * Remove LinkerOptions.TargetFramework, it's not used anymore. * Get rid of mmp's userTargetFramework fried, it's duplicated with the targetFramework field. * Add a few tests, and tweak others a bit. Breaking changes: * Both mtouch and mmp require --target-framework now. The only direct consumers should be the MSBuild tasks, which already pass --target-framework all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
// Verify that our TargetFramework is our limited list of valid target frameworks.
if (!TargetFramework.IsValidFramework (TargetFramework))
throw ErrorHelper.CreateError (70, Errors.MX0070, fx, "'" + string.Join ("', '", TargetFramework.ValidFrameworks.Select ((v) => v.ToString ()).ToArray ()) + "'");
// Only show the warning if no errors were shown.
if (show_0090)
ErrorHelper.Warning (90, Errors.MX0090, /* The target framework '{0}' is deprecated. Use '{1}' instead. */ fx, TargetFramework);
2016-04-21 15:57:02 +03:00
}
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
public static int RunCommand (string path, params string [] args)
{
return RunCommand (path, args, null, (Action<string>) null, (Action<string>) null, false);
}
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
public static int RunCommand (string path, IList<string> args)
{
return RunCommand (path, args, null, (Action<string>) null, (Action<string>) null, false);
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
}
public static int RunCommand (string path, IList<string> args, StringBuilder output)
2016-04-21 15:57:02 +03:00
{
return RunCommand (path, args, null, output, output, false);
}
public static int RunCommand (string path, IList<string> args, StringBuilder output, bool suppressPrintOnErrors)
{
return RunCommand (path, args, null, output, output, suppressPrintOnErrors);
}
public static int RunCommand (string path, IList<string> args, string [] env, StringBuilder output)
{
return RunCommand (path, args, env, output, output, false);
}
public static int RunCommand (string path, IList<string> args, string [] env, StringBuilder output, bool suppressPrintOnErrors)
{
return RunCommand (path, args, env, output, output, suppressPrintOnErrors);
}
public static int RunCommand (string path, IList<string> args, string [] env, StringBuilder output, StringBuilder error)
{
return RunCommand (path, args, env, output, error, false);
}
public static int RunCommand (string path, IList<string> args, StringBuilder output, StringBuilder error)
{
return RunCommand (path, args, null, output, error, false);
}
public static int RunCommand (string path, IList<string> args, StringBuilder output, StringBuilder error, bool suppressPrintOnErrors)
{
return RunCommand (path, args, null, output, error, suppressPrintOnErrors);
}
public static int RunCommand (string path, IList<string> args, string [] env, StringBuilder output, StringBuilder error, bool suppressPrintOnErrors)
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
{
var output_received = output == null ? null : new Action<string> ((v) => { if (v != null) output.AppendLine (v); });
var error_received = error == null ? null : new Action<string> ((v) => { if (v != null) error.AppendLine (v); });
return RunCommand (path, args, env, output_received, error_received, suppressPrintOnErrors);
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
}
static int RunCommand (string path, IList<string> args, string [] env, Action<string> output_received, bool suppressPrintOnErrors)
{
return RunCommand (path, args, env, output_received, output_received, suppressPrintOnErrors);
}
static int RunCommand (string path, IList<string> args, string [] env, Action<string> output_received, Action<string> error_received)
{
return RunCommand (path, args, env, output_received, error_received, false);
}
static int RunCommand (string path, IList<string> args, string[] env, Action<string> output_received, Action<string> error_received, bool suppressPrintOnErrors)
2016-04-21 15:57:02 +03:00
{
Exception stdin_exc = null;
var info = new ProcessStartInfo (path, StringUtils.FormatArguments (args));
2016-04-21 15:57:02 +03:00
info.UseShellExecute = false;
info.RedirectStandardInput = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
System.Threading.ManualResetEvent stdout_completed = new System.Threading.ManualResetEvent (false);
System.Threading.ManualResetEvent stderr_completed = new System.Threading.ManualResetEvent (false);
if (output_received == null ^ error_received == null)
throw new ArgumentException ("Either both or neither of 'output_received' and 'error_received' can be specified.");
var lockobj = new object ();
StringBuilder output = null;
if (output_received == null) {
2016-04-21 15:57:02 +03:00
output = new StringBuilder ();
output_received = (line) => {
if (line != null)
output.AppendLine (line);
};
error_received = output_received;
}
2016-04-21 15:57:02 +03:00
if (env != null){
if (env.Length % 2 != 0)
throw new Exception ("You passed an environment key without a value");
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
for (int i = 0; i < env.Length; i += 2) {
if (env [i + 1] == null) {
info.EnvironmentVariables.Remove (env [i]);
} else {
info.EnvironmentVariables [env [i]] = env [i + 1];
}
}
2016-04-21 15:57:02 +03:00
}
Log (1, "{0} {1}", info.FileName, info.Arguments);
2016-04-21 15:57:02 +03:00
using (var p = Process.Start (info)) {
p.OutputDataReceived += (s, e) => {
if (e.Data != null) {
lock (lockobj)
output_received (e.Data);
2016-04-21 15:57:02 +03:00
} else {
stdout_completed.Set ();
}
};
p.ErrorDataReceived += (s, e) => {
if (e.Data != null) {
lock (lockobj)
error_received (e.Data);
2016-04-21 15:57:02 +03:00
} else {
stderr_completed.Set ();
}
};
p.BeginOutputReadLine ();
p.BeginErrorReadLine ();
p.WaitForExit ();
stderr_completed.WaitOne (TimeSpan.FromSeconds (1));
stdout_completed.WaitOne (TimeSpan.FromSeconds (1));
output_received (null);
2016-04-21 15:57:02 +03:00
if (p.ExitCode != 0) {
// note: this repeat the failing command line. However we can't avoid this since we're often
// running commands in parallel (so the last one printed might not be the one failing)
if (!suppressPrintOnErrors) {
// We re-use the stringbuilder so that we avoid duplicating the amount of required memory,
// while only calling Console.WriteLine once to make it less probable that other threads
// also write to the Console, confusing the output.
if (output == null)
output = new StringBuilder ();
output.Insert (0, $"Process exited with code {p.ExitCode}, command:\n{path} {args}\n");
Console.Error.WriteLine (output);
}
2016-04-21 15:57:02 +03:00
return p.ExitCode;
} else if (Verbosity > 0 && output != null && output.Length > 0 && !suppressPrintOnErrors) {
2016-04-21 15:57:02 +03:00
Console.WriteLine (output.ToString ());
}
if (stdin_exc != null)
throw stdin_exc;
}
return 0;
}
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
public static Task<int> RunCommandAsync (string path, string[] args, string [] env = null, StringBuilder output = null, bool suppressPrintOnErrors = false)
[mtouch] Rework how tasks are built. The previous build system kept a forward-pointing single linked list of tasks to execute: task X had a list of subsequent tasks to execute. If task X was up-to-date, it was not created (and the next tasks were directly added to the list of tasks to execute). In this world it became complicated to merge output from tasks (for instance if the output of task X and task Y should be a consumed by a single task producing a single output, since the corresponding task would end up in both X's and Y's list of subsequent tasks). Example: creating a single framework from the aot-compiled output of multiple assemblies. So I've reversed the logic: now we keep track of the final output, and then each task has a list of dependencies that must be built. This makes it trivial to create merging tasks (for the previous example, there could for instance be a CreateFrameworkTask, where its dependencies would be all the corresponding AotTasks). We also always create every task, and then each task decides when its executed whether it should do anything or not. This makes it unnecessary to 'forward- delete' files when creating tasks (say you have three tasks, A, B, C; B depends on A, and C depends on B; if A's output isn't up-to-date, it has to delete its own output if it exists, otherwise B would not detect that it would have to re-execute, because at task *creation* time, B's input hadn't changed). Additionally make it based on async/await, since much of the work happens in externel processes (and we don't need to spin up additional threads just to run external processes). This makes us have less code run on background threads, which makes any issues with thread-safety less likely.
2017-01-26 12:56:55 +03:00
{
if (output != null)
return RunCommandAsync (path, args, env, (v) => { if (v != null) output.AppendLine (v); }, suppressPrintOnErrors);
return RunCommandAsync (path, args, env, (Action<string>) null, suppressPrintOnErrors);
}
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
public static Task<int> RunCommandAsync (string path, string[] args, string [] env = null, Action<string> output_received = null, bool suppressPrintOnErrors = false)
{
return Task.Run (() => RunCommand (path, args, env, output_received, suppressPrintOnErrors));
[mtouch] Rework how tasks are built. The previous build system kept a forward-pointing single linked list of tasks to execute: task X had a list of subsequent tasks to execute. If task X was up-to-date, it was not created (and the next tasks were directly added to the list of tasks to execute). In this world it became complicated to merge output from tasks (for instance if the output of task X and task Y should be a consumed by a single task producing a single output, since the corresponding task would end up in both X's and Y's list of subsequent tasks). Example: creating a single framework from the aot-compiled output of multiple assemblies. So I've reversed the logic: now we keep track of the final output, and then each task has a list of dependencies that must be built. This makes it trivial to create merging tasks (for the previous example, there could for instance be a CreateFrameworkTask, where its dependencies would be all the corresponding AotTasks). We also always create every task, and then each task decides when its executed whether it should do anything or not. This makes it unnecessary to 'forward- delete' files when creating tasks (say you have three tasks, A, B, C; B depends on A, and C depends on B; if A's output isn't up-to-date, it has to delete its own output if it exists, otherwise B would not detect that it would have to re-execute, because at task *creation* time, B's input hadn't changed). Additionally make it based on async/await, since much of the work happens in externel processes (and we don't need to spin up additional threads just to run external processes). This makes us have less code run on background threads, which makes any issues with thread-safety less likely.
2017-01-26 12:56:55 +03:00
}
2016-04-21 15:57:02 +03:00
#if !MMP_TEST
static void FileMove (string source, string target)
{
Application.TryDelete (target);
File.Move (source, target);
}
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
static void MoveIfDifferent (string path, string tmp, bool use_stamp = false)
{
// Don't read the entire file into memory, it can be quite big in certain cases.
bool move = false;
using (var fs1 = new FileStream (path, FileMode.Open, FileAccess.Read)) {
using (var fs2 = new FileStream (tmp, FileMode.Open, FileAccess.Read)) {
if (fs1.Length != fs2.Length) {
Log (3, "New file '{0}' has different length, writing new file.", path);
move = true;
} else {
move = !Cache.CompareStreams (fs1, fs2);
}
}
}
if (move) {
FileMove (tmp, path);
} else {
Log (3, "Target {0} is up-to-date.", path);
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
if (use_stamp)
Driver.Touch (path + ".stamp");
}
}
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
public static void WriteIfDifferent (string path, string contents, bool use_stamp = false)
2016-04-21 15:57:02 +03:00
{
var tmp = path + ".tmp";
try {
if (!File.Exists (path)) {
Directory.CreateDirectory (Path.GetDirectoryName (path));
2016-04-21 15:57:02 +03:00
File.WriteAllText (path, contents);
Log (3, "File '{0}' does not exist, creating it.", path);
return;
}
File.WriteAllText (tmp, contents);
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
MoveIfDifferent (path, tmp, use_stamp);
} catch (Exception e) {
File.WriteAllText (path, contents);
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (1014, e, Errors.MT1014, path, e.Message);
} finally {
Application.TryDelete (tmp);
}
}
2016-04-21 15:57:02 +03:00
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
public static void WriteIfDifferent (string path, byte[] contents, bool use_stamp = false)
{
var tmp = path + ".tmp";
2016-04-21 15:57:02 +03:00
try {
if (!File.Exists (path)) {
File.WriteAllBytes (path, contents);
Log (3, "File '{0}' does not exist, creating it.", path);
return;
2016-04-21 15:57:02 +03:00
}
File.WriteAllBytes (tmp, contents);
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
MoveIfDifferent (path, tmp, use_stamp);
2016-04-21 15:57:02 +03:00
} catch (Exception e) {
File.WriteAllBytes (path, contents);
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (1014, e, Errors.MT1014, path, e.Message);
2016-04-21 15:57:02 +03:00
} finally {
Application.TryDelete (tmp);
}
}
#endif
internal static string GetFullPath ()
{
return System.Reflection.Assembly.GetExecutingAssembly ().Location;
}
static string xcode_product_version;
public static string XcodeProductVersion {
Bump to use Xcode 10 beta 1 (#4179) * Bump to use Xcode 10 beta 1 * Update Versions.plist * Add a dependency on Xcode 9.4. * [msbuild] Fix build with Xcode 10 beta 1. (#4182) Many years ago (in Xcode 7 according to code comment) Developer/Platforms/iPhoneOS.platform/Developer/usr disappeared, and we coped by looking at Developer/usr instead (and also the subsequent code to locate the bin directory was based on the location of the usr directory). Developer/Platforms/iPhoneOS.platform/Developer/usr reappeared in Xcode 10 beta 1, but it seems useless (for one it doesn't contain a bin directory), so in order to try to keep things sane don't look for this directory in Xcode 10 and instead go directly for Developer/usr (which is what we've been using as the usr directory for years anyway). Fixes this problem when building apps with Xcode 10 beta 1: /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(626,3): error : Could not locate SDK bin directory [/Users/rolf/Projects/TestApp/test-app.csproj] * [runtime] Build 32-bit mac executables using Xcode 9.4. * [mtouch] Work around broken tvOS headers in Xcode 10 beta 1. * [mtouch] Work around build problem with Apple's simd headers in Objective-C++ mode. * Use version-agnostic paths to sdk directories. * [tests][xtro] Add todo files (from unclassified) and adjust ignore files to avoid errors * [macos][security] Re-enable SSL[Get|Set]AlpnProtocols. Fixes #4001 (#4022) * [macos][security] Re-enable SSL[Get}Set]AlpnProtocols. Fixes #4001 This was fixed in macOS 10.13.4 https://github.com/xamarin/xamarin-macios/issues/4001 * [tests][monotouch-tests] Disable a few test cases (one crasher, other failures). Causes to be verified later * [xharness] Fix permission dialog suppression in Xcode 10. * [xharness] Ignore 32-bit macOS tests by default. * [tests] Execute mmp regression tests with Xcode 9.4 since many of them are 32-bit and needs porting to 64-bit. * [mmptest] Ignore 32-bit XM tests if we don't have a 32-bit-capable Xcode. * [registrar] Add workaround for broken headers in Xcode 10 beta 1 (radar 40824697). * [mtouch] Restrict another workaround for an Xcode 10 beta 1 bug to a specific Xcode version to remove it asap. * [tests] Fix some protocol changes (public or not) find by introspection tests * [tests][intro] Fix DefaultCtorAllowed failures * [Intents] Obsolete several Intents classes in watchOS. Several existing Intents classes have been marked as unavailable in watchOS in the headers in Xcode 10 beta 1, and corresponding tests are now failing. So obsolete the managed wrapper types, and fix tests accordingly. * Fix xtro wrt previous Ietents/intro changes * [tests] Minor adjustments to mtouch tests to work with Xcode 10. * [msbuild] Update tests to cope with additional files produced by the Core ML compiler. * [msbuild] Xcode 10 doesn't support building watchOS 1 apps, so show a clear error message explaining it. Also update tests accordingly. * [coreimage] Stub new filters and exclude ?removed? ones from tests * Update GameplayKit and SpriteKit NSSecureCoding _upgrade_ and fix other non-public cases (in tests) * [tests] Ignore some GameKit selectors that don't respond anymore (but seems to be available, at least in header files) * [tests] Fix intro 32bits testing for filters resutls * [msbuild] Slightly change error message to be better English.
2018-06-09 04:45:24 +03:00
get {
return xcode_product_version;
Bump to use Xcode 10 beta 1 (#4179) * Bump to use Xcode 10 beta 1 * Update Versions.plist * Add a dependency on Xcode 9.4. * [msbuild] Fix build with Xcode 10 beta 1. (#4182) Many years ago (in Xcode 7 according to code comment) Developer/Platforms/iPhoneOS.platform/Developer/usr disappeared, and we coped by looking at Developer/usr instead (and also the subsequent code to locate the bin directory was based on the location of the usr directory). Developer/Platforms/iPhoneOS.platform/Developer/usr reappeared in Xcode 10 beta 1, but it seems useless (for one it doesn't contain a bin directory), so in order to try to keep things sane don't look for this directory in Xcode 10 and instead go directly for Developer/usr (which is what we've been using as the usr directory for years anyway). Fixes this problem when building apps with Xcode 10 beta 1: /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(626,3): error : Could not locate SDK bin directory [/Users/rolf/Projects/TestApp/test-app.csproj] * [runtime] Build 32-bit mac executables using Xcode 9.4. * [mtouch] Work around broken tvOS headers in Xcode 10 beta 1. * [mtouch] Work around build problem with Apple's simd headers in Objective-C++ mode. * Use version-agnostic paths to sdk directories. * [tests][xtro] Add todo files (from unclassified) and adjust ignore files to avoid errors * [macos][security] Re-enable SSL[Get|Set]AlpnProtocols. Fixes #4001 (#4022) * [macos][security] Re-enable SSL[Get}Set]AlpnProtocols. Fixes #4001 This was fixed in macOS 10.13.4 https://github.com/xamarin/xamarin-macios/issues/4001 * [tests][monotouch-tests] Disable a few test cases (one crasher, other failures). Causes to be verified later * [xharness] Fix permission dialog suppression in Xcode 10. * [xharness] Ignore 32-bit macOS tests by default. * [tests] Execute mmp regression tests with Xcode 9.4 since many of them are 32-bit and needs porting to 64-bit. * [mmptest] Ignore 32-bit XM tests if we don't have a 32-bit-capable Xcode. * [registrar] Add workaround for broken headers in Xcode 10 beta 1 (radar 40824697). * [mtouch] Restrict another workaround for an Xcode 10 beta 1 bug to a specific Xcode version to remove it asap. * [tests] Fix some protocol changes (public or not) find by introspection tests * [tests][intro] Fix DefaultCtorAllowed failures * [Intents] Obsolete several Intents classes in watchOS. Several existing Intents classes have been marked as unavailable in watchOS in the headers in Xcode 10 beta 1, and corresponding tests are now failing. So obsolete the managed wrapper types, and fix tests accordingly. * Fix xtro wrt previous Ietents/intro changes * [tests] Minor adjustments to mtouch tests to work with Xcode 10. * [msbuild] Update tests to cope with additional files produced by the Core ML compiler. * [msbuild] Xcode 10 doesn't support building watchOS 1 apps, so show a clear error message explaining it. Also update tests accordingly. * [coreimage] Stub new filters and exclude ?removed? ones from tests * Update GameplayKit and SpriteKit NSSecureCoding _upgrade_ and fix other non-public cases (in tests) * [tests] Ignore some GameKit selectors that don't respond anymore (but seems to be available, at least in header files) * [tests] Fix intro 32bits testing for filters resutls * [msbuild] Slightly change error message to be better English.
2018-06-09 04:45:24 +03:00
}
}
2016-04-21 15:57:02 +03:00
static Version xcode_version;
public static Version XcodeVersion {
get {
return xcode_version;
}
}
static void SetCurrentLanguage ()
{
// There's no way to change the current culture from the command-line
// without changing the system settings, so honor LANG if set.
// This eases testing mtouch/mmp with different locales significantly,
// and won't run into issues where changing the system language leaves
// the tester with an incomprehensible system.
var lang_variable = Environment.GetEnvironmentVariable ("LANG");
if (string.IsNullOrEmpty (lang_variable))
return;
// Mimic how mono transforms LANG into a culture name:
// https://github.com/mono/mono/blob/fc6e8a27fc55319141ceb29fbb7b5c63a9030b5e/mono/metadata/locales.c#L568-L576
var lang = lang_variable;
var idx = lang.IndexOf ('.');
if (idx >= 0)
lang = lang.Substring (0, idx);
idx = lang.IndexOf ('@');
if (idx >= 0)
lang = lang.Substring (0, idx);
lang = lang.Replace ('_', '-');
try {
var culture = CultureInfo.GetCultureInfo (lang);
if (culture != null) {
CultureInfo.DefaultThreadCurrentCulture = culture;
Log (2, $"The current language was set to '{culture.DisplayName}' according to the LANG environment variable (LANG={lang_variable}).");
}
} catch (Exception e) {
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (124, e, Errors.MT0124, lang, lang_variable, e.Message);
}
}
static void LogArguments (string [] arguments)
{
if (Verbosity < 1)
return;
if (!arguments.Any ((v) => v.Length > 0 && v [0] == '@'))
return; // no need to print arguments unless we get response files
LogArguments (arguments, 1);
}
static void LogArguments (string [] arguments, int indentation)
{
Log ("Provided arguments:");
var indent = new string (' ', indentation * 4);
foreach (var arg in arguments) {
Log (indent + StringUtils.Quote (arg));
if (arg.Length > 0 && arg [0] == '@') {
var fn = arg.Substring (1);
LogArguments (File.ReadAllLines (fn), indentation + 1);
}
}
}
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
public static void Touch (IEnumerable<string> filenames, DateTime? timestamp = null)
{
if (timestamp == null)
timestamp = DateTime.Now;
foreach (var filename in filenames) {
try {
var fi = new FileInfo (filename);
if (!fi.Exists) {
using (var fo = fi.OpenWrite ()) {
// Create an empty file.
}
}
fi.LastWriteTime = timestamp.Value;
} catch (Exception e) {
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (128, Errors.MT0128, filename, e.Message);
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534) (#3536) * [tests] Improve debug spew for the RebuildTest_WithExtensions test. * [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results. Store/load if the dynamic registrar is removed or not into the cached link results, so that we generate the correct main.m even if cached linker results are used. * [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker. The static registrar must not execute if we're loading cached results from the linker, because the static registrar needs information from the linker that's not restored from the cache. * [mtouch/mmp] Share Touch code. * [mtouch/mmp] Make it possible to touch inexistent files (to create them). * [mtouch/mmp] Fix tracking of whether the static registrar should run again or not. The recent changes to support optimizing away the dynamic registrar caused the Xamarin.MTouch.RebuildTest_WithExtensions test to regress. The problem ----------- * The linker now collects and stores information the static registrar needs. * This information is not restored from disk when the linker realizes that it can reload previously linked assemblies instead of executing again. * The static registrar runs again (for another reason). * The information the static registrar needs isn't available, and incorrect output follows. So fix 1: show an error if the static registrar runs when the linker loaded cached results. The exact scenario the test ran into is this: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk (this is an optimization to avoid compiling the registrar.m file again unless needed). * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is newer than registrar.m's timestamp and run again, but doesn't produce the right result because it doesn't have the information it needs. Considered solutions -------------------- 1. Only track timestamps, not file contents. This is not ideal, since it will result in more work done: in particular for the case above, it would add a registrar.m compilation in build #2, and linker rerun + static registrar rerun + registrar.m compilation + final native link in build #3. 2. Always write the output of the static registrar, even if it hasn't changed. This is not ideal either, since it will also result in more work done: for the case above, it would add a registrar.m compilation + final native link in build #3. 3. Always write the output of the static registrar, but track if it changed or not, and if it didn't, just touch registrar.o instead of recompiling it. This only means the final native link in build #3 is added (see #5 for why this is worse than it sounds). 4. Always write the output of the static registrar, but track it it changed or not, and if it didn't, just touch registrar.o instead of recompiling it, and track that too, so that the final native link in build #3 isn't needed anymore. Unfortunately this may result in incorrect behavior, because now the msbuild tasks will detect that the executable has changed, and may run dsymutil + strip again. The executable didn't actually change, which means it would be the previously stripped executable, and thus we'd end up with an empty .dSYM because we ran dsymtil on an already stripped executable. 5. Idea #4, but write the output of the final link into a temporary directory instead of the .app, so that we could track whether we should update the executable in the .app or not. This is not optimal either, because executables can be *big* (I've seen multi-GB tvOS bitcode executables), and extra copies of such files should not be taken lightly. 6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be rerun even if the timestamp of the executable changed. This might actually work, but now the solution's become quite complex. Implemented solution -------------------- Use stamp files to detect whether a file is up-to-date or not. In particular: * When we don't write to a file because the new contents are identical to the old contents, we now touch a .stamp file. This stamp file means "the accompanying file was determined to be up-to-date when the stamp was touched." * When checking whether a file is up-to-date, also check for the presence of a .stamp file, and if it exists, use the highest timestamp between the stamp file and the actual file. Now the test scenario becomes: * 1st build: everything is new and everything is built. * 2nd build: contents of .exe changes, the linker runs again, the static registrar runs again, but sees that the generated output didn't change, so it doesn't write the new content to disk, but it creates a registrar.m.stamp file to indicate the point in time when registrar.m was considered up-to- date. * 3rd build: only the .exe timestamp changes, the linker sees nothing changes in the contents of the .exe and loads the previously linked assemblies from disk, the static registrar sees that the .exe's timestamp is *older* than registrar.m.stamp's timestamp and doesn't run again. We only use the stamp file for source code (registrar.[m|h], main.[m|h], pinvokes.[m|h]), since using it every time has too much potential for running into other problems (for instance we should never create .stamp files inside the .app). Fixes these test failures: 1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[]) single Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" > 2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[]) dual Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" > 3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[]) llvm Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" > 4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[]) debug Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" > 5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[]) single-framework Expected: <empty> But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" > Fixes https://github.com/xamarin/maccore/issues/641
2018-02-20 13:43:23 +03:00
}
}
}
public static void Touch (params string [] filenames)
{
Touch ((IEnumerable<string>) filenames);
}
static int watch_level;
static Stopwatch watch;
public static int WatchLevel {
get { return watch_level; }
set {
watch_level = value;
if ((watch_level > 0) && (watch == null)) {
watch = new Stopwatch ();
watch.Start ();
}
}
}
public static void Watch (string msg, int level)
{
if ((watch == null) || (level > WatchLevel))
return;
for (int i = 0; i < level; i++)
Console.Write ("!");
Console.WriteLine ("Timestamp {0}: {1} ms", msg, watch.ElapsedMilliseconds);
}
internal static PDictionary FromPList (string name)
{
if (!File.Exists (name))
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (24, Errors.MT0024, name);
return PDictionary.FromFile (name);
}
const string XcodeDefault = "/Applications/Xcode.app";
static string FindSystemXcode ()
{
var output = new StringBuilder ();
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
if (Driver.RunCommand ("xcode-select", new [] { "-p" }, output: output) != 0) {
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (59, Errors.MX0059, output.ToString ());
return null;
}
return output.ToString ().Trim ();
}
static string sdk_root;
static string developer_directory;
public static string DeveloperDirectory {
get {
return developer_directory;
}
}
// This returns the /Applications/Xcode*.app/Contents/Developer/Platforms directory
public static string PlatformsDirectory {
get {
return Path.Combine (DeveloperDirectory, "Platforms");
}
}
// This returns the /Applications/Xcode*.app/Contents/Developer/Platforms/*.platform directory
public static string GetPlatformDirectory (Application app)
{
return Path.Combine (PlatformsDirectory, GetPlatform (app) + ".platform");
}
static string local_build;
public static string WalkUpDirHierarchyLookingForLocalBuild ()
{
if (local_build == null) {
var localPath = Path.GetDirectoryName (GetFullPath ());
while (localPath.Length > 1) {
if (File.Exists (Path.Combine (localPath, "Make.config"))) {
local_build = Path.Combine (localPath, LOCAL_BUILD_DIR, "Library", "Frameworks", PRODUCT + ".framework", "Versions", "Current");
return local_build;
}
localPath = Path.GetDirectoryName (localPath);
}
}
return local_build;
}
// This is the 'Current' directory of the installed framework
// For XI/XM installed from package it's /Library/Frameworks/Xamarin.iOS.framework/Versions/Current or /Library/Frameworks/Xamarin.Mac.framework/Versions/Current
static string framework_dir;
public static string FrameworkDirectory {
get {
if (framework_dir == null) {
var env_framework_dir = Environment.GetEnvironmentVariable (FRAMEWORK_LOCATION_VARIABLE);
if (!string.IsNullOrEmpty (env_framework_dir)) {
framework_dir = env_framework_dir;
} else {
#if DEBUG
// when launched from Visual Studio, the executable is not in the final install location,
// so walk the directory hierarchy to find the root source directory.
framework_dir = WalkUpDirHierarchyLookingForLocalBuild ();
#else
framework_dir = Path.GetDirectoryName (Path.GetDirectoryName (Path.GetDirectoryName (GetFullPath ())));
#endif
}
framework_dir = Target.GetRealPath (framework_dir);
}
return framework_dir;
}
}
// This is the 'Current/bin' directory of the installed framework
// For XI/XM installed from package it's one of these two:
// /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/bin
// /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/bin
public static string FrameworkBinDirectory {
get {
return Path.Combine (FrameworkDirectory, "bin");
}
}
// This is the 'Current/lib' directory of the installed framework
// For XI/XM installed from package it's one of these two:
// /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib
// /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib
public static string FrameworkLibDirectory {
get {
return Path.Combine (FrameworkDirectory, "lib");
}
}
// This is the directory where the platform assembly (Xamarin.*.dll) can be found
public static string GetPlatformFrameworkDirectory (Application app)
{
switch (app.Platform) {
case ApplePlatform.iOS:
return Path.Combine (FrameworkLibDirectory, "mono", "Xamarin.iOS");
case ApplePlatform.WatchOS:
return Path.Combine (FrameworkLibDirectory, "mono", "Xamarin.WatchOS");
case ApplePlatform.TVOS:
return Path.Combine (FrameworkLibDirectory, "mono", "Xamarin.TVOS");
case ApplePlatform.MacOSX:
#if MMP
if (IsUnifiedMobile)
return Path.Combine (FrameworkLibDirectory, "mono", "Xamarin.Mac");
return Path.Combine (FrameworkLibDirectory, "mono", "4.5");
#endif
default:
throw ErrorHelper.CreateError (71, Errors.MX0071, app.Platform, PRODUCT);
}
}
// This is the directory that contains the native libraries (libmono*.[a|dylib]) that come from mono.
// For Xamarin.Mac it can be:
// * /Library/Frameworks/Mono.framework/Versions/Current/lib/ (when using system mono)
// * /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/SDKs/*.sdk/lib
// For Xamarin.iOS it can be:
// * /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/SDKs/*.sdk/lib
static string mono_lib_directory;
public static string GetMonoLibraryDirectory (Application app)
{
if (mono_lib_directory == null) {
#if MMP
if (IsUnifiedFullSystemFramework) {
mono_lib_directory = RunPkgConfig ("--variable=libdir");
} else {
mono_lib_directory = GetProductSdkLibDirectory (app);
}
#else
mono_lib_directory = GetProductSdkLibDirectory (app);
#endif
}
return mono_lib_directory;
}
// /Library/Frameworks/Xamarin.*.framework/Versions/Current/SDKs/*.sdk/Frameworks
public static string GetMonoFrameworksDirectory (Application app)
{
#if MMP
if (IsUnifiedFullSystemFramework)
throw ErrorHelper.CreateError (99, Errors.MX0099, "Calling 'GetMonoFrameworksDirectory' is not allowed when targetting the full system framework.");
#endif
return Path.Combine (GetProductSdkDirectory (app), "Frameworks");
}
// /Library/Frameworks/Xamarin.*.framework/Versions/Current/SDKs/*.sdk/lib
public static string GetProductSdkLibDirectory (Application app)
{
return Path.Combine (GetProductSdkDirectory (app), "lib");
}
// /Library/Frameworks/Xamarin.*.framework/Versions/Current/SDKs/*.sdk/include
public static string GetProductSdkIncludeDirectory (Application app)
{
return Path.Combine (GetProductSdkDirectory (app), "include");
}
// /Library/Frameworks/Xamarin.*.framework/Versions/Current/SDKs/*.sdk/Frameworks
public static string GetProductSdkFrameworksDirectory (Application app)
{
return Path.Combine (GetProductSdkDirectory (app), "Frameworks");
}
// /Library/Frameworks/Xamarin.*.framework/Versions/Current/SDKs/*.sdk
public static string GetProductSdkDirectory (Application app)
{
var sdksDir = Path.Combine (FrameworkDirectory, "SDKs");
string sdkName;
switch (app.Platform) {
case ApplePlatform.iOS:
sdkName = app.IsDeviceBuild ? "MonoTouch.iphoneos.sdk" : "MonoTouch.iphonesimulator.sdk";
break;
case ApplePlatform.WatchOS:
sdkName = app.IsDeviceBuild ? "Xamarin.WatchOS.sdk" : "Xamarin.WatchSimulator.sdk";
break;
case ApplePlatform.TVOS:
sdkName = app.IsDeviceBuild ? "Xamarin.AppleTVOS.sdk" : "Xamarin.AppleTVSimulator.sdk";
break;
case ApplePlatform.MacOSX:
sdkName = "Xamarin.macOS.sdk";
break;
default:
throw ErrorHelper.CreateError (71, Errors.MX0071, app.Platform, PRODUCT);
}
return Path.Combine (sdksDir, sdkName);
}
// This returns the platform to use in /Applications/Xcode*.app/Contents/Developer/Platforms/*.platform
public static string GetPlatform (Application app)
{
switch (app.Platform) {
case ApplePlatform.iOS:
return app.IsDeviceBuild ? "iPhoneOS" : "iPhoneSimulator";
case ApplePlatform.WatchOS:
return app.IsDeviceBuild ? "WatchOS" : "WatchSimulator";
case ApplePlatform.TVOS:
return app.IsDeviceBuild ? "AppleTVOS" : "AppleTVSimulator";
case ApplePlatform.MacOSX:
return "MacOSX";
default:
throw ErrorHelper.CreateError (71, Errors.MX0071, app.Platform, PRODUCT);
}
}
// This returns the correct /Applications/Xcode*.app/Contents/Developer/Platforms/*.platform/Developer/SDKs/*X.Y.sdk directory
public static string GetFrameworkDirectory (Application app)
{
var platform = GetPlatform (app);
return Path.Combine (PlatformsDirectory, platform + ".platform", "Developer", "SDKs", platform + app.SdkVersion.ToString () + ".sdk");
}
public static string GetProductAssembly (Application app)
{
switch (app.Platform) {
case ApplePlatform.iOS:
return "Xamarin.iOS";
case ApplePlatform.WatchOS:
return "Xamarin.WatchOS";
case ApplePlatform.TVOS:
return "Xamarin.TVOS";
case ApplePlatform.MacOSX:
return "Xamarin.Mac";
default:
throw ErrorHelper.CreateError (71, Errors.MX0071, app.Platform, PRODUCT);
}
}
static void ValidateXcode (bool accept_any_xcode_version, bool warn_if_not_found)
{
if (sdk_root == null) {
sdk_root = FindSystemXcode ();
if (sdk_root == null) {
// FindSystemXcode showed a warning in this case. In particular do not use 'string.IsNullOrEmpty' here,
// because FindSystemXcode may return an empty string (with no warning printed) if the xcode-select command
// succeeds, but returns nothing.
sdk_root = null;
} else if (!Directory.Exists (sdk_root)) {
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (60, Errors.MX0060, sdk_root);
sdk_root = null;
} else {
if (!accept_any_xcode_version)
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (61, Errors.MT0061, sdk_root);
}
if (sdk_root == null) {
sdk_root = XcodeDefault;
if (!Directory.Exists (sdk_root)) {
if (warn_if_not_found) {
// mmp: and now we give up, but don't throw like mtouch, because we don't want to change behavior (this sometimes worked it appears)
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (56, Errors.MX0056);
return; // Can't validate the version below if we can't even find Xcode...
}
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (56, Errors.MX0056);
}
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (62, Errors.MT0062, sdk_root);
}
} else if (!Directory.Exists (sdk_root)) {
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (55, Errors.MT0055, sdk_root);
}
// Check what kind of path we got
if (File.Exists (Path.Combine (sdk_root, "Contents", "MacOS", "Xcode"))) {
// path to the Xcode.app
developer_directory = Path.Combine (sdk_root, "Contents", "Developer");
} else if (File.Exists (Path.Combine (sdk_root, "..", "MacOS", "Xcode"))) {
// path to Contents/Developer
developer_directory = Path.GetFullPath (Path.Combine (sdk_root, "..", "..", "Contents", "Developer"));
} else {
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (57, Errors.MT0057, sdk_root);
}
var plist_path = Path.Combine (Path.GetDirectoryName (DeveloperDirectory), "version.plist");
if (File.Exists (plist_path)) {
var plist = FromPList (plist_path);
var version = plist.GetString ("CFBundleShortVersionString");
xcode_version = new Version (version);
xcode_product_version = plist.GetString ("ProductBuildVersion");
} else {
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (58, Errors.MT0058, Path.GetDirectoryName (Path.GetDirectoryName (DeveloperDirectory)), plist_path);
}
if (!accept_any_xcode_version) {
if (min_xcode_version != null && XcodeVersion < min_xcode_version)
2020-01-31 23:02:52 +03:00
throw ErrorHelper.CreateError (51, Errors.MT0051, Constants.Version, XcodeVersion.ToString (), sdk_root, PRODUCT, min_xcode_version);
if (XcodeVersion < SdkVersions.XcodeVersion)
2020-01-31 23:02:52 +03:00
ErrorHelper.Warning (79, Errors.MT0079, Constants.Version, XcodeVersion.ToString (), sdk_root, SdkVersions.Xcode, PRODUCT);
}
Driver.Log (1, "Using Xcode {0} ({2}) found in {1}", XcodeVersion, sdk_root, XcodeProductVersion);
}
Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. (#7177) * Implement a different escaping/quoting algorithm for arguments to System.Diagnostics.Process. mono changed how quotes should be escaped when passed to System.Diagnostic.Process, so we need to change accordingly. The main difference is that single quotes don't have to be escaped anymore. This solves problems like this: System.ComponentModel.Win32Exception : ApplicationName='nuget', CommandLine='restore '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable/CellCustomTable.sln' -Verbosity detailed -SolutionDir '/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories/ios-samples/WorkingWithTables/Part 3 - Customizing a Table\'s appearance/3 - CellCustomTable'', CurrentDirectory='/Users/vsts/agent/2.158.0/work/1/s/tests/sampletester/bin/Debug/repositories', Native error= Cannot find the specified file at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x0029f] in /Users/builder/jenkins/workspace/build-package-osx-mono/2019-08/external/bockbuild/builds/mono-x64/mcs/class/System/System.Diagnostics/Process.cs:778 ref: https://github.com/mono/mono/pull/15047 * Rework process arguments to pass arrays/lists around instead of quoted strings. And then only convert to a string at the very end when we create the Process instance. In the future there will be a ProcessStartInfo.ArgumentList property we can use to give the original array/list of arguments directly to the BCL so that we can avoid quoting at all. These changes gets us almost all the way there already (except that the ArgumentList property isn't available quite yet). We also have to bump to target framework version v4.7.2 from v4.5 in several places because of 'Array.Empty<T> ()' which is now used in more places. * Parse linker flags from LinkWith attributes. * [sampletester] Bump to v4.7.2 for Array.Empty<T> (). * Fix typo. * Rename GetVerbosity -> AddVerbosity. * Remove unnecessary string interpolation. * Remove unused variable. * [mtouch] Simplify code a bit. * Use implicitly typed arrays.
2019-10-14 17:18:46 +03:00
internal static bool TryParseBool (string value, out bool result)
{
if (string.IsNullOrEmpty (value)) {
result = true;
return true;
}
switch (value.ToLowerInvariant ()) {
case "1":
case "yes":
case "true":
case "enable":
result = true;
return true;
case "0":
case "no":
case "false":
case "disable":
result = false;
return true;
default:
return bool.TryParse (value, out result);
}
}
internal static bool ParseBool (string value, string name, bool show_error = true)
{
bool result;
if (!TryParseBool (value, out result))
throw ErrorHelper.CreateError (26, Errors.MX0026, name, value);
return result;
}
static readonly Dictionary<string, string> tools = new Dictionary<string, string> ();
static string FindTool (string tool)
{
string path;
lock (tools) {
if (tools.TryGetValue (tool, out path))
return path;
}
path = LocateTool (tool);
static string LocateTool (string tool)
{
if (XcrunFind (tool, out var path))
return path;
// either /Developer (Xcode 4.2 and earlier), /Applications/Xcode.app/Contents/Developer (Xcode 4.3) or user override
path = Path.Combine (DeveloperDirectory, "usr", "bin", tool);
if (File.Exists (path))
return path;
// Xcode 4.3 (without command-line tools) also has a copy of 'strip'
path = Path.Combine (DeveloperDirectory, "Toolchains", "XcodeDefault.xctoolchain", "usr", "bin", tool);
if (File.Exists (path))
return path;
// Xcode "Command-Line Tools" install a copy in /usr/bin (and it can be there afterward)
path = Path.Combine ("/usr", "bin", tool);
if (File.Exists (path))
return path;
return null;
}
// We can end up finding the same tool multiple times.
// That's not a problem.
lock (tools)
tools [tool] = path;
if (path == null)
throw ErrorHelper.CreateError (5307, Errors.MX5307 /* Missing '{0}' tool. Please install Xcode 'Command-Line Tools' component */, tool);
return path;
}
static bool XcrunFind (string tool, out string path)
{
return XcrunFind (ApplePlatform.None, false, tool, out path);
}
static bool XcrunFind (ApplePlatform platform, bool is_simulator, string tool, out string path)
{
var env = new List<string> ();
// Unset XCODE_DEVELOPER_DIR_PATH. See https://github.com/xamarin/xamarin-macios/issues/3931.
env.Add ("XCODE_DEVELOPER_DIR_PATH");
env.Add (null);
// Set DEVELOPER_DIR if we have it
if (!string.IsNullOrEmpty (DeveloperDirectory)) {
env.Add ("DEVELOPER_DIR");
env.Add (DeveloperDirectory);
}
path = null;
var args = new List<string> ();
if (platform != ApplePlatform.None) {
args.Add ("-sdk");
switch (platform) {
case ApplePlatform.iOS:
args.Add (is_simulator ? "iphonesimulator" : "iphoneos");
break;
case ApplePlatform.MacOSX:
args.Add ("macosx");
break;
case ApplePlatform.TVOS:
args.Add (is_simulator ? "appletvsimulator" : "appletvos");
break;
case ApplePlatform.WatchOS:
args.Add (is_simulator ? "watchsimulator" : "watchos");
break;
default:
throw ErrorHelper.CreateError (71, Errors.MX0071 /* Unknown platform: {0}. This usually indicates a bug in {1}; please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new with a test case. */, platform.ToString (), PRODUCT);
}
}
args.Add ("-f");
args.Add (tool);
var stdout = new StringBuilder ();
var stderr = new StringBuilder ();
var both = new StringBuilder ();
// xcrun can write unrelated stuff to stderr even if it succeeds, so we need to separate stdout and stderr.
// We also want to print out what happened if something went wrong, and in that case we don't want stdout
// and stderr captured separately, because related lines could end up printed far from eachother in time,
// and that's confusing. So capture stdout and stderr by themselves, and also capture both together.
int ret = RunCommand ("xcrun", args, env.ToArray (),
(v) => {
lock (both) {
both.AppendLine (v);
stdout.AppendLine (v);
}
},
(v) => {
lock (both) {
both.AppendLine (v);
stderr.AppendLine (v);
}
});
if (ret == 0) {
path = stdout.ToString ().Trim ();
if (!File.Exists (path)) {
ErrorHelper.Warning (5315, Errors.MX5315 /* The tool xcrun failed to return a valid result (the file {0} does not exist). Check build log for details. */, tool, path);
return false;
}
} else {
Log (1, "Failed to locate the developer tool '{0}', 'xcrun {1}' returned with the exit code {2}:\n{3}", tool, string.Join (" ", args), ret, both.ToString ());
}
return ret == 0;
}
public static void RunXcodeTool (string tool, params string[] arguments)
{
RunXcodeTool (tool, (IList<string>) arguments);
}
public static void RunXcodeTool (string tool, IList<string> arguments)
{
var executable = FindTool (tool);
var rv = RunCommand (executable, arguments);
if (rv != 0)
throw ErrorHelper.CreateError (5309, Errors.MX5309 /* Failed to execute the tool '{0}', it failed with an error code '{1}'. Please check the build log for details. */, tool, rv);
}
public static void RunClang (IList<string> arguments)
{
RunXcodeTool ("clang", arguments);
}
public static void RunInstallNameTool (IList<string> arguments)
{
RunXcodeTool ("install_name_tool", arguments);
}
public static void RunBitcodeStrip (IList<string> arguments)
{
RunXcodeTool ("bitcode_strip", arguments);
}
public static void RunLipo (string output, IEnumerable<string> inputs)
{
var sb = new List<string> ();
sb.AddRange (inputs);
sb.Add ("-create");
sb.Add ("-output");
sb.Add (output);
RunLipo (sb);
}
public static void RunLipo (IList<string> options)
{
RunXcodeTool ("lipo", options);
}
public static void CreateDsym (string output_dir, string appname, string dsym_dir)
{
RunDsymUtil (Path.Combine (output_dir, appname), "-num-threads", "4", "-z", "-o", dsym_dir);
RunCommand ("/usr/bin/mdimport", dsym_dir);
}
public static void RunDsymUtil (params string [] options)
{
RunXcodeTool ("dsymutil", options);
}
public static void RunStrip (IList<string> options)
{
RunXcodeTool ("strip", options);
}
public static string CorlibName {
get {
if (IsDotNet)
return "System.Private.CoreLib";
return "mscorlib";
}
}
public static Frameworks GetFrameworks (Application app)
{
var rv = Frameworks.GetFrameworks (app.Platform, app.IsSimulatorBuild);
if (rv == null)
throw ErrorHelper.CreateError (71, Errors.MX0071, app.Platform, PRODUCT);
return rv;
}
2016-04-21 15:57:02 +03:00
}
}