Merge pull request #381 from yonaskolb/aggregate_dependency

Allow aggregateTargets to be dependencies
This commit is contained in:
Yonas Kolb 2018-08-19 14:21:10 +10:00 committed by GitHub
commit 871b4b900d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 32 deletions

View File

@ -6,7 +6,7 @@
- Added `showEnvVars` to build scripts to disable printing the environment [351](https://github.com/yonaskolb/XcodeGen/pull/351) @keith
- Added `requiresObjCLinking` to `target` [354](https://github.com/yonaskolb/XcodeGen/pull/354) @brentleyjones
- Added `targetTemplates` [355](https://github.com/yonaskolb/XcodeGen/pull/355) @yonaskolb
- Added `aggregateTargets` [353](https://github.com/yonaskolb/XcodeGen/pull/353) @yonaskolb
- Added `aggregateTargets` [353](https://github.com/yonaskolb/XcodeGen/pull/353) [381](https://github.com/yonaskolb/XcodeGen/pull/381) @yonaskolb
- Added `options.groupSortPosition` [356](https://github.com/yonaskolb/XcodeGen/pull/356) @yonaskolb
- Added ability to specify `copyFiles` build phase for sources [345](https://github.com/yonaskolb/XcodeGen/pull/345) @brentleyjones
- Added ability to specify a `minimumXcodeGenVersion` [349](https://github.com/yonaskolb/XcodeGen/pull/349) @brentleyjones

View File

@ -60,6 +60,10 @@ public struct Project: BuildSettingsContainer {
return targetsMap[targetName]
}
public func getProjectTarget(_ targetName: String) -> ProjectTarget? {
return targetsMap[targetName] ?? aggregateTargets.first { $0.name == targetName }
}
public func getConfig(_ configName: String) -> Config? {
return configs.first { $0.name == configName }
}

View File

@ -112,7 +112,7 @@ extension Project {
for target in aggregateTargets {
for dependency in target.targets {
if getTarget(dependency) == nil {
if getProjectTarget(dependency) == nil {
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency))
}
}
@ -120,7 +120,7 @@ extension Project {
for target in targets {
for dependency in target.dependencies {
if dependency.type == .target, getTarget(dependency.reference) == nil {
if dependency.type == .target, getProjectTarget(dependency.reference) == nil {
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
}
}

View File

@ -152,6 +152,18 @@ public class PBXProjGenerator {
}
}
for target in project.aggregateTargets {
let aggregateTarget = createObject(
id: target.name,
PBXAggregateTarget(
name: target.name,
productName: target.name
)
)
targetAggregateObjects[target.name] = aggregateTarget
}
try project.targets.forEach(generateTarget)
try project.aggregateTargets.forEach(generateAggregateTarget)
@ -228,6 +240,8 @@ public class PBXProjGenerator {
func generateAggregateTarget(_ target: AggregateTarget) throws {
let aggregateTarget = targetAggregateObjects[target.name]!.object
let configs: [ObjectReference<XCBuildConfiguration>] = project.configs.map { config in
let buildSettings = project.getBuildSettings(settings: target.settings, config: config)
@ -254,29 +268,20 @@ public class PBXProjGenerator {
var buildPhases: [String] = []
buildPhases += try target.buildScripts.map { try generateBuildScript(targetName: target.name, buildScript: $0) }
let aggregateTarget = createObject(
id: target.name,
PBXAggregateTarget(
name: target.name,
buildConfigurationList: buildConfigList.reference,
buildPhases: buildPhases,
buildRules: [],
dependencies: dependencies,
productName: target.name,
productReference: nil,
productType: nil
)
)
targetAggregateObjects[target.name] = aggregateTarget
aggregateTarget.buildPhases = buildPhases
aggregateTarget.buildConfigurationList = buildConfigList.reference
aggregateTarget.dependencies = dependencies
}
func generateTargetDependency(from: String, to target: String) -> ObjectReference<PBXTargetDependency> {
guard let targetReference = targetObjects[target]?.reference ?? targetAggregateObjects[target]?.reference else {
fatalError("target not found")
}
let targetProxy = createObject(
id: "\(from)-\(target)",
PBXContainerItemProxy(
containerPortal: pbxProj.rootObject,
remoteGlobalIDString: targetObjects[target]!.reference,
remoteGlobalIDString: targetReference,
proxyType: .nativeTarget,
remoteInfo: target
)
@ -285,7 +290,7 @@ public class PBXProjGenerator {
let targetDependency = createObject(
id: "\(from)-\(target)",
PBXTargetDependency(
target: targetObjects[target]!.reference,
target: targetReference,
targetProxy: targetProxy.reference
)
)
@ -459,13 +464,13 @@ public class PBXProjGenerator {
switch dependency.type {
case .target:
let dependencyTargetName = dependency.reference
guard let dependencyTarget = project.getTarget(dependencyTargetName) else { continue }
let dependencyFileReference = targetFileReferences[dependencyTargetName]!
let targetDependency = generateTargetDependency(from: target.name, to: dependencyTargetName)
dependencies.append(targetDependency.reference)
guard let dependencyTarget = project.getTarget(dependencyTargetName) else { continue }
let dependencyFileReference = targetFileReferences[dependencyTargetName]!
let dependecyLinkage = dependencyTarget.defaultLinkage
let link = dependency.link ?? ((dependecyLinkage == .dynamic && target.type != .staticLibrary)
|| (dependecyLinkage == .static && target.type.isExecutable))

View File

@ -190,22 +190,29 @@ class ProjectGeneratorTests: XCTestCase {
func testAggregateTargets() {
describe {
let otherTarget = Target(name: "Other", type: .framework, platform: .iOS, dependencies: [Dependency(type: .target, reference: "AggregateTarget")])
let aggregateTarget = AggregateTarget(name: "AggregateTarget", targets: ["MyApp", "MyFramework"])
let project = Project(basePath: "", name: "test", targets: targets, aggregateTargets: [aggregateTarget])
let aggregateTarget2 = AggregateTarget(name: "AggregateTarget2", targets: ["AggregateTarget"])
let project = Project(basePath: "", name: "test", targets: [app, framework, otherTarget], aggregateTargets: [aggregateTarget, aggregateTarget2])
$0.it("generates aggregate targets") {
let pbxProject = try project.generatePbxProj()
let nativeTargets = pbxProject.objects.nativeTargets.referenceValues
let aggregateTargets = pbxProject.objects.aggregateTargets.referenceValues
try expect(aggregateTargets.count) == 1
guard let pbxAggregateTarget = aggregateTargets.first else {
throw failure("Couldn't find AggregateTarget")
}
try expect(pbxAggregateTarget.name) == "AggregateTarget"
try expect(pbxAggregateTarget.dependencies.count) == 2
try expect(nativeTargets.count) == 3
try expect(aggregateTargets.count) == 2
try expect(aggregateTargets[0].name) == "AggregateTarget"
try expect(aggregateTargets[0].dependencies.count) == 2
try expect(aggregateTargets[1].name) == "AggregateTarget2"
try expect(aggregateTargets[1].dependencies.count) == 1
try expect(nativeTargets[2].dependencies.count) == 1
let targetDependencies = pbxProject.objects.targetDependencies.referenceValues
try expect(targetDependencies.count) == 4
try expect(targetDependencies.count) == 5
}
}
}