in src/TulsiGenerator/PBXTargetGenerator.swift [833:925]
func generateBuildTargetsForRuleEntries(
_ ruleEntries: Set<RuleEntry>,
ruleEntryMap: RuleEntryMap,
pathFilters: Set<String>?
) throws -> [BuildLabel: PBXNativeTarget] {
let namedRuleEntries = generateUniqueNamesForRuleEntries(ruleEntries)
let progressNotifier = ProgressNotifier(name: GeneratingBuildTargets,
maxValue: namedRuleEntries.count)
var testTargetLinkages = [(PBXNativeTarget, BuildLabel?, RuleEntry)]()
var watchAppTargets = [String: (PBXNativeTarget, RuleEntry)]()
var watchExtensionsByEntry = [RuleEntry: PBXNativeTarget]()
var targetsByLabel = [BuildLabel: PBXNativeTarget]()
for (name, entry) in namedRuleEntries {
progressNotifier.incrementValue()
let target = try createBuildTargetForRuleEntry(entry,
named: name,
ruleEntryMap: ruleEntryMap)
targetsByLabel[entry.label] = target
if let script = options[.PreBuildPhaseRunScript, entry.label.value] {
let runScript = PBXShellScriptBuildPhase(shellScript: script, shellPath: "/bin/bash")
runScript.showEnvVarsInLog = true
target.buildPhases.insert(runScript, at: 0)
}
if let script = options[.PostBuildPhaseRunScript, entry.label.value] {
let runScript = PBXShellScriptBuildPhase(shellScript: script, shellPath: "/bin/bash")
runScript.showEnvVarsInLog = true
target.buildPhases.append(runScript)
}
if let hostLabelString = entry.attributes[.test_host] as? String {
let hostLabel = BuildLabel(hostLabelString)
testTargetLinkages.append((target, hostLabel, entry))
} else if entry.pbxTargetType == .UnitTest {
// If there is no host and it's a unit test, assume it doesn't need one, i.e. it's a
// library based test.
testTargetLinkages.append((target, nil, entry))
}
switch entry.pbxTargetType {
case .Watch2App?:
watchAppTargets[name] = (target, entry)
case .Watch2Extension?:
watchExtensionsByEntry[entry] = target
default:
break
}
}
// The watch app target must have an explicit dependency on the watch extension target.
for (_, (watchAppTarget, watchRuleEntry)) in watchAppTargets {
for ext in watchRuleEntry.extensions {
if let extEntry = ruleEntryMap.ruleEntry(buildLabel: ext, depender: watchRuleEntry),
extEntry.pbxTargetType == .Watch2Extension {
if let watchExtensionTarget = watchExtensionsByEntry[extEntry] {
watchAppTarget.createDependencyOn(watchExtensionTarget, proxyType: .targetReference, inProject: project)
} else {
localizedMessageLogger.warning("FindingWatchExtensionFailed",
comment: "Message to show when the watchOS app extension %1$@ could not be found and the resulting project will not be able to launch the watch app.",
values: extEntry.label.value)
}
}
}
}
for (testTarget, testHostLabel, entry) in testTargetLinkages {
let testHostTarget: PBXNativeTarget?
if let hostTargetLabel = testHostLabel {
testHostTarget = targetsByLabel[hostTargetLabel]
if testHostTarget == nil {
// If the user did not choose to include the host target it won't be available so the
// linkage can be skipped. We will still force the generation of this test host target to
// avoid issues when running tests as bundle targets in Xcode.
localizedMessageLogger.warning("MissingTestHost",
comment: "Warning to show when a user has selected an XCTest but not its host application.",
values: entry.label.value, hostTargetLabel.value)
continue
}
} else {
testHostTarget = nil
}
updateTestTarget(testTarget,
withLinkageToHostTarget: testHostTarget,
ruleEntry: entry,
ruleEntryMap: ruleEntryMap,
pathFilters: pathFilters)
}
return targetsByLabel
}