From d1efa9ac6414effa5007523360eaba43df2f2cd7 Mon Sep 17 00:00:00 2001 From: mironal Date: Wed, 4 Oct 2017 14:46:18 +0900 Subject: [PATCH 01/23] Add outputpaths to carthage copy-framewors script According to Carthage README, the Output Files should be set to `carthage copy-frameworks` script. https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos --- .../project.pbxproj | 74 +++++++++++++++++++ Fixtures/TestProject/spec.yml | 1 + Sources/XcodeGenKit/PBXProjGenerator.swift | 3 +- 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj index 14a7e34a..59524070 100644 --- a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj +++ b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ BF3862341101 /* MyFramework.framework in Copy Files */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF4946816301 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG1473702401 /* Main.storyboard */; }; BF5986511201 = {isa = PBXBuildFile; fileRef = FR6523263101 /* TestProject.app */; }; + BF6182896901 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR9215298301 /* Result.framework */; }; BF9001417701 /* TestProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR6877173101 /* TestProjectTests.swift */; }; BF9155249601 /* FrameworkFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR7078510801 /* FrameworkFile.swift */; }; /* End PBXBuildFile section */ @@ -68,9 +69,29 @@ FR6877173101 /* TestProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProjectTests.swift; sourceTree = ""; }; FR7078510801 /* FrameworkFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameworkFile.swift; sourceTree = ""; }; FR7740960501 /* MyFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyFramework.h; sourceTree = ""; }; + FR9215298301 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = ""; }; /* End PBXFileReference section */ +/* Begin PBXFrameworksBuildPhase section */ + FBP652326301 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BF6182896901 /* Result.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + /* Begin PBXGroup section */ + G19527407101 /* Frameworks */ = { + isa = PBXGroup; + children = ( + G28836901501 /* Carthage */, + ); + name = Frameworks; + sourceTree = ""; + }; G26536595301 /* TestProjectTests */ = { isa = PBXGroup; children = ( @@ -81,6 +102,15 @@ path = TestProjectTests; sourceTree = ""; }; + G28836901501 /* Carthage */ = { + isa = PBXGroup; + children = ( + G47994500501 /* iOS */, + ); + name = Carthage; + path = Carthage/Build; + sourceTree = ""; + }; G29934978701 /* MyFramework */ = { isa = PBXGroup; children = ( @@ -92,6 +122,15 @@ path = MyFramework; sourceTree = ""; }; + G47994500501 /* iOS */ = { + isa = PBXGroup; + children = ( + FR9215298301 /* Result.framework */, + ); + name = iOS; + path = iOS; + sourceTree = ""; + }; G65232631501 /* TestProject */ = { isa = PBXGroup; children = ( @@ -124,6 +163,7 @@ G65232631501 /* TestProject */, G26536595301 /* TestProjectTests */, G86202385201 /* Products */, + G19527407101 /* Frameworks */, ); sourceTree = ""; }; @@ -206,7 +246,9 @@ SBP652326301 /* Sources */, RBP652326301 /* Resources */, HBP652326301 /* Headers */, + FBP652326301 /* Frameworks */, CFBP50493301 /* CopyFiles */, + SSBP58567701 /* Carthage */, SSBP24648001 /* Strip Unused Architectures from Frameworks */, SSBP19207501 /* Swiftlint */, ); @@ -313,6 +355,22 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; + SSBP58567701 /* Carthage */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/Carthage/Build/iOS/Result.framework", + ); + name = Carthage; + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Result.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/local/bin/carthage copy-frameworks\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -409,6 +467,10 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = TestProject/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -482,6 +544,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = TestProjectTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -501,6 +567,10 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = TestProject/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -566,6 +636,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = TestProjectTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/Fixtures/TestProject/spec.yml b/Fixtures/TestProject/spec.yml index da59c0a8..05680d63 100644 --- a/Fixtures/TestProject/spec.yml +++ b/Fixtures/TestProject/spec.yml @@ -12,6 +12,7 @@ targets: INFOPLIST_FILE: TestProject/Info.plist dependencies: - target: MyFramework + - carthage: Result scheme: testTargets: - TestProjectTests diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index d169b08f..65a47ad5 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -388,7 +388,8 @@ public class PBXProjGenerator { if target.type.isApp && target.platform != .macOS { let inputPaths = Set(carthageFrameworksToEmbed).map { "$(SRCROOT)/\(carthageBuildPath)/\(target.platform)/\($0)\($0.contains(".") ? "" : ".framework")" } - let carthageScript = PBXShellScriptBuildPhase(reference: generateUUID(PBXShellScriptBuildPhase.self, "Carthage" + target.name), files: [], name: "Carthage", inputPaths: inputPaths, outputPaths: [], shellPath: "/bin/sh", shellScript: "/usr/local/bin/carthage copy-frameworks\n") + let outputPaths = Set(carthageFrameworksToEmbed).map { "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/\($0)\($0.contains(".") ? "" : ".framework")" } + let carthageScript = PBXShellScriptBuildPhase(reference: generateUUID(PBXShellScriptBuildPhase.self, "Carthage" + target.name), files: [], name: "Carthage", inputPaths: inputPaths, outputPaths: outputPaths, shellPath: "/bin/sh", shellScript: "/usr/local/bin/carthage copy-frameworks\n") addObject(carthageScript) buildPhases.append(carthageScript.reference) } From c94de4d6cc6714f1dacfae43d58abb4cb20552f5 Mon Sep 17 00:00:00 2001 From: toshi0383 Date: Sun, 1 Oct 2017 09:23:45 +0900 Subject: [PATCH 02/23] Always embed and link frameworks for macOS --- Sources/XcodeGenKit/PBXProjGenerator.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index d169b08f..178f456a 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -297,6 +297,11 @@ public class PBXProjGenerator { carthageFrameworksByPlatform[target.platform.carthageDirectoryName]?.append(fileReference) targetFrameworkBuildFiles.append(buildFile.reference) + if target.platform == .macOS { + let embedFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference + target.name), fileRef: fileReference, settings: dependency.buildSettings) + addObject(embedFile) + copyFiles.append(embedFile.reference) + } } } From d03fb7785ef9d97eadae8f4d3a38bd430775dbed Mon Sep 17 00:00:00 2001 From: toshi0383 Date: Sun, 1 Oct 2017 19:52:57 +0900 Subject: [PATCH 03/23] add guard for non-app target --- Sources/XcodeGenKit/PBXProjGenerator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 178f456a..4bafcca9 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -297,7 +297,7 @@ public class PBXProjGenerator { carthageFrameworksByPlatform[target.platform.carthageDirectoryName]?.append(fileReference) targetFrameworkBuildFiles.append(buildFile.reference) - if target.platform == .macOS { + if target.platform == .macOS && target.type.isApp { let embedFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference + target.name), fileRef: fileReference, settings: dependency.buildSettings) addObject(embedFile) copyFiles.append(embedFile.reference) From f6d6f17f1b0015c8ca467c8b1b6b5160b1e198c4 Mon Sep 17 00:00:00 2001 From: mironal Date: Thu, 5 Oct 2017 10:53:08 +0900 Subject: [PATCH 04/23] sort carthage dependencies --- Sources/XcodeGenKit/PBXProjGenerator.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 65a47ad5..22c09654 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -381,14 +381,16 @@ public class PBXProjGenerator { buildPhases.append(copyFilesPhase.reference) } - let carthageFrameworksToEmbed = carthageDependencies - .filter { ($0.embed ?? true) } - .map { $0.reference } + let carthageFrameworksToEmbed = Array(Set(carthageDependencies + .filter { $0.embed ?? true } + .map { $0.reference })) + .sorted() + if !carthageFrameworksToEmbed.isEmpty { if target.type.isApp && target.platform != .macOS { - let inputPaths = Set(carthageFrameworksToEmbed).map { "$(SRCROOT)/\(carthageBuildPath)/\(target.platform)/\($0)\($0.contains(".") ? "" : ".framework")" } - let outputPaths = Set(carthageFrameworksToEmbed).map { "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/\($0)\($0.contains(".") ? "" : ".framework")" } + let inputPaths = carthageFrameworksToEmbed.map { "$(SRCROOT)/\(carthageBuildPath)/\(target.platform)/\($0)\($0.contains(".") ? "" : ".framework")" } + let outputPaths = carthageFrameworksToEmbed.map { "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/\($0)\($0.contains(".") ? "" : ".framework")" } let carthageScript = PBXShellScriptBuildPhase(reference: generateUUID(PBXShellScriptBuildPhase.self, "Carthage" + target.name), files: [], name: "Carthage", inputPaths: inputPaths, outputPaths: outputPaths, shellPath: "/bin/sh", shellScript: "/usr/local/bin/carthage copy-frameworks\n") addObject(carthageScript) buildPhases.append(carthageScript.reference) From 5d9c3a9ab85fab7193d8222513a4f0b8b6256cab Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Tue, 10 Oct 2017 13:39:18 -0500 Subject: [PATCH 05/23] Update to xcproj 0.4.0 --- Package.resolved | 13 ++----------- Sources/ProjectSpec/Settings.swift | 2 ++ Sources/XcodeGenKit/PBXProjGenerator.swift | 3 ++- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Package.resolved b/Package.resolved index 8a0e3bcf..a66eca33 100644 --- a/Package.resolved +++ b/Package.resolved @@ -55,15 +55,6 @@ "version": "0.7.2" } }, - { - "package": "Unbox", - "repositoryURL": "https://github.com/JohnSundell/Unbox.git", - "state": { - "branch": null, - "revision": "17ad6aa1cc2f1efa27a0bbbdb66f79796708aa95", - "version": "2.5.0" - } - }, { "package": "Yams", "repositoryURL": "https://github.com/jpsim/Yams.git", @@ -78,8 +69,8 @@ "repositoryURL": "https://github.com/xcodeswift/xcproj.git", "state": { "branch": null, - "revision": "e937b43cefa9c67a1787aba482ceb2f3ba172baf", - "version": "0.3.0" + "revision": "e25c5dfa28cbabec51bc7df0d4a11664be1bbb5f", + "version": "0.4.0" } } ] diff --git a/Sources/ProjectSpec/Settings.swift b/Sources/ProjectSpec/Settings.swift index 6e84eeb8..24836860 100644 --- a/Sources/ProjectSpec/Settings.swift +++ b/Sources/ProjectSpec/Settings.swift @@ -11,6 +11,8 @@ import JSONUtilities import xcproj import PathKit import Yams + +public typealias BuildSettings = [String : Any] public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertible { public let buildSettings: BuildSettings diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 22c09654..3f185750 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -124,7 +124,8 @@ public class PBXProjGenerator { let knownRegions: [String] = ["en", "Base"] let projectAttributes: [String: Any] = ["LastUpgradeCheck": currentXcodeVersion].merged(spec.attributes) - let root = PBXProject(reference: project.rootObject, + let root = PBXProject(name: spec.name, + reference: project.rootObject, buildConfigurationList: buildConfigList.reference, compatibilityVersion: "Xcode 3.2", mainGroup: mainGroup.reference, From 713631a4596a5e0680b197d020088ce3afd8454f Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Wed, 11 Oct 2017 10:44:05 -0500 Subject: [PATCH 06/23] Update GeneratedProject file to use the new classes dictionary format --- .../GeneratedProject.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj index 59524070..384971a9 100644 --- a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj +++ b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj @@ -1,8 +1,8 @@ // !$*UTF8*$! { archiveVersion = 1; - classes = ( - ); + classes = { + }; objectVersion = 46; objects = { @@ -14,7 +14,7 @@ BF2753556301 = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; }; BF3154421201 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FR5980633301 /* Assets.xcassets */; }; BF3515549501 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = FR7740960501 /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BF3862341101 /* MyFramework.framework in Copy Files */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + BF3862341101 /* MyFramework.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF4946816301 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG1473702401 /* Main.storyboard */; }; BF5986511201 = {isa = PBXBuildFile; fileRef = FR6523263101 /* TestProject.app */; }; BF6182896901 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR9215298301 /* Result.framework */; }; @@ -46,7 +46,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - BF3862341101 /* MyFramework.framework in Copy Files */, + BF3862341101 /* MyFramework.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -269,7 +269,7 @@ attributes = { LastUpgradeCheck = 0900; }; - buildConfigurationList = XCCL81399401 /* Build configuration list for PBXProject */; + buildConfigurationList = XCCL81399401 /* Build configuration list for PBXProject "GeneratedProject" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; knownRegions = ( @@ -709,7 +709,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = ""; }; - XCCL81399401 /* Build configuration list for PBXProject */ = { + XCCL81399401 /* Build configuration list for PBXProject "GeneratedProject" */ = { isa = XCConfigurationList; buildConfigurations = ( XCBC47994501 /* Debug */, From ca3c64baa6d89c8d27c195a3813b72fe8ef64b41 Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Thu, 12 Oct 2017 07:31:38 -0500 Subject: [PATCH 07/23] Update xcproj to 0.4.1 and Yams to 0.3.7 --- Package.resolved | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Package.resolved b/Package.resolved index a66eca33..58535b03 100644 --- a/Package.resolved +++ b/Package.resolved @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/jpsim/Yams.git", "state": { "branch": null, - "revision": "5ac9248b378b5e12201c255ba74caf990d1e0f4b", - "version": "0.3.6" + "revision": "05921531200acff0d8d9caab5ec77b2bcf300b6b", + "version": "0.3.7" } }, { @@ -69,8 +69,8 @@ "repositoryURL": "https://github.com/xcodeswift/xcproj.git", "state": { "branch": null, - "revision": "e25c5dfa28cbabec51bc7df0d4a11664be1bbb5f", - "version": "0.4.0" + "revision": "cd1c329c6e092fdf5afbddf10dd59da564293aa6", + "version": "0.4.1" } } ] From 6a168acb4667e558b07afa745c8c8b8c8f1ec4eb Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Thu, 12 Oct 2017 07:37:22 -0500 Subject: [PATCH 08/23] Remove workaround typealias --- Sources/ProjectSpec/Settings.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/ProjectSpec/Settings.swift b/Sources/ProjectSpec/Settings.swift index 24836860..3682a2f8 100644 --- a/Sources/ProjectSpec/Settings.swift +++ b/Sources/ProjectSpec/Settings.swift @@ -12,7 +12,6 @@ import xcproj import PathKit import Yams -public typealias BuildSettings = [String : Any] public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertible { public let buildSettings: BuildSettings From 2f2c89e0c177cb24b6daf32ecccfaa05d6be7fd5 Mon Sep 17 00:00:00 2001 From: ryohey Date: Mon, 25 Sep 2017 22:24:32 +0900 Subject: [PATCH 09/23] fix localisation variant groups --- Sources/XcodeGenKit/PBXProjGenerator.swift | 81 +++++++++++++++++----- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index b303b759..a990fd3e 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -22,6 +22,7 @@ public class PBXProjGenerator { var fileReferencesByPath: [Path: String] = [:] var groupsByPath: [Path: PBXGroup] = [:] + var variantGroupsByPath: [Path: PBXVariantGroup] = [:] var targetNativeReferences: [String: String] = [:] var targetBuildFileReferences: [String: String] = [:] @@ -151,7 +152,6 @@ public class PBXProjGenerator { settings = ["ATTRIBUTES": ["Public"]] } let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference), fileRef: fileReference, settings: settings) - addObject(buildFile) return SourceFile(path: path, fileReference: fileReference, buildFile: buildFile) } @@ -160,11 +160,11 @@ public class PBXProjGenerator { let carthageDependencies = getAllCarthageDependencies(target: target) let sourcePaths = target.sources.map { basePath + $0 } - var sourceFilePaths: [Path] = [] + var sourceFiles: [SourceFile] = [] for source in sourcePaths { let sourceGroups = try getGroups(path: source) - sourceFilePaths += sourceGroups.filePaths + sourceFiles += sourceGroups.sourceFiles } // find all Info.plist @@ -310,7 +310,8 @@ public class PBXProjGenerator { var buildPhases: [String] = [] func getBuildFilesForPhase(_ buildPhase: BuildPhase) -> [String] { - let files = sourceFilePaths.filter { getBuildPhaseForPath($0) == buildPhase }.map(generateSourceFile) + let files = sourceFiles.filter { getBuildPhaseForPath($0.path) == buildPhase } + files.forEach { addObject($0.buildFile) } return files.map { $0.buildFile.reference } } @@ -467,7 +468,7 @@ public class PBXProjGenerator { } } - func getGroups(path: Path, depth: Int = 0) throws -> (filePaths: [Path], groups: [PBXGroup]) { + func getGroups(path: Path, depth: Int = 0) throws -> (sourceFiles: [SourceFile], groups: [PBXGroup]) { let excludedFiles: [String] = [".DS_Store"] @@ -484,34 +485,76 @@ public class PBXProjGenerator { .filter { $0.extension == "lproj" } .sorted { $0.lastComponent < $1.lastComponent } - var groupChildren: [String] = [] - var allFilePaths: [Path] = filePaths + var groupChildren: [String] = filePaths.map { getFileReference(path: $0, inPath: path) } + var allSourceFiles: [SourceFile] = filePaths.map { generateSourceFile(path: $0) } var groups: [PBXGroup] = [] for path in directories { let subGroups = try getGroups(path: path, depth: depth + 1) - allFilePaths += subGroups.filePaths + allSourceFiles += subGroups.sourceFiles groupChildren.append(subGroups.groups.first!.reference) groups += subGroups.groups } - for filePath in filePaths { - let fileReference = getFileReference(path: filePath, inPath: path) - groupChildren.append(fileReference) + // create variant groups of the base localisation first + var baseLocalisationVariantGroups:[PBXVariantGroup] = [] + if let baseLocalisedDirectory = localisedDirectories.first(where: { $0.lastComponent == "Base.lproj" }) { + for path in try baseLocalisedDirectory.children() { + let filePath = "\(baseLocalisedDirectory.lastComponent)/\(path.lastComponent)" + + let variantGroup: PBXVariantGroup + if let cachedGroup = variantGroupsByPath[path] { + variantGroup = cachedGroup + } else { + variantGroup = PBXVariantGroup(reference: generateUUID(PBXVariantGroup.self, filePath), + children: [], + name: path.lastComponent, + sourceTree: .group) + variantGroupsByPath[path] = variantGroup + + addObject(variantGroup) + groupChildren.append(variantGroup.reference) + } + + baseLocalisationVariantGroups.append(variantGroup) + + let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, variantGroup.reference), fileRef: variantGroup.reference, settings: nil) + allSourceFiles.append(SourceFile(path: path, fileReference: variantGroup.reference, buildFile: buildFile)) + } } + // add references to localised resources into base localisation variant groups for localisedDirectory in localisedDirectories { + let localisationName = localisedDirectory.lastComponentWithoutExtension for path in try localisedDirectory.children().sorted { $0.lastComponent < $1.lastComponent } { + guard fileReferencesByPath[path] == nil else { + continue + } + let filePath = "\(localisedDirectory.lastComponent)/\(path.lastComponent)" - let fileReference = PBXFileReference(reference: generateUUID(PBXFileReference.self, localisedDirectory.lastComponent), sourceTree: .group, name: localisedDirectory.lastComponentWithoutExtension, path: filePath) - addObject(fileReference) - let variantGroup = PBXVariantGroup(reference: generateUUID(PBXVariantGroup.self, path.lastComponent), children: [fileReference.reference], name: path.lastComponent, sourceTree: .group) - addObject(variantGroup) + // find base localisation variant group + let name = path.lastComponentWithoutExtension + let variantGroup = baseLocalisationVariantGroups.first(where: { Path($0.name).lastComponentWithoutExtension == name }) - fileReferencesByPath[path] = variantGroup.reference - groupChildren.append(variantGroup.reference) - allFilePaths.append(path) + let reference = PBXFileReference(reference: generateUUID(PBXFileReference.self, path.lastComponent), + sourceTree: .group, + name: variantGroup != nil ? localisationName : path.lastComponent, + path: filePath) + addObject(reference) + fileReferencesByPath[path] = reference.reference + let fileReference = reference.reference + + if let variantGroup = variantGroup { + variantGroup.children.append(fileReference) + } else { + // add SourceFile to group if there is no Base.lproj directory + let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference), + fileRef: fileReference, + settings: nil) + allSourceFiles.append(SourceFile(path: path, fileReference: fileReference, buildFile: buildFile)) + groupChildren.append(fileReference) + } } } @@ -528,6 +571,6 @@ public class PBXProjGenerator { groupsByPath[path] = group } groups.insert(group, at: 0) - return (allFilePaths, groups) + return (allSourceFiles, groups) } } From bc9c007c539900073b908a0c38c05c4da21d4767 Mon Sep 17 00:00:00 2001 From: ryohey Date: Wed, 27 Sep 2017 17:25:33 +0900 Subject: [PATCH 10/23] add test for variant groups --- .../Base.lproj/LocalizedStoryboard.storyboard | 7 ++++ .../en.lproj/LocalizedStoryboard.strings | 1 + Tests/XcodeGenKitTests/FixtureTests.swift | 38 ++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 Fixtures/TestProject/TestProject/Base.lproj/LocalizedStoryboard.storyboard create mode 100644 Fixtures/TestProject/TestProject/en.lproj/LocalizedStoryboard.strings diff --git a/Fixtures/TestProject/TestProject/Base.lproj/LocalizedStoryboard.storyboard b/Fixtures/TestProject/TestProject/Base.lproj/LocalizedStoryboard.storyboard new file mode 100644 index 00000000..f9a048ed --- /dev/null +++ b/Fixtures/TestProject/TestProject/Base.lproj/LocalizedStoryboard.storyboard @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Fixtures/TestProject/TestProject/en.lproj/LocalizedStoryboard.strings b/Fixtures/TestProject/TestProject/en.lproj/LocalizedStoryboard.strings new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Fixtures/TestProject/TestProject/en.lproj/LocalizedStoryboard.strings @@ -0,0 +1 @@ + diff --git a/Tests/XcodeGenKitTests/FixtureTests.swift b/Tests/XcodeGenKitTests/FixtureTests.swift index 644319af..8fad8542 100644 --- a/Tests/XcodeGenKitTests/FixtureTests.swift +++ b/Tests/XcodeGenKitTests/FixtureTests.swift @@ -6,7 +6,7 @@ import ProjectSpec let fixturePath = Path(#file).parent().parent().parent() + "Fixtures" -func generate(specPath: Path, projectPath: Path) throws { +func generate(specPath: Path, projectPath: Path) throws -> XcodeProj { let spec = try ProjectSpec(path: specPath) let generator = ProjectGenerator(spec: spec, path: specPath.parent()) let project = try generator.generateProject() @@ -17,13 +17,47 @@ func generate(specPath: Path, projectPath: Path) throws { if newProject != oldProject { throw failure("\(projectPath.string) has changed. If change is legitimate commit the change and run test again") } + + return newProject } func fixtureTests() { describe("Test Project") { + var project: XcodeProj? + $0.it("generates") { - try generate(specPath: fixturePath + "TestProject/spec.yml", projectPath: fixturePath + "TestProject/GeneratedProject.xcodeproj") + project = try generate(specPath: fixturePath + "TestProject/spec.yml", projectPath: fixturePath + "TestProject/GeneratedProject.xcodeproj") + } + + $0.it("generates variant group") { + guard let project = project else { throw failure("Project is not generated") } + + func getFileReferences(_ path: String) -> [PBXFileReference] { + return project.pbxproj.fileReferences.filter { $0.path == path } + } + + func getVariableGroups(_ name: String?) -> [PBXVariantGroup] { + return project.pbxproj.variantGroups.filter { $0.name == name } + } + + let resourceName = "LocalizedStoryboard.storyboard" + let baseResource = "Base.lproj/LocalizedStoryboard.storyboard" + let localizedResource = "en.lproj/LocalizedStoryboard.strings" + + guard let variableGroup = getVariableGroups(resourceName).first else { throw failure("Couldn't find the variable group") } + + do { + let refs = getFileReferences(baseResource) + try expect(refs.count) == 1 + try expect(variableGroup.children.filter { $0 == refs.first?.reference }.count) == 1 + } + + do { + let refs = getFileReferences(localizedResource) + try expect(refs.count) == 1 + try expect(variableGroup.children.filter { $0 == refs.first?.reference }.count) == 1 + } } } } From 859609158cbbe94930962c9c13848e3e7e46232c Mon Sep 17 00:00:00 2001 From: ryohey Date: Mon, 16 Oct 2017 11:49:52 +0900 Subject: [PATCH 11/23] fix localized sources --- Sources/XcodeGenKit/PBXProjGenerator.swift | 25 ++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index a990fd3e..c42defbb 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -527,23 +527,26 @@ public class PBXProjGenerator { for localisedDirectory in localisedDirectories { let localisationName = localisedDirectory.lastComponentWithoutExtension for path in try localisedDirectory.children().sorted { $0.lastComponent < $1.lastComponent } { - guard fileReferencesByPath[path] == nil else { - continue - } + let filePath = "\(localisedDirectory.lastComponent)/\(path.lastComponent)" // find base localisation variant group let name = path.lastComponentWithoutExtension - let variantGroup = baseLocalisationVariantGroups.first(where: { Path($0.name).lastComponentWithoutExtension == name }) + let variantGroup = baseLocalisationVariantGroups.first { Path($0.name).lastComponentWithoutExtension == name } - let reference = PBXFileReference(reference: generateUUID(PBXFileReference.self, path.lastComponent), - sourceTree: .group, - name: variantGroup != nil ? localisationName : path.lastComponent, - path: filePath) - addObject(reference) - fileReferencesByPath[path] = reference.reference - let fileReference = reference.reference + let fileReference: String + if let cachedFileReference = fileReferencesByPath[path] { + fileReference = cachedFileReference + } else { + let reference = PBXFileReference(reference: generateUUID(PBXFileReference.self, path.lastComponent), + sourceTree: .group, + name: variantGroup != nil ? localisationName : path.lastComponent, + path: filePath) + addObject(reference) + fileReference = reference.reference + fileReferencesByPath[path] = fileReference + } if let variantGroup = variantGroup { variantGroup.children.append(fileReference) From f2c440dd1dfcb50f654f74a87671f2e39a272f03 Mon Sep 17 00:00:00 2001 From: ryohey Date: Fri, 29 Sep 2017 14:44:17 +0900 Subject: [PATCH 12/23] update fixture --- .../project.pbxproj | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj index 384971a9..e5c2a476 100644 --- a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj +++ b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj @@ -10,12 +10,13 @@ BF1073850101 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR1332263601 /* AppDelegate.swift */; }; BF1462768401 = {isa = PBXBuildFile; fileRef = FR2653659501 /* TestProjectTests.xctest */; }; BF1744565901 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR6218091901 /* ViewController.swift */; }; - BF1911148401 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG6405436301 /* LaunchScreen.storyboard */; }; + BF2250910101 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG2043127501 /* Main.storyboard */; }; + BF2445564001 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG2858723001 /* LaunchScreen.storyboard */; }; + BF2513089601 /* LocalizedStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG3182922801 /* LocalizedStoryboard.storyboard */; }; BF2753556301 = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; }; BF3154421201 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FR5980633301 /* Assets.xcassets */; }; BF3515549501 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = FR7740960501 /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; BF3862341101 /* MyFramework.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - BF4946816301 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG1473702401 /* Main.storyboard */; }; BF5986511201 = {isa = PBXBuildFile; fileRef = FR6523263101 /* TestProject.app */; }; BF6182896901 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR9215298301 /* Result.framework */; }; BF9001417701 /* TestProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR6877173101 /* TestProjectTests.swift */; }; @@ -57,18 +58,20 @@ FR1345298501 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; FR1345298502 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; FR1345298503 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FR1473702401 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; FR2653659501 /* TestProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = xctest; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = TestProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; FR2993497801 /* MyFramework.framework */ = {isa = PBXFileReference; explicitFileType = framework; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = MyFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FR3546283901 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = ""; }; - FR3676338401 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - FR3676338402 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + FR4822987701 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LocalizedStoryboard.storyboard; sourceTree = ""; }; FR5980633301 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; FR6218091901 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; FR6334256101 /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = ""; }; + FR6405436301 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; FR6523263101 /* TestProject.app */ = {isa = PBXFileReference; explicitFileType = app; includeInIndex = 0; lastKnownFileType = wrapper.application; path = TestProject.app; sourceTree = BUILT_PRODUCTS_DIR; }; FR6877173101 /* TestProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProjectTests.swift; sourceTree = ""; }; FR7078510801 /* FrameworkFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FrameworkFile.swift; sourceTree = ""; }; FR7740960501 /* MyFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyFramework.h; sourceTree = ""; }; + FR8182352201 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LocalizedStoryboard.strings; sourceTree = ""; }; FR9215298301 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = ""; }; /* End PBXFileReference section */ @@ -138,8 +141,9 @@ FR5980633301 /* Assets.xcassets */, FR1345298502 /* Info.plist */, FR6218091901 /* ViewController.swift */, - VG6405436301 /* LaunchScreen.storyboard */, - VG1473702401 /* Main.storyboard */, + VG2858723001 /* LaunchScreen.storyboard */, + VG3182922801 /* LocalizedStoryboard.storyboard */, + VG2043127501 /* Main.storyboard */, ); name = TestProject; path = TestProject; @@ -305,8 +309,9 @@ buildActionMask = 2147483647; files = ( BF3154421201 /* Assets.xcassets in Resources */, - BF1911148401 /* LaunchScreen.storyboard in Resources */, - BF4946816301 /* Main.storyboard in Resources */, + BF2445564001 /* LaunchScreen.storyboard in Resources */, + BF2513089601 /* LocalizedStoryboard.storyboard in Resources */, + BF2250910101 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -415,22 +420,31 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - VG1473702401 /* Main.storyboard */ = { + VG2043127501 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - FR3676338402 /* Base */, + FR1473702401 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; - VG6405436301 /* LaunchScreen.storyboard */ = { + VG2858723001 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - FR3676338401 /* Base */, + FR6405436301 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; + VG3182922801 /* LocalizedStoryboard.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FR4822987701 /* Base */, + FR8182352201 /* en */, + ); + name = LocalizedStoryboard.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ From 5c39cf4e14d91f361a461c91d4c42cad272e5011 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 16 Oct 2017 21:28:08 -0700 Subject: [PATCH 13/23] Add support for copying Watch apps Watch apps aren't copied to the same place as other targets, they need their own copy files phase with a custom path just for watch targets. --- Sources/XcodeGenKit/PBXProjGenerator.swift | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index c42defbb..fa8764f1 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -230,6 +230,7 @@ public class PBXProjGenerator { var dependencies: [String] = [] var targetFrameworkBuildFiles: [String] = [] var copyFiles: [String] = [] + var copyWatchReferences: [String] = [] var extensions: [String] = [] for dependency in target.dependencies { @@ -260,6 +261,8 @@ public class PBXProjGenerator { if dependencyTarget.type.isExtension { // embed app extension extensions.append(embedFile.reference) + } else if dependencyTarget.type.isApp && dependencyTarget.platform == .watchOS { + copyWatchReferences.append(embedFile.reference) } else { copyFiles.append(embedFile.reference) } @@ -388,6 +391,18 @@ public class PBXProjGenerator { buildPhases.append(copyFilesPhase.reference) } + if !copyWatchReferences.isEmpty { + + let copyFilesPhase = PBXCopyFilesBuildPhase( + reference: generateUUID(PBXCopyFilesBuildPhase.self, "embed watch content" + target.name), + dstPath: "$(CONTENTS_FOLDER_PATH)/Watch", + dstSubfolderSpec: .productsDirectory, + files: copyWatchReferences) + + addObject(copyFilesPhase) + buildPhases.append(copyFilesPhase.reference) + } + let carthageFrameworksToEmbed = Array(Set(carthageDependencies .filter { $0.embed ?? true } .map { $0.reference })) @@ -511,7 +526,7 @@ public class PBXProjGenerator { name: path.lastComponent, sourceTree: .group) variantGroupsByPath[path] = variantGroup - + addObject(variantGroup) groupChildren.append(variantGroup.reference) } From 3ab707170303ac53a952fe78e19d6fdb7de30d81 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 16 Oct 2017 20:39:33 -0700 Subject: [PATCH 14/23] Exclude more file types from resources Entitlements files, gpx files, and explicit lproj directories should never be included in a target's copy resources phase. Ideally this would also include files with the plist extension, but there are some outliers such as AppIntentVocabulary.plist. --- Sources/XcodeGenKit/PBXProjGenerator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index c42defbb..d8e59144 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -450,7 +450,7 @@ public class PBXProjGenerator { switch fileExtension { case "swift", "m", "cpp": return .sources case "h", "hh", "hpp", "ipp", "tpp", "hxx", "def": return .headers - case "xcconfig": return nil + case "xcconfig", "entitlements", "gpx", "lproj", "apns": return nil default: return .resources } } From d24df8677ce51040cae76a7967c2f905503bb0c9 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 16 Oct 2017 20:59:44 -0700 Subject: [PATCH 15/23] Allow copying of resource files from targets Previously we were assuming that all targets that were not app extensions should be added to the copy frameworks build phase, even though we didn't have any guarantee they were actually frameworks. This updates that to ensure that things copied in the copy frameworks phase are actually frameworks, and then falls back to the resources phase instead. This fixes the ability to embed bundle targets, and copy them as resources. --- Sources/ProjectSpec/ProjectExtensions.swift | 4 ++++ Sources/XcodeGenKit/PBXProjGenerator.swift | 17 ++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Sources/ProjectSpec/ProjectExtensions.swift b/Sources/ProjectSpec/ProjectExtensions.swift index eedb2c79..ef05cac1 100644 --- a/Sources/ProjectSpec/ProjectExtensions.swift +++ b/Sources/ProjectSpec/ProjectExtensions.swift @@ -46,6 +46,10 @@ extension PBXProductType { } } + public var isFramework: Bool { + return fileExtension == "framework" + } + public var isExtension: Bool { return fileExtension == "appex" } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index fa8764f1..e33a96d1 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -229,7 +229,8 @@ public class PBXProjGenerator { var dependencies: [String] = [] var targetFrameworkBuildFiles: [String] = [] - var copyFiles: [String] = [] + var copyFrameworksReferences: [String] = [] + var copyResourcesReferences: [String] = [] var copyWatchReferences: [String] = [] var extensions: [String] = [] @@ -261,10 +262,12 @@ public class PBXProjGenerator { if dependencyTarget.type.isExtension { // embed app extension extensions.append(embedFile.reference) + } else if dependencyTarget.type.isFramework { + copyFrameworksReferences.append(embedFile.reference) } else if dependencyTarget.type.isApp && dependencyTarget.platform == .watchOS { copyWatchReferences.append(embedFile.reference) } else { - copyFiles.append(embedFile.reference) + copyResourcesReferences.append(embedFile.reference) } } @@ -283,7 +286,7 @@ public class PBXProjGenerator { if embed { let embedFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference + target.name), fileRef: fileReference, settings: dependency.buildSettings) addObject(embedFile) - copyFiles.append(embedFile.reference) + copyFrameworksReferences.append(embedFile.reference) } case .carthage: if carthageFrameworksByPlatform[target.platform.carthageDirectoryName] == nil { @@ -304,7 +307,7 @@ public class PBXProjGenerator { if target.platform == .macOS && target.type.isApp { let embedFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference + target.name), fileRef: fileReference, settings: dependency.buildSettings) addObject(embedFile) - copyFiles.append(embedFile.reference) + copyFrameworksReferences.append(embedFile.reference) } } } @@ -348,7 +351,7 @@ public class PBXProjGenerator { addObject(sourcesBuildPhase) buildPhases.append(sourcesBuildPhase.reference) - let resourcesBuildPhase = PBXResourcesBuildPhase(reference: generateUUID(PBXResourcesBuildPhase.self, target.name), files: getBuildFilesForPhase(.resources)) + let resourcesBuildPhase = PBXResourcesBuildPhase(reference: generateUUID(PBXResourcesBuildPhase.self, target.name), files: getBuildFilesForPhase(.resources) + copyResourcesReferences) addObject(resourcesBuildPhase) buildPhases.append(resourcesBuildPhase.reference) @@ -379,13 +382,13 @@ public class PBXProjGenerator { buildPhases.append(copyFilesPhase.reference) } - if !copyFiles.isEmpty { + if !copyFrameworksReferences.isEmpty { let copyFilesPhase = PBXCopyFilesBuildPhase( reference: generateUUID(PBXCopyFilesBuildPhase.self, "embed frameworks" + target.name), dstPath: "", dstSubfolderSpec: .frameworks, - files: copyFiles) + files: copyFrameworksReferences) addObject(copyFilesPhase) buildPhases.append(copyFilesPhase.reference) From 739b9f36f70bc6c47711ef44473d0b2eac398326 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 16 Oct 2017 18:18:28 -0700 Subject: [PATCH 16/23] Link framework and library dependencies --- .../GeneratedProject.xcodeproj/project.pbxproj | 2 ++ Sources/ProjectSpec/ProjectExtensions.swift | 8 ++++++++ Sources/XcodeGenKit/PBXProjGenerator.swift | 13 ++++++++----- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj index e5c2a476..ce7e60b9 100644 --- a/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj +++ b/Fixtures/TestProject/GeneratedProject.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ BF3862341101 /* MyFramework.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF5986511201 = {isa = PBXBuildFile; fileRef = FR6523263101 /* TestProject.app */; }; BF6182896901 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR9215298301 /* Result.framework */; }; + BF7015992001 /* MyFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR2993497801 /* MyFramework.framework */; }; BF9001417701 /* TestProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR6877173101 /* TestProjectTests.swift */; }; BF9155249601 /* FrameworkFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR7078510801 /* FrameworkFile.swift */; }; /* End PBXBuildFile section */ @@ -80,6 +81,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + BF7015992001 /* MyFramework.framework in Frameworks */, BF6182896901 /* Result.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/ProjectSpec/ProjectExtensions.swift b/Sources/ProjectSpec/ProjectExtensions.swift index eedb2c79..93317b58 100644 --- a/Sources/ProjectSpec/ProjectExtensions.swift +++ b/Sources/ProjectSpec/ProjectExtensions.swift @@ -46,6 +46,14 @@ extension PBXProductType { } } + public var isFramework: Bool { + return self == .framework + } + + public var isLibrary: Bool { + return self == .staticLibrary || self == .dynamicLibrary + } + public var isExtension: Bool { return fileExtension == "appex" } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index fa8764f1..f0f9e9f4 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -25,7 +25,7 @@ public class PBXProjGenerator { var variantGroupsByPath: [Path: PBXVariantGroup] = [:] var targetNativeReferences: [String: String] = [:] - var targetBuildFileReferences: [String: String] = [:] + var targetBuildFiles: [String: PBXBuildFile] = [:] var targetFileReferences: [String: String] = [:] var topLevelGroups: [PBXGroup] = [] var carthageFrameworksByPlatform: [String: [String]] = [:] @@ -93,7 +93,7 @@ public class PBXProjGenerator { let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, fileReference.reference), fileRef: fileReference.reference) addObject(buildFile) - targetBuildFileReferences[target.name] = buildFile.reference + targetBuildFiles[target.name] = buildFile } let targets = try spec.targets.map(generateTarget) @@ -249,9 +249,12 @@ public class PBXProjGenerator { addObject(targetDependency) dependencies.append(targetDependency.reference) - // don't bother linking a target dependency - // let dependencyBuildFile = targetBuildFileReferences[dependencyTargetName]! - // targetFrameworkBuildFiles.append(dependencyBuildFile) + if dependencyTarget.type.isLibrary || dependencyTarget.type.isFramework { + let dependencyBuildFile = targetBuildFiles[dependencyTargetName]! + let buildFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, dependencyBuildFile.reference + target.name), fileRef: dependencyBuildFile.fileRef) + addObject(buildFile) + targetFrameworkBuildFiles.append(buildFile.reference) + } if embed { let embedSettings = dependency.buildSettings From 5c90d6189c12b1a55f895023d3c249c21d693ee8 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 16 Oct 2017 18:18:46 -0700 Subject: [PATCH 17/23] Don't copy libraries These should only be linked. If we add a library to the project here, Xcode will remove it next time it touches the project --- Sources/XcodeGenKit/PBXProjGenerator.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index f0f9e9f4..99dd66e9 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -256,7 +256,8 @@ public class PBXProjGenerator { targetFrameworkBuildFiles.append(buildFile.reference) } - if embed { + if embed && !dependencyTarget.type.isLibrary { + let embedSettings = dependency.buildSettings let embedFile = PBXBuildFile(reference: generateUUID(PBXBuildFile.self, dependencyFileReference + target.name), fileRef: dependencyFileReference, settings: embedSettings) addObject(embedFile) From 894f00428acef143037cbe8dec88226f48bb79ad Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Tue, 17 Oct 2017 10:09:22 -0700 Subject: [PATCH 18/23] Add tests for PBXProductType booleans --- Tests/LinuxMain.swift | 1 + Tests/XcodeGenKitTests/ProjectSpecTests.swift | 28 +++++++++++++++++++ Tests/XcodeGenKitTests/XCTest.swift | 1 + 3 files changed, 30 insertions(+) create mode 100644 Tests/XcodeGenKitTests/ProjectSpecTests.swift diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 9df44975..7d5c97d1 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -5,4 +5,5 @@ XCTMain([ testCase(GeneratorTests.allTests), testCase(SpecLoadingTests.allTests), testCase(FixtureTests.allTests), + testCase(ProjectSpecTests.allTests), ]) diff --git a/Tests/XcodeGenKitTests/ProjectSpecTests.swift b/Tests/XcodeGenKitTests/ProjectSpecTests.swift new file mode 100644 index 00000000..ae5ec8ad --- /dev/null +++ b/Tests/XcodeGenKitTests/ProjectSpecTests.swift @@ -0,0 +1,28 @@ +import Spectre +import XcodeGenKit +import xcproj +import ProjectSpec + +func projectSpecTests() { + + describe("ProjectSpec") { + + let framework = Target(name: "MyFramework", type: .framework, platform: .iOS, + settings: Settings(buildSettings: ["SETTING_2": "VALUE"])) + let staticLibrary = Target(name: "MyStaticLibrary", type: .staticLibrary, platform: .iOS, + settings: Settings(buildSettings: ["SETTING_2": "VALUE"])) + let dynamicLibrary = Target(name: "MyDynamicLibrary", type: .dynamicLibrary, platform: .iOS, + settings: Settings(buildSettings: ["SETTING_2": "VALUE"])) + + $0.describe("Types") { + $0.it("is a framework when it has the right extension") { + try expect(framework.type.isFramework).to.beTrue() + } + + $0.it("is a library when it has the right type") { + try expect(staticLibrary.type.isLibrary).to.beTrue() + try expect(dynamicLibrary.type.isLibrary).to.beTrue() + } + } + } +} diff --git a/Tests/XcodeGenKitTests/XCTest.swift b/Tests/XcodeGenKitTests/XCTest.swift index cb066129..e989d4bc 100644 --- a/Tests/XcodeGenKitTests/XCTest.swift +++ b/Tests/XcodeGenKitTests/XCTest.swift @@ -7,5 +7,6 @@ class XCodeGenKitTests: XCTestCase { projectGeneratorTests() specLoadingTests() fixtureTests() + projectSpecTests() } } From 98f89ee758e4d8586d702d515a704917db4de66d Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Wed, 18 Oct 2017 08:58:28 -0700 Subject: [PATCH 19/23] Make build a PHONY task This solves the issue where if someone is generating a xcodeproj to work on XcodeGen, and their build directories are local, this command would assume that it should only run if something in that directory is changed, which isn't the case, we want it to run all the time and for swiftpm to decide if something has changed. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 1aab87e7..3fc7958a 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ install: build mkdir -p $(SHARE_PATH) cp -R $(CURRENT_PATH)/SettingPresets $(SHARE_PATH)/SettingPresets +.PHONY: build build: swift build --disable-sandbox -c release -Xswiftc -static-stdlib From 84437181eef1b9e99899772f6a6d1324ff780802 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Wed, 18 Oct 2017 10:40:53 -0700 Subject: [PATCH 20/23] Correct README --help argument This needs dashes, if you run it without it XcodeGen does print some help but only because the command failed. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ac6b6dc..9e043f90 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ $ xcodegen This will look for a project spec in the current directory called `project.yml` -Use `xcodegen help` to see the list of options: +Use `xcodegen --help` to see the list of options: - **--spec**: An optional path to a `.yml` or `.json` project spec - **--project**: An optional path to a directory where the project will be generated. By default this is the current directory From 6135fa66efd9311bf6350354f2c4aa92cc9928f0 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Thu, 19 Oct 2017 18:31:09 +0100 Subject: [PATCH 21/23] Add slack badge to the readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9e043f90..7242769a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,9 @@ + + +

# XcodeGen From 6a9de2208a8caaccf83fdaa261b72d467344f266 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Fri, 20 Oct 2017 12:24:52 +0100 Subject: [PATCH 22/23] don't apply base project settings if config doesn't have a type --- Sources/XcodeGenKit/SettingsBuilder.swift | 3 +-- Tests/XcodeGenKitTests/ProjectGeneratorTests.swift | 9 +++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Sources/XcodeGenKit/SettingsBuilder.swift b/Sources/XcodeGenKit/SettingsBuilder.swift index d549d070..6c81e28c 100644 --- a/Sources/XcodeGenKit/SettingsBuilder.swift +++ b/Sources/XcodeGenKit/SettingsBuilder.swift @@ -16,11 +16,10 @@ import JSONUtilities extension ProjectSpec { public func getProjectBuildSettings(config: Config) -> BuildSettings { - var buildSettings: BuildSettings = [:] - buildSettings += SettingsPresetFile.base.getBuildSettings() if let type = config.type { + buildSettings += SettingsPresetFile.base.getBuildSettings() buildSettings += SettingsPresetFile.config(type).getBuildSettings() } diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 6655c1ed..6fb551a8 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -62,6 +62,15 @@ func projectGeneratorTests() { try expect(configs).contains(name: "config1") try expect(configs).contains(name: "config2") } + + $0.it("clears config settings when missing type") { + let spec = ProjectSpec(name: "test", configs: [Config(name: "config")]) + let project = try getProject(spec) + guard let config = project.pbxproj.buildConfigurations.first else { + throw failure("configuration not found") + } + try expect(config.buildSettings.isEmpty).to.beTrue() + } $0.it("merges settings") { let spec = try ProjectSpec(path: fixturePath + "settings_test.yml") From 55d72d649c7df3d5b66da9bb9b1e3eb8fcb50be1 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Fri, 20 Oct 2017 13:09:31 +0100 Subject: [PATCH 23/23] updated changelog --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 119a371c..fa719390 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,26 @@ ## Master +### Added +- generate output files for Carthage copy-frameworks script [#84](https://github.com/yonaskolb/XcodeGen/pull/84) @mironal + +### Changed +- updated to xcproj 0.4.1 [#85](https://github.com/yonaskolb/XcodeGen/pull/85) @enmiller +- don't copy base settings if config type has been left out [#100](https://github.com/yonaskolb/XcodeGen/pull/100) @yonaskolb +- generate localised files under a single variant group [#70](https://github.com/yonaskolb/XcodeGen/pull/70) @ryohey + +### Fixed +- embed Carthage frameworks for macOS [#82](https://github.com/yonaskolb/XcodeGen/pull/82) @toshi0383 +- fixed copying of watchOS app resources [#96](https://github.com/yonaskolb/XcodeGen/pull/96) @keith +- automatically ignore more file types for a target's sources (entitlements, gpx, apns) [#94](https://github.com/yonaskolb/XcodeGen/pull/94) @keith +- change make build to a PHONY task [#98](https://github.com/yonaskolb/XcodeGen/pull/98) @keith +- allow copying of resource files from dependant targets [#95](https://github.com/yonaskolb/XcodeGen/pull/95) @keith +- fixed library linking [#93](https://github.com/yonaskolb/XcodeGen/pull/93) @keith + + + + + ## 1.2.4 ### Fixed