Skip to content

Commit db21128

Browse files
authored
Merge pull request #78401 from hamishknight/xcodegen-tweaks
[xcodegen] A couple of minor tweaks
2 parents eb6933b + ddfe63b commit db21128

File tree

6 files changed

+40
-57
lines changed

6 files changed

+40
-57
lines changed

utils/swift-xcodegen/Sources/SwiftXcodeGen/BuildArgs/SwiftTargets.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ struct SwiftTargets {
285285

286286
func getTargets(below path: RelativePath) -> [SwiftTarget] {
287287
targets.filter { target in
288-
guard let parent = target.buildRule?.parentPath, parent.hasPrefix(path)
288+
guard let parent = target.buildRule?.parentPath, parent.starts(with: path)
289289
else {
290290
return false
291291
}

utils/swift-xcodegen/Sources/SwiftXcodeGen/Generator/ClangTarget.swift

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
struct ClangTarget {
1414
var name: String
1515
var parentPath: RelativePath
16-
var sources: [Source]
17-
var unbuildableSources: [Source]
16+
var sources: [RelativePath]
17+
var unbuildableSources: [RelativePath]
1818
var headers: [RelativePath]
1919

2020
init(
2121
name: String, parentPath: RelativePath,
22-
sources: [Source], unbuildableSources: [Source] = [],
22+
sources: [RelativePath], unbuildableSources: [RelativePath] = [],
2323
headers: [RelativePath]
2424
) {
2525
self.name = name
@@ -30,13 +30,6 @@ struct ClangTarget {
3030
}
3131
}
3232

33-
extension ClangTarget {
34-
struct Source {
35-
var path: RelativePath
36-
var inferArgs: Bool
37-
}
38-
}
39-
4033
extension RepoBuildDir {
4134
func getCSourceFilePaths(for path: RelativePath) throws -> [RelativePath] {
4235
try getAllRepoSubpaths(of: path).filter(\.isCSourceLike)
@@ -58,24 +51,15 @@ extension RepoBuildDir {
5851
return nil
5952
}
6053

61-
var sources: [ClangTarget.Source] = []
62-
var unbuildableSources: [ClangTarget.Source] = []
54+
var sources: [RelativePath] = []
55+
var unbuildableSources: [RelativePath] = []
6356
for path in sourcePaths {
64-
let source: ClangTarget.Source? =
65-
if try clangArgs.hasBuildArgs(for: path) {
66-
.init(path: path, inferArgs: false)
67-
} else if target.inferArgs {
68-
.init(path: path, inferArgs: true)
69-
} else {
70-
nil
71-
}
72-
guard let source else { continue }
73-
74-
// If we're inferring arguments, or have a known unbuildable, treat as not
57+
// If we have no arguments, or have a known unbuildable, treat as not
7558
// buildable. We'll still include it in the project, but in a separate
7659
// target that isn't built by default.
77-
if source.inferArgs || knownUnbuildables.contains(path) {
78-
unbuildableSources.append(source)
60+
if try !clangArgs.hasBuildArgs(for: path) ||
61+
knownUnbuildables.contains(path) {
62+
unbuildableSources.append(path)
7963
continue
8064
}
8165
// If we have no '.o' present for a given file, assume it's not buildable.
@@ -84,10 +68,10 @@ extension RepoBuildDir {
8468
if target.mayHaveUnbuildableFiles,
8569
try !clangArgs.isObjectFilePresent(for: path) {
8670
log.debug("! Treating '\(path)' as unbuildable; no '.o' file")
87-
unbuildableSources.append(source)
71+
unbuildableSources.append(path)
8872
continue
8973
}
90-
sources.append(source)
74+
sources.append(path)
9175
}
9276

9377
return ClangTarget(

utils/swift-xcodegen/Sources/SwiftXcodeGen/Generator/ClangTargetSource.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,13 @@ struct ClangTargetSource {
1515
var name: String
1616
var path: RelativePath
1717
var mayHaveUnbuildableFiles: Bool
18-
var inferArgs: Bool
1918

2019
init(
2120
at path: RelativePath, named name: String,
22-
mayHaveUnbuildableFiles: Bool,
23-
inferArgs: Bool
21+
mayHaveUnbuildableFiles: Bool
2422
) {
2523
self.name = name
2624
self.path = path
2725
self.mayHaveUnbuildableFiles = mayHaveUnbuildableFiles
28-
self.inferArgs = inferArgs
2926
}
3027
}

utils/swift-xcodegen/Sources/SwiftXcodeGen/Generator/ProjectGenerator.swift

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fileprivate final class ProjectGenerator {
3434
private var groups: [RelativePath: CachedGroup] = [:]
3535
private var files: [RelativePath: Xcode.FileReference] = [:]
3636
private var targets: [String: Xcode.Target] = [:]
37-
private var unbuildableSources: [ClangTarget.Source] = []
37+
private var unbuildableSources: [RelativePath] = []
3838
private var runnableBuildTargets: [RunnableTarget: Xcode.Target] = [:]
3939

4040
/// The group in which external files are stored.
@@ -154,8 +154,9 @@ fileprivate final class ProjectGenerator {
154154
guard let path else { return true }
155155

156156
// Not very efficient, but excludedPaths should be small in practice.
157-
guard let excluded = spec.excludedPaths.first(where: { path.hasPrefix($0.path) })
158-
else {
157+
guard let excluded = spec.excludedPaths.first(
158+
where: { path.starts(with: $0.path) }
159+
) else {
159160
return true
160161
}
161162
if let description, let reason = excluded.reason {
@@ -213,10 +214,18 @@ fileprivate final class ProjectGenerator {
213214
_ name: String, at parentPath: RelativePath?, canUseBuildableFolder: Bool,
214215
productType: Xcode.Target.ProductType?, includeInAllTarget: Bool
215216
) -> Xcode.Target? {
216-
guard targets[name] == nil else {
217-
log.warning("Duplicate target '\(name)', skipping")
218-
return nil
219-
}
217+
let name = {
218+
// If we have a same-named target, disambiguate.
219+
if targets[name] == nil {
220+
return name
221+
}
222+
var i = 2
223+
var newName: String { "\(name)\(i)" }
224+
while targets[newName] != nil {
225+
i += 1
226+
}
227+
return newName
228+
}()
220229
var buildableFolder: Xcode.FileReference?
221230
if let parentPath, !parentPath.components.isEmpty {
222231
// If we've been asked to use buildable folders, see if we can create
@@ -230,7 +239,9 @@ fileprivate final class ProjectGenerator {
230239
group(for: repoRelativePath.appending(parentPath)) != nil else {
231240
// If this isn't a child of an explicitly added reference, something
232241
// has probably gone wrong.
233-
if !spec.referencesToAdd.contains(where: { parentPath.hasPrefix($0.path) }) {
242+
if !spec.referencesToAdd.contains(
243+
where: { parentPath.starts(with: $0.path) }
244+
) {
234245
log.warning("""
235246
Target '\(name)' at '\(repoRelativePath.appending(parentPath))' is \
236247
nested in a folder reference; skipping. This is likely an xcodegen bug.
@@ -310,12 +321,11 @@ fileprivate final class ProjectGenerator {
310321
return false
311322
}
312323
let parent = clangTarget.parentPath
313-
let sources = clangTarget.sources.map(\.path)
314-
let hasConsistentArgs = try sources.allSatisfy {
324+
let hasConsistentArgs = try clangTarget.sources.allSatisfy {
315325
try !buildDir.clangArgs.hasUniqueArgs(for: $0, parent: parent)
316326
}
317327
guard hasConsistentArgs else { return false }
318-
return try canUseBuildableFolder(at: parent, sources: sources)
328+
return try canUseBuildableFolder(at: parent, sources: clangTarget.sources)
319329
}
320330

321331
func canUseBuildableFolder(
@@ -383,15 +393,14 @@ fileprivate final class ProjectGenerator {
383393
let sourcesToBuild = target.addSourcesBuildPhase()
384394

385395
for source in targetInfo.sources {
386-
let sourcePath = source.path
387-
guard let sourceRef = getOrCreateRepoRef(.file(sourcePath)) else {
396+
guard let sourceRef = getOrCreateRepoRef(.file(source)) else {
388397
continue
389398
}
390399
let buildFile = sourcesToBuild.addBuildFile(fileRef: sourceRef)
391400

392401
// Add any per-file settings.
393402
var fileArgs = try buildDir.clangArgs.getUniqueArgs(
394-
for: sourcePath, parent: targetPath, infer: source.inferArgs
403+
for: source, parent: targetPath, infer: spec.inferArgs
395404
)
396405
if !fileArgs.isEmpty {
397406
applyBaseSubstitutions(to: &fileArgs)
@@ -747,12 +756,7 @@ fileprivate final class ProjectGenerator {
747756
let target = try buildDir.getClangTarget(
748757
for: targetSource, knownUnbuildables: spec.knownUnbuildables
749758
)
750-
guard var target else { continue }
751-
// We may have a Swift target with the same name, disambiguate.
752-
// FIXME: We ought to be able to support mixed-source targets.
753-
if targets[target.name] != nil {
754-
target.name = "\(target.name)-clang"
755-
}
759+
guard let target else { continue }
756760
try generateClangTarget(target)
757761
}
758762

utils/swift-xcodegen/Sources/SwiftXcodeGen/Generator/ProjectSpec.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,7 @@ extension ProjectSpec {
206206
guard let path = mapPath(path, for: "Clang target") else { return }
207207
let name = name ?? path.fileName
208208
clangTargetSources.append(ClangTargetSource(
209-
at: path, named: name,
210-
mayHaveUnbuildableFiles: mayHaveUnbuildableFiles,
211-
inferArgs: inferArgs
209+
at: path, named: name, mayHaveUnbuildableFiles: mayHaveUnbuildableFiles
212210
))
213211
}
214212

utils/swift-xcodegen/Sources/SwiftXcodeGen/Path/PathProtocol.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ public extension PathProtocol {
7878
return exts.contains(where: { ext == $0.rawValue })
7979
}
8080

81-
func hasPrefix(_ other: Self) -> Bool {
82-
rawPath.hasPrefix(other.rawPath)
81+
func starts(with other: Self) -> Bool {
82+
self.storage.starts(with: other.storage)
8383
}
8484

8585
var components: FilePath.ComponentView {

0 commit comments

Comments
 (0)