xamarin-macios/tests/xharness/WatchOSTarget.cs

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

2016-05-26 16:06:52 +03:00
using System;
using System.Collections.Generic;
2016-05-26 16:06:52 +03:00
using System.IO;
using System.Xml;
using Xamarin;
using Xamarin.Utils;
2016-05-26 16:06:52 +03:00
namespace xharness
{
public class WatchOSTarget : iOSTarget
2016-05-26 16:06:52 +03:00
{
public string AppName { get; private set; }
public string ExtensionName { get; private set; }
public string WatchOSAppGuid { get; private set; }
public string WatchOSExtensionGuid { get; private set; }
public string WatchOSGuid { get { return ProjectGuid; } private set { ProjectGuid = value; } }
public string WatchOSAppProjectPath { get; private set; }
public string WatchOSExtensionProjectPath { get; private set; }
public string WatchOSProjectPath { get { return ProjectPath; } private set { ProjectPath = value; } }
2019-01-29 10:16:42 +03:00
public override string SimulatorArchitectures {
get { return "i386"; }
}
public override string DeviceArchitectures {
get { return "ARMv7k, ARM64_32"; }
}
2016-05-26 16:06:52 +03:00
void CreateWatchOSAppProject ()
{
var csproj = new XmlDocument ();
var suffix = Suffix + "-app";
2016-05-26 16:06:52 +03:00
csproj.LoadWithoutNetworkAccess (Path.Combine (Harness.WatchOSAppTemplate, "App.csproj"));
csproj.FindAndReplace ("%WATCHAPP_PATH%", Path.GetFullPath (Harness.WatchOSAppTemplate).Replace ('/', '\\') + "\\");
csproj.FindAndReplace ("%WATCHEXTENSION_CSPROJ%", Path.GetFileName (WatchOSExtensionProjectPath));
csproj.SetProjectReferenceValue (Path.GetFileName (WatchOSExtensionProjectPath), "Project", WatchOSExtensionGuid);
csproj.SetProjectReferenceValue (Path.GetFileName (WatchOSExtensionProjectPath), "Name", Path.GetFileNameWithoutExtension (WatchOSExtensionProjectPath));
2016-05-26 16:06:52 +03:00
WatchOSAppGuid = "{" + Harness.NewStableGuid ().ToString ().ToUpper () + "}";
csproj.SetProjectGuid (WatchOSAppGuid);
csproj.FixInfoPListInclude (suffix);
if (MonoNativeInfo != null) {
csproj.AddAdditionalDefines ("MONO_NATIVE_WATCH");
MonoNativeHelper.AddProjectDefines (csproj, MonoNativeInfo.Flavor);
MonoNativeHelper.RemoveSymlinkMode (csproj);
}
2016-05-26 16:06:52 +03:00
Harness.Save (csproj, WatchOSAppProjectPath);
XmlDocument info_plist = new XmlDocument ();
var target_info_plist = Path.Combine (TargetDirectory, $"Info{Suffix}-app.plist");
2016-05-26 16:06:52 +03:00
info_plist.LoadWithoutNetworkAccess (Path.Combine (Harness.WatchOSAppTemplate, "Info.plist"));
info_plist.SetCFBundleIdentifier (BundleIdentifier + ".watchkitapp");
info_plist.SetPListStringValue ("WKCompanionAppBundleIdentifier", BundleIdentifier);
info_plist.SetPListStringValue ("CFBundleName", Name);
info_plist.SetMinimumOSVersion (GetMinimumOSVersion (info_plist.GetMinimumOSVersion ()));
2016-05-26 16:06:52 +03:00
Harness.Save (info_plist, target_info_plist);
}
void CreateWatchOSContainerProject ()
{
var csproj = new XmlDocument ();
csproj.LoadWithoutNetworkAccess (Path.Combine (Harness.WatchOSContainerTemplate, "Container.csproj"));
csproj.FindAndReplace ("%CONTAINER_PATH%", Path.GetFullPath (Harness.WatchOSContainerTemplate).Replace ('/', '\\') + "\\");
csproj.FindAndReplace ("%WATCHAPP_CSPROJ%", Path.GetFileName (WatchOSAppProjectPath));
csproj.SetProjectReferenceValue (Path.GetFileName (WatchOSAppProjectPath), "Name", Path.GetFileNameWithoutExtension (WatchOSAppProjectPath));
2016-05-26 16:06:52 +03:00
WatchOSGuid = "{" + Harness.NewStableGuid ().ToString ().ToUpper () + "}";
csproj.SetProjectGuid (WatchOSGuid);
csproj.FixInfoPListInclude (Suffix);
if (MonoNativeInfo != null) {
csproj.AddAdditionalDefines ("MONO_NATIVE_WATCH");
MonoNativeHelper.AddProjectDefines (csproj, MonoNativeInfo.Flavor);
MonoNativeHelper.RemoveSymlinkMode (csproj);
}
2016-05-26 16:06:52 +03:00
Harness.Save (csproj, WatchOSProjectPath);
XmlDocument info_plist = new XmlDocument ();
var target_info_plist = Path.Combine (TargetDirectory, $"Info{Suffix}.plist");
2016-05-26 16:06:52 +03:00
info_plist.LoadWithoutNetworkAccess (Path.Combine (Harness.WatchOSContainerTemplate, "Info.plist"));
info_plist.SetCFBundleIdentifier (BundleIdentifier);
info_plist.SetCFBundleName (Name);
info_plist.SetMinimumOSVersion ("9.0");
2016-05-26 16:06:52 +03:00
Harness.Save (info_plist, target_info_plist);
}
void CreateWatchOSExtensionProject ()
{
var csproj = inputProject;
var suffix = Suffix + "-extension";
2019-01-29 10:16:42 +03:00
// Remove unused configurations
csproj.DeleteConfiguration ("iPhone", "Release-bitcode");
csproj.DeleteConfiguration ("iPhone", "Release64");
csproj.DeleteConfiguration ("iPhone", "Debug64");
csproj.FixArchitectures ("i386", "ARMv7k", "iPhone", "Release32");
csproj.FixArchitectures ("i386", "ARMv7k", "iPhone", "Debug32");
// add Release64_32 and set the correct architecture
csproj.CloneConfiguration ("iPhone", "Release", "Release64_32");
csproj.FixArchitectures ("i386", "ARM64_32", "iPhone", "Release64_32");
// add Debug64_32 and set the correct architecture
csproj.CloneConfiguration ("iPhone", "Debug", "Debug64_32");
csproj.FixArchitectures ("i386", "ARM64_32", "iPhone", "Debug64_32");
csproj.FixArchitectures (SimulatorArchitectures, DeviceArchitectures, "iPhoneSimulator", "Debug");
csproj.FixArchitectures (SimulatorArchitectures, DeviceArchitectures, "iPhoneSimulator", "Release");
csproj.FixArchitectures (SimulatorArchitectures, DeviceArchitectures, "iPhone", "Debug");
csproj.FixArchitectures (SimulatorArchitectures, DeviceArchitectures, "iPhone", "Release");
2016-05-26 16:06:52 +03:00
csproj.SetProjectTypeGuids ("{1E2E965C-F6D2-49ED-B86E-418A60C69EEF};" + LanguageGuid);
csproj.SetOutputPath ("bin\\$(Platform)\\$(Configuration)" + suffix);
csproj.SetIntermediateOutputPath ("obj\\$(Platform)\\$(Configuration)" + suffix);
csproj.RemoveTargetFrameworkIdentifier ();
csproj.SetPlatformAssembly ("Xamarin.WatchOS");
csproj.SetImport (IsFSharp ? "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.AppExtension.FSharp.targets" : "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.AppExtension.CSharp.targets");
csproj.FixProjectReferences ("-watchos");
2019-01-29 10:16:42 +03:00
2016-05-26 16:06:52 +03:00
csproj.FixInfoPListInclude (suffix);
csproj.SetOutputType ("Library");
csproj.AddAdditionalDefines ("BITCODE", "iPhone", "Release");
csproj.AddAdditionalDefines ("XAMCORE_2_0;XAMCORE_3_0;FEATURE_NO_BSD_SOCKETS;MONOTOUCH_WATCH;");
csproj.RemoveReferences ("OpenTK-1.0");
2016-05-26 16:06:52 +03:00
var ext = IsFSharp ? "fs" : "cs";
csproj.AddCompileInclude ("InterfaceController." + ext, Path.Combine (Harness.WatchOSExtensionTemplate, "InterfaceController." + ext));
csproj.SetExtraLinkerDefs ("extra-linker-defs" + ExtraLinkerDefsSuffix + ".xml");
2016-05-26 16:06:52 +03:00
csproj.SetMtouchUseBitcode (true, "iPhone", "Release");
csproj.SetMtouchUseLlvm (true, "iPhone", "Release");
if (MonoNativeInfo != null) {
csproj.AddAdditionalDefines ("MONO_NATIVE_WATCH");
MonoNativeHelper.AddProjectDefines (csproj, MonoNativeInfo.Flavor);
MonoNativeHelper.RemoveSymlinkMode (csproj);
}
// Not linking a watch extensions requires passing -Os to the native compiler.
// https://github.com/mono/mono/issues/9867
2019-01-29 10:16:42 +03:00
var configurations = new string [] { "Debug", "Debug32", "Debug64_32", "Release", "Release32", "Release64_32" };
foreach (var c in configurations) {
var flags = "-fembed-bitcode-marker";
if (csproj.GetMtouchLink ("iPhone", c) == "None")
flags += " -Os";
csproj.AddExtraMtouchArgs ($"--gcc_flags='{flags}'", "iPhone", c);
}
2016-05-26 16:06:52 +03:00
Harness.Save (csproj, WatchOSExtensionProjectPath);
WatchOSExtensionGuid = csproj.GetProjectGuid ();
XmlDocument info_plist = new XmlDocument ();
var target_info_plist = Path.Combine (TargetDirectory, $"Info{Suffix}-extension.plist");
2016-05-26 16:06:52 +03:00
info_plist.LoadWithoutNetworkAccess (Path.Combine (TargetDirectory, "Info.plist"));
[d16-2] [xharness] Don't use a dash in the bundle identifer for watchOS projects. (#6118) * [xharness] Don't use a dash in the bundle identifer for watchOS projects. It causes problems with the mscorlib test project, which can't be launched properly. I'm not sure what's the underlying cause, but here are some of the symptoms: * The watch app actually shows up fine on the device, but: * mlaunch isn't notified about the new process, so it thinks the app didn't launch. * The new process doesn't receive any environment variables we try to give it, which for instance means that it won't auto-start the tests upon launch. * If we ask mlaunch to attach with lldb, mlaunch will ask watchOS to launch the process in a suspended state while lldb attaches. Yet the watch app shows up on the device as if not asked to be suspended upon launch. It seems that the dash (I assume, because I haven't investigated this very deeply, I just happened to find a solution that worked) makes watchOS launch the app as if tapped, instead of launched from an IDE. The strangest part is that this only happens with the mscorlib test project, not any of the other test projects we run on the watch, and they all have dashes in their bundle identifiers... yet replacing the dash with another character (underscore, letter, removing it altogether) all made things work as expected. * [monotouch-test] Adjust expected value for watchOS bundle id. The watchOS bundle ID changed in fc5067ee673bb7005031e5373a0130e43124d875, and the test failure wasn't caught properly.
2019-05-24 18:47:02 +03:00
BundleIdentifier = info_plist.GetCFBundleIdentifier () + "_watch";
if (BundleIdentifier.Length >= 58)
BundleIdentifier = BundleIdentifier.Substring (0, 57); // If the main app's bundle id is 58 characters (or sometimes more), then the watch extension crashes at launch. radar #29847128.
2016-05-26 16:06:52 +03:00
info_plist.SetCFBundleIdentifier (BundleIdentifier + ".watchkitapp.watchkitextension");
info_plist.SetMinimumOSVersion (GetMinimumOSVersion ("2.0"));
2016-05-26 16:06:52 +03:00
info_plist.SetUIDeviceFamily (4);
info_plist.AddPListStringValue ("RemoteInterfacePrincipleClass", "InterfaceController");
info_plist.AddPListKeyValuePair ("NSExtension", "dict", string.Format (
@"
<key>NSExtensionAttributes</key>
<dict>
<key>WKAppBundleIdentifier</key>
<string>{0}.watchkitapp</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.watchkit</string>
", BundleIdentifier));
if (!info_plist.ContainsKey ("NSAppTransportSecurity")) {
info_plist.AddPListKeyValuePair ("NSAppTransportSecurity", "dict",
@"
<key>NSAllowsArbitraryLoads</key>
<true/>
");
}
Harness.Save (info_plist, target_info_plist);
}
protected override string Imports {
get {
return IsFSharp ? "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.FSharp.targets" : "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.CSharp.targets";
}
}
protected override string BindingsImports {
get {
return IsFSharp ? "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.ObjCBinding.FSharp.targets" : "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.ObjCBinding.CSharp.targets";
}
}
void CreateWatchOSLibraryProject ()
{
var csproj = inputProject;
csproj.SetProjectTypeGuids ("{FC940695-DFE0-4552-9F25-99AF4A5619A1};" + LanguageGuid);
csproj.SetOutputPath ("bin\\$(Platform)\\$(Configuration)" + Suffix);
csproj.SetIntermediateOutputPath ("obj\\$(Platform)\\$(Configuration)" + Suffix);
csproj.RemoveTargetFrameworkIdentifier ();
csproj.SetPlatformAssembly ("Xamarin.WatchOS");
csproj.SetImport (IsBindingProject ? BindingsImports : Imports);
csproj.AddAdditionalDefines ("XAMCORE_2_0;XAMCORE_3_0;MONOTOUCH_WATCH;");
2016-05-26 16:06:52 +03:00
csproj.FixProjectReferences (Suffix);
csproj.SetExtraLinkerDefs ("extra-linker-defs" + ExtraLinkerDefsSuffix + ".xml");
2016-05-26 16:06:52 +03:00
csproj.FixTestLibrariesReferences (Platform);
Harness.Save (csproj, WatchOSProjectPath);
WatchOSGuid = csproj.GetProjectGuid ();
}
protected override void ExecuteInternal ()
{
ExtensionName = Name + " Extension";
AppName = Name + " App";
var templateName = Path.GetFileName (TemplateProjectPath);
if (templateName.EndsWith (".template", StringComparison.OrdinalIgnoreCase))
templateName = Path.GetFileNameWithoutExtension (templateName);
templateName = Path.GetFileNameWithoutExtension (templateName);
2016-05-26 16:06:52 +03:00
switch (OutputType) {
case "Exe":
WatchOSExtensionProjectPath = Path.Combine (TargetDirectory, templateName + Suffix + "-extension.csproj");
WatchOSAppProjectPath = Path.Combine (TargetDirectory, templateName + Suffix + "-app.csproj");
2016-05-26 16:06:52 +03:00
CreateWatchOSExtensionProject ();
CreateWatchOSAppProject ();
CreateWatchOSContainerProject ();
break;
case "Library":
CreateWatchOSLibraryProject ();
break;
default:
throw new Exception (string.Format ("Unknown OutputType: {0}", OutputType));
}
}
protected override void CalculateName ()
{
if (TargetDirectory.Contains ("BCLTests"))
Name = TestProject.Name;
else
base.CalculateName ();
if (MonoNativeInfo != null)
Name = Name + MonoNativeInfo.FlavorSuffix;
}
protected override string GetMinimumOSVersion (string templateMinimumOSVersion)
{
if (MonoNativeInfo == null)
return templateMinimumOSVersion;
return MonoNativeHelper.GetMinimumOSVersion (DevicePlatform.watchOS, MonoNativeInfo.Flavor);
}
2016-05-26 16:06:52 +03:00
public override string Suffix {
get {
return MonoNativeInfo != null ? MonoNativeInfo.FlavorSuffix + "-watchos" : "-watchos";
}
}
public override string ExtraLinkerDefsSuffix {
2016-05-26 16:06:52 +03:00
get {
return "-watchos";
}
}
public override string Platform {
get {
return "watchos";
}
}
protected override bool SupportsBitcode {
get {
return true;
}
}
public override IEnumerable<RelatedProject> GetRelatedProjects ()
{
return new RelatedProject [] {
new RelatedProject { Guid = WatchOSExtensionGuid, ProjectPath = WatchOSExtensionProjectPath },
new RelatedProject { Guid = WatchOSAppGuid, ProjectPath = WatchOSAppProjectPath },
};
}
2016-05-26 16:06:52 +03:00
}
}