public void CreateTemporaryApp(string code = null) { var testDir = CreateTemporaryDirectory(); var app = Path.Combine(testDir, "testApp.app"); Directory.CreateDirectory(app); AppPath = app; Executable = MTouch.CompileTestAppExecutable(testDir, code: code, profile: Profile); }
public string CreateTemporaryDirectory() { var tmpDir = MTouch.GetTempDirectory(); if (directories_to_delete == null) { directories_to_delete = new List <string> (); } directories_to_delete.Add(tmpDir); return(tmpDir); }
public void CreateTemporararyServiceExtension(string code = null) { var testDir = CreateTemporaryDirectory(); var app = Path.Combine(testDir, "testApp.appex"); Directory.CreateDirectory(app); if (code == null) { code = @"using UserNotifications; [Foundation.Register (""NotificationService"")] public partial class NotificationService : UNNotificationServiceExtension { protected NotificationService (System.IntPtr handle) : base (handle) {} }"; } AppPath = app; Executable = MTouch.CompileTestAppLibrary(testDir, code: code, profile: Profile); File.WriteAllText(Path.Combine(app, "Info.plist"), @"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd""> <plist version=""1.0""> <dict> <key>CFBundleDisplayName</key> <string>serviceextension</string> <key>CFBundleName</key> <string>serviceextension</string> <key>CFBundleIdentifier</key> <string>com.xamarin.testapp.serviceextension</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> <string>XPC!</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1.0</string> <key>MinimumOSVersion</key> <string>10.0</string> <key>NSExtension</key> <dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.usernotifications.service</string> <key>NSExtensionPrincipalClass</key> <string>NotificationService</string> </dict> </dict> </plist> "); }
public string CreateTemporarySatelliteAssembly(string culture = "en-AU") { var asm_dir = Path.Combine(Path.GetDirectoryName(RootAssembly), culture); Directory.CreateDirectory(asm_dir); var asm_name = Path.GetFileNameWithoutExtension(RootAssembly) + ".resources.dll"; // Cheat a bit, by compiling a normal assembly with code instead of creating a resource assembly return(MTouch.CompileTestAppLibrary(asm_dir, "class X {}", appName: Path.GetFileNameWithoutExtension(asm_name))); }
public void CreateTemporaryWatchKitExtension(string code = null) { var testDir = CreateTemporaryDirectory(); var app = Path.Combine(testDir, "testApp.appex"); Directory.CreateDirectory(app); if (code == null) { code = @"using WatchKit; public partial class NotificationController : WKUserNotificationInterfaceController { protected NotificationController (System.IntPtr handle) : base (handle) {} }"; } AppPath = app; Executable = MTouch.CompileTestAppLibrary(testDir, code: code, profile: Profile); File.WriteAllText(Path.Combine(app, "Info.plist"), @"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd""> <plist version=""1.0""> <dict> <key>CFBundleDisplayName</key> <string>testapp</string> <key>CFBundleName</key> <string>testapp</string> <key>CFBundleIdentifier</key> <string>com.xamarin.testapp</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleVersion</key> <string>1.0</string> <key>MinimumOSVersion</key> <string>2.0</string> <key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>WKAppBundleIdentifier</key> <string>com.xamarin.testapp.watchkitapp</string> </dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.watchkit</string> </dict> <key>RemoteInterfacePrincipleClass</key> <string>InterfaceController</string> <key>CFBundleShortVersionString</key> <string>1.0</string> </dict> </plist> "); }
public void NoLLVMFailuresInWatchOS(string asm) { MTouch.AssertDeviceAvailable(); // Run LLVM on every assembly we ship in watchOS, using the arguments we usually use when done from mtouch. var aot_compiler = Path.Combine(Configuration.BinDirXI, "armv7k-unknown-darwin-mono-sgen"); var tmpdir = Cache.CreateTemporaryDirectory(); var llvm_path = Path.Combine(Configuration.SdkRootXI, "LLVM", "bin"); var env = new Dictionary <string, string> { { "MONO_PATH", watchOSPath } }; var arch = "armv7k"; var arch_dir = Path.Combine(tmpdir, arch); Directory.CreateDirectory(arch_dir); var args = new StringBuilder(); args.Append("--debug "); args.Append("--llvm "); args.Append("-O=float32 "); args.Append($"--aot=mtriple={arch}-ios"); args.Append($",data-outfile={Path.Combine (arch_dir, Path.GetFileNameWithoutExtension (asm) + ".aotdata." + arch)}"); args.Append($",static,asmonly,direct-icalls,llvmonly,nodebug,dwarfdebug,direct-pinvoke"); args.Append($",msym-dir={Path.Combine (arch_dir, Path.GetFileNameWithoutExtension (asm) + ".mSYM")}"); args.Append($",llvm-path={llvm_path}"); args.Append($",llvm-outfile={Path.Combine (arch_dir, Path.GetFileName (asm) + ".bc")} "); args.Append(Path.Combine(watchOSPath, asm)); StringBuilder output = new StringBuilder(); var rv = ExecutionHelper.Execute(aot_compiler, args.ToString(), stdout: output, stderr: output, environmentVariables: env, timeout: TimeSpan.FromMinutes(5)); var llvm_failed = output.ToString().Split('\n').Where((v) => v.Contains("LLVM failed")); Console.WriteLine(output); int expected_exit_code = 0; if (known_llvm_failures.TryGetValue(asm, out var known_failures)) { expected_exit_code = known_failures.Item1; Assert.AreEqual(expected_exit_code, rv, "AOT compilation"); if (known_failures.Item2 != null) { // Check if there are known failures for failures we've fixed var known_inexistent_failures = known_failures.Item2.Where((v) => !llvm_failed.Contains(v)); Assert.IsEmpty(string.Join("\n", known_inexistent_failures), $"Redundant known failures: should be removed from dictionary for {asm}"); // Filter the known failures from the failed llvm lines. llvm_failed = llvm_failed.Where((v) => !known_failures.Item2.Contains(v)); } } Assert.AreEqual(expected_exit_code, rv, "AOT compilation"); Assert.IsEmpty(string.Join("\n", llvm_failed), "LLVM failed"); }
public void CreateTemporaryApp(bool hasPlist = false, string appName = "testApp", string code = null) { var testDir = CreateTemporaryDirectory(); var app = Path.Combine(testDir, appName + ".app"); Directory.CreateDirectory(app); AppPath = app; Executable = MTouch.CompileTestAppExecutable(testDir, code, "", Profile, appName); if (hasPlist) { File.WriteAllText(Path.Combine(app, "Info.plist"), CreatePlist(Profile, appName)); } }
public void InvalidStructOffset() { MTouch.AssertDeviceAvailable(); var str = "invalid struct offset"; var contents = ASCIIEncoding.ASCII.GetBytes(str); foreach (var sdk in new string [] { "iphoneos", "iphonesimulator" }) { foreach (var ext in new string [] { "dylib", "a" }) { var fn = Path.Combine(Configuration.MonoTouchRootDirectory, "SDKs", "MonoTouch." + sdk + ".sdk", "usr", "lib", "libmonosgen-2.0." + ext); Assert.IsFalse(Contains(fn, contents), "Found \"{0}\" in {1}", str, fn); } } }
public void VerifySymbols() { MTouch.AssertDeviceAvailable(); var prohibited_symbols = new string [] { "_NSGetEnviron", "PKService", "SPPluginDelegate" }; foreach (var symbol in prohibited_symbols) { var contents = ASCIIEncoding.ASCII.GetBytes(symbol); var sdk = "iphoneos"; // we don't care about private symbols for simulator builds foreach (var static_lib in Directory.EnumerateFiles(Path.Combine(Configuration.MonoTouchRootDirectory, "SDKs", "MonoTouch." + sdk + ".sdk", "usr", "lib"), "*.a")) { Assert.IsFalse(Contains(static_lib, contents), "Found \"{0}\" in {1}", symbol, static_lib); } } }
public void TestDeviceDylib(Profile profile, string version, string mono_native_dylib) { using (var mtouch = new MTouchTool()) { mtouch.Profile = profile; if (profile == Profile.watchOS) { mtouch.CreateTemporaryWatchKitExtension(code: MonoNativeWatchInitialize, extraCode: MonoNativeInitialize); } else { mtouch.CreateTemporaryApp(code: MonoNativeInitialize); } mtouch.Linker = LinkerOption.LinkAll; mtouch.AssemblyBuildTargets.Add("@all=dynamiclibrary"); mtouch.TargetVer = version; mtouch.AssertExecute(MTouchAction.BuildDev, "build"); var files = Directory.EnumerateFiles(mtouch.AppPath, "libmono-native*", SearchOption.AllDirectories).Select(Path.GetFileName); Assert.That(files.Count, Is.EqualTo(1), "One single libmono-native* library"); Assert.That(files.First(), Is.EqualTo(mono_native_dylib)); var mono_native_path = Path.Combine(mtouch.AppPath, mono_native_dylib); var symbols = MTouch.GetNativeSymbols(mono_native_path); var otool_dylib = ExecutionHelper.Execute("otool", new [] { "-L", mono_native_path }, hide_output: true); Assert.That(symbols, Does.Contain("_mono_native_initialize")); Assert.That(otool_dylib, Does.Contain($"@rpath/{mono_native_dylib}")); Assert.That(otool_dylib.Replace(mono_native_path, ""), Does.Not.Contain("/Users/")); if (profile == Profile.iOS) { Assert.That(symbols, Does.Contain("_NetSecurityNative_ImportUserName")); Assert.That(otool_dylib, Does.Contain("/System/Library/Frameworks/GSS.framework/GSS")); } else { Assert.That(symbols, Does.Not.Contain("_NetSecurityNative_ImportUserName")); Assert.That(otool_dylib, Does.Not.Contain("/System/Library/Frameworks/GSS.framework/GSS")); } var otool_exe = ExecutionHelper.Execute("otool", new [] { "-L", mtouch.NativeExecutablePath }, hide_output: true); Assert.That(otool_exe, Does.Not.Contain("GSS")); Assert.That(otool_exe, Does.Contain($"@rpath/{mono_native_dylib}")); } }
public void CreateTemporaryApp(bool hasPlist = false, string appName = "testApp", string code = null, string extraArg = "", string extraCode = null, string usings = null, bool use_csc = false) { string testDir; if (RootAssembly == null) { testDir = CreateTemporaryDirectory(); } else { // We're rebuilding an existing executable, so just reuse that testDir = Path.GetDirectoryName(RootAssembly); } var app = AppPath ?? Path.Combine(testDir, appName + ".app"); Directory.CreateDirectory(app); AppPath = app; RootAssembly = MTouch.CompileTestAppExecutable(testDir, code, extraArg, Profile, appName, extraCode, usings, use_csc); if (hasPlist) { File.WriteAllText(Path.Combine(app, "Info.plist"), CreatePlist(Profile, appName)); } }
public void CreateTemporaryApp_LinkWith() { AppPath = CreateTemporaryAppDirectory(); RootAssembly = MTouch.CompileTestAppExecutableLinkWith(Path.GetDirectoryName(AppPath), profile: Profile); }
public void CreateTemporaryWatchOSIntentsExtension(string code = null, string appName = "intentsExtension") { string testDir; if (RootAssembly == null) { testDir = CreateTemporaryDirectory(); } else { // We're rebuilding an existing executable, so just reuse that directory testDir = Path.GetDirectoryName(RootAssembly); } var app = AppPath ?? Path.Combine(testDir, $"{appName}.appex"); Directory.CreateDirectory(app); if (code == null) { code = @" using System; using Foundation; using Intents; using WatchKit; [Register (""IntentHandler"")] public class IntentHandler : INExtension, IINRidesharingDomainHandling { protected IntentHandler (System.IntPtr handle) : base (handle) {} public void HandleRequestRide (INRequestRideIntent intent, Action<INRequestRideIntentResponse> completion) { } public void HandleListRideOptions (INListRideOptionsIntent intent, Action<INListRideOptionsIntentResponse> completion) { } public void HandleRideStatus (INGetRideStatusIntent intent, Action<INGetRideStatusIntentResponse> completion) { } public void StartSendingUpdates (INGetRideStatusIntent intent, IINGetRideStatusIntentResponseObserver observer) { } public void StopSendingUpdates (INGetRideStatusIntent intent) { } }"; } AppPath = app; Extension = true; RootAssembly = MTouch.CompileTestAppLibrary(testDir, code: code, profile: Profile.watchOS, appName: appName); File.WriteAllText(Path.Combine(app, "Info.plist"), $@"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd""> <plist version=""1.0""> <dict> <key>BuildMachineOSBuild</key> <string>17E199</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleDisplayName</key> <string>{appName}</string> <key>CFBundleExecutable</key> <string>{appName}</string> <key>CFBundleIdentifier</key> <string>com.xamarin.testapp.watchkitapp.watchkitextension.intentswatch</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>{appName}</string> <key>CFBundlePackageType</key> <string>XPC!</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>1.0</string> <key>MinimumOSVersion</key> <string>3.2</string> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>IntentsRestrictedWhileLocked</key> <array/> <key>IntentsSupported</key> <array> <string>INRequestRideIntent</string> <string>INListRideOptionsIntent</string> <string>INGetRideStatusIntent</string> </array> </dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.intents-service</string> <key>NSExtensionPrincipalClass</key> <string>IntentHandler</string> </dict> <key>UIDeviceFamily</key> <array> <integer>4</integer> </array> </dict> </plist> "); }
public void CreateTemporaryTodayExtension(string code = null, string extraCode = null, IList <string> extraArgs = null, string appName = "testTodayExtension") { string testDir; if (RootAssembly == null) { testDir = CreateTemporaryDirectory(); } else { // We're rebuilding an existing executable, so just reuse that testDir = Path.GetDirectoryName(RootAssembly); } var app = AppPath ?? Path.Combine(testDir, $"{appName}.appex"); Directory.CreateDirectory(app); if (code == null) { code = @"using System; using Foundation; using NotificationCenter; using UIKit; public partial class TodayViewController : UIViewController, INCWidgetProviding { public TodayViewController (IntPtr handle) : base (handle) { } [Export (""widgetPerformUpdateWithCompletionHandler:"")] public void WidgetPerformUpdate (Action<NCUpdateResult> completionHandler) { completionHandler (NCUpdateResult.NewData); } } "; } if (extraCode != null) { code += extraCode; } AppPath = app; Extension = true; RootAssembly = MTouch.CompileTestAppLibrary(testDir, code: code, profile: Profile, extraArgs: extraArgs, appName: appName); var info_plist = // FIXME: this includes a NSExtensionMainStoryboard key which points to a non-existent storyboard. This won't matter as long as we're only building, and not running the extension. @"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd""> <plist version=""1.0""> <dict> <key>CFBundleDisplayName</key> <string>todayextension</string> <key>CFBundleName</key> <string>todayextension</string> <key>CFBundleIdentifier</key> <string>com.xamarin.testapp.todayextension</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> <string>XPC!</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1.0</string> <key>MinimumOSVersion</key> <string>10.0</string> <key>NSExtension</key> <dict> <key>NSExtensionPointIdentifier</key> <string>widget-extension</string> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> </dict> </dict> </plist> "; var plist_path = Path.Combine(app, "Info.plist"); if (!File.Exists(plist_path) || File.ReadAllText(plist_path) != info_plist) { File.WriteAllText(plist_path, info_plist); } }
public void CreateTemporaryServiceExtension(string code = null, string extraCode = null, IList <string> extraArgs = null, string appName = "testServiceExtension") { string testDir; if (RootAssembly == null) { testDir = CreateTemporaryDirectory(); } else { // We're rebuilding an existing executable, so just reuse that testDir = Path.GetDirectoryName(RootAssembly); } var app = AppPath ?? Path.Combine(testDir, $"{appName}.appex"); Directory.CreateDirectory(app); if (code == null) { code = @"using UserNotifications; [Foundation.Register (""NotificationService"")] public partial class NotificationService : UNNotificationServiceExtension { protected NotificationService (System.IntPtr handle) : base (handle) {} }"; } if (extraCode != null) { code += extraCode; } AppPath = app; Extension = true; RootAssembly = MTouch.CompileTestAppLibrary(testDir, code: code, profile: Profile, extraArgs: extraArgs, appName: appName); var info_plist = @"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd""> <plist version=""1.0""> <dict> <key>CFBundleDisplayName</key> <string>serviceextension</string> <key>CFBundleName</key> <string>serviceextension</string> <key>CFBundleIdentifier</key> <string>com.xamarin.testapp.serviceextension</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleInfoDictionaryVersion</key> <string>7.0</string> <key>CFBundlePackageType</key> <string>XPC!</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1.0</string> <key>MinimumOSVersion</key> <string>10.0</string> <key>NSExtension</key> <dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.usernotifications.service</string> <key>NSExtensionPrincipalClass</key> <string>NotificationService</string> </dict> </dict> </plist> "; var plist_path = Path.Combine(app, "Info.plist"); if (!File.Exists(plist_path) || File.ReadAllText(plist_path) != info_plist) { File.WriteAllText(plist_path, info_plist); } }
string BuildArguments() { var sb = new StringBuilder(); switch (Action) { case MLaunchAction.None: break; case MLaunchAction.Sim: if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Append(" --launchsim ").Append(StringUtils.Quote(AppPath)); break; default: throw new Exception("MLaunchAction not specified."); } if (SdkRoot == None) { // do nothing } else if (!string.IsNullOrEmpty(SdkRoot)) { sb.Append(" --sdkroot ").Append(StringUtils.Quote(SdkRoot)); } else { sb.Append(" --sdkroot ").Append(StringUtils.Quote(Configuration.xcode_root)); } sb.Append(" ").Append(GetVerbosity()); if (Sdk == None) { // do nothing } else if (!string.IsNullOrEmpty(Sdk)) { sb.Append(" --sdk ").Append(Sdk); } else { sb.Append(" --sdk ").Append(MTouch.GetSdkVersion(Profile)); } string platformName = null; string simType = null; switch (Profile) { case Profile.iOS: platformName = "iOS"; simType = "iPhone-SE"; break; case Profile.tvOS: platformName = "tvOS"; simType = "Apple-TV-1080p"; break; default: throw new Exception("Profile not specified."); } if (!string.IsNullOrEmpty(platformName) && !string.IsNullOrEmpty(simType)) { var device = string.Format(":v2:runtime=com.apple.CoreSimulator.SimRuntime.{0}-{1},devicetype=com.apple.CoreSimulator.SimDeviceType.{2}", platformName, Configuration.sdk_version.Replace('.', '-'), simType); sb.Append(" --device:").Append(StringUtils.Quote(device)); } return(sb.ToString()); }
public static string CreatePlist(Profile profile, string appName) { string plist = null; switch (profile) { case Profile.iOS: plist = string.Format(@"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd""> <plist version=""1.0""> <dict> <key>CFBundleDisplayName</key> <string>{0}</string> <key>CFBundleIdentifier</key> <string>com.xamarin.{0}</string> <key>CFBundleExecutable</key> <string>{0}</string> <key>MinimumOSVersion</key> <string>{1}</string> <key>UIDeviceFamily</key> <array> <integer>1</integer> <integer>2</integer> </array> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> </dict> </plist> ", appName, MTouch.GetSdkVersion(profile)); break; case Profile.tvOS: plist = string.Format(@"<?xml version=""1.0"" encoding=""UTF-8""?> <!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd""> <plist version=""1.0""> <dict> <key>CFBundleDisplayName</key> <string>Extensiontest</string> <key>CFBundleIdentifier</key> <string>com.xamarin.{0}</string> <key>CFBundleExecutable</key> <string>{0}</string> <key>MinimumOSVersion</key> <string>{1}</string> <key>UIDeviceFamily</key> <array> <integer>3</integer> </array> </dict> </plist> ", appName, MTouch.GetSdkVersion(profile)); break; default: throw new Exception("Profile not specified."); } return(plist); }
protected override void BuildArguments(IList <string> sb) { base.BuildArguments(sb); switch (Action.Value) { case MTouchAction.None: break; case MTouchAction.BuildDev: MTouch.AssertDeviceAvailable(); if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Add("--dev"); sb.Add(AppPath); break; case MTouchAction.BuildSim: if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Add("--sim"); sb.Add(AppPath); break; case MTouchAction.LaunchSim: if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Add("--launchsim"); sb.Add(AppPath); break; default: throw new NotImplementedException(); } if (FastDev.HasValue && FastDev.Value) { sb.Add("--fastdev"); } if (PackageMdb.HasValue) { sb.Add($"--package-mdb:{(PackageMdb.Value ? "true" : "false")}"); } if (NoStrip.HasValue && NoStrip.Value) { sb.Add("--nostrip"); } if (NoSymbolStrip != null) { if (NoSymbolStrip.Length == 0) { sb.Add("--nosymbolstrip"); } else { sb.Add($"--nosymbolstrip:{NoSymbolStrip}"); } } if (!string.IsNullOrEmpty(SymbolList)) { sb.Add($"--symbollist={SymbolList}"); } if (MSym.HasValue) { sb.Add($"--msym:{(MSym.Value ? "true" : "false")}"); } if (DSym.HasValue) { sb.Add($"--dsym:{(DSym.Value ? "true" : "false")}"); } foreach (var appext in AppExtensions) { sb.Add($"--app-extension"); sb.Add(appext.AppPath); } foreach (var framework in Frameworks) { sb.Add($"--framework"); sb.Add(framework); } if (!string.IsNullOrEmpty(Mono)) { sb.Add($"--mono:{Mono}"); } if (Dlsym.HasValue) { sb.Add($"--dlsym:{(Dlsym.Value ? "true" : "false")}"); } else if (!string.IsNullOrEmpty(DlsymString)) { sb.Add($"--dlsym:{DlsymString}"); } if (!string.IsNullOrEmpty(Executable)) { sb.Add("--executable"); sb.Add(Executable); } switch (SymbolMode) { case MTouchSymbolMode.Ignore: sb.Add("--dynamic-symbol-mode=ignore"); break; case MTouchSymbolMode.Code: sb.Add("--dynamic-symbol-mode=code"); break; case MTouchSymbolMode.Default: sb.Add("--dynamic-symbol-mode=default"); break; case MTouchSymbolMode.Linker: sb.Add("--dynamic-symbol-mode=linker"); break; case MTouchSymbolMode.Unspecified: break; default: throw new NotImplementedException(); } if (NoFastSim.HasValue && NoFastSim.Value) { sb.Add("--nofastsim"); } if (!string.IsNullOrEmpty(Device)) { sb.Add($"--device:{Device}"); } if (!string.IsNullOrEmpty(LLVMOptimizations)) { sb.Add($"--llvm-opt={LLVMOptimizations}"); } if (Bitcode != MTouchBitcode.Unspecified) { sb.Add($"--bitcode:{Bitcode.ToString ().ToLower ()}"); } foreach (var abt in AssemblyBuildTargets) { sb.Add($"--assembly-build-target={abt}"); } if (!string.IsNullOrEmpty(AotArguments)) { sb.Add($"--aot:{AotArguments}"); } if (!string.IsNullOrEmpty(AotOtherArguments)) { sb.Add($"--aot-options:{AotOtherArguments}"); } }
string BuildArguments(MTouchAction action) { var sb = new StringBuilder(); var isDevice = false; switch (action) { case MTouchAction.None: break; case MTouchAction.BuildDev: MTouch.AssertDeviceAvailable(); if (AppPath == null) { throw new Exception("No AppPath specified."); } isDevice = true; sb.Append(" --dev ").Append(MTouch.Quote(AppPath)); break; case MTouchAction.BuildSim: isDevice = false; if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Append(" --sim ").Append(MTouch.Quote(AppPath)); break; case MTouchAction.LaunchSim: isDevice = false; if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Append(" --launchsim ").Append(MTouch.Quote(AppPath)); break; default: throw new NotImplementedException(); } if (SdkRoot == None) { // do nothing } else if (!string.IsNullOrEmpty(SdkRoot)) { sb.Append(" --sdkroot ").Append(MTouch.Quote(SdkRoot)); } else { sb.Append(" --sdkroot ").Append(MTouch.Quote(Configuration.xcode_root)); } sb.Append(" ").Append(GetVerbosity()); if (Sdk == None) { // do nothing } else if (!string.IsNullOrEmpty(Sdk)) { sb.Append(" --sdk ").Append(Sdk); } else { sb.Append(" --sdk ").Append(MTouch.GetSdkVersion(Profile)); } if (TargetVer == None) { // do nothing } else if (!string.IsNullOrEmpty(TargetVer)) { sb.Append(" --targetver ").Append(TargetVer); } if (Debug.HasValue && Debug.Value) { sb.Append(" --debug"); } if (FastDev.HasValue && FastDev.Value) { sb.Append(" --fastdev"); } if (Extension == true) { sb.Append(" --extension"); } foreach (var appext in AppExtensions) { sb.Append(" --app-extension ").Append(MTouch.Quote(appext)); } foreach (var framework in Frameworks) { sb.Append(" --framework ").Append(MTouch.Quote(framework)); } if (!string.IsNullOrEmpty(HttpMessageHandler)) { sb.Append(" --http-message-handler=").Append(MTouch.Quote(HttpMessageHandler)); } if (Dlsym.HasValue) { sb.Append(" --dlsym:").Append(Dlsym.Value ? "true" : "false"); } if (References != null) { foreach (var r in References) { sb.Append(" -r:").Append(MTouch.Quote(r)); } } if (!string.IsNullOrEmpty(Executable)) { sb.Append(" ").Append(MTouch.Quote(Executable)); } if (TargetFramework == None) { // do nothing } else if (!string.IsNullOrEmpty(TargetFramework)) { sb.Append(" --target-framework ").Append(TargetFramework); } else if (!NoPlatformAssemblyReference) { // make the implicit default the way tests have been running until now, and at the same time the very minimum to make apps build. switch (Profile) { case MTouch.Profile.Unified: sb.Append(" -r:").Append(MTouch.Quote(Configuration.XamarinIOSDll)); break; case MTouch.Profile.TVOS: case MTouch.Profile.WatchOS: sb.Append(" --target-framework ").Append(MTouch.GetTargetFramework(Profile)); sb.Append(" -r:").Append(MTouch.Quote(MTouch.GetBaseLibrary(Profile))); break; default: throw new NotImplementedException(); } } if (!string.IsNullOrEmpty(Abi)) { sb.Append(" --abi ").Append(Abi); } else { switch (Profile) { case MTouch.Profile.Unified: break; // not required case MTouch.Profile.TVOS: sb.Append(isDevice ? " --abi arm64" : " --abi x86_64"); break; case MTouch.Profile.WatchOS: sb.Append(isDevice ? " --abi armv7k" : " --abi i386"); break; default: throw new NotImplementedException(); } } switch (Linker) { case MTouchLinker.LinkAll: case MTouchLinker.Unspecified: break; case MTouchLinker.DontLink: sb.Append(" --nolink"); break; case MTouchLinker.LinkSdk: sb.Append(" --linksdkonly"); break; default: throw new NotImplementedException(); } if (NoFastSim.HasValue && NoFastSim.Value) { sb.Append(" --nofastsim"); } switch (Registrar) { case MTouchRegistrar.Unspecified: break; case MTouchRegistrar.Dynamic: sb.Append(" --registrar:dynamic"); break; case MTouchRegistrar.Static: sb.Append(" --registrar:static"); break; default: throw new NotImplementedException(); } if (I18N != I18N.None) { sb.Append(" --i18n "); int count = 0; if ((I18N & I18N.CJK) == I18N.CJK) { sb.Append(count++ == 0 ? string.Empty : ",").Append("cjk"); } if ((I18N & I18N.MidEast) == I18N.MidEast) { sb.Append(count++ == 0 ? string.Empty : ",").Append("mideast"); } if ((I18N & I18N.Other) == I18N.Other) { sb.Append(count++ == 0 ? string.Empty : ",").Append("other"); } if ((I18N & I18N.Rare) == I18N.Rare) { sb.Append(count++ == 0 ? string.Empty : ",").Append("rare"); } if ((I18N & I18N.West) == I18N.West) { sb.Append(count++ == 0 ? string.Empty : ",").Append("west"); } } if (!string.IsNullOrEmpty(Cache)) { sb.Append(" --cache ").Append(MTouch.Quote(Cache)); } if (!string.IsNullOrEmpty(Device)) { sb.Append(" --device:").Append(MTouch.Quote(Device)); } return(sb.ToString()); }
string BuildArguments(MTouchAction action) { var sb = new StringBuilder(); var isDevice = false; switch (action) { case MTouchAction.None: break; case MTouchAction.BuildDev: MTouch.AssertDeviceAvailable(); if (AppPath == null) { throw new Exception("No AppPath specified."); } isDevice = true; sb.Append(" --dev ").Append(StringUtils.Quote(AppPath)); break; case MTouchAction.BuildSim: isDevice = false; if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Append(" --sim ").Append(StringUtils.Quote(AppPath)); break; case MTouchAction.LaunchSim: isDevice = false; if (AppPath == null) { throw new Exception("No AppPath specified."); } sb.Append(" --launchsim ").Append(StringUtils.Quote(AppPath)); break; default: throw new NotImplementedException(); } if (SdkRoot == None) { // do nothing } else if (!string.IsNullOrEmpty(SdkRoot)) { sb.Append(" --sdkroot ").Append(StringUtils.Quote(SdkRoot)); } else { sb.Append(" --sdkroot ").Append(StringUtils.Quote(Configuration.xcode_root)); } sb.Append(" ").Append(GetVerbosity()); if (Sdk == None) { // do nothing } else if (!string.IsNullOrEmpty(Sdk)) { sb.Append(" --sdk ").Append(Sdk); } else { sb.Append(" --sdk ").Append(MTouch.GetSdkVersion(Profile)); } if (TargetVer == None) { // do nothing } else if (!string.IsNullOrEmpty(TargetVer)) { sb.Append(" --targetver ").Append(TargetVer); } if (Debug.HasValue && Debug.Value) { sb.Append(" --debug"); } if (FastDev.HasValue && FastDev.Value) { sb.Append(" --fastdev"); } if (PackageMdb.HasValue) { sb.Append(" --package-mdb:").Append(PackageMdb.Value ? "true" : "false"); } if (NoStrip.HasValue && NoStrip.Value) { sb.Append(" --nostrip"); } if (NoSymbolStrip != null) { if (NoSymbolStrip.Length == 0) { sb.Append(" --nosymbolstrip"); } else { sb.Append(" --nosymbolstrip:").Append(NoSymbolStrip); } } if (Profiling.HasValue) { sb.Append(" --profiling:").Append(Profiling.Value ? "true" : "false"); } if (!string.IsNullOrEmpty(SymbolList)) { sb.Append(" --symbollist=").Append(StringUtils.Quote(SymbolList)); } if (MSym.HasValue) { sb.Append(" --msym:").Append(MSym.Value ? "true" : "false"); } if (DSym.HasValue) { sb.Append(" --dsym:").Append(DSym.Value ? "true" : "false"); } if (Extension == true) { sb.Append(" --extension"); } foreach (var appext in AppExtensions) { sb.Append(" --app-extension ").Append(StringUtils.Quote(appext.AppPath)); } foreach (var framework in Frameworks) { sb.Append(" --framework ").Append(StringUtils.Quote(framework)); } if (!string.IsNullOrEmpty(Mono)) { sb.Append(" --mono:").Append(StringUtils.Quote(Mono)); } if (!string.IsNullOrEmpty(GccFlags)) { sb.Append(" --gcc_flags ").Append(StringUtils.Quote(GccFlags)); } if (!string.IsNullOrEmpty(HttpMessageHandler)) { sb.Append(" --http-message-handler=").Append(StringUtils.Quote(HttpMessageHandler)); } if (Dlsym.HasValue) { sb.Append(" --dlsym:").Append(Dlsym.Value ? "true" : "false"); } if (References != null) { foreach (var r in References) { sb.Append(" -r:").Append(StringUtils.Quote(r)); } } if (!string.IsNullOrEmpty(Executable)) { sb.Append(" --executable ").Append(StringUtils.Quote(Executable)); } if (!string.IsNullOrEmpty(RootAssembly)) { sb.Append(" ").Append(StringUtils.Quote(RootAssembly)); } if (TargetFramework == None) { // do nothing } else if (!string.IsNullOrEmpty(TargetFramework)) { sb.Append(" --target-framework ").Append(TargetFramework); } else if (!NoPlatformAssemblyReference) { // make the implicit default the way tests have been running until now, and at the same time the very minimum to make apps build. switch (Profile) { case Profile.iOS: sb.Append(" -r:").Append(StringUtils.Quote(Configuration.XamarinIOSDll)); break; case Profile.tvOS: case Profile.watchOS: sb.Append(" --target-framework ").Append(MTouch.GetTargetFramework(Profile)); sb.Append(" -r:").Append(StringUtils.Quote(MTouch.GetBaseLibrary(Profile))); break; default: throw new NotImplementedException(); } } if (Abi == None) { // add nothing } else if (!string.IsNullOrEmpty(Abi)) { sb.Append(" --abi ").Append(Abi); } else { switch (Profile) { case Profile.iOS: break; // not required case Profile.tvOS: sb.Append(isDevice ? " --abi arm64" : " --abi x86_64"); break; case Profile.watchOS: sb.Append(isDevice ? " --abi armv7k" : " --abi i386"); break; default: throw new NotImplementedException(); } } switch (Linker) { case MTouchLinker.LinkAll: case MTouchLinker.Unspecified: break; case MTouchLinker.DontLink: sb.Append(" --nolink"); break; case MTouchLinker.LinkSdk: sb.Append(" --linksdkonly"); break; default: throw new NotImplementedException(); } if (Optimize != null) { foreach (var opt in Optimize) { sb.Append(" --optimize:").Append(opt); } } switch (SymbolMode) { case MTouchSymbolMode.Ignore: sb.Append(" --dynamic-symbol-mode=ignore"); break; case MTouchSymbolMode.Code: sb.Append(" --dynamic-symbol-mode=code"); break; case MTouchSymbolMode.Default: sb.Append(" --dynamic-symbol-mode=default"); break; case MTouchSymbolMode.Linker: sb.Append(" --dynamic-symbol-mode=linker"); break; case MTouchSymbolMode.Unspecified: break; default: throw new NotImplementedException(); } if (NoFastSim.HasValue && NoFastSim.Value) { sb.Append(" --nofastsim"); } switch (Registrar) { case MTouchRegistrar.Unspecified: break; case MTouchRegistrar.Dynamic: sb.Append(" --registrar:dynamic"); break; case MTouchRegistrar.Static: sb.Append(" --registrar:static"); break; default: throw new NotImplementedException(); } if (I18N != I18N.None) { sb.Append(" --i18n "); int count = 0; if ((I18N & I18N.CJK) == I18N.CJK) { sb.Append(count++ == 0 ? string.Empty : ",").Append("cjk"); } if ((I18N & I18N.MidEast) == I18N.MidEast) { sb.Append(count++ == 0 ? string.Empty : ",").Append("mideast"); } if ((I18N & I18N.Other) == I18N.Other) { sb.Append(count++ == 0 ? string.Empty : ",").Append("other"); } if ((I18N & I18N.Rare) == I18N.Rare) { sb.Append(count++ == 0 ? string.Empty : ",").Append("rare"); } if ((I18N & I18N.West) == I18N.West) { sb.Append(count++ == 0 ? string.Empty : ",").Append("west"); } } if (!string.IsNullOrEmpty(Cache)) { sb.Append(" --cache ").Append(StringUtils.Quote(Cache)); } if (!string.IsNullOrEmpty(Device)) { sb.Append(" --device:").Append(StringUtils.Quote(Device)); } if (!string.IsNullOrEmpty(LLVMOptimizations)) { sb.Append(" --llvm-opt=").Append(StringUtils.Quote(LLVMOptimizations)); } if (CustomArguments != null) { foreach (var arg in CustomArguments) { sb.Append(" ").Append(arg); } } if (NoWarn != null) { if (NoWarn.Length > 0) { sb.Append(" --nowarn:"); foreach (var code in NoWarn) { sb.Append(code).Append(','); } sb.Length--; } else { sb.Append(" --nowarn"); } } if (WarnAsError != null) { if (WarnAsError.Length > 0) { sb.Append(" --warnaserror:"); foreach (var code in WarnAsError) { sb.Append(code).Append(','); } sb.Length--; } else { sb.Append(" --warnaserror"); } } if (Bitcode != MTouchBitcode.Unspecified) { sb.Append(" --bitcode:").Append(Bitcode.ToString().ToLower()); } foreach (var abt in AssemblyBuildTargets) { sb.Append(" --assembly-build-target=").Append(StringUtils.Quote(abt)); } if (!string.IsNullOrEmpty(AotArguments)) { sb.Append(" --aot:").Append(StringUtils.Quote(AotArguments)); } if (!string.IsNullOrEmpty(AotOtherArguments)) { sb.Append(" --aot-options:").Append(StringUtils.Quote(AotOtherArguments)); } if (LinkSkip?.Length > 0) { foreach (var ls in LinkSkip) { sb.Append(" --linkskip:").Append(StringUtils.Quote(ls)); } } if (XmlDefinitions?.Length > 0) { foreach (var xd in XmlDefinitions) { sb.Append(" --xml:").Append(StringUtils.Quote(xd)); } } if (!string.IsNullOrEmpty(ResponseFile)) { sb.Append(" @").Append(StringUtils.Quote(ResponseFile)); } return(sb.ToString()); }