diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index f4fab391..5561483e 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -456,15 +456,25 @@ public class PBXProjGenerator { return "\(carthagePath)/\(platformName)" } - func getAllCarthageDependencies(target: Target) -> [Dependency] { + func getAllCarthageDependencies(target: Target, visitedTargets: [String: Bool] = [:]) -> [Dependency] { + + // this is used to resolve cyclical target dependencies + var visitedTargets = visitedTargets + visitedTargets[target.name] = true + var frameworks: [Dependency] = [] + for dependency in target.dependencies { switch dependency.type { case .carthage: frameworks.append(dependency) case .target: - if let target = spec.getTarget(dependency.reference) { - frameworks += getAllCarthageDependencies(target: target) + let targetName = dependency.reference + if visitedTargets[targetName] == true { + return [] + } + if let target = spec.getTarget(targetName) { + frameworks += getAllCarthageDependencies(target: target, visitedTargets: visitedTargets) } default: break } diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index ab4189a3..8697fa52 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -13,7 +13,6 @@ func projectGeneratorTests() { } func getPbxProj(_ spec: ProjectSpec) throws -> PBXProj { - try spec.validate() let project = try getProject(spec).pbxproj try project.validate() return project @@ -171,6 +170,14 @@ func projectGeneratorTests() { try expect(script1.shellScript) == "script1" try expect(script2.shellScript) == "script2" } + + $0.it("generates targets with cylical dependencies") { + let target1 = Target(name: "target1", type: .framework, platform: .iOS, dependencies: [Dependency(type: .target, reference: "target2")]) + let target2 = Target(name: "target2", type: .framework, platform: .iOS, dependencies: [Dependency(type: .target, reference: "target1")]) + let spec = ProjectSpec(basePath: "", name: "test", targets: [target1, target2]) + + _ = try getPbxProj(spec) + } } $0.describe("Schemes") {