Example #1
0
		static PlistDocument LoadSdkSettings (IPhoneSdkVersion sdk)
		{
			var doc = new PlistDocument ();
			doc.LoadFromXmlFile ("/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" + sdk.ToString ()
			                     + ".sdk/SDKSettings.plist");
			return doc;
		}
		public IPhoneExecutionCommand (TargetRuntime runtime, TargetFramework framework, FilePath appPath, 
		                               FilePath logDirectory, bool debugMode, IPhoneSimulatorTarget target, 
		                               IPhoneSdkVersion minimumOSVersion, TargetDevice supportedDevices)
		{
			this.AppPath = appPath;
			this.LogDirectory = logDirectory;
			this.Framework = framework;
			this.Runtime = runtime;
			this.DebugMode = debugMode;
			this.SimulatorTarget = target;
			this.MinimumOSVersion = minimumOSVersion;
			this.SupportedDevices = supportedDevices;
		}
		public static IPhoneSdkVersion GetClosestInstalledSdk (IPhoneSdkVersion v)
		{
			IPhoneSdkVersion? previous = null;
			foreach (var i in InstalledSdkVersions) {
				var cmp = v.CompareTo (i);
				if (cmp == 0) {
					return i;
				} else if (cmp > 0) {
					return previous ?? i;	
				}
				previous = i;
			}
			return IPhoneSdkVersion.Default;
		}
		public static IPhoneSdkVersion GetClosestInstalledSdk (IPhoneSdkVersion v)
		{
			//sorted low to high, so get first that's >= requested version
			foreach (var i in InstalledSdkVersions) {
				if (i.CompareTo (v) >= 0)
					return i;
			}
			return IPhoneSdkVersion.UseDefault;
		}
		static BuildResult ProcessPackaging (IProgressMonitor monitor, IPhoneSdkVersion sdkVersion, IPhoneProject proj,
			IPhoneProjectConfiguration conf, IPhoneAppIdentity identity)
		{
			//don't bother signing in the sim
			bool isDevice = conf.Platform == IPhoneProject.PLAT_IPHONE;
			if (!isDevice)
				return null;
			
			BuildResult result = new BuildResult ();
			
			var pkgInfo = conf.AppDirectory.Combine ("PkgInfo");
			if (!File.Exists (pkgInfo))
				using (var f = File.OpenWrite (pkgInfo))
					f.Write (new byte [] { 0X41, 0X50, 0X50, 0X4C, 0x3f, 0x3f, 0x3f, 0x3f}, 0, 8);
			
			if (result.Append (CompressResources (monitor, conf)).ErrorCount > 0)
				return result;
			
			if (result.Append (EmbedProvisioningProfile (monitor, conf, identity.Profile)).ErrorCount > 0)
				return result;
			
			string xcent;
			if (result.Append (GenXcent (monitor, sdkVersion, proj, conf, identity, out xcent)).ErrorCount > 0)
				return result;
			
			string resRules;
			if (result.Append (PrepareResourceRules (monitor, sdkVersion, conf, out resRules)).ErrorCount > 0)
				return result;
			
			if (result.Append (SignAppBundle (monitor, proj, conf, identity.SigningKey, resRules, xcent)).ErrorCount > 0)
				return result;
			
			return result;
		}
		static IEnumerable<FilePair> GetIconContentFiles (IPhoneSdkVersion sdkVersion, IPhoneProject proj,
			IPhoneProjectConfiguration conf)
		{
			bool v3_2_orNewer = sdkVersion >= IPhoneSdkVersion.V3_2;
			bool v4_0_orNewer = sdkVersion >= IPhoneSdkVersion.V4_0;
			bool supportsIPhone = (proj.SupportedDevices & TargetDevice.IPhone) != 0;
			bool supportsIPad = (proj.SupportedDevices & TargetDevice.IPad) != 0;
			var appDir = conf.AppDirectory;
			
			if (supportsIPhone && !proj.BundleIcon.IsNullOrEmpty)
					yield return new FilePair (proj.BundleIcon, appDir.Combine ("Icon.png"));
			
			if (!proj.BundleIconSpotlight.IsNullOrEmpty)
				yield return new FilePair (proj.BundleIconSpotlight, appDir.Combine ("Icon-Small.png"));
			
			if (v3_2_orNewer && supportsIPad) {
				if (!proj.BundleIconIPad.IsNullOrEmpty)
					yield return new FilePair (proj.BundleIconIPad, appDir.Combine ("Icon-72.png"));
				if (!proj.BundleIconIPadSpotlight.IsNullOrEmpty)
					yield return new FilePair (proj.BundleIconIPadSpotlight, appDir.Combine ("Icon-Small-50.png"));
			}
			
			if (supportsIPhone && v4_0_orNewer) {
				if (!proj.BundleIconHigh.IsNullOrEmpty)
					yield return new FilePair (proj.BundleIconHigh, appDir.Combine ("*****@*****.**"));
				if (!proj.BundleIconSpotlightHigh.IsNullOrEmpty)
					yield return new FilePair (proj.BundleIconSpotlightHigh, appDir.Combine ("*****@*****.**"));
			}
		}
		public static IEnumerable<IPhoneSimulatorTarget> GetSimulatorTargets ()
		{
			var v32 = new IPhoneSdkVersion (new int[] { 3, 2 });
			foreach (var v in IPhoneFramework.InstalledSdkVersions) {
				yield return new IPhoneSimulatorTarget (TargetDevice.IPhone, v);
				if (v.CompareTo (v32) >= 0)
					yield return new IPhoneSimulatorTarget (TargetDevice.IPad, v);
			}
		}
Example #8
0
		public static IEnumerable<IPhoneSimulatorTarget> GetSimulatorTargets (IPhoneSdkVersion minVersion, TargetDevice projSupportedDevices)
		{	
			return GetSimulatorTargets ().Where (t => t.Supports (minVersion, projSupportedDevices));
		}
Example #9
0
        protected override string GenerateCommandLineCommands()
        {
            var args = new ProcessArgumentBuilder ();
            TargetArchitecture architectures;

            if (string.IsNullOrEmpty (Architectures) || !Enum.TryParse (Architectures, out architectures))
                architectures = TargetArchitecture.Default;

            if (architectures == TargetArchitecture.ARMv6) {
                Log.LogError ("Target architecture ARMv6 is no longer supported in Xamarin.iOS. Please select a supported architecture.");
                return null;
            }

            if (IsClassic && minimumOSVersion < IPhoneSdkVersion.V3_1 && architectures.HasFlag (TargetArchitecture.ARMv7)) {
                Log.LogWarning (null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Deployment Target changed from iOS {0} to iOS 3.1 (minimum requirement for ARMv7)", minimumOSVersion);
                minimumOSVersion = IPhoneSdkVersion.V3_1;
            }

            if (!string.IsNullOrEmpty (IntermediateOutputPath)) {
                Directory.CreateDirectory (IntermediateOutputPath);

                args.Add ("--cache");
                args.AddQuoted (Path.GetFullPath (IntermediateOutputPath));
            }

            if (IsClassic || IPhoneSdks.MonoTouch.Version < new IPhoneSdkVersion (8, 5, 0)) {
                args.Add ("--nomanifest");
                args.Add ("--nosign");
            }

            args.Add (SdkIsSimulator ? "--sim" : "--dev");
            args.AddQuoted (Path.GetFullPath (AppBundleDir));

            if (AppleSdkSettings.XcodeVersion.Major >= 5 && IPhoneSdks.MonoTouch.Version.CompareTo (new IPhoneSdkVersion (6, 3, 7)) < 0)
                args.Add ("--compiler", "clang");

            args.Add ("--executable");
            args.AddQuoted (ExecutableName);

            if (IsAppExtension)
                args.Add ("--extension");

            if (Debug) {
                if (FastDev && IPhoneSdks.MonoTouch.SupportsFastDev)
                    args.Add ("--fastdev");

                args.Add ("--debug");
            }

            if (Profiling)
                args.Add ("--profiling");

            if (LinkerDumpDependencies)
                args.Add ("--linkerdumpdependencies");

            switch (LinkMode.ToLowerInvariant ()) {
            case "sdkonly": args.Add ("--linksdkonly"); break;
            case "none":    args.Add ("--nolink"); break;
            }

            if (!string.IsNullOrEmpty (I18n)) {
                args.Add ("--i18n");
                args.AddQuotedFormat (I18n);
            }

            args.Add ("--sdkroot");
            args.AddQuoted (SdkRoot);

            args.Add ("--sdk");
            args.AddQuoted (SdkVersion);

            if (!minimumOSVersion.IsUseDefault) {
                args.Add ("--targetver");
                args.AddQuoted (minimumOSVersion.ToString ());
            }

            if (UseFloat32 /* We want to compile 32-bit floating point code to use 32-bit floating point operations */)
                args.Add ("--aot-options=-O=float32");

            if (IPhoneSdks.MonoTouch.SupportsGenericValueTypeSharing) {
                if (!EnableGenericValueTypeSharing)
                    args.Add ("--gsharedvt=false");
            }

            if (LinkDescriptions != null) {
                foreach (var desc in LinkDescriptions)
                    args.AddQuoted (string.Format ("--xml={0}", desc.ItemSpec));
            }

            if (EnableBitcode) {
                switch (Framework) {
                case PlatformFramework.WatchOS:
                    args.Add ("--bitcode=full");
                    break;
                case PlatformFramework.TVOS:
                    args.Add ("--bitcode=asmonly");
                    break;
                default:
                    throw new InvalidOperationException (string.Format ("Bitcode is currently not supported on {0}.", Framework));
                }
            }

            if (!string.IsNullOrEmpty (HttpClientHandler))
                args.Add (string.Format ("--http-message-handler={0}", HttpClientHandler));

            if (!string.IsNullOrEmpty (TLSProvider))
                args.Add (string.Format ("--tls-provider={0}", TLSProvider.ToLowerInvariant()));

            string thumb = UseThumb && UseLlvm ? "+thumb2" : "";
            string llvm = UseLlvm ? "+llvm" : "";
            string abi = "";

            if (SdkIsSimulator) {
                if (architectures.HasFlag (TargetArchitecture.i386))
                    abi += (abi.Length > 0 ? "," : "") + "i386";

                if (architectures.HasFlag (TargetArchitecture.x86_64))
                    abi += (abi.Length > 0 ? "," : "") + "x86_64";

                if (string.IsNullOrEmpty (abi)) {
                    architectures = TargetArchitecture.i386;
                    abi = "i386";
                }
            } else {
                if (architectures == TargetArchitecture.Default)
                    architectures = TargetArchitecture.ARMv7;

                if (architectures.HasFlag (TargetArchitecture.ARMv7))
                    abi += (abi.Length > 0 ? "," : "") + "armv7" + llvm + thumb;

                if (architectures.HasFlag (TargetArchitecture.ARMv7s))
                    abi += (abi.Length > 0 ? "," : "") + "armv7s" + llvm + thumb;

                if (architectures.HasFlag (TargetArchitecture.ARM64)) {
                    // Note: ARM64 does not have thumb.
                    abi += (abi.Length > 0 ? "," : "") + "arm64" + llvm;
                }

                if (architectures.HasFlag (TargetArchitecture.ARMv7k))
                    abi += (abi.Length > 0 ? "," : "") + "armv7k";

                if (string.IsNullOrEmpty (abi))
                    abi = "armv7" + llvm + thumb;
            }

            // Output the CompiledArchitectures
            CompiledArchitectures = architectures.ToString ();

            args.Add ("--abi=" + abi);

            // output symbols to preserve when stripping
            args.Add ("--symbollist");
            args.AddQuoted (Path.GetFullPath (SymbolsList));

            // don't have mtouch generate the dsyms...
            args.Add ("--dsym=no");

            var gcc = new GccOptions ();

            if (!string.IsNullOrEmpty (ExtraArgs)) {
                var extraArgs = ProcessArgumentBuilder.Parse (ExtraArgs);
                var target = MainAssembly.ItemSpec;
                string projectDir;

                if (ProjectDir.StartsWith ("~/", StringComparison.Ordinal)) {
                    // Note: Since the Visual Studio plugin doesn't know the user's home directory on the Mac build host,
                    // it simply uses paths relative to "~/". Expand these paths to their full path equivalents.
                    var home = Environment.GetFolderPath (Environment.SpecialFolder.UserProfile);

                    projectDir = Path.Combine (home, ProjectDir.Substring (2));
                } else {
                    projectDir = ProjectDir;
                }

                var customTags = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase) {
                    { "projectdir",   projectDir },
                    // Apparently msbuild doesn't propagate the solution path, so we can't get it.
                    // { "solutiondir",  proj.ParentSolution != null ? proj.ParentSolution.BaseDirectory : proj.BaseDirectory },
                    { "appbundledir", AppBundleDir },
                    { "targetpath",   Path.Combine (Path.GetDirectoryName (target), Path.GetFileName (target)) },
                    { "targetdir",    Path.GetDirectoryName (target) },
                    { "targetname",   Path.GetFileName (target) },
                    { "targetext",    Path.GetExtension (target) },
                };

                for (int i = 0; i < extraArgs.Length; i++) {
                    if (extraArgs[i] == "-gcc_flags" || extraArgs[i] == "--gcc_flags") {
                        // user-defined -gcc_flags argument
                        if (i + 1 < extraArgs.Length && !string.IsNullOrEmpty (extraArgs[i + 1])) {
                            var gccArgs = ProcessArgumentBuilder.Parse (extraArgs[i + 1]);

                            for (int j = 0; j < gccArgs.Length; j++)
                                gcc.Arguments.Add (StringParserService.Parse (gccArgs[j], customTags));
                        }

                        i++;
                    } else {
                        // other user-defined mtouch arguments
                        args.AddQuoted (StringParserService.Parse (extraArgs[i], customTags));
                    }
                }
            }

            BuildNativeReferenceFlags (gcc);
            BuildEntitlementFlags (gcc);

            foreach (var framework in gcc.Frameworks) {
                args.Add ("-framework");
                args.AddQuoted (framework);
            }

            foreach (var framework in gcc.WeakFrameworks) {
                args.Add ("-weak-framework");
                args.AddQuoted (framework);
            }

            if (gcc.Cxx)
                args.Add ("--cxx");

            if (gcc.Arguments.Length > 0) {
                args.Add ("--gcc_flags");
                args.AddQuoted (gcc.Arguments.ToString ());
            }

            foreach (var asm in References) {
                args.Add ("-r");
                if (IsFrameworkItem(asm)) {
                    args.AddQuoted (ResolveFrameworkFile(asm.ItemSpec));
                } else {
                    args.AddQuoted (Path.GetFullPath (asm.ItemSpec));
                }
            }

            foreach (var ext in AppExtensionReferences) {
                args.Add ("--app-extension");
                args.AddQuoted (Path.GetFullPath (ext.ItemSpec));
            }

            args.Add ("--target-framework");
            args.Add (TargetFrameworkIdentifier + "," + TargetFrameworkVersion);

            args.AddQuoted (MainAssembly.ItemSpec);

            // We give the priority to the ExtraArgs to set the mtouch verbosity.
            if (string.IsNullOrEmpty (ExtraArgs) || (!string.IsNullOrEmpty (ExtraArgs) && !ExtraArgs.Contains ("-q") && !ExtraArgs.Contains ("-v")))
                args.Add (GetVerbosityLevel (Verbosity));

            if (!string.IsNullOrWhiteSpace (License))
                args.Add (string.Format("--license={0}", License));

            return args.ToString ();
        }
Example #10
0
        public override bool Execute()
        {
            PDictionary plist;
            PString value;

            Log.LogTaskName ("MTouch");
            Log.LogTaskProperty ("AppBundleDir", AppBundleDir);
            Log.LogTaskProperty ("AppExtensionReferences", AppExtensionReferences);
            Log.LogTaskProperty ("AppManifest", AppManifest);
            Log.LogTaskProperty ("Architectures", Architectures);
            Log.LogTaskProperty ("BitcodeEnabled", EnableBitcode);
            Log.LogTaskProperty ("CompiledEntitlements", CompiledEntitlements);
            Log.LogTaskProperty ("Debug", Debug);
            Log.LogTaskProperty ("EnableGenericValueTypeSharing", EnableGenericValueTypeSharing);
            Log.LogTaskProperty ("Entitlements", Entitlements);
            Log.LogTaskProperty ("ExecutableName", ExecutableName);
            Log.LogTaskProperty ("ExtraArgs", ExtraArgs);
            Log.LogTaskProperty ("FastDev", FastDev);
            Log.LogTaskProperty ("HttpClientHandler", HttpClientHandler);
            Log.LogTaskProperty ("I18n", I18n);
            Log.LogTaskProperty ("IntermediateOutputPath", IntermediateOutputPath);
            Log.LogTaskProperty ("IsAppExtension", IsAppExtension);
            Log.LogTaskProperty ("LinkerDumpDependencies", LinkerDumpDependencies);
            Log.LogTaskProperty ("LinkMode", LinkMode);
            Log.LogTaskProperty ("MainAssembly", MainAssembly);
            Log.LogTaskProperty ("NativeReferences", NativeReferences);
            Log.LogTaskProperty ("OutputPath", OutputPath);
            Log.LogTaskProperty ("Profiling", Profiling);
            Log.LogTaskProperty ("ProjectDir", ProjectDir);
            Log.LogTaskProperty ("References", References);
            Log.LogTaskProperty ("SdkIsSimulator", SdkIsSimulator);
            Log.LogTaskProperty ("SdkRoot", SdkRoot);
            Log.LogTaskProperty ("SdkVersion", SdkVersion);
            Log.LogTaskProperty ("SymbolsList", SymbolsList);
            Log.LogTaskProperty ("TargetFrameworkIdentifier", TargetFrameworkIdentifier);
            Log.LogTaskProperty ("TLSProvider", TLSProvider);
            Log.LogTaskProperty ("UseFloat32", UseFloat32);
            Log.LogTaskProperty ("UseLlvm", UseLlvm);
            Log.LogTaskProperty ("UseThumb", UseThumb);
            Log.LogTaskProperty ("Verbosity", Verbosity.ToString ());

            try {
                plist = PDictionary.FromFile (AppManifest.ItemSpec);
            } catch (Exception ex) {
                Log.LogError (null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Could not load Info.plist: {0}", ex.Message);
                return false;
            }

            //			deviceType = plist.GetUIDeviceFamily ();

            if (plist.TryGetValue (ManifestKeys.MinimumOSVersion, out value)) {
                if (!IPhoneSdkVersion.TryParse (value.Value, out minimumOSVersion)) {
                    Log.LogError (null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Could not parse MinimumOSVersion '{0}'", value);
                    return false;
                }
            } else {
                switch (Framework) {
                case PlatformFramework.iOS:
                    if (IsUnified) {
                        IPhoneSdkVersion sdkVersion;
                        if (!IPhoneSdkVersion.TryParse (SdkVersion, out sdkVersion)) {
                            Log.LogError (null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Could not parse SdkVersion '{0}'", SdkVersion);
                            return false;
                        }

                        minimumOSVersion = sdkVersion;
                    } else {
                        minimumOSVersion = IPhoneSdkVersion.V5_1_1;
                    }
                    break;
                case PlatformFramework.WatchOS:
                case PlatformFramework.TVOS:
                    minimumOSVersion = IPhoneSdkVersion.UseDefault;
                    break;
                default:
                    throw new InvalidOperationException (string.Format ("Invalid framework: {0}", Framework));
                }
            }

            Directory.CreateDirectory (AppBundleDir);

            var mtouchExecution = base.Execute ();

            try {
                var nativeLibrariesPath = Directory.EnumerateFiles (AppBundleDir, "*.dylib", SearchOption.AllDirectories);
                var nativeLibraryItems = new List<ITaskItem> ();

                foreach (var nativeLibrary in nativeLibrariesPath) {
                    nativeLibraryItems.Add (new TaskItem (nativeLibrary));
                }

                NativeLibraries = nativeLibraryItems.ToArray ();
            } catch (Exception ex) {
                Log.LogError (null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Could not get native libraries: {0}", ex.Message);
                return false;
            }

            return mtouchExecution;
        }
		static internal void AppendExtrasMtouchArgs (ProcessArgumentBuilder args, IPhoneSdkVersion sdkVersion, 
			IPhoneProject proj, IPhoneProjectConfiguration conf)
		{
			if (conf.MtouchDebug)
				args.Add ("-debug");
			
			switch (conf.MtouchLink) {
			case MtouchLinkMode.SdkOnly:
				args.Add ("-linksdkonly");
				break;
			case MtouchLinkMode.None:
				args.Add ("-nolink");
				break;
			case MtouchLinkMode.Full:
			default:
				break;
			}
			
			if (!string.IsNullOrEmpty (conf.MtouchI18n)) {
				args.AddQuotedFormat ("-i18n={0}", conf.MtouchI18n);
			}
			
			if (!sdkVersion.Equals (IPhoneSdkVersion.V3_0))
				args.AddQuotedFormat ("-sdk={0}", sdkVersion);
			
			if (conf.MtouchMinimumOSVersion != "3.0")
				args.AddQuotedFormat ("-targetver={0}", conf.MtouchMinimumOSVersion);
			
			
			AddExtraArgs (args, conf.MtouchExtraArgs, proj, conf);
		}
Example #12
0
        public override bool Execute()
        {
            PDictionary plist;
            PString     value;

            Log.LogTaskName("MTouch");
            Log.LogTaskProperty("AppBundleDir", AppBundleDir);
            Log.LogTaskProperty("AppExtensionReferences", AppExtensionReferences);
            Log.LogTaskProperty("AppManifest", AppManifest);
            Log.LogTaskProperty("Architectures", Architectures);
            Log.LogTaskProperty("ArchiveSymbols", ArchiveSymbols);
            Log.LogTaskProperty("BitcodeEnabled", EnableBitcode);
            Log.LogTaskProperty("CompiledEntitlements", CompiledEntitlements);
            Log.LogTaskProperty("Debug", Debug);
            Log.LogTaskProperty("EnableGenericValueTypeSharing", EnableGenericValueTypeSharing);
            Log.LogTaskProperty("EnableSGenConc", EnableSGenConc);
            Log.LogTaskProperty("Entitlements", Entitlements);
            Log.LogTaskProperty("ExecutableName", ExecutableName);
            Log.LogTaskProperty("ExtraArgs", ExtraArgs);
            Log.LogTaskProperty("FastDev", FastDev);
            Log.LogTaskProperty("HttpClientHandler", HttpClientHandler);
            Log.LogTaskProperty("I18n", I18n);
            Log.LogTaskProperty("IntermediateOutputPath", IntermediateOutputPath);
            Log.LogTaskProperty("IsAppExtension", IsAppExtension);
            Log.LogTaskProperty("LinkerDumpDependencies", LinkerDumpDependencies);
            Log.LogTaskProperty("LinkMode", LinkMode);
            Log.LogTaskProperty("MainAssembly", MainAssembly);
            Log.LogTaskProperty("NativeReferences", NativeReferences);
            Log.LogTaskProperty("OutputPath", OutputPath);
            Log.LogTaskProperty("Profiling", Profiling);
            Log.LogTaskProperty("ProjectDir", ProjectDir);
            Log.LogTaskProperty("References", References);
            Log.LogTaskProperty("SdkIsSimulator", SdkIsSimulator);
            Log.LogTaskProperty("SdkRoot", SdkRoot);
            Log.LogTaskProperty("SdkVersion", SdkVersion);
            Log.LogTaskProperty("SymbolsList", SymbolsList);
            Log.LogTaskProperty("TargetFrameworkIdentifier", TargetFrameworkIdentifier);
            Log.LogTaskProperty("UseFloat32", UseFloat32);
            Log.LogTaskProperty("UseLlvm", UseLlvm);
            Log.LogTaskProperty("UseThumb", UseThumb);
            Log.LogTaskProperty("Verbosity", Verbosity.ToString());

            try {
                plist = PDictionary.FromFile(AppManifest.ItemSpec);
            } catch (Exception ex) {
                Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Could not load Info.plist: {0}", ex.Message);
                return(false);
            }

//			deviceType = plist.GetUIDeviceFamily ();

            if (plist.TryGetValue(ManifestKeys.MinimumOSVersion, out value))
            {
                if (!IPhoneSdkVersion.TryParse(value.Value, out minimumOSVersion))
                {
                    Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Could not parse MinimumOSVersion '{0}'", value);
                    return(false);
                }
            }
            else
            {
                switch (Framework)
                {
                case PlatformFramework.iOS:
                    IPhoneSdkVersion sdkVersion;
                    if (!IPhoneSdkVersion.TryParse(SdkVersion, out sdkVersion))
                    {
                        Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Could not parse SdkVersion '{0}'", SdkVersion);
                        return(false);
                    }

                    minimumOSVersion = sdkVersion;
                    break;

                case PlatformFramework.WatchOS:
                case PlatformFramework.TVOS:
                    minimumOSVersion = IPhoneSdkVersion.UseDefault;
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Invalid framework: {0}", Framework));
                }
            }

            Directory.CreateDirectory(AppBundleDir);

            return(base.Execute());
        }
Example #13
0
        protected override bool Compile(PDictionary plist)
        {
            var currentSDK = Sdks.GetAppleSdk(Platform);

            sdkVersion = IPhoneSdkVersion.Parse(DefaultSdkVersion);
            if (!currentSDK.SdkIsInstalled(sdkVersion, SdkIsSimulator))
            {
                Log.LogError(null, null, null, null, 0, 0, 0, 0, MSBStrings.E0013, Platform, sdkVersion);
                return(false);
            }

            supportedDevices = plist.GetUIDeviceFamily();

            if (!IsWatchApp)
            {
                var version = Sdks.XamIOS.ExtendedVersion;
                // This key is our supported way of determining if an app
                // was built with Xamarin, so it needs to be present in all apps.

                var dict = new PDictionary();
                dict.Add("Version", new PString(string.Format("{0} ({1}: {2})", version.Version, version.Branch, version.Hash)));
                plist.Add("com.xamarin.ios", dict);
            }

            var sdkSettings = currentSDK.GetSdkSettings(sdkVersion, SdkIsSimulator);
            var dtSettings  = currentSDK.GetAppleDTSettings();

            SetValue(plist, ManifestKeys.BuildMachineOSBuild, dtSettings.BuildMachineOSBuild);
            // We have an issue here, this is for consideration by the platform:
            // CFLocaleCopyCurrent(), used in the mono code to get the current locale (locale.c line 421), will return the value of the application's CFBundleDevelopmentRegion Info.plist key if all of the following conditions are true:
            //
            // * CFBundleDevelopmentRegion is present in the Info.plist
            // * The CFBundleDevelopmentRegion language is in the list of preferred languages on the iOS device, but isn't the first one
            // * There are no localized resources (i.e. no .lproj directory) in the app for the first preferred locale
            //
            // This differs from iOS 10 where the presence of the CFBundleDevelopmentRegion key had no effect. Commenting this line out, ensures that CurrentCulture is correct and behaves like the iOS 10 version.
            // plist.SetIfNotPresent (ManifestKeys.CFBundleDevelopmentRegion, "en");

            if (IsIOS)
            {
                var executable = plist.GetCFBundleExecutable();
                if (executable.EndsWith(".app", StringComparison.Ordinal))
                {
                    LogAppManifestError(MSBStrings.E0014, executable);
                }
            }

            if (!string.IsNullOrEmpty(ResourceRules))
            {
                plist.SetIfNotPresent(ManifestKeys.CFBundleResourceSpecification, Path.GetFileName(ResourceRules));
            }
            if (!plist.ContainsKey(ManifestKeys.CFBundleSupportedPlatforms))
            {
                plist[ManifestKeys.CFBundleSupportedPlatforms] = new PArray {
                    SdkPlatform
                }
            }
            ;

            string dtCompiler        = null;
            string dtPlatformBuild   = null;
            string dtSDKBuild        = null;
            string dtPlatformName    = null;
            string dtPlatformVersion = null;
            string dtXcode           = null;
            string dtXcodeBuild      = null;

            if (!SdkIsSimulator)
            {
                dtCompiler      = sdkSettings.DTCompiler;
                dtPlatformBuild = dtSettings.DTPlatformBuild;
                dtSDKBuild      = sdkSettings.DTSDKBuild;
            }

            dtPlatformName = SdkPlatform.ToLowerInvariant();
            if (!SdkIsSimulator)
            {
                dtPlatformVersion = dtSettings.DTPlatformVersion;
            }

            var dtSDKName = sdkSettings.CanonicalName;

            // older sdksettings didn't have a canonicalname for sim
            if (SdkIsSimulator && string.IsNullOrEmpty(dtSDKName))
            {
                var deviceSdkSettings = currentSDK.GetSdkSettings(sdkVersion, false);
                dtSDKName = deviceSdkSettings.AlternateSDK;
            }

            if (!SdkIsSimulator)
            {
                dtXcode      = AppleSdkSettings.DTXcode;
                dtXcodeBuild = dtSettings.DTXcodeBuild;
            }

            SetValueIfNotNull(plist, "DTCompiler", dtCompiler);
            SetValueIfNotNull(plist, "DTPlatformBuild", dtPlatformBuild);
            SetValueIfNotNull(plist, "DTSDKBuild", dtSDKBuild);
            plist.SetIfNotPresent("DTPlatformName", dtPlatformName);
            SetValueIfNotNull(plist, "DTPlatformVersion", dtPlatformVersion);
            SetValue(plist, "DTSDKName", dtSDKName);
            SetValueIfNotNull(plist, "DTXcode", dtXcode);
            SetValueIfNotNull(plist, "DTXcodeBuild", dtXcodeBuild);

            SetDeviceFamily(plist);

            if (IsWatchExtension)
            {
                // Note: Only watchOS1 Extensions target Xamarin.iOS
                if (Platform == ApplePlatform.iOS)
                {
                    PObject value;

                    if (!plist.TryGetValue(ManifestKeys.UIRequiredDeviceCapabilities, out value))
                    {
                        var capabilities = new PArray();
                        capabilities.Add(new PString("watch-companion"));

                        plist.Add(ManifestKeys.UIRequiredDeviceCapabilities, capabilities);
                    }
                    else if (value is PDictionary)
                    {
                        var capabilities = (PDictionary)value;

                        if (!capabilities.ContainsKey("watch-companion"))
                        {
                            capabilities.Add("watch-companion", new PBoolean(true));
                        }
                    }
                    else
                    {
                        var  capabilities = (PArray)value;
                        bool exists       = false;

                        foreach (var capability in capabilities.OfType <PString> ())
                        {
                            if (capability.Value != "watch-companion")
                            {
                                continue;
                            }

                            exists = true;
                            break;
                        }

                        if (!exists)
                        {
                            capabilities.Add(new PString("watch-companion"));
                        }
                    }
                }

                if (Debug)
                {
                    SetAppTransportSecurity(plist);
                }
            }

            // Remove any Xamarin Studio specific keys
            plist.Remove(ManifestKeys.XSLaunchImageAssets);
            plist.Remove(ManifestKeys.XSAppIconAssets);

            SetRequiredArchitectures(plist);

            if (IsIOS)
            {
                Validation(plist);
            }

            return(!Log.HasLoggedErrors);
        }

        void SetValueIfNotNull(PDictionary dict, string key, string value)
        {
            if (value == null)
            {
                return;
            }
            SetValue(dict, key, value);
        }

        void SetRequiredArchitectures(PDictionary plist)
        {
            PObject capabilities;

            if (plist.TryGetValue(ManifestKeys.UIRequiredDeviceCapabilities, out capabilities))
            {
                if (capabilities is PArray)
                {
                    var architectureValues = new HashSet <string> (new[] { "armv6", "armv7", "arm64" });
                    var array = (PArray)capabilities;

                    // Remove any architecture values
                    for (int i = 0; i < array.Count; i++)
                    {
                        var value = array[i] as PString;

                        if (value == null || !architectureValues.Contains(value.Value))
                        {
                            continue;
                        }

                        array.RemoveAt(i);
                    }

                    // If-and-only-if the TargetArchitecture is a single architecture, set it as a required device capability
                    switch (architectures)
                    {
                    case TargetArchitecture.ARM64:
                        array.Add(new PString("arm64"));
                        break;

                    case TargetArchitecture.ARMv7:
                        array.Add(new PString("armv7"));
                        break;
                    }
                }
                else if (capabilities is PDictionary)
                {
                    var dict = (PDictionary)capabilities;

                    switch (architectures)
                    {
                    case TargetArchitecture.ARM64:
                        dict["arm64"] = new PBoolean(true);
                        dict.Remove("armv6");
                        dict.Remove("armv7");
                        break;

                    case TargetArchitecture.ARMv7:
                        dict["armv7"] = new PBoolean(true);
                        dict.Remove("armv6");
                        dict.Remove("arm64");
                        break;

                    default:
                        dict.Remove("armv6");
                        dict.Remove("armv7");
                        dict.Remove("arm64");
                        break;
                    }
                }
            }
            else
            {
                var array = new PArray();

                // If-and-only-if the TargetArchitecture is a single architecture, set it as a required device capability
                switch (architectures)
                {
                case TargetArchitecture.ARM64:
                    array.Add(new PString("arm64"));
                    break;

                case TargetArchitecture.ARMv7:
                    array.Add(new PString("armv7"));
                    break;
                }

                if (array.Count > 0)
                {
                    plist.Add(ManifestKeys.UIRequiredDeviceCapabilities, array);
                }
            }
        }

        void SetDeviceFamily(PDictionary plist)
        {
            switch (Platform)
            {
            case ApplePlatform.iOS:
                SetIOSDeviceFamily(plist);
                break;

            case ApplePlatform.WatchOS:
                plist.SetUIDeviceFamily(IPhoneDeviceType.Watch);
                break;

            case ApplePlatform.TVOS:
                plist.SetUIDeviceFamily(IPhoneDeviceType.TV);
                break;
            }
        }

        void SetIOSDeviceFamily(PDictionary plist)
        {
            if (IsWatchApp)
            {
                if (SdkIsSimulator)
                {
                    plist.SetUIDeviceFamily(IPhoneDeviceType.IPhone | IPhoneDeviceType.Watch);
                }
                else
                {
                    plist.SetUIDeviceFamily(IPhoneDeviceType.Watch);
                }
            }
            else
            {
                if (!IsAppExtension)
                {
                    plist.SetIfNotPresent(ManifestKeys.LSRequiresIPhoneOS, true);
                }

                if (supportedDevices == IPhoneDeviceType.NotSet)
                {
                    plist.SetUIDeviceFamily(IPhoneDeviceType.IPhone);
                }
            }
        }

        void SetAppTransportSecurity(PDictionary plist)
        {
            // Debugging over http has a couple of gotchas:
            // * We can't use https, because that requires a valid server certificate,
            //   which we can't ensure.
            //   It would also require a hostname for the mac, which it might not have either.
            // * NSAppTransportSecurity/NSExceptionDomains does not allow exceptions based
            //   on IP address (only hostname).
            // * Which means the only way to make sure watchOS allows connections from
            //   the app on device to the mac is to disable App Transport Security altogether.
            // Good news: watchOS 3 will apparently not apply ATS when connecting
            // directly to IP addresses, which means we won't have to do this at all
            // (sometime in the future).

            PDictionary ats;

            if (!plist.TryGetValue(ManifestKeys.NSAppTransportSecurity, out ats))
            {
                plist.Add(ManifestKeys.NSAppTransportSecurity, ats = new PDictionary());
            }

            if (ats.GetBoolean(ManifestKeys.NSAllowsArbitraryLoads))
            {
                Log.LogMessage(MessageImportance.Low, MSBStrings.M0017);
            }
            else
            {
                Log.LogMessage(MessageImportance.Low, MSBStrings.M0018);
                ats.SetBooleanOrRemove(ManifestKeys.NSAllowsArbitraryLoads, true);
            }
        }

        void Validation(PDictionary plist)
        {
            var supportsIPhone = (supportedDevices & IPhoneDeviceType.IPhone) != 0 ||
                                 supportedDevices == IPhoneDeviceType.NotSet;
            var supportsIPad = (supportedDevices & IPhoneDeviceType.IPad) != 0;

            // Validation...
            if (!IsAppExtension && sdkVersion >= IPhoneSdkVersion.V3_2)
            {
                IPhoneOrientation orientation;

                if (supportsIPhone)
                {
                    orientation = plist.GetUISupportedInterfaceOrientations(false);
                    if (orientation == IPhoneOrientation.None)
                    {
                        LogAppManifestWarning(MSBStrings.W0019);
                    }
                    else if (!orientation.IsValidPair())
                    {
                        LogAppManifestWarning(MSBStrings.W0020);
                    }
                }

                if (supportsIPad)
                {
                    orientation = plist.GetUISupportedInterfaceOrientations(true);
                    if (orientation == IPhoneOrientation.None)
                    {
                        LogAppManifestWarning(MSBStrings.W0021);
                    }
                    else if (!orientation.IsValidPair())
                    {
                        LogAppManifestWarning(MSBStrings.W0022);
                    }
                }
            }
        }
    }
Example #14
0
		public static DTSdkSettings GetSdkSettings (IPhoneSdkVersion sdk)
		{
			DTSdkSettings settings;
			if (sdkSettingsCache.TryGetValue (sdk.ToString (), out settings))
				return settings;
			
			settings = new DTSdkSettings ();
			var doc = new PlistDocument ();
			doc.LoadFromXmlFile (GetSdkPlistFilename (sdk.ToString ()));
			var dict = (PlistDictionary) doc.Root;
			
			settings.AlternateSDK = ((PlistString)dict["AlternateSDK"]).Value;
			settings.CanonicalName = ((PlistString)dict["CanonicalName"]).Value;
			var props = (PlistDictionary) dict["DefaultProperties"];
			settings.DTCompiler = ((PlistString)props["GCC_VERSION"]).Value;
			
			var sdkPath = GetSdkPath (sdk.ToString ());
			var file = sdkPath + "/System/Library/CoreServices/SystemVersion.plist";
			settings.DTPlatformBuild = GrabRootString (file, "ProductBuildVersion");
			
			sdkSettingsCache[sdk.ToString ()] = settings;
			return settings;
		}
		static BuildResult GenXcent (IProgressMonitor monitor, IPhoneSdkVersion sdkVersion, IPhoneProject proj, 
			IPhoneProjectConfiguration conf, IPhoneAppIdentity identity, out string xcentName)
		{
			xcentName = conf.CompiledOutputName.ChangeExtension (".xcent");
			
			monitor.BeginTask (GettextCatalog.GetString ("Processing entitlements file"), 0);
			
			string srcFile;
			
			if (!string.IsNullOrEmpty (conf.CodesignEntitlements)) {
				if (!File.Exists (conf.CodesignEntitlements))
					return BuildError ("Entitlements file \"" + conf.CodesignEntitlements + "\" not found.");
				srcFile = conf.CodesignEntitlements;
			} else {
				srcFile = "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" + sdkVersion.ToString ()
					+ ".sdk/Entitlements.plist";
			}
			
			var doc = new PlistDocument ();
			try {
				doc.LoadFromXmlFile (srcFile);
			} catch (Exception ex) {
				monitor.Log.WriteLine (ex.ToString ());
				return BuildError ("Error loading entitlements source file '" + srcFile +"'.");
			}
			
			//insert the app ID into the plist at the beginning
			var oldDict = doc.Root as PlistDictionary;
			var newDict = new PlistDictionary ();
			doc.Root = newDict;
			newDict["application-identifier"] = identity.AppID;
			var keychainGroups = new PlistArray (new [] { identity.AppID } );
			newDict["keychain-access-groups"] = keychainGroups;
			
			//merge in the user's values
			foreach (var item in oldDict) {
				//FIXME: we currently ignore these items, and write our own, but maybe we should do substitutes
				//i.e. $(AppIdentifierPrefix)$(CFBundleIdentifier)
				if (item.Key == "application-identifier") {
					var str = item.Value as PlistString;
					if (str == null || string.IsNullOrEmpty (str.Value) || str.Value.Contains ('$'))
						continue;
				} else if (item.Key == "keychain-access-groups") {
					//special handling, merge into the array
					var keyArr = item.Value as PlistArray;
					foreach (var key in keyArr) {
						var str = key as PlistString;
						if (str != null && !string.IsNullOrEmpty (str.Value) && !str.Value.Contains ('$')) {
							keychainGroups.Add (str.Value);
						}
					}
					continue;
				}
				newDict[item.Key] = item.Value;
			}
			
			//merge in the settings from the provisioning profile, skipping some
			foreach (var item in identity.Profile.Entitlements)
				if (item.Key != "application-identifier" && item.Key != "keychain-access-groups")
					newDict[item.Key] = item.Value;
			
			try {
				WriteXcent (doc, xcentName);
			} catch (Exception ex) {
				monitor.Log.WriteLine (ex.ToString ());
				return BuildError ("Error writing entitlements file '" + xcentName +"'.");
			}
			
			monitor.EndTask ();
			return null;
		}
		void LoadSdkValues (IPhoneSdkVersion selectedVersion)
		{
			sdkStore.Clear ();
			sdkStore.AppendValues (GettextCatalog.GetString ("Default"), IPhoneSdkVersion.UseDefault);
			
			int idx = 0;
			var sdks = IPhoneFramework.InstalledSdkVersions;
			for (int i = 0; i < sdks.Count; i++) {
				var v = sdks[i];
				if (selectedVersion.Equals (v))
					idx = i + 1;
				sdkStore.AppendValues (v.ToString (), v);
			}
			
			if (idx == 0 && !selectedVersion.IsUseDefault) {
				sdkStore.AppendValues (GettextCatalog.GetString ("{0} (not installed)", selectedVersion), selectedVersion);
				idx = sdks.Count + 1;
			}
			
			sdkCombo.Active = idx;
		}
		static BuildResult PrepareResourceRules (IProgressMonitor monitor, IPhoneSdkVersion sdkVersion, IPhoneProjectConfiguration conf, out string resRulesFile)
		{
			resRulesFile = conf.AppDirectory.Combine ("ResourceRules.plist");
			
			monitor.BeginTask (GettextCatalog.GetString ("Preparing resources rules"), 0);
			
			if (File.Exists (resRulesFile))
				File.Delete (resRulesFile);
			
			string resRulesSrc = String.IsNullOrEmpty (conf.CodesignResourceRules)
				? "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS"
					+ sdkVersion.ToString () + ".sdk/ResourceRules.plist"
				: (string) conf.CodesignResourceRules;
			if (File.Exists (resRulesSrc)) {
				File.Copy (resRulesSrc, resRulesFile, true);
			} else {
				return BuildError ("Resources rules file \"" + conf.CodesignResourceRules + "\" not found.");
			}
			
			monitor.EndTask ();
			return null;
		}
Example #18
0
        public override bool Execute()
        {
            PDictionary plist;

            Log.LogTaskName ("CompileAppManifest");
            Log.LogTaskProperty ("AppBundleName", AppBundleName);
            Log.LogTaskProperty ("AppBundleDir", AppBundleDir);
            Log.LogTaskProperty ("AppManifest", AppManifest);
            Log.LogTaskProperty ("Architecture", Architecture);
            Log.LogTaskProperty ("AssemblyName", AssemblyName);
            Log.LogTaskProperty ("BundleIdentifier", BundleIdentifier);
            Log.LogTaskProperty ("DefaultSdkVersion", DefaultSdkVersion);
            Log.LogTaskProperty ("IsAppExtension", IsAppExtension);
            Log.LogTaskProperty ("IsWatchApp", IsWatchApp);
            Log.LogTaskProperty ("IsWatchExtension", IsWatchExtension);
            Log.LogTaskProperty ("PartialAppManifests", PartialAppManifests);
            Log.LogTaskProperty ("ResourceRules", ResourceRules);
            Log.LogTaskProperty ("SdkPlatform", SdkPlatform);
            Log.LogTaskProperty ("SdkIsSimulator", SdkIsSimulator);
            Log.LogTaskProperty ("TargetFrameworkIdentifier", TargetFrameworkIdentifier);

            try {
                plist = PDictionary.FromFile (AppManifest);
            } catch (Exception ex) {
                LogAppManifestError ("Error loading '{0}': {1}", AppManifest, ex.Message);
                return false;
            }

            sdkVersion = IPhoneSdkVersion.Parse (DefaultSdkVersion);
            var text = plist.GetMinimumOSVersion ();
            if (string.IsNullOrEmpty (text)) {
                minimumOSVersion = sdkVersion;
            } else if (!IPhoneSdkVersion.TryParse (text, out minimumOSVersion)) {
                LogAppManifestError ("Could not parse MinimumOSVersion value '{0}'", text);
                return false;
            }

            switch (Framework) {
            case PlatformFramework.iOS:
                IsIOS = true;
                break;
            case PlatformFramework.WatchOS:
                break;
            case PlatformFramework.TVOS:
                break;
            default:
                throw new InvalidOperationException (string.Format ("Invalid framework: {0}", Framework));
            }

            return Compile (plist);
        }
		static internal void AppendExtrasMtouchArgs (ProcessArgumentBuilder args, IPhoneSdkVersion sdkVersion, 
			IPhoneProject proj, IPhoneProjectConfiguration conf)
		{
			if (conf.MtouchDebug)
				args.Add ("-debug");
			
			switch (conf.MtouchLink) {
			case MtouchLinkMode.SdkOnly:
				args.Add ("-linksdkonly");
				break;
			case MtouchLinkMode.None:
				args.Add ("-nolink");
				break;
			case MtouchLinkMode.Full:
			default:
				break;
			}
			
			if (!string.IsNullOrEmpty (conf.MtouchI18n)) {
				args.AddQuotedFormat ("-i18n={0}", conf.MtouchI18n);
			}
			
			if (!sdkVersion.Equals (IPhoneSdkVersion.V3_0))
				args.AddQuotedFormat ("-sdk={0}", sdkVersion);
			
			if (conf.MtouchMinimumOSVersion != "3.0")
				args.AddQuotedFormat ("-targetver={0}", conf.MtouchMinimumOSVersion);
			
			if (IPhoneFramework.MonoTouchVersion >= new IPhoneSdkVersion (3, 99)) {
				if (conf.MtouchUseSGen)
					args.Add ("--sgen");
				if (conf.MtouchUseLlvm) {
					args.Add ("--llvm");
					switch (conf.MtouchArch) {
					case MtouchArch.ARMv6_ARMv7:
						args.Add ("--fat");
						break;
					case MtouchArch.ARMv7:
						args.Add ("--armv7");
						break;
					}
					if (conf.MtouchArch != MtouchArch.ARMv6 && conf.MtouchUseThumb)
						args.Add ("--thumb");
				}
			}
			
			AddExtraArgs (args, conf.MtouchExtraArgs, proj, conf);
		}
Example #20
0
		public static bool SdkIsInstalled (IPhoneSdkVersion version)
		{
			return SdkIsInstalled (version.ToString ());
		}
		BuildResult UpdateInfoPlist (IProgressMonitor monitor, IPhoneSdkVersion sdkVersion, IPhoneProject proj,
			IPhoneProjectConfiguration conf, IPhoneAppIdentity identity, ProjectFile template, string plistOut)
		{
			return MacBuildUtilities.CreateMergedPlist (monitor, template, plistOut, (PlistDocument doc) => {
				var result = new BuildResult ();
				var dict = doc.Root as PlistDictionary;
				if (dict == null)
					doc.Root = dict = new PlistDictionary ();
				
				bool sim = conf.Platform != IPhoneProject.PLAT_IPHONE;
				bool v3_2_orNewer = sdkVersion >= IPhoneSdkVersion.V3_2;
				bool v3_1_orNewer = sdkVersion >= IPhoneSdkVersion.V3_1;
				bool v4_0_orNewer = sdkVersion >= IPhoneSdkVersion.V4_0;
				bool supportsIPhone = (proj.SupportedDevices & TargetDevice.IPhone) != 0;
				bool supportsIPad = (proj.SupportedDevices & TargetDevice.IPad) != 0;
				
				var sdkSettings = IPhoneFramework.GetSdkSettings (sdkVersion);
				var dtSettings = IPhoneFramework.GetDTSettings ();
				
				SetIfNotPresent (dict, "BuildMachineOSBuild", dtSettings.BuildMachineOSBuild);
				
				SetIfNotPresent (dict, "CFBundleDevelopmentRegion",
					String.IsNullOrEmpty (proj.BundleDevelopmentRegion)? "en" : proj.BundleDevelopmentRegion);
				
				SetIfNotPresent (dict, "CFBundleDisplayName", proj.BundleDisplayName ?? proj.Name);
				SetIfNotPresent (dict, "CFBundleExecutable", conf.NativeExe.FileName);
				
				// < 3.2 icon
				if (supportsIPhone) {
					if (!dict.ContainsKey ("CFBundleIconFile")) {
						var icon = proj.BundleIcon.ToRelative (proj.BaseDirectory);
						if (icon.IsNullOrEmpty || icon.ToString () == ".")
							result.AddWarning ("Application bundle icon has not been set (iPhone Application options panel)");
						else
							dict ["CFBundleIconFile"] = icon.FileName;
					}
				}
				
				//newer icons - see http://developer.apple.com/library/ios/#qa/qa2010/qa1686.html
				if (v3_2_orNewer && !dict.ContainsKey ("CFBundleIconFiles")) {
					var arr = new PlistArray ();
					dict["CFBundleIconFiles"] = arr;
					
					if (supportsIPhone)
						AddIconRelativeIfNotEmpty (proj, arr, proj.BundleIcon, "Icon.png");
					
					if (v4_0_orNewer && supportsIPhone)
						if (!AddIconRelativeIfNotEmpty (proj, arr, proj.BundleIconHigh, "*****@*****.**"))
							result.AddWarning ("iPhone high res bundle icon has not been set (iPhone Application options panel)");
					
					if (supportsIPad)
						if (!AddIconRelativeIfNotEmpty (proj, arr, proj.BundleIconIPad, "Icon-72.png"))
							result.AddWarning ("iPad bundle icon has not been set (iPhone Application options panel)");
					
					AddIconRelativeIfNotEmpty (proj, arr, proj.BundleIconSpotlight, "Icon-Small.png");
					
					if (supportsIPad)
						AddIconRelativeIfNotEmpty (proj, arr, proj.BundleIconIPadSpotlight, "Icon-Small-50.png");
					
					if (v4_0_orNewer && supportsIPhone)
						AddIconRelativeIfNotEmpty (proj, arr, proj.BundleIconSpotlightHigh, "*****@*****.**");
				}
				
				SetIfNotPresent (dict, "CFBundleIdentifier", identity.BundleID);
				SetIfNotPresent (dict, "CFBundleInfoDictionaryVersion", "6.0");
				SetIfNotPresent (dict, "CFBundleName", proj.Name);
				SetIfNotPresent (dict, "CFBundlePackageType", "APPL");
				if (!sim)
					dict["CFBundleResourceSpecification"] = "ResourceRules.plist";
				SetIfNotPresent (dict, "CFBundleSignature", "????");
				SetIfNotPresent (dict,  "CFBundleSupportedPlatforms",
					new PlistArray () { sim? "iPhoneSimulator" : "iPhoneOS" });
				SetIfNotPresent (dict, "CFBundleVersion", proj.BundleVersion ?? "1.0");
				
				if (!sim) {
					SetIfNotPresent (dict, "DTCompiler", sdkSettings.DTCompiler);
					SetIfNotPresent (dict, "DTPlatformBuild", dtSettings.DTPlatformBuild);
					SetIfNotPresent (dict, "DTSDKBuild", sdkSettings.DTSDKBuild);
				}
				SetIfNotPresent (dict, "DTPlatformName", sim? "iphonesimulator" : "iphoneos");
				if (!sim) {
					SetIfNotPresent (dict, "DTPlatformVersion", dtSettings.DTPlatformVersion);
				}
				SetIfNotPresent (dict, "DTSDKName", sim? sdkSettings.AlternateSDK : sdkSettings.CanonicalName);
				if (!sim) {
					SetIfNotPresent (dict, "DTXcode", dtSettings.DTXcode);
					SetIfNotPresent (dict, "DTXcodeBuild", dtSettings.DTXcodeBuild);
				}
				
				SetIfNotPresent (dict,  "LSRequiresIPhoneOS", true);
				if (v3_2_orNewer)
					SetIfNotPresent (dict,  "UIDeviceFamily", GetSupportedDevices (proj.SupportedDevices));
				
				if (v3_1_orNewer) {
					if (conf.MtouchArch != MtouchArch.ARMv6_ARMv7) {
						var val = conf.MtouchArch == MtouchArch.ARMv6? "armv6" : "armv7";
						var key = "UIRequiredDeviceCapabilities";
						var caps = dict.TryGetValue (key) ?? (dict[key] = new PlistArray ());
						var a = caps as PlistArray;
						if (a != null) {
							a.Add (val);
						} else {
							var d = (PlistDictionary) caps;
							d[val] = new PlistBoolean (true);
						}
					}
				}
				
				SetIfNotPresent (dict, "MinimumOSVersion", conf.MtouchMinimumOSVersion);
				
				SetNibProperty (dict, proj, proj.MainNibFile, "NSMainNibFile");
				if (proj.SupportedDevices == TargetDevice.IPhoneAndIPad)
					SetNibProperty (dict, proj, proj.MainNibFileIPad, "NSMainNibFile~ipad");
				
				
				if (v3_2_orNewer) {
					if (!dict.ContainsKey (OrientationUtil.KEY)) {
						result.AddWarning ("Supported orientations have not been set (iPhone Application options panel)");
					} else {
						var val = OrientationUtil.Parse ((PlistArray)dict[OrientationUtil.KEY]);
						if (!OrientationUtil.IsValidPair (val))
							result.AddWarning ("Supported orientations are not matched pairs (Info.plist)");
						if (dict.ContainsKey (OrientationUtil.KEY_IPAD)) {
							var pad = OrientationUtil.Parse ((PlistArray)dict[OrientationUtil.KEY_IPAD]);
							if (pad != Orientation.None && !OrientationUtil.IsValidPair (pad))
								result.AddWarning ("iPad orientations are not matched pairs (Info.plist)");
						}
					}
				}   
				
				return result;
			});
		}
Example #22
0
		public static string GetDTSdkName (IPhoneSdkVersion sdk, bool sim)
		{
			var cache = sim? dtSdkNameSim : dtSdkName;
			string name;
			if (cache.TryGetValue (sdk.ToString (), out name))
				return name;
			
			string keyName = sim? "AlternateSDK" : "CanonicalName";
			var doc = LoadSdkSettings (sdk);
			var dict = (PlistDictionary) doc.Root;
			return cache[sdk.ToString ()] = ((PlistString) dict[keyName]).Value;
		}
Example #23
0
        public override bool Execute()
        {
            PDictionary plist;
            PString     value;

            try {
                plist = PDictionary.FromFile(AppManifest.ItemSpec);
            } catch (Exception ex) {
                Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, MSBStrings.E0055, ex.Message);
                return(false);
            }

//			deviceType = plist.GetUIDeviceFamily ();

            if (plist.TryGetValue(ManifestKeys.MinimumOSVersion, out value))
            {
                if (!IPhoneSdkVersion.TryParse(value.Value, out minimumOSVersion))
                {
                    Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, MSBStrings.E0011, value);
                    return(false);
                }
            }
            else
            {
                switch (Framework)
                {
                case ApplePlatform.iOS:
                    IPhoneSdkVersion sdkVersion;
                    if (!IPhoneSdkVersion.TryParse(SdkVersion, out sdkVersion))
                    {
                        Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, MSBStrings.E0056, SdkVersion);
                        return(false);
                    }

                    minimumOSVersion = sdkVersion;
                    break;

                case ApplePlatform.WatchOS:
                case ApplePlatform.TVOS:
                    minimumOSVersion = IPhoneSdkVersion.UseDefault;
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Invalid framework: {0}", Framework));
                }
            }

            Directory.CreateDirectory(AppBundleDir);

            var executableLastWriteTime = default(DateTime);
            var executable = Path.Combine(AppBundleDir, ExecutableName);

            if (File.Exists(executable))
            {
                executableLastWriteTime = File.GetLastWriteTimeUtc(executable);
            }

            var result = base.Execute();

            CopiedFrameworks = GetCopiedFrameworks();

            if (File.Exists(executable) && File.GetLastWriteTimeUtc(executable) != executableLastWriteTime)
            {
                NativeExecutable = new TaskItem(executable);
            }

            return(result);
        }