public static ProcessStartInfo CreateMtouchSimStartInfo (IPhoneExecutionCommand cmd, bool logSimOutput, IPhoneSimulatorTarget forceTarget) { string mtouchPath = cmd.Runtime.GetToolPath (cmd.Framework, "mtouch"); if (string.IsNullOrEmpty (mtouchPath)) throw new InvalidOperationException ("Cannot execute iPhone application. mtouch tool is missing."); var outLog = cmd.OutputLogPath; var errLog = cmd.ErrorLogPath; try { if (File.Exists (errLog)) File.Delete (errLog); if (File.Exists (outLog)) File.Delete (outLog); } catch (IOException) {} var cb = new ProcessArgumentBuilder (); cb.AddQuotedFormat ("-launchsim={0}", cmd.AppPath); if (logSimOutput) { cb.AddQuotedFormat ("-stderr={0}", errLog); cb.AddQuotedFormat ("-stdout={0}", outLog); } if (forceTarget != null) { var version = forceTarget.Version; if (!version.IsUseDefault && !IPhoneFramework.SdkIsInstalled (version, true)) { version = IPhoneFramework.GetClosestInstalledSdk (version, true); LoggingService.LogWarning ("iOS SDK '{0}' not installed, falling back to simulator '{1}'", forceTarget.Version, version); } if (!version.IsUseDefault) cb.AddQuotedFormat ("-sdk={0}", forceTarget.Version); if (forceTarget.Device == TargetDevice.IPad) cb.Add ("-device=2"); } var psi = new ProcessStartInfo (mtouchPath, cb.ToString ()) { WorkingDirectory = cmd.LogDirectory, UseShellExecute = false }; return psi; }
void GenerateXCodeProject (IPhoneProject proj, IPhoneProjectConfiguration conf, ConfigurationSelector slnConf) { string mtouchPath = IPhoneUtility.GetMtouchPath (proj.TargetRuntime, proj.TargetFramework); var xcodeDir = conf.OutputDirectory.Combine ("XcodeProject"); if (!Directory.Exists (xcodeDir)) { try { Directory.CreateDirectory (xcodeDir); } catch (IOException ex) { MessageService.ShowException (ex, "Failed to create directory '" + xcodeDir +"' for Xcode project"); return; } } var args = new ProcessArgumentBuilder (); args.AddQuotedFormat ("-xcode={0}", xcodeDir); args.Add ("-v"); foreach (ProjectFile pf in proj.Files) { if (pf.BuildAction == BuildAction.Content) { var rel = pf.ProjectVirtualPath; args.AddQuotedFormat ("-res={0},{1}", pf.FilePath, rel); //hack around mtouch 1.0 bug. create resource directories string subdir = rel.ParentDirectory; if (string.IsNullOrEmpty (subdir)) continue; subdir = xcodeDir.Combine (subdir); try { if (!Directory.Exists (subdir)) Directory.CreateDirectory (subdir); } catch (IOException ex) { MessageService.ShowException (ex, "Failed to create directory '" + subdir +"' for Xcode project"); return; } } else if (pf.BuildAction == BuildAction.Page) { args.AddQuotedFormat ("-res={0}", pf.FilePath); } } args.AddQuotedFormat ("-res={0},Info.plist", conf.AppDirectory.Combine ("Info.plist")); foreach (string asm in proj.GetReferencedAssemblies (slnConf).Distinct ()) args.AddQuotedFormat ("-r={0}", asm); var sdkVersion = conf.MtouchSdkVersion.ResolveIfDefault (); if (!IPhoneFramework.SdkIsInstalled (sdkVersion)) sdkVersion = IPhoneFramework.GetClosestInstalledSdk (sdkVersion); IPhoneBuildExtension.AppendExtrasMtouchArgs (args, sdkVersion, proj, conf); args.AddQuoted (conf.CompiledOutputName); string argStr = args.ToString (); var console = (IConsole) IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor ( GettextCatalog.GetString ("Generate Xcode project"), MonoDevelop.Ide.Gui.Stock.RunProgramIcon, true, true); console.Log.WriteLine (mtouchPath + " " + argStr); Runtime.ProcessService.StartConsoleProcess (mtouchPath, argStr, conf.OutputDirectory, console, null); }
protected override BuildResult Build (IProgressMonitor monitor, SolutionEntityItem item, ConfigurationSelector configuration) { IPhoneProject proj = item as IPhoneProject; if (proj == null || proj.CompileTarget != CompileTarget.Exe) return base.Build (monitor, item, configuration); IPhoneFramework.CheckInfoCaches (); //prebuild var conf = (IPhoneProjectConfiguration) proj.GetConfiguration (configuration); bool isDevice = conf.Platform == IPhoneProject.PLAT_IPHONE; if (IPhoneFramework.SimOnly && isDevice) { //if in the GUI, show a dialog too if (MonoDevelop.Ide.IdeApp.IsInitialized) Gtk.Application.Invoke (delegate { IPhoneFramework.ShowSimOnlyDialog (); } ); return IPhoneFramework.GetSimOnlyError (); } var result = new BuildResult (); var sdkVersion = conf.MtouchSdkVersion.ResolveIfDefault (); if (!IPhoneFramework.SdkIsInstalled (sdkVersion)) { sdkVersion = IPhoneFramework.GetClosestInstalledSdk (sdkVersion); if (sdkVersion.IsUseDefault || !IPhoneFramework.SdkIsInstalled (sdkVersion)) { if (conf.MtouchSdkVersion.IsUseDefault) result.AddError ( string.Format ("The Apple iPhone SDK is not installed.")); else result.AddError ( string.Format ("Apple iPhone SDK version '{0}' is not installed, and no newer version was found.", conf.MtouchSdkVersion)); return result; } result.AddWarning ( string.Format ("Apple iPhone SDK version '{0}' is not installed. Using newer version '{1}' instead'.", conf.MtouchSdkVersion, sdkVersion)); } IPhoneAppIdentity identity = null; if (isDevice) { monitor.BeginTask (GettextCatalog.GetString ("Detecting signing identity..."), 0); if ((result = GetIdentity (monitor, proj, conf, out identity).Append (result)).ErrorCount > 0) return result; monitor.Log.WriteLine ("Provisioning profile: \"{0}\" ({1})", identity.Profile.Name, identity.Profile.Uuid); monitor.Log.WriteLine ("Signing Identity: \"{0}\"", Keychain.GetCertificateCommonName (identity.SigningKey)); monitor.Log.WriteLine ("App ID: \"{0}\"", identity.AppID); monitor.EndTask (); } else { identity = new IPhoneAppIdentity () { BundleID = !string.IsNullOrEmpty (proj.BundleIdentifier)? proj.BundleIdentifier : GetDefaultBundleID (proj, null) }; } result = base.Build (monitor, item, configuration).Append (result); if (result.ErrorCount > 0) return result; if (!Directory.Exists (conf.AppDirectory)) Directory.CreateDirectory (conf.AppDirectory); var assemblyRefs = proj.GetReferencedAssemblies (configuration).Distinct ().ToList (); FilePath mtouchOutput = conf.NativeExe; if (new FilePair (conf.CompiledOutputName, mtouchOutput).NeedsBuilding ()) { BuildResult error; var mtouch = GetMTouch (proj, monitor, out error); if (error != null) return error.Append (result); var args = new ProcessArgumentBuilder (); //FIXME: make verbosity configurable? args.Add ("-v"); args.Add ("--nomanifest", "--nosign"); //FIXME: should we error out if the platform is invalid? if (conf.Platform == IPhoneProject.PLAT_IPHONE) { args.Add ("-dev"); args.AddQuoted (conf.AppDirectory); } else { args.Add ("-sim"); args.AddQuoted (conf.AppDirectory); } foreach (string asm in assemblyRefs) args.AddQuotedFormat ("-r={0}", asm); IPhoneSdkVersion osVersion = IPhoneSdkVersion.V3_0; try { osVersion = IPhoneSdkVersion.Parse (conf.MtouchMinimumOSVersion); } catch { result.AddWarning ("Could not parse minimum OS version '" + conf.MtouchMinimumOSVersion + "'"); } if (osVersion < IPhoneSdkVersion.V3_0 && conf.MtouchArch == MtouchArch.ARMv7) { result.AddError ("Apps with a minimum OS older than 3.1 cannot be ARMv7 only"); return result; } AppendExtrasMtouchArgs (args, sdkVersion, proj, conf); args.AddQuoted (conf.CompiledOutputName); mtouch.WorkingDirectory = conf.OutputDirectory; mtouch.Arguments = args.ToString (); monitor.BeginTask (GettextCatalog.GetString ("Compiling to native code"), 0); string output; int code; monitor.Log.WriteLine ("{0} {1}", mtouch.FileName, mtouch.Arguments); if ((code = MacBuildUtilities.ExecuteCommand (monitor, mtouch, out output)) != 0) { if (String.IsNullOrEmpty (output)) { result.AddError (null, 0, 0, code.ToString (), "mtouch failed with no output"); } else { result.AddError (null, 0, 0, code.ToString (), "mtouch failed with the following message:\n" + output); } return result; } monitor.EndTask (); } //unpack nibs and content from dll resources (MT 4+ only) if (IPhoneFramework.MonoTouchVersion >= new IPhoneSdkVersion (3, 99)) if (result.Append (UnpackContent (monitor, conf, assemblyRefs)).ErrorCount > 0) return result; //create the info.plist, merging in the template if it exists var plistOut = conf.AppDirectory.Combine ("Info.plist"); ProjectFile appInfoIn = proj.Files.GetFile (proj.BaseDirectory.Combine ("Info.plist")); if (new FilePair (proj.FileName, plistOut).NeedsBuilding () || (appInfoIn != null && new FilePair (appInfoIn.FilePath, plistOut).NeedsBuilding ())) { try { monitor.BeginTask (GettextCatalog.GetString ("Updating application manifest"), 0); if (result.Append (UpdateInfoPlist (monitor, sdkVersion, proj, conf, identity, appInfoIn, plistOut)).ErrorCount > 0) return result; } finally { monitor.EndTask (); } } //create the Setting.bundle plist for debug settings, merging in the template if it exists try { monitor.BeginTask (GettextCatalog.GetString ("Updating debug settings manifest"), 0); var sbRootRel = Path.Combine ("Settings.bundle", "Root.plist"); var sbRootOut = conf.AppDirectory.Combine (sbRootRel); var sbRootIn = proj.Files.GetFile (proj.BaseDirectory.Combine (sbRootRel)); if (result.Append (UpdateDebugSettingsPlist (monitor, conf, sbRootIn, sbRootOut)).ErrorCount > 0) return result; } finally { monitor.EndTask (); } try { if (result.Append (ProcessPackaging (monitor, sdkVersion, proj, conf, identity)).ErrorCount > 0) return result; } finally { //if packaging failed, make sure that it's marked as needing building if (result.ErrorCount > 0 && File.Exists (conf.AppDirectory.Combine ("PkgInfo"))) File.Delete (conf.AppDirectory.Combine ("PkgInfo")); } //TODO: create/update the xcode project return result; }
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); }
static BuildResult SignAppBundle (IProgressMonitor monitor, IPhoneProject proj, IPhoneProjectConfiguration conf, X509Certificate2 key, string resRules, string xcent) { monitor.BeginTask (GettextCatalog.GetString ("Signing application"), 0); var args = new ProcessArgumentBuilder (); args.Add ("-v", "-f", "-s"); args.AddQuoted (Keychain.GetCertificateCommonName (key)); args.AddQuotedFormat ("--resource-rules={0}", resRules); args.Add ("--entitlements"); args.AddQuoted (xcent); args.AddQuoted (conf.AppDirectory); AddExtraArgs (args, conf.CodesignExtraArgs, proj, conf); int signResultCode; var psi = new ProcessStartInfo ("codesign") { UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, Arguments = args.ToString (), }; monitor.Log.WriteLine ("codesign " + psi.Arguments); psi.EnvironmentVariables.Add ("CODESIGN_ALLOCATE", "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate"); string output; if ((signResultCode = MacBuildUtilities.ExecuteCommand (monitor, psi, out output)) != 0) { monitor.Log.WriteLine (output); return BuildError (string.Format ("Code signing failed with error code {0}. See output for details.", signResultCode)); } monitor.EndTask (); return null; }
void AddDirArgs (ProcessArgumentBuilder pb) { foreach (var dir in HelpService.Sources) pb.AddQuotedFormat ("--docdir={0}", dir); }
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); }