예제 #1
0
		public static BuildResult CompileXibFiles (IProgressMonitor monitor, IEnumerable<ProjectFile> files,
		                                           FilePath outputRoot)
		{
			var result = new BuildResult ();
			var ibfiles = GetIBFilePairs (files, outputRoot).Where (NeedsBuilding).ToList ();
			
			if (ibfiles.Count > 0) {
				monitor.BeginTask (GettextCatalog.GetString ("Compiling interface definitions"), 0);	
				foreach (var file in ibfiles) {
					file.EnsureOutputDirectory ();
					var args = new ProcessArgumentBuilder ();
					args.AddQuoted (file.Input);
					args.Add ("--compile");
					args.AddQuoted (file.Output);
					var psi = new ProcessStartInfo ("ibtool", args.ToString ());
					monitor.Log.WriteLine (psi.FileName + " " + psi.Arguments);
					psi.WorkingDirectory = outputRoot;
					string errorOutput;
					int code;
					try {
					code = ExecuteCommand (monitor, psi, out errorOutput);
					} catch (System.ComponentModel.Win32Exception ex) {
						LoggingService.LogError ("Error running ibtool", ex);
						result.AddError (null, 0, 0, null, "ibtool not found. Please ensure the Apple SDK is installed.");
						return result;
					}
					if (code != 0) {
						//FIXME: parse the plist that ibtool returns
						result.AddError (null, 0, 0, null, "ibtool returned error code " + code);
					}
				}
				monitor.EndTask ();
			}
			return result;
		}
        public static string GetInterpreterArguments(PythonConfiguration config)
        {
            if (config == null)
                throw new ArgumentNullException ("configuration");

            var args = new ProcessArgumentBuilder ();
            args.Add ("-m");
            args.AddQuoted (config.MainModule);
            args.Add ("-u");

            if (config.Optimize)
                args.Add ("-O");

            if (config.LangVersion == LangVersion.Python30)
                args.Add ("-X:Python30");

            if (config.ShowExceptionDetails)
                args.Add ("-X:ExceptionDetail");

            if (config.ShowClrExceptions)
                args.Add ("-X:ShowClrExceptions");

            if (!String.IsNullOrEmpty (config.InterpreterArguments))
                args.Add (config.InterpreterArguments);

            return args.ToString ();
        }
예제 #3
0
		public BuildResult Build (ProgressMonitor monitor, ConfigurationSelector configuration)
		{
			BuildResult results = new BuildResult ("", 0, 0);
			
			string moFileName  = GetOutFile (configuration);
			string moDirectory = Path.GetDirectoryName (moFileName);
			if (!Directory.Exists (moDirectory))
				Directory.CreateDirectory (moDirectory);
			
			var pb = new ProcessArgumentBuilder ();
			pb.AddQuoted (PoFile);
			pb.Add ("-o");
			pb.AddQuoted (moFileName);
			
			ProcessWrapper process = null;
			try {
				process = Runtime.ProcessService.StartProcess (GetTool ("msgfmt"), pb.ToString (),
					parentProject.BaseDirectory, monitor.Log, monitor.Log, null);
			} catch (System.ComponentModel.Win32Exception) {
				var msg = GettextCatalog.GetString ("Did not find msgfmt. Please ensure that gettext tools are installed.");
				monitor.ReportError (msg, null);
				results.AddError (msg);
				return results;
			}
			
			process.WaitForOutput ();

			if (process.ExitCode == 0) {
				monitor.Log.WriteLine (GettextCatalog.GetString ("Translation {0}: Compilation succeeded.", IsoCode));
			} else {
				string message = GettextCatalog.GetString ("Translation {0}: Compilation failed. See log for details.", IsoCode);
				monitor.Log.WriteLine (message);
				results.AddError (PoFile, 1, 1, "", message);
				results.FailedBuildCount = 1;
			}
			return results;
		}
예제 #4
0
		public void UpdateTranslations (IProgressMonitor monitor, params Translation[] translations)
		{
			monitor.BeginTask (null, Translations.Count + 1);
			
			try {
				List<Project> projects = new List<Project> ();
				foreach (Project p in ParentSolution.GetAllProjects ()) {
					if (IsIncluded (p))
						projects.Add (p);
				}
				monitor.BeginTask (GettextCatalog.GetString ("Updating message catalog"), projects.Count);
				CreateDefaultCatalog (monitor);
				monitor.Log.WriteLine (GettextCatalog.GetString ("Done"));
			} finally { 
				monitor.EndTask ();
				monitor.Step (1);
			}
			if (monitor.IsCancelRequested) {
				monitor.Log.WriteLine (GettextCatalog.GetString ("Operation cancelled."));
				return;
			}
			
			Dictionary<string, bool> isIncluded = new Dictionary<string, bool> ();
			foreach (Translation translation in translations) {
				isIncluded[translation.IsoCode] = true;
			}
			foreach (Translation translation in this.Translations) {
				if (!isIncluded.ContainsKey (translation.IsoCode))
					continue;
				string poFileName  = translation.PoFile;
				monitor.BeginTask (GettextCatalog.GetString ("Updating {0}", translation.PoFile), 1);
				try {
					var pb = new ProcessArgumentBuilder ();
					pb.Add ("-U");
					pb.AddQuoted (poFileName);
					pb.Add ("-v");
					pb.AddQuoted (this.BaseDirectory.Combine ("messages.po"));
					
					var process = Runtime.ProcessService.StartProcess (Translation.GetTool ("msgmerge"),
						pb.ToString (), this.BaseDirectory, monitor.Log, monitor.Log, null);
					process.WaitForOutput ();
				}
				catch (System.ComponentModel.Win32Exception) {
					var msg = GettextCatalog.GetString ("Did not find msgmerge. Please ensure that gettext tools are installed.");
					monitor.ReportError (msg, null);
				}
				catch (Exception ex) {
					monitor.ReportError (GettextCatalog.GetString ("Could not update file {0}", translation.PoFile), ex);
				}
				finally {
					monitor.EndTask ();
					monitor.Step (1);
				}
				if (monitor.IsCancelRequested) {
					monitor.Log.WriteLine (GettextCatalog.GetString ("Operation cancelled."));
					return;
				}
			}
		}
예제 #5
0
		public static BuildResult CompileXibFiles (IProgressMonitor monitor, IEnumerable<ProjectFile> files,
			FilePath outputRoot)
		{
			var result = new BuildResult ();
			var ibfiles = GetIBFilePairs (files, outputRoot).Where (NeedsBuilding).ToList ();
			
			if (ibfiles.Count > 0) {
				monitor.BeginTask (GettextCatalog.GetString ("Compiling interface definitions"), 0);
				foreach (var file in ibfiles) {
					file.EnsureOutputDirectory ();
					var args = new ProcessArgumentBuilder ();
					args.Add ("--errors", "--warnings", "--notices", "--output-format", "human-readable-text");
					args.AddQuoted (file.Input);
					args.Add ("--compile");
					args.AddQuoted (file.Output);
					var ibtoolPath = AppleSdkSettings.DeveloperRoot.Combine ("usr", "bin", "ibtool");
					var psi = new ProcessStartInfo (ibtoolPath, args.ToString ());
					monitor.Log.WriteLine (psi.FileName + " " + psi.Arguments);
					int code;
					try {
						code = MacBuildUtilities.ExecuteBuildCommand (monitor, psi);
					} catch (System.ComponentModel.Win32Exception ex) {
						LoggingService.LogError ("Error running ibtool", ex);
						result.AddError (null, 0, 0, null, "ibtool not found. Please ensure the Apple SDK is installed.");
						return result;
					}
					if (monitor.IsCancelRequested)
						return result;
					
					if (code != 0) {
						result.AddError (null, 0, 0, null, "ibtool returned error code " + code);
						return result;
					}
				}
				monitor.EndTask ();
			}
			return result;
		}
예제 #6
0
		public static bool BuildPackage (IProgressMonitor monitor, MonoMacProject project,
			ConfigurationSelector conf, MonoMacPackagingSettings settings, FilePath target)
		{
			string bundleKey = settings.BundleSigningKey;
			string packageKey = settings.PackageSigningKey;
			
			if (settings.SignBundle || (settings.CreatePackage && settings.SignPackage)) {
				var identities = Keychain.GetAllSigningIdentities ();
				
				if (string.IsNullOrEmpty (bundleKey)) {
					bundleKey = identities.FirstOrDefault (k => k.StartsWith (MonoMacPackagingSettingsWidget.APPLICATION_PREFIX));
					if (string.IsNullOrEmpty (bundleKey)) {
						monitor.ReportError ("Did not find default app signing key", null);
						return false;
					} else if (!identities.Any (k => k == bundleKey)) {
						monitor.ReportError ("Did not find app signing key in keychain", null);
						return false;
					}
				}
				
				if (string.IsNullOrEmpty (packageKey)) {
					packageKey = identities.FirstOrDefault (k => k.StartsWith (MonoMacPackagingSettingsWidget.INSTALLER_PREFIX));
					if (string.IsNullOrEmpty (packageKey)) {
						monitor.ReportError ("Did not find default package signing key", null);
						return false;
					} else if (!identities.Any (k => k == packageKey)) {
						monitor.ReportError ("Did not find package signing key in keychain", null);
						return false;
					}
				}
			}
			
			if (project.NeedsBuilding (conf)) {
				BuildResult res = project.Build (monitor, conf);
				if (res.ErrorCount > 0) {
					foreach (BuildError e in res.Errors)
						monitor.ReportError (e.ToString (), null);
					monitor.ReportError (GettextCatalog.GetString ("The project failed to build."), null);
					return false;
				}
			}
			
			var cfg = (MonoMacProjectConfiguration) project.GetConfiguration (conf);
			
			FilePath tempDir = "/tmp/monomac-build-" + DateTime.Now.Ticks;
			FilePath workingApp = tempDir.Combine (cfg.AppDirectory.FileName);
			
			try {
				//user will have agreed to overwrite when they picked the target
				if (Directory.Exists (target))
					Directory.Delete (target, true);
				else if (File.Exists (target))
					File.Delete (target);
				
				monitor.BeginTask (GettextCatalog.GetString ("Creating app bundle"), 0);
				var files = Directory.GetFiles (cfg.AppDirectory, "*", SearchOption.AllDirectories);
				HashSet<string> createdDirs = new HashSet<string> ();
				foreach (FilePath f in files) {
					var rel = f.ToRelative (cfg.AppDirectory);
					var parentDir = rel.ParentDirectory;
					if (settings.IncludeMono) {
						if (parentDir.IsNullOrEmpty || parentDir == "." || parentDir == "Contents/MacOS")
							continue;
						var ext = rel.Extension;
						if (ext == ".mdb" || ext == ".exe" || ext == ".dll")
							continue;
					}
					if (monitor.IsCancelRequested)
						return false;
					if (createdDirs.Add (parentDir))
						Directory.CreateDirectory (workingApp.Combine (parentDir));
					monitor.Log.WriteLine (rel);
					File.Copy (f, workingApp.Combine (rel));
				}
				monitor.EndTask ();
				
				if (settings.IncludeMono) {
					monitor.BeginTask (GettextCatalog.GetString ("Merging Mono into app bundle"), 0);
					
					var args = new ProcessArgumentBuilder ();
					switch (settings.LinkerMode){
					case MonoMacLinkerMode.LinkNone:
						args.Add ("--nolink");
						break;
						
					case MonoMacLinkerMode.LinkFramework:
						args.Add ("--linksdkonly");
						break;
						
					case MonoMacLinkerMode.LinkAll:
						// nothing
						break;
					}
					
					args.Add ("-o");
					args.AddQuoted (tempDir);
					args.Add ("-n");
					args.AddQuoted (cfg.AppName);
					
					var assemblies = project.GetReferencedAssemblies (conf, true);
					foreach (var a in assemblies) {
						args.Add ("-a");
						args.AddQuoted (a);
					}
					args.AddQuoted (cfg.CompiledOutputName);
					
					string mmpPath = Mono.Addins.AddinManager.CurrentAddin.GetFilePath ("mmp");
					
					//FIXME: workaround for Mono.Addins losing the executable bit during packaging
					var mmpInfo = new Mono.Unix.UnixFileInfo (mmpPath);
					if ((mmpInfo.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserExecute) == 0)
						mmpInfo.FileAccessPermissions |=  Mono.Unix.FileAccessPermissions.UserExecute;
					
					var psi = new ProcessStartInfo (mmpPath, args.ToString ());
					if (MacBuildUtilities.ExecuteBuildCommand (monitor, psi) != 0) {
						monitor.ReportError ("Merging Mono failed", null);
						return false;
					}
					
					var plistFile = workingApp.Combine ("Contents", "Info.plist");
					var plistDoc = new PlistDocument ();
					plistDoc.LoadFromXmlFile (plistFile);
					((PlistDictionary)plistDoc.Root)["MonoBundleExecutable"] = cfg.CompiledOutputName.FileName;
					plistDoc.WriteToFile (plistFile);
					
					monitor.EndTask ();
				}
				
				//TODO: verify bundle details if for app store?
					
				if (settings.SignBundle) {
					monitor.BeginTask (GettextCatalog.GetString ("Signing app bundle"), 0);

					// Sign any dynamic libraries, before we sign the bundle
					var dylibs = Directory.GetFiles (workingApp, "*.dylib", SearchOption.AllDirectories);
					foreach (var dylib in dylibs){
						if (!Sign (monitor, bundleKey, dylib))
							return false;
					}
					
					if (!Sign (monitor, bundleKey, workingApp))
						return false;
					
					monitor.EndTask ();
				}
				
				if (settings.CreatePackage) {
					monitor.BeginTask (GettextCatalog.GetString ("Creating installer"), 0);
					
					var args = new ProcessArgumentBuilder ();
					args.Add ("--component");
					args.AddQuoted (workingApp);
					args.Add ("/Applications");
					if (settings.SignPackage) {
						args.Add ("--sign");
						args.AddQuoted (packageKey);
					}
					if (!settings.ProductDefinition.IsNullOrEmpty) {
						args.Add ("--product");
						args.AddQuoted (settings.ProductDefinition);
					}
					args.AddQuoted (target);
					
					var psi = new ProcessStartInfo ("productbuild", args.ToString ());
					try {
						if (MacBuildUtilities.ExecuteBuildCommand (monitor, psi) != 0) {
							monitor.ReportError ("Package creation failed", null);
							return false;
						}
					} catch (System.ComponentModel.Win32Exception) {
						monitor.ReportError ("productbuild not found", null);
						return false;
					}
					monitor.EndTask ();
				} else {
					Directory.Move (workingApp, target);
				}
			} finally {
				try {
					if (Directory.Exists (tempDir))
						Directory.Delete (tempDir, true);
				} catch (Exception ex) {
					LoggingService.LogError ("Error removing temp directory", ex);
				}
			}
			
			return true;
		}
예제 #7
0
		static bool Sign (IProgressMonitor monitor, string bundleKey, string path)
		{
			var args = new ProcessArgumentBuilder ();
			args.Add ("-v", "-f", "-s");
			args.AddQuoted (bundleKey, path);
			
			var psi = new ProcessStartInfo ("codesign", args.ToString ());
			if (MacBuildUtilities.ExecuteBuildCommand (monitor, psi) != 0) {
				monitor.ReportError ("Signing failed", null);
				return false;
			}
			return true;
		}
예제 #8
0
		protected override void Run ()
		{
			var proj = DefaultUploadToDeviceHandler.GetActiveExecutableIPhoneProject ();
			var conf = (IPhoneProjectConfiguration)proj.GetConfiguration (IdeApp.Workspace.ActiveConfiguration);
			
			IdeApp.ProjectOperations.Build (proj).Completed += delegate (IAsyncOperation op) {
				if (!op.Success) {
					MessageService.ShowError (
						GettextCatalog.GetString ("Cannot zip app bundle"),
						GettextCatalog.GetString ("Project did not build successfully"));
					return;
				}
				
				var dlg = new MonoDevelop.Components.SelectFileDialog (
					GettextCatalog.GetString ("Save zipped app bundle"), Gtk.FileChooserAction.Save);
					dlg.InitialFileName = string.Format ("{0}-{1}.zip", conf.CompiledOutputName.FileNameWithoutExtension, proj.BundleVersion);
					dlg.DefaultFilter = dlg.AddFilter ("Zip file", "*.zip");
				
				if (!dlg.Run ())
					return;
				
				var zipFile = dlg.SelectedFile;
				var builder = new ProcessArgumentBuilder ();
				builder.Add ("-r", "-y");
				builder.AddQuoted (zipFile);
				builder.AddQuoted (conf.AppDirectory.FileName);
				var cmd = builder.ToString ();
				var workingDirectory = conf.AppDirectory.ParentDirectory;
				
				new System.Threading.Thread (delegate () {
					IProgressMonitor monitor = null;
					AggregatedOperationMonitor opMon = null;
					IProcessAsyncOperation procOp = null;
					
					try {
						monitor = IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor (
							GettextCatalog.GetString ("Zip App Bundle"), MonoDevelop.Ide.Gui.Stock.RunProgramIcon, true, true);
						monitor.BeginTask (GettextCatalog.GetString ("Zipping app bundle"), 0);
						
						var console = (IConsole) monitor;
						console.Log.WriteLine ("zip " + cmd);
						
						//don't use StartConsoleProcess, it disposes the pad
						procOp = Runtime.ProcessService.StartProcess (
							"zip", cmd, workingDirectory, console.Out, console.Error, null);
						opMon = new AggregatedOperationMonitor (monitor, procOp);
						
						procOp.WaitForCompleted ();
						
						monitor.EndTask ();
							
						if (procOp.ExitCode != 0)
							monitor.ReportError (GettextCatalog.GetString ("Failed to zip app"), null);
						else
							monitor.ReportSuccess (GettextCatalog.GetString ("Saved zipped app to '{0}'", zipFile));
					} catch (Exception ex) {
						LoggingService.LogError ("Error in app zipper", ex);
						//be super-safe, crashing thread crashes whole app
						try {
							monitor.ReportError ("App zipping failed", ex);
						} catch {}
					}
					if (opMon != null)
						opMon.Dispose ();
					if (procOp != null)
						procOp.Dispose ();
					if (monitor != null)
						monitor.Dispose ();
				}).Start ();
			};
		}
예제 #9
0
		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);
		}
		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;
		}
예제 #11
0
		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;
		}
예제 #12
0
		static void AddExtraArgs (ProcessArgumentBuilder args, string extraArgs, IPhoneProject proj,
			IPhoneProjectConfiguration conf)
		{
			if (!string.IsNullOrEmpty (extraArgs)) {
				var customTags = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase) {
					{ "projectdir",   proj.BaseDirectory },
					{ "solutiondir",  proj.ParentSolution.BaseDirectory },
					{ "appbundledir", conf.AppDirectory },
					{ "targetpath",   conf.CompiledOutputName },
					{ "targetdir",    conf.CompiledOutputName.ParentDirectory },
					{ "targetname",   conf.CompiledOutputName.FileName },
					{ "targetext",    conf.CompiledOutputName.Extension },
				};
				args.Add (StringParserService.Parse (extraArgs, customTags));
			}
		}
예제 #13
0
		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);
		}
예제 #14
0
		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;
		}
		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);
		}