diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index 376c0153f..1376aa724 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -147,7 +147,8 @@ extension Project { for target in aggregateTargets { for dependency in target.targets { - if getProjectTarget(dependency) == nil { + if getProjectTarget(dependency) == nil, let projectName = dependency.components(separatedBy: "/").first, + (getPackage(projectName) == nil && getProjectReference(projectName) == nil) { errors.append(.invalidTargetDependency(target: target.name, dependency: dependency)) } } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 60ebdfca3..927ddbfc0 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -336,7 +336,33 @@ public class PBXProjGenerator { return addObject(buildConfig) } - let dependencies = target.targets.map { generateTargetDependency(from: target.name, to: $0, platform: nil) } + let dependencies: [PBXTargetDependency] = target.targets.map { + let dependency = $0 + if dependency.contains("/") && dependency.components(separatedBy: "/").count == 2 { + let tokens: [String] = dependency.components(separatedBy: "/") + let projectName: String = tokens[0] + let targetName: String = tokens[1] + + if nil != project.packages[projectName] { + let productName = targetName + let packageDependency = addObject( + XCSwiftPackageProductDependency(productName: productName) + ) + + let targetDependency = addObject( + PBXTargetDependency( product: packageDependency) + ) + return targetDependency + } + + do { + return try generateExternalTargetDependency(from: target.name, to: targetName, in: projectName, platform: .iOS).0 + } catch { + print("Error: \(error)") + } + } + return generateTargetDependency(from: target.name, to: $0, platform: nil) + } let defaultConfigurationName = project.options.defaultConfig ?? project.configs.first?.name ?? "" let buildConfigList = addObject(XCConfigurationList( diff --git a/Tests/Fixtures/paths_test/included_paths_test.yml b/Tests/Fixtures/paths_test/included_paths_test.yml index f40bf5aed..4606b7063 100644 --- a/Tests/Fixtures/paths_test/included_paths_test.yml +++ b/Tests/Fixtures/paths_test/included_paths_test.yml @@ -32,6 +32,7 @@ aggregateTargets: IncludedAggregateTarget: targets: - IncludedTarget + - AnotherProject/ExternalTarget configFiles: Config: config buildScripts: diff --git a/Tests/ProjectSpecTests/SpecLoadingTests.swift b/Tests/ProjectSpecTests/SpecLoadingTests.swift index 0c9c96657..380f842f7 100644 --- a/Tests/ProjectSpecTests/SpecLoadingTests.swift +++ b/Tests/ProjectSpecTests/SpecLoadingTests.swift @@ -97,7 +97,7 @@ class SpecLoadingTests: XCTestCase { try expect(project.aggregateTargets) == [ AggregateTarget( name: "IncludedAggregateTarget", - targets: ["IncludedTarget"], + targets: ["IncludedTarget", "AnotherProject/ExternalTarget"], configFiles: ["Config": "paths_test/config"], buildScripts: [BuildScript(script: .path("paths_test/buildScript"))] ), diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 4ed5ae082..72fa201d4 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -243,12 +243,21 @@ class ProjectGeneratorTests: XCTestCase { func testAggregateTargets() { describe { - + let externalProjectPath = fixturePath + "TestProject/AnotherProject/AnotherProject.xcodeproj" + let projectReference1 = ProjectReference(name: "AnotherProject", path: externalProjectPath.string) + + var target = app + target.dependencies = [ + Dependency(type: .target, reference: "AnotherProject/ExternalTarget") + ] + let otherTarget = Target(name: "Other", type: .framework, platform: .iOS, dependencies: [Dependency(type: .target, reference: "AggregateTarget")]) let otherTarget2 = Target(name: "Other2", type: .framework, platform: .iOS, dependencies: [Dependency(type: .target, reference: "Other")], transitivelyLinkDependencies: true) - let aggregateTarget = AggregateTarget(name: "AggregateTarget", targets: ["MyApp", "MyFramework"]) + let aggregateTarget = AggregateTarget(name: "AggregateTarget", targets: ["MyApp", "MyFramework", "AnotherProject/ExternalTarget"]) let aggregateTarget2 = AggregateTarget(name: "AggregateTarget2", targets: ["AggregateTarget"]) - let project = Project(name: "test", targets: [app, framework, otherTarget, otherTarget2], aggregateTargets: [aggregateTarget, aggregateTarget2]) + + let project = Project(name: "test", targets: [target, framework, otherTarget, otherTarget2], aggregateTargets: [aggregateTarget, aggregateTarget2], projectReferences: [projectReference1]) + $0.it("generates aggregate targets") { let pbxProject = try project.generatePbxProj() @@ -259,7 +268,7 @@ class ProjectGeneratorTests: XCTestCase { try expect(aggregateTargets.count) == 2 let aggregateTarget1 = aggregateTargets.first { $0.name == "AggregateTarget" } - try expect(aggregateTarget1?.dependencies.count) == 2 + try expect(aggregateTarget1?.dependencies.count) == 3 let aggregateTarget2 = aggregateTargets.first { $0.name == "AggregateTarget2" } try expect(aggregateTarget2?.dependencies.count) == 1 @@ -270,7 +279,7 @@ class ProjectGeneratorTests: XCTestCase { let target2 = nativeTargets.first { $0.name == "Other2" } try expect(target2?.dependencies.count) == 2 - try expect(pbxProject.targetDependencies.count) == 7 + try expect(pbxProject.targetDependencies.count) == 8 } } }