public static IAsyncOperation Package (MonoMacProject project, ConfigurationSelector configSel, MonoMacPackagingSettings settings, FilePath target) { IProgressMonitor mon = IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor ( GettextCatalog.GetString ("Packaging Output"), MonoDevelop.Ide.Gui.Stock.RunProgramIcon, true, true); var t = new System.Threading.Thread (() => { try { using (mon) { BuildPackage (mon, project, configSel, settings, target); } } catch (Exception ex) { mon.ReportError ("Unhandled error in packaging", null); LoggingService.LogError ("Unhandled exception in packaging", ex); } finally { mon.Dispose (); } }) { IsBackground = true, Name = "Mac Packaging", }; t.Start (); return mon.AsyncOperation; }
public static IAsyncOperation Package(MonoMacProject project, ConfigurationSelector configSel, MonoMacPackagingSettings settings, FilePath target) { IProgressMonitor mon = IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor( GettextCatalog.GetString("Packaging Output"), MonoDevelop.Ide.Gui.Stock.RunProgramIcon, true, true); var t = new System.Threading.Thread(() => { try { using (mon) { BuildPackage(mon, project, configSel, settings, target); } } catch (Exception ex) { mon.ReportError("Unhandled error in packaging", null); LoggingService.LogError("Unhandled exception in packaging", ex); } finally { mon.Dispose(); } }) { IsBackground = true, Name = "Mac Packaging", }; t.Start(); return(mon.AsyncOperation); }
public void SaveSettings (MonoMacPackagingSettings settings) { settings.IncludeMono = includeMonoCheck.Active; settings.SignBundle = signBundleCheck.Active; settings.BundleSigningKey = bundleIdentityCombo.SelectedName; settings.LinkerMode = (MonoMacLinkerMode)linkerCombo.Active; settings.CreatePackage = createPackageCheck.Active; settings.SignPackage = signPackageCheck.Active; settings.PackageSigningKey = packageIdentityCombo.SelectedName; settings.ProductDefinition = productDefinitionFileEntry.Path; if (settings.ProductDefinition.IsEmpty) settings.ProductDefinition = FilePath.Null; }
public void SaveSettings(MonoMacPackagingSettings settings) { settings.IncludeMono = includeMonoCheck.Active; settings.SignBundle = signBundleCheck.Sensitive && signBundleCheck.Active; settings.BundleSigningKey = bundleIdentityCombo.SelectedName; settings.LinkerMode = (MonoMacLinkerMode)linkerCombo.Active; settings.CreatePackage = createPackageCheck.Sensitive && createPackageCheck.Active; settings.SignPackage = signPackageCheck.Sensitive && signPackageCheck.Active; settings.PackageSigningKey = packageIdentityCombo.SelectedName; settings.ProductDefinition = productDefinitionFileEntry.Path; if (settings.ProductDefinition.IsEmpty) { settings.ProductDefinition = FilePath.Null; } }
public void LoadSettings(MonoMacPackagingSettings settings) { //refill every time in case the value is an unknown - don't want those to be kept in the list hasBundleCerts = FillIdentities(bundleIdentityCombo, APPLICATION_PREFIX, INSTALLER_PREFIX, signBundleCheck, signBundleImage); hasPackageCerts = FillIdentities(packageIdentityCombo, INSTALLER_PREFIX, APPLICATION_PREFIX, signPackageCheck, signInstallerImage); includeMonoCheck.Active = settings.IncludeMono; signBundleCheck.Active = settings.SignBundle; bundleIdentityCombo.SelectedName = settings.BundleSigningKey; linkerCombo.Active = (int)settings.LinkerMode; createPackageCheck.Active = settings.CreatePackage; signPackageCheck.Active = settings.SignPackage; packageIdentityCombo.SelectedName = settings.PackageSigningKey; productDefinitionFileEntry.Path = settings.ProductDefinition.ToString() ?? ""; UpdateSensitivity(); }
public void LoadSettings (MonoMacPackagingSettings settings) { //refill every time in case the value is an unknown - don't want those to be kept in the list FillIdentities (bundleIdentityCombo, APPLICATION_PREFIX, INSTALLER_PREFIX); FillIdentities (packageIdentityCombo, INSTALLER_PREFIX, APPLICATION_PREFIX); includeMonoCheck.Active = settings.IncludeMono; signBundleCheck.Active = settings.SignBundle; bundleIdentityCombo.SelectedName = settings.BundleSigningKey; linkerCombo.Active = (int) settings.LinkerMode; createPackageCheck.Active = settings.CreatePackage; signPackageCheck.Active = settings.SignPackage; packageIdentityCombo.SelectedName = settings.PackageSigningKey; productDefinitionFileEntry.Path = settings.ProductDefinition.ToString () ?? ""; UpdateSensitivity (); }
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; }
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); } 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); }
public void SaveSettings (MonoMacPackagingSettings settings) { settingsWidget.SaveSettings (settings); }
public void LoadSettings (MonoMacPackagingSettings settings) { settingsWidget.LoadSettings (settings); }
public void SaveSettings(MonoMacPackagingSettings settings) { settingsWidget.SaveSettings(settings); }
public void LoadSettings(MonoMacPackagingSettings settings) { settingsWidget.LoadSettings(settings); }
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.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 { 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 (); 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"); var psi = new ProcessStartInfo (mmpPath, args.ToString ()); monitor.Log.WriteLine ("mmp " + psi.Arguments); string err; if (MacBuildUtilities.ExecuteCommand (monitor, psi, out err) != 0) { monitor.Log.WriteLine (err); 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); var args = new ProcessArgumentBuilder (); args.Add ("-v", "-f", "-s"); args.AddQuoted (bundleKey, workingApp); var psi = new ProcessStartInfo ("codesign", args.ToString ()); monitor.Log.WriteLine ("codesign " + psi.Arguments); string err; if (MacBuildUtilities.ExecuteCommand (monitor, psi, out err) != 0) { monitor.Log.WriteLine (err); monitor.ReportError ("Signing failed", null); 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", "--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 ()); monitor.Log.WriteLine ("productbuild " + psi.Arguments); string err; if (MacBuildUtilities.ExecuteCommand (monitor, psi, out err) != 0) { monitor.Log.WriteLine (err); monitor.ReportError ("Package creation failed", 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; }