public bool CreatePodfile(Podfile podfile, string podfilePath) { if (CancellationToken.IsCancellationRequested) { Log.LogError("Task was canceled."); return(false); } var podfileContents = $"{(podfile.UseFrameworks ? "use_frameworks!" : "")}\n" + $"platform :{podfile.PlatformName}, '{podfile.PlatformVersion}'\n" + $"target '{podfile.TargetName}' do\n"; foreach (var pod in podfile.Pods) { podfileContents += $" pod '{pod.Id}', '{pod.Version}'\n"; } podfileContents += $"end"; Ssh.CreateDirectory(CrossPath.GetDirectoryNameSsh(podfilePath)); using (var stream = Utilities.GetStreamFromText(podfileContents)) { Ssh.CreateFile(stream, podfilePath); } return(true); }
public bool BuildXCodeProject(XCodeBuildParameters parameters, XCodeBuildOutputs outputs) { outputs.ProjectDirectory = CrossPath.GetDirectoryNameSsh(parameters.ProjectFilePath); outputs.OutputDirectory = parameters.OutputDirectory ?? CrossPath.CombineSsh(outputs.ProjectDirectory, "out"); outputs.ArtifactsDirectory = parameters.ArtifactsDirectory ?? CrossPath.CombineSsh(outputs.ProjectDirectory, "build"); foreach (var arch in parameters.SplitArchitectures) { if (CancellationToken.IsCancellationRequested) { Log.LogError("Task was canceled."); return(false); } var artifactsPath = CrossPath.CombineSsh(outputs.ArtifactsDirectory, parameters.ArchitectureSettings.GetArtifactDirectoryName("Release", arch: arch)); // build the project var result = Ssh.ExecuteLaunchCtlCommand( workingDirectory: outputs.ProjectDirectory, arguments: new[] { XCodeBuildToolPath, "-project", parameters.ProjectFilePath, "-target", parameters.BuildTargets[0], // TODO "-configuration", "Release", "-arch", arch.ToString().ToLowerInvariant(), "-sdk", parameters.ArchitectureSettings.GetSdk(arch).ToString().ToLowerInvariant(), "build" }); if (!result) { Log.LogError($"Error building the XCode project."); return(false); } if (CancellationToken.IsCancellationRequested) { Log.LogError("Task was canceled."); return(false); } // copy the artifacts to the intermediates directory, naming them per architecture foreach (var target in parameters.OutputTargets) { // this might be set multiple times as this is target-based, // but we are building the same target multiple times for each arch outputs[target].IntermediateDirectory = CrossPath.CombineSsh(outputs.OutputDirectory, target, "obj"); Ssh.CreateDirectory(outputs[target].IntermediateDirectory); var currentIntermediate = outputs[target].Intermediates[arch]; currentIntermediate.IsFrameworks = parameters.IsFrameworks; if (parameters.IsFrameworks) { var cleanTarget = CleanFrameworkName(target); currentIntermediate.Path = CrossPath.CombineSsh(outputs[target].IntermediateDirectory, $"{cleanTarget}-{arch}.framework"); Ssh.CopyPath(CrossPath.CombineSsh(artifactsPath, $"{cleanTarget}.framework"), currentIntermediate.Path); } else { currentIntermediate.Path = CrossPath.CombineSsh(outputs.OutputDirectory, target, "obj", $"lib{target}-{arch}.a"); Ssh.CopyPath(CrossPath.CombineSsh(artifactsPath, $"lib{target}.a"), currentIntermediate.Path); } } } // run lipo on the outputs, from the obj to the out foreach (var targetOutput in outputs) { targetOutput.Directory = CrossPath.CombineSsh(parameters.OutputDirectory, targetOutput.Target); // lipo the .a var staticIntermediates = targetOutput.Intermediates.Where(i => !i.IsFrameworks); if (staticIntermediates.Any()) { targetOutput.ArchiveOutput = new BuildArchitectureOutput(targetOutput) { Architecture = Utilities.CreateEnum(staticIntermediates.Select(i => i.Architecture)), IsFrameworks = false, Path = CrossPath.CombineSsh(parameters.OutputDirectory, targetOutput.Target, $"lib{targetOutput.Target}.a") }; if (!RunLipo(targetOutput.ArchiveOutput.Path, staticIntermediates.Select(i => i.Path))) { return(false); } } // lipo the .framework var frameworkIntermediates = targetOutput.Intermediates.Where(i => i.IsFrameworks); if (frameworkIntermediates.Any()) { var cleanTarget = CleanFrameworkName(targetOutput.Target); targetOutput.FrameworkOutput = new BuildArchitectureOutput(targetOutput) { Architecture = Utilities.CreateEnum(frameworkIntermediates.Select(i => i.Architecture)), IsFrameworks = true, Path = CrossPath.CombineSsh(parameters.OutputDirectory, targetOutput.Target, $"{cleanTarget}.framework") }; // copy the first arch as we need the other files var firstArch = frameworkIntermediates.First(); Ssh.CopyPath(firstArch.Path, targetOutput.FrameworkOutput.Path); // now lipo the archive if (!RunLipo(CrossPath.CombineSsh(targetOutput.FrameworkOutput.Path, cleanTarget), frameworkIntermediates.Select(i => CrossPath.CombineSsh(i.Path, cleanTarget)))) { return(false); } } } return(true); }