Exemple #1
0
        protected override string GenerateCommandLineCommands()
        {
            var args = new ProcessArgumentBuilder();

            args.Add("--compress");
            args.AddQuoted(InputScene);
            args.Add("-o");
            args.AddQuoted(OutputScene);
            args.AddQuotedFormat("--sdk-root={0}", SdkRoot);
            args.AddQuotedFormat("--target-version-{0}={1}", OperatingSystem, SdkVersion);
            args.AddQuotedFormat("--target-build-dir={0}", IntermediateOutputPath);

            return(args.ToString());
        }
Exemple #2
0
 void AddDirArgs(ProcessArgumentBuilder pb)
 {
     foreach (var dir in HelpService.Sources)
     {
         pb.AddQuotedFormat("--docdir={0}", dir);
     }
 }
        int CopySceneKitAssets(string scnassets, string output, string intermediate)
        {
            var environment = new Dictionary <string, string> ();
            var args        = new ProcessArgumentBuilder();

            environment.Add("PATH", DeveloperRootBinDir);
            environment.Add("DEVELOPER_DIR", SdkDevPath);
            environment.Add("XCODE_DEVELOPER_USR_PATH", DeveloperRootBinDir);

            args.AddQuoted(Path.GetFullPath(scnassets));
            args.Add("-o");
            args.AddQuoted(Path.GetFullPath(output));
            args.AddQuotedFormat("--sdk-root={0}", SdkRoot);
            args.AddQuotedFormat("--target-version-{0}={1}", OperatingSystem, SdkVersion);
            args.AddQuotedFormat("--target-build-dir={0}", Path.GetFullPath(intermediate));

            var startInfo = GetProcessStartInfo(environment, GetFullPathToTool(), args.ToString());

            try {
                using (var process = new Process()) {
                    Log.LogMessage(MessageImportance.Normal, "Tool {0} execution started with arguments: {1}", startInfo.FileName, startInfo.Arguments);

                    process.StartInfo           = startInfo;
                    process.OutputDataReceived += (sender, e) => {
                        if (e.Data == null)
                        {
                            return;
                        }

                        Log.LogMessage(MessageImportance.Low, "{0}", e.Data);
                    };

                    process.Start();
                    process.BeginOutputReadLine();
                    process.WaitForExit();

                    Log.LogMessage(MessageImportance.Low, "Tool {0} execution finished.", startInfo.FileName);

                    return(process.ExitCode);
                }
            } catch (Exception ex) {
                Log.LogError("Error executing tool '{0}': {1}", startInfo.FileName, ex.Message);
                return(-1);
            }
        }
Exemple #4
0
        protected override string GenerateCommandLineCommands()
        {
            var args = new ProcessArgumentBuilder();
            TargetArchitecture architectures;
            bool msym;

            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" + llvm;
                }

                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");

            if (!string.IsNullOrEmpty(ArchiveSymbols) && bool.TryParse(ArchiveSymbols.Trim(), out msym))
            {
                args.Add("--msym=" + (msym ? "yes" : "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());
        }
Exemple #5
0
        protected override string GenerateCommandLineCommands()
        {
            var args = new ProcessArgumentBuilder ();

            args.Add ("--compress");
            args.AddQuoted (InputScene);
            args.Add ("-o");
            args.AddQuoted (OutputScene);
            args.AddQuotedFormat ("--sdk-root={0}", SdkRoot);
            args.AddQuotedFormat ("--target-version-{0}={1}", OperatingSystem, SdkVersion);
            args.AddQuotedFormat ("--target-build-dir={0}", IntermediateOutputPath);

            return args.ToString ();
        }
		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);
			
			//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);
				
				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 ();
			}
			
			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);
			
			
			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;
		}
        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);
        }