From e6a0af79a86753e53d308916b54018093b8b87ee Mon Sep 17 00:00:00 2001 From: Brentley Jones Date: Fri, 14 Sep 2018 13:47:27 -0500 Subject: [PATCH] Allow specifying phase order for copy files phases Copy Files phases don't stop dependent targets from starting to compile. If some of the files being copied are needed for the dependent target to compile then they need to happen before the Compile Sources phase. This change allows specifying that. --- Docs/ProjectSpec.md | 3 +++ Sources/ProjectSpec/TargetSource.swift | 20 +++++++++++++++++-- Sources/XcodeGenKit/PBXProjGenerator.swift | 11 ++++++++-- Sources/XcodeGenKit/SourceGenerator.swift | 6 ++++-- .../Project.xcodeproj/project.pbxproj | 2 +- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index ebb3a3f2..8196db5c 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -275,6 +275,9 @@ A source can be provided via a string (the path) or an object of the form: - `sharedSupport` - `plugins` - [ ] **subpath**: **String** - The path inside of the destination to copy the files. + - [ ] **phaseOrder**: **String** - When the Copy Files phase should execute in relation to other phases. This can be one of the following values: + - `preCompile`: Run before the Compile Sources phase + - `postCompile`: Run after the Compile Sources phase - `none` - Will not be added to any build phases - [ ] **type**: **String**: This can be one of the following values - `file`: a file reference with a parent group will be created (Default for files or directories with extensions) diff --git a/Sources/ProjectSpec/TargetSource.swift b/Sources/ProjectSpec/TargetSource.swift index 08bc65cd..74aed837 100644 --- a/Sources/ProjectSpec/TargetSource.swift +++ b/Sources/ProjectSpec/TargetSource.swift @@ -42,7 +42,8 @@ public struct TargetSource: Equatable { public struct CopyFilesSettings: Equatable, Hashable { public static let xpcServices = CopyFilesSettings( destination: .productsDirectory, - subpath: "$(CONTENTS_FOLDER_PATH)/XPCServices" + subpath: "$(CONTENTS_FOLDER_PATH)/XPCServices", + phaseOrder: .postCompile ) public enum Destination: String { @@ -72,13 +73,26 @@ public struct TargetSource: Equatable { } } } + + public enum PhaseOrder: String { + /// Run before the Compile Sources phase + case preCompile + /// Run after the Compile Sources and post-compile Run Script phases + case postCompile + } public var destination: Destination public var subpath: String + public var phaseOrder: PhaseOrder - public init(destination: Destination, subpath: String) { + public init( + destination: Destination, + subpath: String, + phaseOrder: PhaseOrder + ) { self.destination = destination self.subpath = subpath + self.phaseOrder = phaseOrder } } @@ -119,6 +133,7 @@ public struct TargetSource: Equatable { self.type = type self.optional = optional self.buildPhase = buildPhase + self.headerVisibility = headerVisibility } } @@ -189,5 +204,6 @@ extension TargetSource.BuildPhase.CopyFilesSettings: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { destination = try jsonDictionary.json(atKeyPath: "destination") subpath = jsonDictionary.json(atKeyPath: "subpath") ?? "" + phaseOrder = jsonDictionary.json(atKeyPath: "phaseOrder") ?? .postCompile } } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 9dac781d..c7b0d40c 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -646,7 +646,13 @@ public class PBXProjGenerator { return sourceFilesByCopyFiles.mapValues { getBuildFilesForSourceFiles($0) } } + copyFilesBuildPhasesFiles.merge(getBuildFilesForCopyFilesPhases()) { $0 + $1 } + buildPhases += try target.prebuildScripts.map { try generateBuildScript(targetName: target.name, buildScript: $0) } + + buildPhases += copyFilesBuildPhasesFiles + .filter { $0.key.phaseOrder == .preCompile } + .map { generateCopyFiles(targetName: target.name, copyFiles: $0, buildPhaseFiles: $1) } let headersBuildPhaseFiles = getBuildFilesForPhase(.headers) if !headersBuildPhaseFiles.isEmpty && (target.type == .framework || target.type == .dynamicLibrary) { @@ -689,8 +695,9 @@ public class PBXProjGenerator { buildPhases.append(script.reference) } - copyFilesBuildPhasesFiles.merge(getBuildFilesForCopyFilesPhases()) { $0 + $1 } - buildPhases += copyFilesBuildPhasesFiles.map { generateCopyFiles(targetName: target.name, copyFiles: $0, buildPhaseFiles: $1) } + buildPhases += copyFilesBuildPhasesFiles + .filter { $0.key.phaseOrder == .postCompile } + .map { generateCopyFiles(targetName: target.name, copyFiles: $0, buildPhaseFiles: $1) } if !targetFrameworkBuildFiles.isEmpty { diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index a56614e3..12709f61 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -73,7 +73,8 @@ class SourceGenerator { if headerVisibility == .public { chosenBuildPhase = .copyFiles(TargetSource.BuildPhase.CopyFilesSettings( destination: .productsDirectory, - subpath: "include/$(PRODUCT_NAME)" + subpath: "include/$(PRODUCT_NAME)", + phaseOrder: .preCompile )) } else { chosenBuildPhase = nil @@ -194,7 +195,8 @@ class SourceGenerator { guard targetType == .staticLibrary else { return nil } return .copyFiles(TargetSource.BuildPhase.CopyFilesSettings( destination: .productsDirectory, - subpath: "include/$(PRODUCT_NAME)" + subpath: "include/$(PRODUCT_NAME)", + phaseOrder: .preCompile )) case "framework": return .frameworks case "xpc": return .copyFiles(.xpcServices) diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index badfd0f1..7804b3e4 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -913,8 +913,8 @@ isa = PBXNativeTarget; buildConfigurationList = CL_399755008402 /* Build configuration list for PBXNativeTarget "StaticLibrary_ObjC" */; buildPhases = ( - SBP_39975500840 /* Sources */, CFBP_3265670993 /* CopyFiles */, + SBP_39975500840 /* Sources */, ); buildRules = ( );