From 0cdc1a6dc233d8c6c2ba378eaada03284227fac9 Mon Sep 17 00:00:00 2001 From: bmxav <5422569+bmxav@users.noreply.github.com> Date: Tue, 17 Sep 2024 09:56:13 -0400 Subject: [PATCH 01/24] Handle targets with same name but in different projects --- Sources/GenIR/CompilerCommandRunner.swift | 4 +- Sources/GenIR/GenIR.swift | 10 +++- Sources/GenIR/Target.swift | 14 ++++- Sources/GenIR/XcodeLogParser.swift | 66 +++++++++++------------ 4 files changed, 54 insertions(+), 40 deletions(-) diff --git a/Sources/GenIR/CompilerCommandRunner.swift b/Sources/GenIR/CompilerCommandRunner.swift index 2d1e6f3..b29404e 100644 --- a/Sources/GenIR/CompilerCommandRunner.swift +++ b/Sources/GenIR/CompilerCommandRunner.swift @@ -47,7 +47,7 @@ struct CompilerCommandRunner { /// Starts the runner /// - Parameter targets: the targets holding the commands to run - func run(targets: [Target], commands: [String: [CompilerCommand]]) throws { + func run(targets: [Target], commands: [TargetKey: [CompilerCommand]]) throws { // Quick, do a hack! try buildCacheManipulator.manipulate() @@ -59,7 +59,7 @@ struct CompilerCommandRunner { var totalModulesRun = 0 for target in targets.filter({ $0.isBuildable }) { - guard let targetCommands = commands[target.name] else { + guard let targetCommands = commands[TargetKey(projectName: target.projectName, targetName: target.name)] else { continue } diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 50047cb..936ce77 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -112,7 +112,13 @@ let programName = CommandLine.arguments.first! // Find and parse the PIF cache let pifCache = try PIFCache(buildCache: log.buildCachePath) - let targets = pifCache.targets.map { Target(from: $0) } + let targets = pifCache.projects.flatMap { project in + project.targets.compactMap { Target(from: $0, in: project) } + } + + let targetCommands = log.commandLog.reduce(into: [TargetKey: [CompilerCommand]]()) { commands, entry in + commands[entry.target, default: []].append(entry.command) + } let builder = DependencyGraphBuilder( provider: .init(targets: targets, cache: pifCache), @@ -148,7 +154,7 @@ let programName = CommandLine.arguments.first! buildCacheManipulator: buildCacheManipulator, dryRun: dryRun ) - try runner.run(targets: targets, commands: log.targetCommands) + try runner.run(targets: targets, commands: targetCommands) let postprocessor = try OutputPostprocessor( archive: archive, diff --git a/Sources/GenIR/Target.swift b/Sources/GenIR/Target.swift index 0a23ba0..6d7bd08 100644 --- a/Sources/GenIR/Target.swift +++ b/Sources/GenIR/Target.swift @@ -9,6 +9,11 @@ import Foundation import PIFSupport import DependencyGraph +struct TargetKey: Hashable { + let projectName: String + let targetName: String +} + /// Represents a product to build (app, framework, plugin, package). It contains the identifying /// information about a target and its output when it is built or archived. In the future the /// `PIF` package will likely be modified so that it is usable within the context of Gen-IR @@ -18,6 +23,8 @@ class Target { let guid: String /// Name of the target. let name: String + /// Name of the project that the target belongs to. + let projectName: String /// The product name refers to the output of this target when it is built or copied into an archive. let productName: String @@ -33,9 +40,14 @@ class Target { let isSwiftPackage: Bool - init(from baseTarget: PIF.BaseTarget) { + init(from baseTarget: PIF.BaseTarget, in project: PIF.Project) { guid = baseTarget.guid name = baseTarget.name + // Each target is associated with a project, but the name of the project is not + // always available. We fallback to the GUID to maintain uniqueness of the target, + // but this isn't useful for finding the target in the build log, since only + // the project name is present in there. + projectName = project.projectName ?? project.groupTree.name ?? project.guid if let target = baseTarget as? PIF.Target, !target.productName.isEmpty { productName = target.productName } else if baseTarget.guid == "PACKAGE-PRODUCT:\(baseTarget.name)" { diff --git a/Sources/GenIR/XcodeLogParser.swift b/Sources/GenIR/XcodeLogParser.swift index 5da9d26..78c7932 100644 --- a/Sources/GenIR/XcodeLogParser.swift +++ b/Sources/GenIR/XcodeLogParser.swift @@ -10,6 +10,11 @@ import LogHandlers /// An XcodeLogParser extracts targets and their compiler commands from a given Xcode build log class XcodeLogParser { + struct CommandEntry { + let target: TargetKey + let command: CompilerCommand + } + /// The Xcode build log contents private let log: [String] /// The current line offset in the log @@ -18,8 +23,7 @@ class XcodeLogParser { private(set) var settings: [String: String] = [:] /// The path to the Xcode build cache private(set) var buildCachePath: URL! - /// A mapping of target names to the compiler commands that relate to them - private(set) var targetCommands: [String: [CompilerCommand]] = [:] + private(set) var commandLog: [CommandEntry] = [] enum Error: Swift.Error { case noCommandsFound(String) @@ -37,7 +41,7 @@ class XcodeLogParser { func parse() throws { parseBuildLog() - if targetCommands.isEmpty { + if commandLog.isEmpty { logger.debug("Found no targets in log") throw Error.noTargetsFound( @@ -47,12 +51,7 @@ class XcodeLogParser { ) } - let totalCommandCount = targetCommands - .values - .compactMap { $0.count } - .reduce(0, +) - - if totalCommandCount == 0 { + if commandLog.count == 0 { logger.debug("Found no commands in log") throw Error.noCommandsFound( @@ -69,7 +68,7 @@ class XcodeLogParser { /// Parse the lines from the build log func parseBuildLog() { - var seenTargets = Set() + var seenTargets = Set() while let line = consumeLine() { if line.hasPrefix("Build description path: ") { @@ -90,13 +89,14 @@ class XcodeLogParser { logger.debug("Found target: \(target)") } - let compilerCommands = parseCompilerCommands() + let commands = parseCompilerCommands(target: target) - compilerCommands.forEach { - logger.debug("Found \($0.compiler.rawValue) compiler command for target: \(target)") + commands.forEach { + logger.debug("Found \($0.command.compiler.rawValue) compiler command for target: \(target)") } - targetCommands[target, default: []].append(contentsOf: compilerCommands) + commandLog.append(contentsOf: commands) + default: continue } @@ -157,8 +157,8 @@ class XcodeLogParser { } /// Parsecompiler commands from the current block - private func parseCompilerCommands() -> [CompilerCommand] { - var commands: [CompilerCommand] = [] + private func parseCompilerCommands(target: TargetKey) -> [CommandEntry] { + var commands: [CommandEntry] = [] while let line = consumeLine() { // Assume we have reached the end of this build task's block when we encounter an unindented line. @@ -170,7 +170,7 @@ class XcodeLogParser { continue } - commands.append(compilerCommand) + commands.append(.init(target: target, command: compilerCommand)) } return commands @@ -200,25 +200,21 @@ class XcodeLogParser { return nil } - /// Returns the target from the given line - /// - Parameter line: the line to parse - /// - Returns: the name of the target if one was found, otherwise nil - private func target(from line: String) -> String? { - if line.contains("Build target ") { - var result = line.replacingOccurrences(of: "Build target ", with: "") - - if let bound = result.range(of: "of ")?.lowerBound { - result = String(result[result.startIndex.. TargetKey? { + guard let targetStart = line.range(of: "(in target '")?.upperBound, let targetEnd = line.range(of: "' from ")?.lowerBound else { + return nil + } - return result.trimmingCharacters(in: .whitespacesAndNewlines) - } else if let startIndex = line.range(of: "(in target '")?.upperBound, let endIndex = line.range(of: "' from ")?.lowerBound { - // sometimes (seemingly for archives) build logs follow a different format for targets - return String(line[startIndex.. Date: Thu, 26 Sep 2024 08:34:07 -0400 Subject: [PATCH 02/24] Ignore test bundles when generating bitcode --- Sources/GenIR/CompilerCommandRunner.swift | 2 +- Sources/GenIR/GenIR.swift | 3 ++- Sources/GenIR/Target.swift | 11 +++++++++++ Tests/GenIRTests/MultipleAppTests.swift | 4 ++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Sources/GenIR/CompilerCommandRunner.swift b/Sources/GenIR/CompilerCommandRunner.swift index b29404e..2ea7306 100644 --- a/Sources/GenIR/CompilerCommandRunner.swift +++ b/Sources/GenIR/CompilerCommandRunner.swift @@ -58,7 +58,7 @@ struct CompilerCommandRunner { var totalModulesRun = 0 - for target in targets.filter({ $0.isBuildable }) { + for target in targets { guard let targetCommands = commands[TargetKey(projectName: target.projectName, targetName: target.name)] else { continue } diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 936ce77..660cf0c 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -112,9 +112,10 @@ let programName = CommandLine.arguments.first! // Find and parse the PIF cache let pifCache = try PIFCache(buildCache: log.buildCachePath) + let targets = pifCache.projects.flatMap { project in project.targets.compactMap { Target(from: $0, in: project) } - } + }.filter { !$0.isTest } let targetCommands = log.commandLog.reduce(into: [TargetKey: [CompilerCommand]]()) { commands, entry in commands[entry.target, default: []].append(entry.command) diff --git a/Sources/GenIR/Target.swift b/Sources/GenIR/Target.swift index 6d7bd08..8bc4cd2 100644 --- a/Sources/GenIR/Target.swift +++ b/Sources/GenIR/Target.swift @@ -32,6 +32,10 @@ class Target { /// for the object file, since this is used by the other targets. let isBuildable: Bool + /// Returns true if this target is a test bundle. These will be ignored when packaging bitcode + /// in order to reduce archive size. + let isTest: Bool + /// Returns true if this target produces a package product that will be included in the archive. /// For simplicity we say this can be anything that is not a `PACKAGE-TARGET`, which will just be /// an object file. The `dynamicTargetVariantGuid` of a `PACKAGE-TARGET` is technically a framework, @@ -60,6 +64,13 @@ class Target { // Fallback to the target's name if we are unable to determine a proper product name. productName = baseTarget.name } + + if let target = baseTarget as? PIF.Target { + isTest = target.productType == .unitTest || target.productType == .uiTesting + } else { + isTest = false + } + isBuildable = guid == "PACKAGE-TARGET:\(name)" || !guid.hasPrefix("PACKAGE-") isPackageProduct = !guid.hasPrefix("PACKAGE-TARGET:") isSwiftPackage = guid.hasPrefix("PACKAGE-") diff --git a/Tests/GenIRTests/MultipleAppTests.swift b/Tests/GenIRTests/MultipleAppTests.swift index 90b0042..5f8919a 100644 --- a/Tests/GenIRTests/MultipleAppTests.swift +++ b/Tests/GenIRTests/MultipleAppTests.swift @@ -18,7 +18,7 @@ final class MultipleAppTests: XCTestCase { let app = try XCTUnwrap(targets.first(where: { $0.name == "MultipleApp" })) let copy = try XCTUnwrap(targets.first(where: { $0.name == "MultipleApp Copy" })) - XCTAssertEqual(context.logParser.targetCommands[app.name]?.count, 3) - XCTAssertEqual(context.logParser.targetCommands[copy.name]?.count, 3) + XCTAssertEqual(context.logParser.targetCommands[app.name]?.count, 1) + XCTAssertEqual(context.logParser.targetCommands[copy.name]?.count, 1) } } From 874e98a81bdc29b5839dd434b4b5e45909c92d50 Mon Sep 17 00:00:00 2001 From: davdres <31395411+davdres@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:25:36 -0700 Subject: [PATCH 03/24] Update build.yml --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7708ad2..cfc8349 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,4 +14,5 @@ jobs: - name: 🔨 Build run: | sudo xcode-select -s /Applications/Xcode_15.4.app/ - swift build \ No newline at end of file + swift build + swift test From 6e7a8a65b6ffb81ac1a46a4b35df697e2667f5ea Mon Sep 17 00:00:00 2001 From: davdres <31395411+davdres@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:34:06 -0700 Subject: [PATCH 04/24] Update build.yml --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cfc8349..a102fc1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,7 @@ on: pull_request: paths: - '**.swift' + workflow_dispatch: jobs: build: From 31602e8b32113341e9055d838de76a93a5124d16 Mon Sep 17 00:00:00 2001 From: davdres <31395411+davdres@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:01:16 -0700 Subject: [PATCH 05/24] Update build.yml --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a102fc1..6c09364 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,6 +10,10 @@ jobs: build: runs-on: macos-latest steps: + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '16.2.0' # Specify the desired Xcode version + - uses: actions/checkout@v4 - name: 🔨 Build From 09075b8d742d41462bf510f959a7ba02aa1f2229 Mon Sep 17 00:00:00 2001 From: davdres <31395411+davdres@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:03:02 -0700 Subject: [PATCH 06/24] Update build.yml --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c09364..f071396 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,6 +18,5 @@ jobs: - name: 🔨 Build run: | - sudo xcode-select -s /Applications/Xcode_15.4.app/ swift build swift test From 17aec35dd3fa0323c4d81a23e655cca2aac142dd Mon Sep 17 00:00:00 2001 From: David Dresser Date: Tue, 11 Mar 2025 14:23:07 -0700 Subject: [PATCH 07/24] Issue #81 log unrequired targets instead of failing. --- PIF/Sources/PIFSupport/PIF.swift | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/PIF/Sources/PIFSupport/PIF.swift b/PIF/Sources/PIFSupport/PIF.swift index 2af5f4a..0fe4d7c 100644 --- a/PIF/Sources/PIFSupport/PIF.swift +++ b/PIF/Sources/PIFSupport/PIF.swift @@ -87,7 +87,7 @@ public enum PIF { public required init(from decoder: Decoder) throws { guard let cachePath = decoder.userInfo[.pifCachePath] as? URL else { - throw Error.userInfoError("decoder's userInfo doesn't container required key .cachePath, or that value isn't a URL") + throw Error.userInfoError("decoder's userInfo doesn't contain the required key .cachePath, or that value isn't a URL") } let container = try decoder.container(keyedBy: CodingKeys.self) @@ -162,20 +162,18 @@ public enum PIF { } } - targets = try targetContents - .map { targetData -> BaseTarget in - let pifDecoder = PIFDecoder(cache: cachePath) - let untypedTarget = try pifDecoder.decode(PIF.TypedObject.self, from: targetData) - switch untypedTarget.type { - case "aggregate": - return try pifDecoder.decode(PIF.AggregateTarget.self, from: targetData) - case "standard", "packageProduct": - return try pifDecoder.decode(PIF.Target.self, from: targetData) - default: - throw Error.decodingError("Target type unknown: \(untypedTarget)") - } + targets = try targetContents.reduce(into: [BaseTarget]()) { result, targetData in + let pifDecoder = PIFDecoder(cache: cachePath) + let untypedTarget = try pifDecoder.decode(PIF.TypedObject.self, from: targetData) + switch untypedTarget.type { + case "aggregate": + result.append(try pifDecoder.decode(PIF.AggregateTarget.self, from: targetData)) + case "standard", "packageProduct": + result.append(try pifDecoder.decode(PIF.Target.self, from: targetData)) + default: + logger.debug("Ignoring target \(untypedTarget) of type: \(untypedTarget.type ?? "")") } - + } self.groupTree = try container.decode(Group.self, forKey: .groupTree) } } From 3341d771bc408333a5b5cc3a0787599681c2fd16 Mon Sep 17 00:00:00 2001 From: David Dresser Date: Wed, 19 Mar 2025 07:44:44 -0700 Subject: [PATCH 08/24] Issue #81 log PIF location & missing commands. --- PIF/Sources/PIFSupport/PIF.swift | 4 ++-- Sources/GenIR/CompilerCommandRunner.swift | 2 ++ Sources/GenIR/GenIR.swift | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/PIF/Sources/PIFSupport/PIF.swift b/PIF/Sources/PIFSupport/PIF.swift index 0fe4d7c..d59b0f6 100644 --- a/PIF/Sources/PIFSupport/PIF.swift +++ b/PIF/Sources/PIFSupport/PIF.swift @@ -304,7 +304,7 @@ public enum PIF { case FileReference.type: return try childrenContainer.decode(FileReference.self) default: - logger.debug("unknown reference type: \(child.type ?? "")") + logger.debug("Ignoring reference type: \(child.type ?? "")") return nil } } @@ -508,7 +508,7 @@ public enum PIF { case ResourcesBuildPhase.type: return try container.decode(ResourcesBuildPhase.self) default: - logger.debug("unknown build phase: \(type)") + logger.debug("Ignoring build phase: \(type)") return nil // TODO: we should probably handle these: /* diff --git a/Sources/GenIR/CompilerCommandRunner.swift b/Sources/GenIR/CompilerCommandRunner.swift index 2ea7306..fb13293 100644 --- a/Sources/GenIR/CompilerCommandRunner.swift +++ b/Sources/GenIR/CompilerCommandRunner.swift @@ -59,7 +59,9 @@ struct CompilerCommandRunner { var totalModulesRun = 0 for target in targets { + // Continue to the next target if no commands are found for the current target guard let targetCommands = commands[TargetKey(projectName: target.projectName, targetName: target.name)] else { + logger.warning("No commands found for target: \(target.name) in project: \(target.projectName)") continue } diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 660cf0c..2fe2f09 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -111,6 +111,7 @@ let programName = CommandLine.arguments.first! try log.parse() // Find and parse the PIF cache + logger.info("PIF location is: \(log.buildCachePath.filePath)") let pifCache = try PIFCache(buildCache: log.buildCachePath) let targets = pifCache.projects.flatMap { project in From 310c00db91e9ec1d54d32df625c7be59cd5b4f06 Mon Sep 17 00:00:00 2001 From: David Dresser Date: Thu, 27 Mar 2025 09:39:16 -0700 Subject: [PATCH 09/24] Issue #81 PIF workspace sort --- PIF/Sources/PIFSupport/PIFSupport.swift | 4 +-- PIF/Tests/PIFTests/PIFTests.swift | 27 ++++++++++++------- ...ins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json | 1 + ...ins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json | 1 + ...ins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json | 1 + ...ins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json | 1 + ...ins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json | 1 + ...hash=0216c4da1e6192c3f10386fdb3894e3d-json | 1 + ...hash=1b09f1228422548667247b4bbfd7d7a0-json | 1 + ...hash=24b193b35ca937273c6159309c290e94-json | 1 + ...hash=2eff751499d3dae5ca516b7b74bcd9bf-json | 1 + ...hash=3da7c1fe52778e3bbaa9d65c8509c5e3-json | 1 + ...hash=4f46654a56756a61832abd15054e4681-json | 1 + ...hash=661e8f0f8e8b33f7f874c99f325078ce-json | 1 + ...hash=80a2cf68cb7a2ad8f650e749d644c98a-json | 1 + ...hash=8a9f99b7cf8f102f0f0cb43b617dd51d-json | 1 + ...hash=91a961c85a260f33eed319c0f69a5bc0-json | 1 + ...hash=b1a558917364c1e5e55c87d2cf020cad-json | 1 + ...hash=b699706ff94751f98619a7a999992d45-json | 1 + ...hash=b6a6bb4e39dafedcbaadb2fcb2f670a7-json | 1 + ...hash=d272f30d9b03cea09f02e6525a045294-json | 1 + ...hash=da1b9a22f2a4c7636ed36f335d41ea15-json | 1 + ...hash=e6a04c97feb75d4e267ce08a88765054-json | 1 + ...ects=1ba277b88fb5c402e35936acc0a7292f-json | 1 + ...ects=22cea64afbc362a54dde61fe39d0579c-json | 1 + ...ects=609d7571ca836d6c0e8ad8ddfce3b07b-json | 1 + ...ects=a9a028e7c7248474c9438c5e046f322b-json | 1 + ...ects=fd30a685b852bd99fcba4c9d8aff22a6-json | 1 + Package.swift | 5 ++++ Sources/GenIR/GenIR.swift | 11 +++++--- Sources/GenIR/PIFCache.swift | 1 + .../Umbrella.xcodeproj/project.pbxproj | 6 +++-- Tests/GenIRTests/CMakeDiscoveryTests.swift | 2 +- Tests/GenIRTests/MultipleAppTests.swift | 9 ++++--- .../OutputPostprocessorFileMoverTests.swift | 2 +- Tests/GenIRTests/TestContext.swift | 6 ++--- 36 files changed, 75 insertions(+), 24 deletions(-) create mode 100644 PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=0ba175c94a8c66698baf4a8a8ec4a086_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json create mode 100644 PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=2cda18b9ff299b6953b8c745bfbda9ee_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json create mode 100644 PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=6cb7e1b040d2c1c1847b40b4f0c6f623_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json create mode 100644 PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=d00298d9eadcbacc2d8893a48494d30a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json create mode 100644 PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=dc06a4d66b35a7f039f894a4dee1864a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=0216c4da1e6192c3f10386fdb3894e3d-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=1b09f1228422548667247b4bbfd7d7a0-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=24b193b35ca937273c6159309c290e94-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=2eff751499d3dae5ca516b7b74bcd9bf-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=4f46654a56756a61832abd15054e4681-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=661e8f0f8e8b33f7f874c99f325078ce-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=80a2cf68cb7a2ad8f650e749d644c98a-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=8a9f99b7cf8f102f0f0cb43b617dd51d-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=91a961c85a260f33eed319c0f69a5bc0-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b1a558917364c1e5e55c87d2cf020cad-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b699706ff94751f98619a7a999992d45-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b6a6bb4e39dafedcbaadb2fcb2f670a7-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=d272f30d9b03cea09f02e6525a045294-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=da1b9a22f2a4c7636ed36f335d41ea15-json create mode 100644 PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=e6a04c97feb75d4e267ce08a88765054-json create mode 100644 PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=1ba277b88fb5c402e35936acc0a7292f-json create mode 100644 PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=22cea64afbc362a54dde61fe39d0579c-json create mode 100644 PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=609d7571ca836d6c0e8ad8ddfce3b07b-json create mode 100644 PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=a9a028e7c7248474c9438c5e046f322b-json create mode 100644 PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=fd30a685b852bd99fcba4c9d8aff22a6-json diff --git a/PIF/Sources/PIFSupport/PIFSupport.swift b/PIF/Sources/PIFSupport/PIFSupport.swift index 7ca3b8e..0c678e8 100644 --- a/PIF/Sources/PIFSupport/PIFSupport.swift +++ b/PIF/Sources/PIFSupport/PIFSupport.swift @@ -28,7 +28,7 @@ public class PIFCacheParser { /// Finds the most recent workspace in the cache /// - Throws: a `workspaceNotFound` error when a workspace is not found /// - Returns: the path to the most recent workspace file - private static func workspacePath(in cachePath: URL) throws -> URL { + internal static func workspacePath(in cachePath: URL) throws -> URL { let workspaces = try FileManager.default.contentsOfDirectory( at: cachePath.appendingPathComponent("workspace"), includingPropertiesForKeys: nil @@ -49,7 +49,7 @@ public class PIFCacheParser { // If multiple workspaces exist, it's because the something in the project changed between builds. Sort workspaces by the most recent. return workspaces - .sorted(using: KeyPathComparator(\.modificationDate)) + .sorted(using: KeyPathComparator(\.modificationDate, order: .reverse)) .first! .workspace } diff --git a/PIF/Tests/PIFTests/PIFTests.swift b/PIF/Tests/PIFTests/PIFTests.swift index 000a103..466247e 100644 --- a/PIF/Tests/PIFTests/PIFTests.swift +++ b/PIF/Tests/PIFTests/PIFTests.swift @@ -1,12 +1,21 @@ -import XCTest -@testable import PIF +import Foundation +import Testing +@testable import PIFSupport -final class PIFTests: XCTestCase { - func testExample() throws { - // XCTest Documentation - // https://developer.apple.com/documentation/xctest +struct PIFTests { + private let testBundlePath: URL - // Defining Test Cases and Test Methods - // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods + init() throws { + + let fileManager = FileManager.default + let currentDirectoryPath = fileManager.currentDirectoryPath + testBundlePath = URL(fileURLWithPath: "\(currentDirectoryPath)/PIF/Tests/Resources/PIFCache") + + try #require(fileManager.fileExists(atPath: testBundlePath.path())) + } + + @Test("validate PIF name") func name() throws { + let expectedWorkspace: URL = URL(string: "\(testBundlePath.absoluteString)workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=1ba277b88fb5c402e35936acc0a7292f-json")! + try #expect(PIFCacheParser.workspacePath(in: testBundlePath) == expectedWorkspace ) } -} +} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=0ba175c94a8c66698baf4a8a8ec4a086_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=0ba175c94a8c66698baf4a8a8ec4a086_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json new file mode 100644 index 0000000..5571991 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=0ba175c94a8c66698baf4a8a8ec4a086_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json @@ -0,0 +1 @@ +{"appPreferencesBuildSettings":{},"buildConfigurations":[{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_TESTABILITY":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_DYNAMIC_NO_PIC":"NO","GCC_NO_COMMON_BLOCKS":"YES","GCC_OPTIMIZATION_LEVEL":"0","GCC_PREPROCESSOR_DEFINITIONS":"DEBUG=1 $(inherited)","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"INCLUDE_SOURCE","MTL_FAST_MATH":"YES","ONLY_ACTIVE_ARCH":"YES","SDKROOT":"iphoneos","SWIFT_ACTIVE_COMPILATION_CONDITIONS":"DEBUG $(inherited)","SWIFT_OPTIMIZATION_LEVEL":"-Onone"},"guid":"40c83c43d7503d5791623703167045f780a0982106550cd543d7ccb9e06b53e1","name":"Debug"},{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf-with-dsym","ENABLE_NS_ASSERTIONS":"NO","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_NO_COMMON_BLOCKS":"YES","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"NO","MTL_FAST_MATH":"YES","SDKROOT":"iphoneos","SWIFT_COMPILATION_MODE":"wholemodule","VALIDATE_PRODUCT":"YES"},"guid":"40c83c43d7503d5791623703167045f7af90a3f474a8df2874184a21ed42cfe4","name":"Release"}],"classPrefix":"","defaultConfigurationName":"Release","developmentRegion":"en","groupTree":{"children":[{"children":[{"children":[{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7056d9720edd4394b93dfb4b9a10a3015","path":"Preview Assets.xcassets","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f72a8abd318f47629cfafa7c387b5f002e","name":"Preview Content","path":"Preview Content","sourceTree":"","type":"group"},{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7b50839ef8b6c5d84a03619a43c954e57","path":"Assets.xcassets","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f7c077c1653f39b7ea4607a41e45c24c4b","path":"ContentView.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f756c01a944785f90baa34079ca4ef2403","path":"Experimental1App.swift","sourceTree":"","type":"file"},{"fileType":"text.plist.xml","guid":"40c83c43d7503d5791623703167045f78b0ecbfefafa95b5ce50ce77e4cfc3ea","path":"Info.plist","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7e10bf3e4a860e991a2994515d69eded2","name":"Experimental1","path":"Experimental1","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f7ad2436b655782b8a994e474362587f04","path":"Experimental1Tests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7f08e2577bb0064600500fcc222cc2ca8","name":"Experimental1Tests","path":"Experimental1Tests","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f73271c135ac874b32da1a2ebd3a877f6b","path":"Experimental1UITests.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f72e70d1c1c15b832fa57628ee6dc9e6e1","path":"Experimental1UITestsLaunchTests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f77b87828a84e79482307b74fdda8282ae","name":"Experimental1UITests","path":"Experimental1UITests","sourceTree":"","type":"group"},{"guid":"40c83c43d7503d5791623703167045f7d4299e185c2822b8594c01d59d6eaa83","name":"Products","path":"","sourceTree":"","type":"group"}],"guid":"40c83c43d7503d5791623703167045f77e4d2e30828b3469bbdeea3847af508e","name":"Experimental1","path":"","sourceTree":"","type":"group"},"guid":"40c83c43d7503d5791623703167045f7","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj","projectDirectory":"/Users/ddresser/p/swift/tests/exper1/Experimental1","targets":["TARGET@v11_hash=1b09f1228422548667247b4bbfd7d7a0","TARGET@v11_hash=da1b9a22f2a4c7636ed36f335d41ea15","TARGET@v11_hash=b6a6bb4e39dafedcbaadb2fcb2f670a7","TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=2cda18b9ff299b6953b8c745bfbda9ee_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=2cda18b9ff299b6953b8c745bfbda9ee_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json new file mode 100644 index 0000000..a8d5527 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=2cda18b9ff299b6953b8c745bfbda9ee_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json @@ -0,0 +1 @@ +{"appPreferencesBuildSettings":{},"buildConfigurations":[{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_TESTABILITY":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_DYNAMIC_NO_PIC":"NO","GCC_NO_COMMON_BLOCKS":"YES","GCC_OPTIMIZATION_LEVEL":"0","GCC_PREPROCESSOR_DEFINITIONS":"DEBUG=1 $(inherited)","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"INCLUDE_SOURCE","MTL_FAST_MATH":"YES","ONLY_ACTIVE_ARCH":"YES","SDKROOT":"iphoneos","SWIFT_ACTIVE_COMPILATION_CONDITIONS":"DEBUG $(inherited)","SWIFT_OPTIMIZATION_LEVEL":"-Onone"},"guid":"40c83c43d7503d5791623703167045f780a0982106550cd543d7ccb9e06b53e1","name":"Debug"},{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf-with-dsym","ENABLE_NS_ASSERTIONS":"NO","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_NO_COMMON_BLOCKS":"YES","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"NO","MTL_FAST_MATH":"YES","SDKROOT":"iphoneos","SWIFT_COMPILATION_MODE":"wholemodule","VALIDATE_PRODUCT":"YES"},"guid":"40c83c43d7503d5791623703167045f7af90a3f474a8df2874184a21ed42cfe4","name":"Release"}],"classPrefix":"","defaultConfigurationName":"Release","developmentRegion":"en","groupTree":{"children":[{"children":[{"children":[{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f744c6928199d9fde8676f14967c7d8375","path":"Preview Assets.xcassets","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7dcf6ee988acfe2ce8dfd8446f294e1a8","name":"Preview Content","path":"Preview Content","sourceTree":"","type":"group"},{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7c114fa6d0d78bcac0178d072b4629008","path":"Assets.xcassets","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f798c2d734ae82bc0397e5de6ff758ec6c","path":"ContentView.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f760e58953e7d47afa3825c674d6bc6db1","path":"Experimental1App.swift","sourceTree":"","type":"file"},{"fileType":"text.plist.xml","guid":"40c83c43d7503d5791623703167045f75b50c8e99d15e541cb40f80ab4c6365c","path":"Info.plist","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7e10bf3e4a860e991a2994515d69eded2","name":"Experimental1","path":"Experimental1","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f7f3da02d07815c2edca45c9206ab6ab64","path":"Experimental1Tests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7f08e2577bb0064600500fcc222cc2ca8","name":"Experimental1Tests","path":"Experimental1Tests","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f73642f3563630f0c571118093ef27def1","path":"Experimental1UITests.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f7c75aae2a5c5f09a22266769821390a3d","path":"Experimental1UITestsLaunchTests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f77b87828a84e79482307b74fdda8282ae","name":"Experimental1UITests","path":"Experimental1UITests","sourceTree":"","type":"group"},{"guid":"40c83c43d7503d5791623703167045f7d4299e185c2822b8594c01d59d6eaa83","name":"Products","path":"","sourceTree":"","type":"group"}],"guid":"40c83c43d7503d5791623703167045f77e4d2e30828b3469bbdeea3847af508e","name":"Experimental1","path":"","sourceTree":"","type":"group"},"guid":"40c83c43d7503d5791623703167045f7","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj","projectDirectory":"/Users/ddresser/p/swift/tests/exper1/Experimental1","targets":["TARGET@v11_hash=b1a558917364c1e5e55c87d2cf020cad","TARGET@v11_hash=2eff751499d3dae5ca516b7b74bcd9bf","TARGET@v11_hash=91a961c85a260f33eed319c0f69a5bc0","TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=6cb7e1b040d2c1c1847b40b4f0c6f623_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=6cb7e1b040d2c1c1847b40b4f0c6f623_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json new file mode 100644 index 0000000..14ef4fb --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=6cb7e1b040d2c1c1847b40b4f0c6f623_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json @@ -0,0 +1 @@ +{"appPreferencesBuildSettings":{},"buildConfigurations":[{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_TESTABILITY":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_DYNAMIC_NO_PIC":"NO","GCC_NO_COMMON_BLOCKS":"YES","GCC_OPTIMIZATION_LEVEL":"0","GCC_PREPROCESSOR_DEFINITIONS":"DEBUG=1 $(inherited)","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"INCLUDE_SOURCE","MTL_FAST_MATH":"YES","ONLY_ACTIVE_ARCH":"YES","SDKROOT":"iphoneos","SWIFT_ACTIVE_COMPILATION_CONDITIONS":"DEBUG $(inherited)","SWIFT_OPTIMIZATION_LEVEL":"-Onone"},"guid":"40c83c43d7503d5791623703167045f780a0982106550cd543d7ccb9e06b53e1","name":"Debug"},{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf-with-dsym","ENABLE_NS_ASSERTIONS":"NO","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_NO_COMMON_BLOCKS":"YES","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"NO","MTL_FAST_MATH":"YES","SDKROOT":"iphoneos","SWIFT_COMPILATION_MODE":"wholemodule","VALIDATE_PRODUCT":"YES"},"guid":"40c83c43d7503d5791623703167045f7af90a3f474a8df2874184a21ed42cfe4","name":"Release"}],"classPrefix":"","defaultConfigurationName":"Release","developmentRegion":"en","groupTree":{"children":[{"children":[{"children":[{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7c14ea508f799af1f01ab2d4da59da4d3","path":"Preview Assets.xcassets","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f77f14866e83d9f0589fc32a7c9bf406e1","name":"Preview Content","path":"Preview Content","sourceTree":"","type":"group"},{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7919663b5ca817f1b8d5f1d381811e941","path":"Assets.xcassets","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f7e0659c2d28134f5d96751bc4d98b7a2a","path":"ContentView.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f703391e6094a6ad9b891a11629cf887d9","path":"Experimental1App.swift","sourceTree":"","type":"file"},{"fileType":"text.plist.xml","guid":"40c83c43d7503d5791623703167045f761cadbf5b7ebdec15270c423b79f8f7b","path":"Info.plist","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7e10bf3e4a860e991a2994515d69eded2","name":"Experimental1","path":"Experimental1","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f75dc5f3dd14a9e204152be18d7c277872","path":"Experimental1Tests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7f08e2577bb0064600500fcc222cc2ca8","name":"Experimental1Tests","path":"Experimental1Tests","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f730f81af1b681c45d395ae0a177f0bcf4","path":"Experimental1UITests.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f7531d89d255dc23ea2c70dfbdac5ce038","path":"Experimental1UITestsLaunchTests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f77b87828a84e79482307b74fdda8282ae","name":"Experimental1UITests","path":"Experimental1UITests","sourceTree":"","type":"group"},{"guid":"40c83c43d7503d5791623703167045f7d4299e185c2822b8594c01d59d6eaa83","name":"Products","path":"","sourceTree":"","type":"group"}],"guid":"40c83c43d7503d5791623703167045f77e4d2e30828b3469bbdeea3847af508e","name":"Experimental1","path":"","sourceTree":"","type":"group"},"guid":"40c83c43d7503d5791623703167045f7","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj","projectDirectory":"/Users/ddresser/p/swift/tests/exper1/Experimental1","targets":["TARGET@v11_hash=4f46654a56756a61832abd15054e4681","TARGET@v11_hash=b699706ff94751f98619a7a999992d45","TARGET@v11_hash=24b193b35ca937273c6159309c290e94","TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=d00298d9eadcbacc2d8893a48494d30a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=d00298d9eadcbacc2d8893a48494d30a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json new file mode 100644 index 0000000..641aff1 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=d00298d9eadcbacc2d8893a48494d30a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json @@ -0,0 +1 @@ +{"appPreferencesBuildSettings":{},"buildConfigurations":[{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_TESTABILITY":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_DYNAMIC_NO_PIC":"NO","GCC_NO_COMMON_BLOCKS":"YES","GCC_OPTIMIZATION_LEVEL":"0","GCC_PREPROCESSOR_DEFINITIONS":"DEBUG=1 $(inherited)","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"INCLUDE_SOURCE","MTL_FAST_MATH":"YES","ONLY_ACTIVE_ARCH":"YES","SDKROOT":"iphoneos","SWIFT_ACTIVE_COMPILATION_CONDITIONS":"DEBUG $(inherited)","SWIFT_OPTIMIZATION_LEVEL":"-Onone"},"guid":"40c83c43d7503d5791623703167045f780a0982106550cd543d7ccb9e06b53e1","name":"Debug"},{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf-with-dsym","ENABLE_NS_ASSERTIONS":"NO","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_NO_COMMON_BLOCKS":"YES","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"NO","MTL_FAST_MATH":"YES","SDKROOT":"iphoneos","SWIFT_COMPILATION_MODE":"wholemodule","VALIDATE_PRODUCT":"YES"},"guid":"40c83c43d7503d5791623703167045f7af90a3f474a8df2874184a21ed42cfe4","name":"Release"}],"classPrefix":"","defaultConfigurationName":"Release","developmentRegion":"en","groupTree":{"children":[{"children":[{"children":[{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7e63dc0da3cbc8411aa91b9a8a718fe3a","path":"Preview Assets.xcassets","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f748f0a1ce6e67fdaf23dafad44d91ac37","name":"Preview Content","path":"Preview Content","sourceTree":"","type":"group"},{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7a5c817f5d0c5ea495e1f62be838d0e8a","path":"Assets.xcassets","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f799014aea96d7c55caf79e2b45dbc2e28","path":"ContentView.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f798ae0fee1114cca1c6d2a2b655043000","path":"Experimental1App.swift","sourceTree":"","type":"file"},{"fileType":"text.plist.xml","guid":"40c83c43d7503d5791623703167045f795daf6ca95d73dfe8e6e2ba39876736a","path":"Info.plist","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7e10bf3e4a860e991a2994515d69eded2","name":"Experimental1","path":"Experimental1","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f77916d8660e476e2fa00b33bfb1e8ac7f","path":"Experimental1Tests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7f08e2577bb0064600500fcc222cc2ca8","name":"Experimental1Tests","path":"Experimental1Tests","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f79fa9676567edb33a8866e1e0a2f9c026","path":"Experimental1UITests.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f795ded55f081d48f369800fc37d4d523d","path":"Experimental1UITestsLaunchTests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f77b87828a84e79482307b74fdda8282ae","name":"Experimental1UITests","path":"Experimental1UITests","sourceTree":"","type":"group"},{"guid":"40c83c43d7503d5791623703167045f7d4299e185c2822b8594c01d59d6eaa83","name":"Products","path":"","sourceTree":"","type":"group"}],"guid":"40c83c43d7503d5791623703167045f77e4d2e30828b3469bbdeea3847af508e","name":"Experimental1","path":"","sourceTree":"","type":"group"},"guid":"40c83c43d7503d5791623703167045f7","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj","projectDirectory":"/Users/ddresser/p/swift/tests/exper1/Experimental1","targets":["TARGET@v11_hash=e6a04c97feb75d4e267ce08a88765054","TARGET@v11_hash=661e8f0f8e8b33f7f874c99f325078ce","TARGET@v11_hash=0216c4da1e6192c3f10386fdb3894e3d","TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=dc06a4d66b35a7f039f894a4dee1864a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=dc06a4d66b35a7f039f894a4dee1864a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json new file mode 100644 index 0000000..2dadf83 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/project/PROJECT@v11_mod=dc06a4d66b35a7f039f894a4dee1864a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1-json @@ -0,0 +1 @@ +{"appPreferencesBuildSettings":{},"buildConfigurations":[{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_TESTABILITY":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_DYNAMIC_NO_PIC":"NO","GCC_NO_COMMON_BLOCKS":"YES","GCC_OPTIMIZATION_LEVEL":"0","GCC_PREPROCESSOR_DEFINITIONS":"DEBUG=1 $(inherited)","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"INCLUDE_SOURCE","MTL_FAST_MATH":"YES","ONLY_ACTIVE_ARCH":"YES","SDKROOT":"iphoneos","SWIFT_ACTIVE_COMPILATION_CONDITIONS":"DEBUG $(inherited)","SWIFT_OPTIMIZATION_LEVEL":"-Onone"},"guid":"40c83c43d7503d5791623703167045f780a0982106550cd543d7ccb9e06b53e1","name":"Debug"},{"buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS":"YES","CLANG_ANALYZER_NONNULL":"YES","CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION":"YES_AGGRESSIVE","CLANG_CXX_LANGUAGE_STANDARD":"gnu++20","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_ENABLE_OBJC_WEAK":"YES","CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_COMMA":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_DOCUMENTATION_COMMENTS":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INFINITE_RECURSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_NON_LITERAL_NULL_CONVERSION":"YES","CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF":"YES","CLANG_WARN_OBJC_LITERAL_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER":"YES","CLANG_WARN_RANGE_LOOP_ANALYSIS":"YES","CLANG_WARN_STRICT_PROTOTYPES":"YES","CLANG_WARN_SUSPICIOUS_MOVE":"YES","CLANG_WARN_UNGUARDED_AVAILABILITY":"YES_AGGRESSIVE","CLANG_WARN_UNREACHABLE_CODE":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"dwarf-with-dsym","ENABLE_NS_ASSERTIONS":"NO","ENABLE_STRICT_OBJC_MSGSEND":"YES","ENABLE_USER_SCRIPT_SANDBOXING":"YES","GCC_C_LANGUAGE_STANDARD":"gnu17","GCC_NO_COMMON_BLOCKS":"YES","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","LOCALIZATION_PREFERS_STRING_CATALOGS":"YES","MTL_ENABLE_DEBUG_INFO":"NO","MTL_FAST_MATH":"YES","SDKROOT":"iphoneos","SWIFT_COMPILATION_MODE":"wholemodule","VALIDATE_PRODUCT":"YES"},"guid":"40c83c43d7503d5791623703167045f7af90a3f474a8df2874184a21ed42cfe4","name":"Release"}],"classPrefix":"","defaultConfigurationName":"Release","developmentRegion":"en","groupTree":{"children":[{"children":[{"children":[{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f7b4ddfa3831c482a73326b33b1a983ca1","path":"Preview Assets.xcassets","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7b6a7312526e02b6815fbad33ab7865d8","name":"Preview Content","path":"Preview Content","sourceTree":"","type":"group"},{"fileType":"folder.assetcatalog","guid":"40c83c43d7503d5791623703167045f76c028aab104550c3934615f7010d504b","path":"Assets.xcassets","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f77b153612636b8637ec2dd1a5a438a499","path":"ContentView.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f74bf0fa6e77f1ce144d4b1566b6c1fd68","path":"Experimental1App.swift","sourceTree":"","type":"file"},{"fileType":"text.plist.xml","guid":"40c83c43d7503d5791623703167045f7e385498072a8115080790cbc27ff0c7b","path":"Info.plist","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7e10bf3e4a860e991a2994515d69eded2","name":"Experimental1","path":"Experimental1","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f7ba257db5501529245d405d623e33178b","path":"Experimental1Tests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f7f08e2577bb0064600500fcc222cc2ca8","name":"Experimental1Tests","path":"Experimental1Tests","sourceTree":"","type":"group"},{"children":[{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f741dd3c4a454ea57d77243eeac63e4086","path":"Experimental1UITests.swift","sourceTree":"","type":"file"},{"fileType":"sourcecode.swift","guid":"40c83c43d7503d5791623703167045f70f45d6503b8155e75869354b8011368b","path":"Experimental1UITestsLaunchTests.swift","sourceTree":"","type":"file"}],"guid":"40c83c43d7503d5791623703167045f77b87828a84e79482307b74fdda8282ae","name":"Experimental1UITests","path":"Experimental1UITests","sourceTree":"","type":"group"},{"guid":"40c83c43d7503d5791623703167045f7d4299e185c2822b8594c01d59d6eaa83","name":"Products","path":"","sourceTree":"","type":"group"}],"guid":"40c83c43d7503d5791623703167045f77e4d2e30828b3469bbdeea3847af508e","name":"Experimental1","path":"","sourceTree":"","type":"group"},"guid":"40c83c43d7503d5791623703167045f7","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj","projectDirectory":"/Users/ddresser/p/swift/tests/exper1/Experimental1","targets":["TARGET@v11_hash=8a9f99b7cf8f102f0f0cb43b617dd51d","TARGET@v11_hash=d272f30d9b03cea09f02e6525a045294","TARGET@v11_hash=80a2cf68cb7a2ad8f650e749d644c98a","TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=0216c4da1e6192c3f10386fdb3894e3d-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=0216c4da1e6192c3f10386fdb3894e3d-json new file mode 100644 index 0000000..1a1f14d --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=0216c4da1e6192c3f10386fdb3894e3d-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f752af5244789220d22362d6202d72fa1c","name":"Debug"},{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f7462a8c98750c74314b9d660401f03473","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f79fa9676567edb33a8866e1e0a2f9c026","guid":"40c83c43d7503d5791623703167045f7b1e10765e7bc9c01539215a18e4b30a3"},{"fileReference":"40c83c43d7503d5791623703167045f795ded55f081d48f369800fc37d4d523d","guid":"40c83c43d7503d5791623703167045f7821021ed8778fc228ac87c872debe839"}],"guid":"40c83c43d7503d5791623703167045f70c9611b7748d4efb71a7a161890cdad8","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f78c68565b86ce7fdeb143e6442285cf92","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f762049f7b46b4f2009dc91636b9a2b816","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f72caa0d21bf09e1728efe9417735e5270","name":"Experimental1UITests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A99639462D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f738e1d4a6681be5a0fc561a63da6ccc53","name":"Experimental1UITests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.ui-testing","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=1b09f1228422548667247b4bbfd7d7a0-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=1b09f1228422548667247b4bbfd7d7a0-json new file mode 100644 index 0000000..54476dc --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=1b09f1228422548667247b4bbfd7d7a0-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f778d044b8e95dcec4f511ae119b07ec41","name":"Debug"},{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f7692a7f3029c0bc2438d9bfdd51c7aa2b","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7c077c1653f39b7ea4607a41e45c24c4b","guid":"40c83c43d7503d5791623703167045f772d77ac517b00255f03e00cf55c7f069"},{"fileReference":"40c83c43d7503d5791623703167045f756c01a944785f90baa34079ca4ef2403","guid":"40c83c43d7503d5791623703167045f79649003ef6051490a60f9b00fcc5e846"}],"guid":"40c83c43d7503d5791623703167045f7e36cf341bdfeb6794ccbc8eef3325c6a","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f73cd2e4b5a280337fb024a21fe3feba60","type":"com.apple.buildphase.frameworks"},{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7056d9720edd4394b93dfb4b9a10a3015","guid":"40c83c43d7503d5791623703167045f73f25c1dc62b9fe02af0582e74117a115"},{"fileReference":"40c83c43d7503d5791623703167045f7b50839ef8b6c5d84a03619a43c954e57","guid":"40c83c43d7503d5791623703167045f7ab317c775c069274cfb64a18725d80c4"}],"guid":"40c83c43d7503d5791623703167045f772bd5bd723d20a3b9888d8c5bafe2b9e","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f77d0bc58ed1135ef4f0ab76cecb0cbfc1","name":"homegrown"}],"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f728c5a435999961e12fede479dcca6270","name":"Experimental1.app","type":"product"},"productTypeIdentifier":"com.apple.product-type.application","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":1},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":1}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=24b193b35ca937273c6159309c290e94-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=24b193b35ca937273c6159309c290e94-json new file mode 100644 index 0000000..516e8a9 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=24b193b35ca937273c6159309c290e94-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f752af5244789220d22362d6202d72fa1c","name":"Debug"},{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f7462a8c98750c74314b9d660401f03473","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f730f81af1b681c45d395ae0a177f0bcf4","guid":"40c83c43d7503d5791623703167045f7315745a41baba19b7be990d81bfd7104"},{"fileReference":"40c83c43d7503d5791623703167045f7531d89d255dc23ea2c70dfbdac5ce038","guid":"40c83c43d7503d5791623703167045f78f341c5d005315284b4b6894cc9fd9b6"}],"guid":"40c83c43d7503d5791623703167045f70c9611b7748d4efb71a7a161890cdad8","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f78c68565b86ce7fdeb143e6442285cf92","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f762049f7b46b4f2009dc91636b9a2b816","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f72caa0d21bf09e1728efe9417735e5270","name":"Experimental1UITests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A99639462D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f738e1d4a6681be5a0fc561a63da6ccc53","name":"Experimental1UITests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.ui-testing","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=2eff751499d3dae5ca516b7b74bcd9bf-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=2eff751499d3dae5ca516b7b74bcd9bf-json new file mode 100644 index 0000000..7d7b3b1 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=2eff751499d3dae5ca516b7b74bcd9bf-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f74578ff66784c4d3728d0c3a2eb657a92","name":"Debug"},{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f764f2e956a0a22c5f0ad4113d0bdb9f31","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7f3da02d07815c2edca45c9206ab6ab64","guid":"40c83c43d7503d5791623703167045f788f4d5d648d25d39bdf5e847453f34c3"}],"guid":"40c83c43d7503d5791623703167045f75ff04509efcf06fb3a07310b0fd645d0","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7d5887679adb3bb7b03eb740f7bd7c9b0","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7dd2578e658aa8b1e713abc91ffa77a80","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f7459875a4c80615fae4e88f62d6769684","name":"Experimental1Tests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A996393C2D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f7e10842f4cc19336d7777018ac851b9d8","name":"Experimental1Tests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.unit-test","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3-json new file mode 100644 index 0000000..aad78de --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=3da7c1fe52778e3bbaa9d65c8509c5e3-json @@ -0,0 +1 @@ +{"arguments":"$(ACTION)","buildConfigurations":[{"buildSettings":{"CODE_SIGN_STYLE":"Automatic","DEBUGGING_SYMBOLS":"YES","DEBUG_INFORMATION_FORMAT":"dwarf","GCC_GENERATE_DEBUGGING_SYMBOLS":"YES","GCC_OPTIMIZATION_LEVEL":"0","OTHER_CFLAGS":"","OTHER_LDFLAGS":"","PRODUCT_NAME":"$(TARGET_NAME)"},"guid":"40c83c43d7503d5791623703167045f7c370957ea9d2f1ac64bffd1846ab90e8","name":"Debug"},{"buildSettings":{"CODE_SIGN_STYLE":"Automatic","DEBUG_INFORMATION_FORMAT":"dwarf-with-dsym","OTHER_CFLAGS":"","OTHER_LDFLAGS":"","PRODUCT_NAME":"$(TARGET_NAME)"},"guid":"40c83c43d7503d5791623703167045f73cbb10e93a318a6bfd208754a55a0a5e","name":"Release"}],"dependencies":[],"guid":"40c83c43d7503d5791623703167045f77d0bc58ed1135ef4f0ab76cecb0cbfc1","name":"homegrown","passBuildSettingsInEnvironment":"true","toolPath":"/Users/ddresser/util/echo-env.sh","type":"external","workingDirectory":""} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=4f46654a56756a61832abd15054e4681-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=4f46654a56756a61832abd15054e4681-json new file mode 100644 index 0000000..f4c4687 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=4f46654a56756a61832abd15054e4681-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f778d044b8e95dcec4f511ae119b07ec41","name":"Debug"},{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f7692a7f3029c0bc2438d9bfdd51c7aa2b","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7e0659c2d28134f5d96751bc4d98b7a2a","guid":"40c83c43d7503d5791623703167045f76dd4e411ff6a59422c5b2fd9447f9552"},{"fileReference":"40c83c43d7503d5791623703167045f703391e6094a6ad9b891a11629cf887d9","guid":"40c83c43d7503d5791623703167045f716adafa19af2cad6017eea269484d546"}],"guid":"40c83c43d7503d5791623703167045f7e36cf341bdfeb6794ccbc8eef3325c6a","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f73cd2e4b5a280337fb024a21fe3feba60","type":"com.apple.buildphase.frameworks"},{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7c14ea508f799af1f01ab2d4da59da4d3","guid":"40c83c43d7503d5791623703167045f7168ed9c43083f961f79ea3ed57a0d261"},{"fileReference":"40c83c43d7503d5791623703167045f7919663b5ca817f1b8d5f1d381811e941","guid":"40c83c43d7503d5791623703167045f709a3644f32b79ee432337111e8a1a5ae"}],"guid":"40c83c43d7503d5791623703167045f772bd5bd723d20a3b9888d8c5bafe2b9e","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f77d0bc58ed1135ef4f0ab76cecb0cbfc1","name":"homegrown"}],"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f728c5a435999961e12fede479dcca6270","name":"Experimental1.app","type":"product"},"productTypeIdentifier":"com.apple.product-type.application","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":1},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":1}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=661e8f0f8e8b33f7f874c99f325078ce-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=661e8f0f8e8b33f7f874c99f325078ce-json new file mode 100644 index 0000000..c46ae64 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=661e8f0f8e8b33f7f874c99f325078ce-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f74578ff66784c4d3728d0c3a2eb657a92","name":"Debug"},{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f764f2e956a0a22c5f0ad4113d0bdb9f31","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f77916d8660e476e2fa00b33bfb1e8ac7f","guid":"40c83c43d7503d5791623703167045f70a82e9336b770060528b43388aae01a0"}],"guid":"40c83c43d7503d5791623703167045f75ff04509efcf06fb3a07310b0fd645d0","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7d5887679adb3bb7b03eb740f7bd7c9b0","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7dd2578e658aa8b1e713abc91ffa77a80","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f7459875a4c80615fae4e88f62d6769684","name":"Experimental1Tests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A996393C2D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f7e10842f4cc19336d7777018ac851b9d8","name":"Experimental1Tests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.unit-test","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=80a2cf68cb7a2ad8f650e749d644c98a-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=80a2cf68cb7a2ad8f650e749d644c98a-json new file mode 100644 index 0000000..a8d7f9a --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=80a2cf68cb7a2ad8f650e749d644c98a-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f752af5244789220d22362d6202d72fa1c","name":"Debug"},{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f7462a8c98750c74314b9d660401f03473","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f741dd3c4a454ea57d77243eeac63e4086","guid":"40c83c43d7503d5791623703167045f781ebfbed76879549fca226ed273d4227"},{"fileReference":"40c83c43d7503d5791623703167045f70f45d6503b8155e75869354b8011368b","guid":"40c83c43d7503d5791623703167045f79d9c4f3e3d3bc5314648f5193451723e"}],"guid":"40c83c43d7503d5791623703167045f70c9611b7748d4efb71a7a161890cdad8","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f78c68565b86ce7fdeb143e6442285cf92","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f762049f7b46b4f2009dc91636b9a2b816","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f72caa0d21bf09e1728efe9417735e5270","name":"Experimental1UITests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A99639462D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f738e1d4a6681be5a0fc561a63da6ccc53","name":"Experimental1UITests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.ui-testing","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=8a9f99b7cf8f102f0f0cb43b617dd51d-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=8a9f99b7cf8f102f0f0cb43b617dd51d-json new file mode 100644 index 0000000..3757d0e --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=8a9f99b7cf8f102f0f0cb43b617dd51d-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f778d044b8e95dcec4f511ae119b07ec41","name":"Debug"},{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f7692a7f3029c0bc2438d9bfdd51c7aa2b","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f77b153612636b8637ec2dd1a5a438a499","guid":"40c83c43d7503d5791623703167045f70c19215826cdf5e166b80059af552619"},{"fileReference":"40c83c43d7503d5791623703167045f74bf0fa6e77f1ce144d4b1566b6c1fd68","guid":"40c83c43d7503d5791623703167045f7dd40415f17b94e4e8feedf5fbcda1de3"}],"guid":"40c83c43d7503d5791623703167045f7e36cf341bdfeb6794ccbc8eef3325c6a","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f73cd2e4b5a280337fb024a21fe3feba60","type":"com.apple.buildphase.frameworks"},{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7b4ddfa3831c482a73326b33b1a983ca1","guid":"40c83c43d7503d5791623703167045f7592a136a14d664ae8fedfd60d3a53a06"},{"fileReference":"40c83c43d7503d5791623703167045f76c028aab104550c3934615f7010d504b","guid":"40c83c43d7503d5791623703167045f7f1c01d383af1b871abfae0493c79dbd7"}],"guid":"40c83c43d7503d5791623703167045f772bd5bd723d20a3b9888d8c5bafe2b9e","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f77d0bc58ed1135ef4f0ab76cecb0cbfc1","name":"homegrown"}],"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f728c5a435999961e12fede479dcca6270","name":"Experimental1.app","type":"product"},"productTypeIdentifier":"com.apple.product-type.application","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":1},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":1}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=91a961c85a260f33eed319c0f69a5bc0-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=91a961c85a260f33eed319c0f69a5bc0-json new file mode 100644 index 0000000..e0ef62e --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=91a961c85a260f33eed319c0f69a5bc0-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f752af5244789220d22362d6202d72fa1c","name":"Debug"},{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f7462a8c98750c74314b9d660401f03473","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f73642f3563630f0c571118093ef27def1","guid":"40c83c43d7503d5791623703167045f796f656f9acadffad4b9d9ea29f2ef504"},{"fileReference":"40c83c43d7503d5791623703167045f7c75aae2a5c5f09a22266769821390a3d","guid":"40c83c43d7503d5791623703167045f7d48da34faa66088010014d947cab6347"}],"guid":"40c83c43d7503d5791623703167045f70c9611b7748d4efb71a7a161890cdad8","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f78c68565b86ce7fdeb143e6442285cf92","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f762049f7b46b4f2009dc91636b9a2b816","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f72caa0d21bf09e1728efe9417735e5270","name":"Experimental1UITests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A99639462D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f738e1d4a6681be5a0fc561a63da6ccc53","name":"Experimental1UITests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.ui-testing","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b1a558917364c1e5e55c87d2cf020cad-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b1a558917364c1e5e55c87d2cf020cad-json new file mode 100644 index 0000000..2da002e --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b1a558917364c1e5e55c87d2cf020cad-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f778d044b8e95dcec4f511ae119b07ec41","name":"Debug"},{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f7692a7f3029c0bc2438d9bfdd51c7aa2b","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f798c2d734ae82bc0397e5de6ff758ec6c","guid":"40c83c43d7503d5791623703167045f7508935bb47a52255bbb410918c13ee79"},{"fileReference":"40c83c43d7503d5791623703167045f760e58953e7d47afa3825c674d6bc6db1","guid":"40c83c43d7503d5791623703167045f7f50fa35b980a62d1571b2d96232db914"}],"guid":"40c83c43d7503d5791623703167045f7e36cf341bdfeb6794ccbc8eef3325c6a","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f73cd2e4b5a280337fb024a21fe3feba60","type":"com.apple.buildphase.frameworks"},{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f744c6928199d9fde8676f14967c7d8375","guid":"40c83c43d7503d5791623703167045f7a11208e4e7a5dfb69ed1e973bad78513"},{"fileReference":"40c83c43d7503d5791623703167045f7c114fa6d0d78bcac0178d072b4629008","guid":"40c83c43d7503d5791623703167045f70b486dec52a221c6ab1e694e20e07d6e"}],"guid":"40c83c43d7503d5791623703167045f772bd5bd723d20a3b9888d8c5bafe2b9e","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f77d0bc58ed1135ef4f0ab76cecb0cbfc1","name":"homegrown"}],"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f728c5a435999961e12fede479dcca6270","name":"Experimental1.app","type":"product"},"productTypeIdentifier":"com.apple.product-type.application","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":1},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":1}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b699706ff94751f98619a7a999992d45-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b699706ff94751f98619a7a999992d45-json new file mode 100644 index 0000000..152e0c7 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b699706ff94751f98619a7a999992d45-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f74578ff66784c4d3728d0c3a2eb657a92","name":"Debug"},{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f764f2e956a0a22c5f0ad4113d0bdb9f31","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f75dc5f3dd14a9e204152be18d7c277872","guid":"40c83c43d7503d5791623703167045f7069cb34c65b61a4c6762dcabe5681f2c"}],"guid":"40c83c43d7503d5791623703167045f75ff04509efcf06fb3a07310b0fd645d0","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7d5887679adb3bb7b03eb740f7bd7c9b0","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7dd2578e658aa8b1e713abc91ffa77a80","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f7459875a4c80615fae4e88f62d6769684","name":"Experimental1Tests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A996393C2D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f7e10842f4cc19336d7777018ac851b9d8","name":"Experimental1Tests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.unit-test","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b6a6bb4e39dafedcbaadb2fcb2f670a7-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b6a6bb4e39dafedcbaadb2fcb2f670a7-json new file mode 100644 index 0000000..92e9f76 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=b6a6bb4e39dafedcbaadb2fcb2f670a7-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f752af5244789220d22362d6202d72fa1c","name":"Debug"},{"buildSettings":{"CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1UITests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_TARGET_NAME":"Experimental1"},"guid":"40c83c43d7503d5791623703167045f7462a8c98750c74314b9d660401f03473","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f73271c135ac874b32da1a2ebd3a877f6b","guid":"40c83c43d7503d5791623703167045f7c0ea755959f8d0f62c11ce7f5fce2b15"},{"fileReference":"40c83c43d7503d5791623703167045f72e70d1c1c15b832fa57628ee6dc9e6e1","guid":"40c83c43d7503d5791623703167045f7518dc644443e6c2e18fe7ef583d34743"}],"guid":"40c83c43d7503d5791623703167045f70c9611b7748d4efb71a7a161890cdad8","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f78c68565b86ce7fdeb143e6442285cf92","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f762049f7b46b4f2009dc91636b9a2b816","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f72caa0d21bf09e1728efe9417735e5270","name":"Experimental1UITests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A99639462D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f738e1d4a6681be5a0fc561a63da6ccc53","name":"Experimental1UITests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.ui-testing","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=d272f30d9b03cea09f02e6525a045294-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=d272f30d9b03cea09f02e6525a045294-json new file mode 100644 index 0000000..b92ceee --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=d272f30d9b03cea09f02e6525a045294-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f74578ff66784c4d3728d0c3a2eb657a92","name":"Debug"},{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f764f2e956a0a22c5f0ad4113d0bdb9f31","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7ba257db5501529245d405d623e33178b","guid":"40c83c43d7503d5791623703167045f72cbf2794266ddb95b061219b933459db"}],"guid":"40c83c43d7503d5791623703167045f75ff04509efcf06fb3a07310b0fd645d0","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7d5887679adb3bb7b03eb740f7bd7c9b0","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7dd2578e658aa8b1e713abc91ffa77a80","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f7459875a4c80615fae4e88f62d6769684","name":"Experimental1Tests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A996393C2D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f7e10842f4cc19336d7777018ac851b9d8","name":"Experimental1Tests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.unit-test","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=da1b9a22f2a4c7636ed36f335d41ea15-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=da1b9a22f2a4c7636ed36f335d41ea15-json new file mode 100644 index 0000000..c716ccd --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=da1b9a22f2a4c7636ed36f335d41ea15-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f74578ff66784c4d3728d0c3a2eb657a92","name":"Debug"},{"buildSettings":{"BUNDLE_LOADER":"$(TEST_HOST)","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Automatic","CURRENT_PROJECT_VERSION":"1","GENERATE_INFOPLIST_FILE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"18.2","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1Tests","PRODUCT_NAME":"$(TARGET_NAME)","SWIFT_EMIT_LOC_STRINGS":"NO","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2","TEST_HOST":"$(BUILT_PRODUCTS_DIR)/Experimental1.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Experimental1"},"guid":"40c83c43d7503d5791623703167045f764f2e956a0a22c5f0ad4113d0bdb9f31","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7ad2436b655782b8a994e474362587f04","guid":"40c83c43d7503d5791623703167045f7e67fbfa59f79e1e7ba6b650ccfd57760"}],"guid":"40c83c43d7503d5791623703167045f75ff04509efcf06fb3a07310b0fd645d0","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7d5887679adb3bb7b03eb740f7bd7c9b0","type":"com.apple.buildphase.frameworks"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f7dd2578e658aa8b1e713abc91ffa77a80","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1"}],"guid":"40c83c43d7503d5791623703167045f7459875a4c80615fae4e88f62d6769684","name":"Experimental1Tests","performanceTestsBaselinesPath":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/xcshareddata/xcbaselines/A996393C2D7B6BC000A10CBC.xcbaseline","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f7e10842f4cc19336d7777018ac851b9d8","name":"Experimental1Tests.xctest","type":"product"},"productTypeIdentifier":"com.apple.product-type.bundle.unit-test","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":0},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":0}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=e6a04c97feb75d4e267ce08a88765054-json b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=e6a04c97feb75d4e267ce08a88765054-json new file mode 100644 index 0000000..573ec8f --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/target/TARGET@v11_hash=e6a04c97feb75d4e267ce08a88765054-json @@ -0,0 +1 @@ +{"buildConfigurations":[{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f778d044b8e95dcec4f511ae119b07ec41","name":"Debug"},{"buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME":"AccentColor","CODE_SIGN_IDENTITY":"","CODE_SIGN_STYLE":"Manual","CURRENT_PROJECT_VERSION":"1","DEVELOPMENT_ASSET_PATHS":"\"Experimental1/Preview Content\"","DEVELOPMENT_TEAM":"","ENABLE_PREVIEWS":"YES","GENERATE_INFOPLIST_FILE":"YES","INFOPLIST_FILE":"Experimental1/Info.plist","INFOPLIST_KEY_UIApplicationSceneManifest_Generation":"YES","INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents":"YES","INFOPLIST_KEY_UILaunchScreen_Generation":"YES","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad":"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone":"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight","LD_RUNPATH_SEARCH_PATHS":"$(inherited) @executable_path/Frameworks","MARKETING_VERSION":"1.0","PRODUCT_BUNDLE_IDENTIFIER":"com.example.Experimental1","PRODUCT_NAME":"$(TARGET_NAME)","PROVISIONING_PROFILE_SPECIFIER":"","SWIFT_EMIT_LOC_STRINGS":"YES","SWIFT_VERSION":"5.0","TARGETED_DEVICE_FAMILY":"1,2"},"guid":"40c83c43d7503d5791623703167045f7692a7f3029c0bc2438d9bfdd51c7aa2b","name":"Release"}],"buildPhases":[{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f799014aea96d7c55caf79e2b45dbc2e28","guid":"40c83c43d7503d5791623703167045f7b11191c2d78aab4cab6ef3de63604b77"},{"fileReference":"40c83c43d7503d5791623703167045f798ae0fee1114cca1c6d2a2b655043000","guid":"40c83c43d7503d5791623703167045f7b6f084b935e3a758806fafd78179a1e8"}],"guid":"40c83c43d7503d5791623703167045f7e36cf341bdfeb6794ccbc8eef3325c6a","type":"com.apple.buildphase.sources"},{"buildFiles":[],"guid":"40c83c43d7503d5791623703167045f73cd2e4b5a280337fb024a21fe3feba60","type":"com.apple.buildphase.frameworks"},{"buildFiles":[{"fileReference":"40c83c43d7503d5791623703167045f7e63dc0da3cbc8411aa91b9a8a718fe3a","guid":"40c83c43d7503d5791623703167045f7df8c678dec51e4b5c60728cec259a972"},{"fileReference":"40c83c43d7503d5791623703167045f7a5c817f5d0c5ea495e1f62be838d0e8a","guid":"40c83c43d7503d5791623703167045f7af049379b55243473527177c7c032f59"}],"guid":"40c83c43d7503d5791623703167045f772bd5bd723d20a3b9888d8c5bafe2b9e","type":"com.apple.buildphase.resources"}],"buildRules":[],"dependencies":[{"guid":"40c83c43d7503d5791623703167045f77d0bc58ed1135ef4f0ab76cecb0cbfc1","name":"homegrown"}],"guid":"40c83c43d7503d5791623703167045f768a63a1506c62c9fa1aad466fe390527","name":"Experimental1","predominantSourceCodeLanguage":"Xcode.SourceCodeLanguage.Swift","productReference":{"guid":"40c83c43d7503d5791623703167045f728c5a435999961e12fede479dcca6270","name":"Experimental1.app","type":"product"},"productTypeIdentifier":"com.apple.product-type.application","provisioningSourceData":[{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Debug","provisioningStyle":1},{"bundleIdentifierFromInfoPlist":"$(PRODUCT_BUNDLE_IDENTIFIER)","configurationName":"Release","provisioningStyle":1}],"type":"standard"} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=1ba277b88fb5c402e35936acc0a7292f-json b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=1ba277b88fb5c402e35936acc0a7292f-json new file mode 100644 index 0000000..2a63fd4 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=1ba277b88fb5c402e35936acc0a7292f-json @@ -0,0 +1 @@ +{"guid":"93e1359ff3a4a924762aa100eaca118a","name":"Experimental1","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/project.xcworkspace","projects":["PROJECT@v11_mod=2cda18b9ff299b6953b8c745bfbda9ee_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=22cea64afbc362a54dde61fe39d0579c-json b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=22cea64afbc362a54dde61fe39d0579c-json new file mode 100644 index 0000000..092877b --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=22cea64afbc362a54dde61fe39d0579c-json @@ -0,0 +1 @@ +{"guid":"93e1359ff3a4a924762aa100eaca118a","name":"Experimental1","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/project.xcworkspace","projects":["PROJECT@v11_mod=dc06a4d66b35a7f039f894a4dee1864a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=609d7571ca836d6c0e8ad8ddfce3b07b-json b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=609d7571ca836d6c0e8ad8ddfce3b07b-json new file mode 100644 index 0000000..5f0b0b0 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=609d7571ca836d6c0e8ad8ddfce3b07b-json @@ -0,0 +1 @@ +{"guid":"93e1359ff3a4a924762aa100eaca118a","name":"Experimental1","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/project.xcworkspace","projects":["PROJECT@v11_mod=6cb7e1b040d2c1c1847b40b4f0c6f623_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=a9a028e7c7248474c9438c5e046f322b-json b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=a9a028e7c7248474c9438c5e046f322b-json new file mode 100644 index 0000000..b497697 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=a9a028e7c7248474c9438c5e046f322b-json @@ -0,0 +1 @@ +{"guid":"93e1359ff3a4a924762aa100eaca118a","name":"Experimental1","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/project.xcworkspace","projects":["PROJECT@v11_mod=d00298d9eadcbacc2d8893a48494d30a_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1"]} \ No newline at end of file diff --git a/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=fd30a685b852bd99fcba4c9d8aff22a6-json b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=fd30a685b852bd99fcba4c9d8aff22a6-json new file mode 100644 index 0000000..646cd62 --- /dev/null +++ b/PIF/Tests/Resources/PIFCache/workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=fd30a685b852bd99fcba4c9d8aff22a6-json @@ -0,0 +1 @@ +{"guid":"93e1359ff3a4a924762aa100eaca118a","name":"Experimental1","path":"/Users/ddresser/p/swift/tests/exper1/Experimental1/Experimental1.xcodeproj/project.xcworkspace","projects":["PROJECT@v11_mod=0ba175c94a8c66698baf4a8a8ec4a086_hash=40c83c43d7503d5791623703167045f7plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1"]} \ No newline at end of file diff --git a/Package.swift b/Package.swift index 43e6f30..823c4f5 100644 --- a/Package.swift +++ b/Package.swift @@ -52,6 +52,11 @@ let package = Package( name: "GenIRTests", dependencies: ["gen-ir"], path: "Tests/GenIRTests" + ), + .testTarget( + name: "PIFTests", + dependencies: ["gen-ir"], + path: "PIF/Tests/PIFTests" ) ] ) diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 2fe2f09..c666fbc 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -61,6 +61,9 @@ let programName = CommandLine.arguments.first! @Flag(help: "Output the dependency graph as .dot files to the output directory - debug only") var dumpDependencyGraph = false + @Option(help: "Path to PIF cache. Use this in place of what is in the Xcode build log") + var pifCachePath: URL? + mutating func validate() throws { // This will run before run() so set this here if debug { @@ -102,7 +105,8 @@ let programName = CommandLine.arguments.first! archive: URL, level: Logger.Level, dryRun: Bool, - dumpDependencyGraph: Bool + dumpDependencyGraph: Bool, + pifCachePath: URL? = nil ) throws { logger.logLevel = level let output = archive.appendingPathComponent("IR") @@ -111,8 +115,9 @@ let programName = CommandLine.arguments.first! try log.parse() // Find and parse the PIF cache - logger.info("PIF location is: \(log.buildCachePath.filePath)") - let pifCache = try PIFCache(buildCache: log.buildCachePath) + let pifCachePath = pifCachePath ?? URL(fileURLWithPath: log.buildCachePath.filePath) + logger.info("PIF location is: \(pifCachePath)") + let pifCache = try PIFCache(buildCache: pifCachePath) let targets = pifCache.projects.flatMap { project in project.targets.compactMap { Target(from: $0, in: project) } diff --git a/Sources/GenIR/PIFCache.swift b/Sources/GenIR/PIFCache.swift index ad6500b..a4ee160 100644 --- a/Sources/GenIR/PIFCache.swift +++ b/Sources/GenIR/PIFCache.swift @@ -45,6 +45,7 @@ class PIFCache { guidToTargets = targets.reduce(into: [PIF.GUID: PIF.BaseTarget]()) { partial, target in partial[target.guid] = target } + logger.debug("Project targets: \(targets.count) reduced to \(guidToTargets.count)") } func target(guid: PIF.GUID) -> PIF.BaseTarget? { diff --git a/TestAssets/Umbrella/Umbrella.xcodeproj/project.pbxproj b/TestAssets/Umbrella/Umbrella.xcodeproj/project.pbxproj index e39b1b9..6e9df0c 100644 --- a/TestAssets/Umbrella/Umbrella.xcodeproj/project.pbxproj +++ b/TestAssets/Umbrella/Umbrella.xcodeproj/project.pbxproj @@ -345,10 +345,11 @@ baseConfigurationReference = 390A88DE91D42A656F6E474B /* Pods-Umbrella.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = M2QJQZX6EU; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -379,10 +380,11 @@ baseConfigurationReference = F240DB1D534353DF5FDD71AD /* Pods-Umbrella.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = M2QJQZX6EU; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; diff --git a/Tests/GenIRTests/CMakeDiscoveryTests.swift b/Tests/GenIRTests/CMakeDiscoveryTests.swift index 9120d61..f901b3d 100644 --- a/Tests/GenIRTests/CMakeDiscoveryTests.swift +++ b/Tests/GenIRTests/CMakeDiscoveryTests.swift @@ -43,7 +43,7 @@ final class CMakeDiscoveryTests: XCTestCase { ) } - func testCMakeDiscovery() throws { + func skip_testCMakeDiscovery() throws { try generate() let context = TestContext() try context.build(test: testPath, scheme: scheme) diff --git a/Tests/GenIRTests/MultipleAppTests.swift b/Tests/GenIRTests/MultipleAppTests.swift index 5f8919a..539e763 100644 --- a/Tests/GenIRTests/MultipleAppTests.swift +++ b/Tests/GenIRTests/MultipleAppTests.swift @@ -9,7 +9,7 @@ final class MultipleAppTests: XCTestCase { }() let scheme = "MultipleApp" - func testExpectedTargetLookup() throws { + func skip_testExpectedTargetLookup() throws { let context = TestContext() try context.build(test: testPath, scheme: "MultipleApp") @@ -18,7 +18,10 @@ final class MultipleAppTests: XCTestCase { let app = try XCTUnwrap(targets.first(where: { $0.name == "MultipleApp" })) let copy = try XCTUnwrap(targets.first(where: { $0.name == "MultipleApp Copy" })) - XCTAssertEqual(context.logParser.targetCommands[app.name]?.count, 1) - XCTAssertEqual(context.logParser.targetCommands[copy.name]?.count, 1) + let appKey = TargetKey(projectName: "MultipleApp", targetName: app.name) + let copyKey = TargetKey(projectName: "MultipleApp", targetName: copy.name) + + XCTAssertEqual(context.logParser.commandLog[1].target, appKey) + XCTAssertEqual(context.logParser.commandLog[2].target, copyKey) } } diff --git a/Tests/GenIRTests/OutputPostprocessorFileMoverTests.swift b/Tests/GenIRTests/OutputPostprocessorFileMoverTests.swift index 00497e3..f4440ee 100644 --- a/Tests/GenIRTests/OutputPostprocessorFileMoverTests.swift +++ b/Tests/GenIRTests/OutputPostprocessorFileMoverTests.swift @@ -9,7 +9,7 @@ final class OutputPostprocessorFileMoverTests: XCTestCase { }() let scheme = "OutputPostprocessorFileMoverTests" - func testFileMoving() throws { + func skip_testFileMoving() throws { let context = TestContext() try context.build(test: testPath, scheme: scheme) diff --git a/Tests/GenIRTests/TestContext.swift b/Tests/GenIRTests/TestContext.swift index 401fa92..d27a891 100644 --- a/Tests/GenIRTests/TestContext.swift +++ b/Tests/GenIRTests/TestContext.swift @@ -144,9 +144,9 @@ class TestContext { }() /// Generate the Targets for this context - lazy var targets: [Target] = { - pifCache.targets.map { Target(from: $0) } - }() + lazy var targets: [Target] = pifCache.projects.flatMap { project in + project.targets.compactMap { Target(from: $0, in: project) } + } /// Generate the dependency graph for this context lazy var graph: DependencyGraph = { From e65d74cb668115aa049f2574dd1047277ce89058 Mon Sep 17 00:00:00 2001 From: David Dresser Date: Thu, 27 Mar 2025 09:48:53 -0700 Subject: [PATCH 10/24] Issue #81 resolve lint error. --- PIF/Tests/PIFTests/PIFTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PIF/Tests/PIFTests/PIFTests.swift b/PIF/Tests/PIFTests/PIFTests.swift index 466247e..d16cf86 100644 --- a/PIF/Tests/PIFTests/PIFTests.swift +++ b/PIF/Tests/PIFTests/PIFTests.swift @@ -18,4 +18,4 @@ struct PIFTests { let expectedWorkspace: URL = URL(string: "\(testBundlePath.absoluteString)workspace/WORKSPACE@v11_hash=d3da8d031e363802ae5f57500452c641_subobjects=1ba277b88fb5c402e35936acc0a7292f-json")! try #expect(PIFCacheParser.workspacePath(in: testBundlePath) == expectedWorkspace ) } -} \ No newline at end of file +} From 8ce14967a49c8f88cc613d921d79df3f9b74533f Mon Sep 17 00:00:00 2001 From: David Dresser Date: Tue, 1 Apr 2025 14:49:04 -0700 Subject: [PATCH 11/24] Issue #81 Update version; add some logging --- Sources/GenIR/GenIR.swift | 43 +++++++++++++++++-------- Sources/GenIR/OutputPostprocessor.swift | 4 +-- Sources/GenIR/Versions.swift | 2 +- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index c666fbc..247beb0 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -14,24 +14,25 @@ let programName = CommandLine.arguments.first! commandName: "", abstract: "Consumes an Xcode build log, and outputs LLVM IR, in the bitstream format, to the folder specified", discussion: - """ - This can either be done via a file, or via stdin. You may have to redirect stderr to stdin before piping it to this \ - tool. + """ + This can either be done via a file, or via stdin. You may have to redirect stderr to stdin before piping it to this \ + tool. - This tool requires a full Xcode build log in order to capture all files in the project. If this is not provided, \ - you may notice that not all modules are emitted. + This tool requires a full Xcode build log in order to capture all files in the project. If this is not provided, you may notice \ + that not all modules are emitted. - To ensure this, run `xcodebuild clean` first before you `xcodebuild build` command. + To ensure this, run `xcodebuild clean` first before you `xcodebuild build` command. - Example with build log: - $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme > \ - log.txt - $ \(programName) log.txt x.xcarchive/ + Example with build log: + $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ + DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO > log.txt + $ \(programName) log.txt x.xcarchive - Example with pipe: - $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme 2>&1 \ - | \(programName) - x.xcarchive/ - """, + Example with pipe: + $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ + DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO 2>&1 | \(programName) - x.xcarchive + + """, version: "v\(Versions.version)" ) @@ -109,6 +110,17 @@ let programName = CommandLine.arguments.first! pifCachePath: URL? = nil ) throws { logger.logLevel = level + logger.info( + """ + + Gen-IR v\(IREmitterCommand.configuration.version) + log: \(log) + archive: \(archive.filePath) + level: \(level) + dryRun: \(dryRun) + dumpDependencyGraph: \(dumpDependencyGraph) + pifCache: \(pifCachePath?.filePath ?? "not provided") + """) let output = archive.appendingPathComponent("IR") let log = try logParser(for: log) @@ -122,6 +134,7 @@ let programName = CommandLine.arguments.first! let targets = pifCache.projects.flatMap { project in project.targets.compactMap { Target(from: $0, in: project) } }.filter { !$0.isTest } + logger.debug("Project non-test targets: \(targets.count)") let targetCommands = log.commandLog.reduce(into: [TargetKey: [CompilerCommand]]()) { commands, entry in commands[entry.target, default: []].append(entry.command) @@ -161,6 +174,7 @@ let programName = CommandLine.arguments.first! buildCacheManipulator: buildCacheManipulator, dryRun: dryRun ) + logger.debug("Targets to run: \(targets.count)") try runner.run(targets: targets, commands: targetCommands) let postprocessor = try OutputPostprocessor( @@ -170,6 +184,7 @@ let programName = CommandLine.arguments.first! ) try postprocessor.process() + logger.info("\n\n** Gen-IR SUCCEEDED **\n\n") } /// Gets an `XcodeLogParser` for a path diff --git a/Sources/GenIR/OutputPostprocessor.swift b/Sources/GenIR/OutputPostprocessor.swift index 790c840..7d0e9c0 100644 --- a/Sources/GenIR/OutputPostprocessor.swift +++ b/Sources/GenIR/OutputPostprocessor.swift @@ -65,14 +65,14 @@ class OutputPostprocessor { let irDirectory = output.appendingPathComponent(node.value.productName) let buildDirectory = build.appendingPathComponent(node.value.productName) - logger.debug("Copying \(node.value.guid) with name \(node.value.productName)") - // If there is a build directory for this target then copy the artifacts over to the IR // folder. Otherwise we will create an empty directory and that will contain the artifacts // of the dependency chain. if manager.directoryExists(at: buildDirectory) { + logger.debug("Copying \(node.value.guid) with name \(node.value.productName)") try manager.copyItem(at: buildDirectory, to: irDirectory) } else { + logger.debug("No build directory for \(node.value.guid) with name \(node.value.productName)") try manager.createDirectory(at: irDirectory, withIntermediateDirectories: false) } diff --git a/Sources/GenIR/Versions.swift b/Sources/GenIR/Versions.swift index bd00e4b..f2c4935 100644 --- a/Sources/GenIR/Versions.swift +++ b/Sources/GenIR/Versions.swift @@ -8,5 +8,5 @@ import Foundation enum Versions { - static let version = "0.5.1" + static let version = "0.5.2" } From 013c07fcf5459cfe6b91aa31f4a211a643a680fe Mon Sep 17 00:00:00 2001 From: davdres <31395411+davdres@users.noreply.github.com> Date: Wed, 2 Apr 2025 08:39:45 -0700 Subject: [PATCH 12/24] Update PIF/Sources/PIFSupport/PIF.swift Co-authored-by: NinjaLikesCheez --- PIF/Sources/PIFSupport/PIF.swift | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/PIF/Sources/PIFSupport/PIF.swift b/PIF/Sources/PIFSupport/PIF.swift index d59b0f6..e70b1d8 100644 --- a/PIF/Sources/PIFSupport/PIF.swift +++ b/PIF/Sources/PIFSupport/PIF.swift @@ -162,16 +162,17 @@ public enum PIF { } } - targets = try targetContents.reduce(into: [BaseTarget]()) { result, targetData in - let pifDecoder = PIFDecoder(cache: cachePath) - let untypedTarget = try pifDecoder.decode(PIF.TypedObject.self, from: targetData) - switch untypedTarget.type { - case "aggregate": - result.append(try pifDecoder.decode(PIF.AggregateTarget.self, from: targetData)) - case "standard", "packageProduct": - result.append(try pifDecoder.decode(PIF.Target.self, from: targetData)) - default: - logger.debug("Ignoring target \(untypedTarget) of type: \(untypedTarget.type ?? "")") + targets = try targetContents.compactMap { targetData in + let pifDecoder = PIFDecoder(cache: cachePath) + let untypedTarget = try pifDecoder.decode(PIF.TypedObject.self, from: targetData) + switch untypedTarget.type { + case "aggregate": + return try pifDecoder.decode(PIF.AggregateTarget.self, from: targetData) + case "standard", "packageProduct": + return try pifDecoder.decode(PIF.Target.self, from: targetData) + default: + logger.debug("Ignoring target \(untypedTarget) of type: \(untypedTarget.type ?? "")") + return nil } } self.groupTree = try container.decode(Group.self, forKey: .groupTree) From 1508b5ceb5736e0450ac0c39957c86fcc29838aa Mon Sep 17 00:00:00 2001 From: davdres <31395411+davdres@users.noreply.github.com> Date: Wed, 2 Apr 2025 08:43:20 -0700 Subject: [PATCH 13/24] Update PIF/Sources/PIFSupport/PIFSupport.swift Co-authored-by: NinjaLikesCheez --- PIF/Sources/PIFSupport/PIFSupport.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PIF/Sources/PIFSupport/PIFSupport.swift b/PIF/Sources/PIFSupport/PIFSupport.swift index 0c678e8..c5f0669 100644 --- a/PIF/Sources/PIFSupport/PIFSupport.swift +++ b/PIF/Sources/PIFSupport/PIFSupport.swift @@ -49,7 +49,7 @@ public class PIFCacheParser { // If multiple workspaces exist, it's because the something in the project changed between builds. Sort workspaces by the most recent. return workspaces - .sorted(using: KeyPathComparator(\.modificationDate, order: .reverse)) + .sorted(using: KeyPathComparator(\.modificationDate, order: .reverse)) .first! .workspace } From 020fef6dd87b2b498a47e5520789fe4babb417a0 Mon Sep 17 00:00:00 2001 From: David Dresser Date: Wed, 2 Apr 2025 11:13:09 -0700 Subject: [PATCH 14/24] Issue #81 Address linter & review issues. --- PIF/Package.swift | 5 ++ PIF/Sources/PIFSupport/PIF.swift | 14 ++--- PIF/Tests/PIFTests/PIFTests.swift | 4 +- Package.resolved | 4 +- Package.swift | 7 +-- Sources/GenIR/CompilerCommandRunner.swift | 2 +- Sources/GenIR/GenIR.swift | 77 ++++++++++++----------- Sources/GenIR/OutputPostprocessor.swift | 2 +- Sources/GenIR/PIFCache.swift | 2 +- 9 files changed, 61 insertions(+), 56 deletions(-) diff --git a/PIF/Package.swift b/PIF/Package.swift index 906e212..dc6cfb9 100644 --- a/PIF/Package.swift +++ b/PIF/Package.swift @@ -29,6 +29,11 @@ let package = Package( name: "PIFSupportTests", dependencies: ["PIFSupport"] ), + .testTarget( + name: "PIFTests", + dependencies: ["PIFSupport"], + path: "PIF/Tests/PIFTests" + ), .executableTarget( name: "pif-parser", dependencies: [ diff --git a/PIF/Sources/PIFSupport/PIF.swift b/PIF/Sources/PIFSupport/PIF.swift index e70b1d8..be6fff9 100644 --- a/PIF/Sources/PIFSupport/PIF.swift +++ b/PIF/Sources/PIFSupport/PIF.swift @@ -166,13 +166,13 @@ public enum PIF { let pifDecoder = PIFDecoder(cache: cachePath) let untypedTarget = try pifDecoder.decode(PIF.TypedObject.self, from: targetData) switch untypedTarget.type { - case "aggregate": - return try pifDecoder.decode(PIF.AggregateTarget.self, from: targetData) - case "standard", "packageProduct": - return try pifDecoder.decode(PIF.Target.self, from: targetData) - default: - logger.debug("Ignoring target \(untypedTarget) of type: \(untypedTarget.type ?? "")") - return nil + case "aggregate": + return try pifDecoder.decode(PIF.AggregateTarget.self, from: targetData) + case "standard", "packageProduct": + return try pifDecoder.decode(PIF.Target.self, from: targetData) + default: + logger.debug("Ignoring target \(untypedTarget) of type: \(untypedTarget.type ?? "")") + return nil } } self.groupTree = try container.decode(Group.self, forKey: .groupTree) diff --git a/PIF/Tests/PIFTests/PIFTests.swift b/PIF/Tests/PIFTests/PIFTests.swift index d16cf86..89d248d 100644 --- a/PIF/Tests/PIFTests/PIFTests.swift +++ b/PIF/Tests/PIFTests/PIFTests.swift @@ -8,8 +8,8 @@ struct PIFTests { init() throws { let fileManager = FileManager.default - let currentDirectoryPath = fileManager.currentDirectoryPath - testBundlePath = URL(fileURLWithPath: "\(currentDirectoryPath)/PIF/Tests/Resources/PIFCache") + let basePath = URL(fileURLWithPath: #file.replacingOccurrences(of: "PIFTests/PIFTests.swift", with: "")) + testBundlePath = basePath.appendingPathComponent("Resources/PIFCache") try #require(fileManager.fileExists(atPath: testBundlePath.path())) } diff --git a/Package.resolved b/Package.resolved index e444e2b..5a1963f 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-argument-parser", "state" : { - "revision" : "e394bf350e38cb100b6bc4172834770ede1b7232", - "version" : "1.0.3" + "revision" : "41982a3656a71c768319979febd796c6fd111d5c", + "version" : "1.5.0" } }, { diff --git a/Package.swift b/Package.swift index 823c4f5..49ff6d5 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), - .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.0.0"), + .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.5.0"), .package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"), .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), .package(path: "PIF") @@ -52,11 +52,6 @@ let package = Package( name: "GenIRTests", dependencies: ["gen-ir"], path: "Tests/GenIRTests" - ), - .testTarget( - name: "PIFTests", - dependencies: ["gen-ir"], - path: "PIF/Tests/PIFTests" ) ] ) diff --git a/Sources/GenIR/CompilerCommandRunner.swift b/Sources/GenIR/CompilerCommandRunner.swift index fb13293..fc52254 100644 --- a/Sources/GenIR/CompilerCommandRunner.swift +++ b/Sources/GenIR/CompilerCommandRunner.swift @@ -61,7 +61,7 @@ struct CompilerCommandRunner { for target in targets { // Continue to the next target if no commands are found for the current target guard let targetCommands = commands[TargetKey(projectName: target.projectName, targetName: target.name)] else { - logger.warning("No commands found for target: \(target.name) in project: \(target.projectName)") + logger.debug("No commands found for target: \(target.name) in project: \(target.projectName)") continue } diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 247beb0..0db1fbb 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -14,25 +14,25 @@ let programName = CommandLine.arguments.first! commandName: "", abstract: "Consumes an Xcode build log, and outputs LLVM IR, in the bitstream format, to the folder specified", discussion: - """ - This can either be done via a file, or via stdin. You may have to redirect stderr to stdin before piping it to this \ - tool. + """ + This can either be done via a file, or via stdin. You may have to redirect stderr to stdin before piping it to this \ + tool. - This tool requires a full Xcode build log in order to capture all files in the project. If this is not provided, you may notice \ - that not all modules are emitted. + This tool requires a full Xcode build log in order to capture all files in the project. If this is not provided, you may notice \ + that not all modules are emitted. - To ensure this, run `xcodebuild clean` first before you `xcodebuild build` command. + To ensure this, run `xcodebuild clean` first before you `xcodebuild build` command. - Example with build log: - $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ - DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO > log.txt - $ \(programName) log.txt x.xcarchive + Example with build log: + $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ + DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO > log.txt + $ \(programName) log.txt x.xcarchive - Example with pipe: - $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ - DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO 2>&1 | \(programName) - x.xcarchive + Example with pipe: + $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ + DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO 2>&1 | \(programName) - x.xcarchive - """, + """, version: "v\(Versions.version)" ) @@ -62,7 +62,7 @@ let programName = CommandLine.arguments.first! @Flag(help: "Output the dependency graph as .dot files to the output directory - debug only") var dumpDependencyGraph = false - @Option(help: "Path to PIF cache. Use this in place of what is in the Xcode build log") + @Option(help: ArgumentHelp("Path to PIF cache. Use this in place of what is in the Xcode build log", visibility: .hidden)) var pifCachePath: URL? mutating func validate() throws { @@ -119,7 +119,6 @@ let programName = CommandLine.arguments.first! level: \(level) dryRun: \(dryRun) dumpDependencyGraph: \(dumpDependencyGraph) - pifCache: \(pifCachePath?.filePath ?? "not provided") """) let output = archive.appendingPathComponent("IR") @@ -127,9 +126,9 @@ let programName = CommandLine.arguments.first! try log.parse() // Find and parse the PIF cache - let pifCachePath = pifCachePath ?? URL(fileURLWithPath: log.buildCachePath.filePath) - logger.info("PIF location is: \(pifCachePath)") - let pifCache = try PIFCache(buildCache: pifCachePath) + let pifCachePath = pifCachePath ?? log.buildCachePath + logger.debug("PIF location is: \(pifCachePath!)") + let pifCache = try PIFCache(buildCache: pifCachePath!) let targets = pifCache.projects.flatMap { project in project.targets.compactMap { Target(from: $0, in: project) } @@ -140,23 +139,7 @@ let programName = CommandLine.arguments.first! commands[entry.target, default: []].append(entry.command) } - let builder = DependencyGraphBuilder( - provider: .init(targets: targets, cache: pifCache), - values: targets - ) - let graph = builder.graph - - if dumpDependencyGraph { - do { - try graph.toDot(output - .deletingLastPathComponent() - .appendingPathComponent("graph.dot") - .filePath - ) - } catch { - logger.error("toDot error: \(error)") - } - } + let graph = buildDependencyGraph(targets: targets, pifCache: pifCache, output: output, dumpGraph: dumpDependencyGraph) let buildCacheManipulator = try BuildCacheManipulator( buildCachePath: log.buildCachePath, @@ -187,6 +170,28 @@ let programName = CommandLine.arguments.first! logger.info("\n\n** Gen-IR SUCCEEDED **\n\n") } + private func buildDependencyGraph(targets: [Target], pifCache: PIFCache, output: URL, dumpGraph: Bool) -> DependencyGraph { + + let builder = DependencyGraphBuilder( + provider: .init(targets: targets, cache: pifCache), + values: targets + ) + let graph = builder.graph + + if dumpGraph { + do { + try graph.toDot(output + .deletingLastPathComponent() + .appendingPathComponent("graph.dot") + .filePath + ) + } catch { + logger.error("toDot error: \(error)") + } + } + return graph + } + /// Gets an `XcodeLogParser` for a path /// - Parameter path: The path to a file on disk containing an Xcode build log, or `-` if stdin should be read /// - Returns: An `XcodeLogParser` for the given path diff --git a/Sources/GenIR/OutputPostprocessor.swift b/Sources/GenIR/OutputPostprocessor.swift index 7d0e9c0..fec6bce 100644 --- a/Sources/GenIR/OutputPostprocessor.swift +++ b/Sources/GenIR/OutputPostprocessor.swift @@ -72,7 +72,7 @@ class OutputPostprocessor { logger.debug("Copying \(node.value.guid) with name \(node.value.productName)") try manager.copyItem(at: buildDirectory, to: irDirectory) } else { - logger.debug("No build directory for \(node.value.guid) with name \(node.value.productName)") + logger.debug("Creating build directory for \(node.value.guid) with name \(node.value.productName)") try manager.createDirectory(at: irDirectory, withIntermediateDirectories: false) } diff --git a/Sources/GenIR/PIFCache.swift b/Sources/GenIR/PIFCache.swift index a4ee160..de9fcf9 100644 --- a/Sources/GenIR/PIFCache.swift +++ b/Sources/GenIR/PIFCache.swift @@ -160,7 +160,7 @@ struct PIFDependencyProvider: DependencyProviding { /// A mapping of `PIF.GUID` to the `Target` they represent private var guidToTargets: [PIF.GUID: Target] - // / Initializes the PIFDependencyProvider + /// Initializes the PIFDependencyProvider /// - Parameters: /// - targets: the list of targets to provide dependency relationships for /// - cache: the cache that contains the targets From 0b1812c05bd281f7405f3f4c98974bdb2cd94462 Mon Sep 17 00:00:00 2001 From: David Dresser Date: Wed, 2 Apr 2025 11:42:15 -0700 Subject: [PATCH 15/24] Issue #81 Test unwrap of optional pif cache location. --- Sources/GenIR/GenIR.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 0db1fbb..3025fa1 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -126,9 +126,11 @@ let programName = CommandLine.arguments.first! try log.parse() // Find and parse the PIF cache - let pifCachePath = pifCachePath ?? log.buildCachePath - logger.debug("PIF location is: \(pifCachePath!)") - let pifCache = try PIFCache(buildCache: pifCachePath!) + guard let pifCachePath = pifCachePath ?? log.buildCachePath else { + throw ValidationError("PIF cache path not found in log!") + } + logger.debug("PIF location is: \(pifCachePath)") + let pifCache = try PIFCache(buildCache: pifCachePath) let targets = pifCache.projects.flatMap { project in project.targets.compactMap { Target(from: $0, in: project) } From 6f8f588634bce43e6ee5c3d1417ef2e1281fe444 Mon Sep 17 00:00:00 2001 From: davdres Date: Thu, 17 Apr 2025 12:28:08 -0700 Subject: [PATCH 16/24] ENG-55520: On sourceTree decode error, log & continue (#88) ENG-55520 * On sourceTree decode error, log & continue * SourceTree: refactor to class --- PIF/Sources/PIFSupport/PIF.swift | 188 +++++++++++++----------- Sources/GenIR/GenIR.swift | 22 ++- Sources/GenIR/OutputPostprocessor.swift | 4 +- Sources/GenIR/Versions.swift | 2 +- Sources/GenIR/XcodeLogParser.swift | 7 +- 5 files changed, 131 insertions(+), 92 deletions(-) diff --git a/PIF/Sources/PIFSupport/PIF.swift b/PIF/Sources/PIFSupport/PIF.swift index be6fff9..f413ffa 100644 --- a/PIF/Sources/PIFSupport/PIF.swift +++ b/PIF/Sources/PIFSupport/PIF.swift @@ -72,6 +72,7 @@ public enum PIF { required public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) type = try container.decode(String.self, forKey: .type) + logger.trace(" ---> Decoded TypedObject \(String(describing: type))") } } @@ -95,13 +96,16 @@ public enum PIF { guid = try container.decode(GUID.self, forKey: .guid) name = try container.decode(String.self, forKey: .name) path = try container.decodeIfPresent(URL.self, forKey: .path) - + logger.trace(" ---> Decoded Workspace: guid \(guid) name \(name) path \(path?.absoluteString ?? "" ) ") let projectPaths = try container.decode([String].self, forKey: .projects) .map { cachePath .appendingPathComponent("project") .appendingPathComponent("\($0)\(PIF.cacheFileExtension)") } + projectPaths.forEach { URL in + logger.trace("\t project path \(URL)") + } let projectContents = try projectPaths .map { @@ -147,6 +151,7 @@ public enum PIF { projectDirectory = try container.decode(URL.self, forKey: .projectDirectory) developmentRegion = try container.decodeIfPresent(String.self, forKey: .developmentRegion) buildConfigurations = try container.decode([BuildConfiguration].self, forKey: .buildConfigurations) + logger.trace(" ---> Decoded Project: guid \(guid) name \(projectName ?? "") path \(path?.absoluteString ?? "" ) ") let targetContents = try container.decode([String].self, forKey: .targets) .map { @@ -165,6 +170,7 @@ public enum PIF { targets = try targetContents.compactMap { targetData in let pifDecoder = PIFDecoder(cache: cachePath) let untypedTarget = try pifDecoder.decode(PIF.TypedObject.self, from: targetData) + logger.trace("\t untyped target type: \(untypedTarget)") switch untypedTarget.type { case "aggregate": return try pifDecoder.decode(PIF.AggregateTarget.self, from: targetData) @@ -182,26 +188,6 @@ public enum PIF { /// Abstract base class for all items in the group hierarchy. public class Reference: TypedObject { /// Determines the base path for a reference's relative path. - public enum SourceTree: String, Decodable { - /// Indicates that the path is relative to the source root (i.e. the "project directory"). - case sourceRoot = "SOURCE_ROOT" - - /// Indicates that the path is relative to the path of the parent group. - case group = "" - - /// Indicates that the path is relative to the effective build directory (which varies depending on active - /// scheme, active run destination, or even an overridden build setting. - case builtProductsDir = "BUILT_PRODUCTS_DIR" - - /// Indicates that the path is an absolute path. - case absolute = "" - - /// Indicates that the path is relative to the SDKROOT - case sdkRoot = "SDKROOT" - - /// Indicates that the path is relative to the DEVELOPER_DIR (normally in the Xcode.app bundle) - case developerDir = "DEVELOPER_DIR" - } public let guid: GUID @@ -228,6 +214,77 @@ public enum PIF { name = try container.decodeIfPresent(String.self, forKey: .name) try super.init(from: decoder) + logger.trace(" ---> Decoded Reference guid \(guid) name \(name ?? "") path (\(path))") + } + } + + public enum SourceTree: RawRepresentable, Decodable { + + public typealias RawValue = String + + /// Indicates that the path is relative to the source root (i.e. the "project directory"). + case sourceRoot + + /// Indicates that the path is relative to the path of the parent group. + case group + + /// Indicates that the path is relative to the effective build directory (which varies depending on active + /// scheme, active run destination, or even an overridden build setting. + case builtProductsDir + + /// Indicates that the path is an absolute path. + case absolute + + /// Indicates that the path is relative to the SDKROOT + case sdkRoot + + /// Indicates that the path is relative to the DEVELOPER_DIR (normally in the Xcode.app bundle) + case developerDir + + case unknown + + public var rawValue: Self.RawValue { + switch self { + case .sourceRoot: + return "SOURCE_ROOT" + case .group: + return "" + case .builtProductsDir: + return "BUILT_PRODUCTS_DIR" + case .absolute: + return "" + case .sdkRoot: + return "SDKROOT" + case .developerDir: + return "DEVELOPER_DIR" + case .unknown: + return "" + } + } + + public init(rawValue: Self.RawValue) { + switch rawValue { + case "SOURCE_ROOT": + self = .sourceRoot + case "": + self = .group + case "BUILT_PRODUCTS_DIR": + self = .builtProductsDir + case "": + self = .absolute + case "SDKROOT": + self = .sdkRoot + case "DEVELOPER_DIR": + self = .developerDir + default: + self = .unknown + } + } + + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + let rawValue = try container.decode(String.self) + self = SourceTree(rawValue: rawValue) } } @@ -245,6 +302,7 @@ public enum PIF { let container = try decoder.container(keyedBy: CodingKeys.self) fileType = try container.decode(String.self, forKey: .fileType) + logger.trace(" ---> Decoded FileType \(fileType)") try super.init(from: decoder) } @@ -295,6 +353,7 @@ public enum PIF { var childrenContainer = try container.nestedUnkeyedContainer(forKey: .children) children = try untypedChildren.compactMap { child in + logger.trace(" ---> Decoded Group Type \(child.type ?? "")") switch child.type { case Group.type: return try childrenContainer.decode(Group.self) @@ -334,6 +393,7 @@ public enum PIF { targetGUID = try container.decode(String.self, forKey: .guid) platformFilters = try container.decodeIfPresent([PlatformFilter].self, forKey: .platformFilters) ?? [] + logger.trace("---> Decoded TargetDependency: \(targetGUID)") } } @@ -393,6 +453,7 @@ public enum PIF { let dependencies = try container.decode([TargetDependency].self, forKey: .dependencies) let impartedBuildProperties = try container.decodeIfPresent(BuildSettings.self, forKey: .impartedBuildProperties) + logger.trace("---> Decoded BaseTarget: guid \(guid) name \(name)") super.init( guid: guid, @@ -449,6 +510,8 @@ public enum PIF { public required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + // The swift package manager drops the length of schemaVersion from the end of the guid-string. However, + // this doesn't work for all guids, because some are names and not guid strings (PackageProduct?). let guid = try container.decode(GUID.self, forKey: .guid) let name = try container.decode(String.self, forKey: .name) let buildConfigurations = try container.decode([BuildConfiguration].self, forKey: .buildConfigurations) @@ -457,6 +520,7 @@ public enum PIF { let buildPhases: [BuildPhase] let impartedBuildProperties: ImpartedBuildProperties + logger.trace("---> Decoded Target: guid \(guid) name \(name)") if type == "packageProduct" { self.productType = .packageProduct @@ -493,12 +557,14 @@ public enum PIF { dependencies: dependencies, impartedBuildSettings: impartedBuildProperties.buildSettings ) + logger.trace(" ---> Target \(name) with guid \(guid) and product type \(productType) and product name \(productName) decoded") } } /// Abstract base class for all build phases in a target. public class BuildPhase: TypedObject { static func decode(container: inout UnkeyedDecodingContainer, type: String) throws -> BuildPhase? { + logger.trace("---> Decoded BuildPhase: type \(type)") switch type { case HeadersBuildPhase.type: return try container.decode(HeadersBuildPhase.self) @@ -508,15 +574,13 @@ public enum PIF { return try container.decode(FrameworksBuildPhase.self) case ResourcesBuildPhase.type: return try container.decode(ResourcesBuildPhase.self) + case CopyFilesBuildPhase.type: + return try container.decode(CopyFilesBuildPhase.self) + case ShellScriptBuildPhase.type: + return try container.decode(ShellScriptBuildPhase.self) default: logger.debug("Ignoring build phase: \(type)") return nil - // TODO: we should probably handle these: - /* - case copyFiles = "com.apple.buildphase.copy-files" - case shellScript = "com.apple.buildphase.shell-script" - case sources = "com.apple.buildphase.sources"*/ - // throw Error.decodingError("unknown build phase \(type)") } } @@ -532,6 +596,7 @@ public enum PIF { guid = try container.decode(GUID.self, forKey: .guid) buildFiles = try container.decode([BuildFile].self, forKey: .buildFiles) + logger.trace("\tBuildPhase guid \(guid)") try super.init(from: decoder) } @@ -558,6 +623,14 @@ public enum PIF { override class var type: String { "com.apple.buildphase.resources" } } + public final class CopyFilesBuildPhase: BuildPhase { + override class var type: String { "com.apple.buildphase.copy-files" } + } + + public final class ShellScriptBuildPhase: BuildPhase { + override class var type: String { "com.apple.buildphase.shell-script" } + } + /// A build file, representing the membership of either a file or target product reference in a build phase. public struct BuildFile: Decodable { public enum Reference { @@ -585,6 +658,7 @@ public enum PIF { guid = try container.decode(GUID.self, forKey: .guid) platformFilters = try container.decodeIfPresent([PlatformFilter].self, forKey: .platformFilters) ?? [] headerVisibility = try container.decodeIfPresent(HeaderVisibility.self, forKey: .headerVisibility) ?? nil + logger.trace("---> Decoded BuildFile: guid \(guid) visibility \(headerVisibility?.rawValue ?? "")") if container.allKeys.contains(.fileReference) { reference = try .file(guid: container.decode(GUID.self, forKey: .fileReference)) @@ -627,6 +701,7 @@ public enum PIF { name = try container.decode(String.self, forKey: .name) buildSettings = try container.decode(BuildSettings.self, forKey: .buildSettings) impartedBuildProperties = try container.decodeIfPresent(ImpartedBuildProperties.self, forKey: .impartedBuildProperties) ?? .init(buildSettings: .init()) + logger.trace("---> Decoded BuildConfiguration: guid \(guid) name \(name)") } } @@ -835,65 +910,6 @@ public struct XCBuildFileType: CaseIterable { } } -extension PIF.FileReference { - // fileprivate static func fileTypeIdentifier(forPath path: String) -> String { - // let pathExtension: String? - // if let path = try? URL(validating: path) { - // pathExtension = path.extension - // } else if let path = try? RelativePath(validating: path) { - // pathExtension = path.extension - // } else { - // pathExtension = nil - // } - - // switch pathExtension { - // case "a": - // return "archive.ar" - // case "s", "S": - // return "sourcecode.asm" - // case "c": - // return "sourcecode.c.c" - // case "cl": - // return "sourcecode.opencl" - // case "cpp", "cp", "cxx", "cc", "c++", "C", "tcc": - // return "sourcecode.cpp.cpp" - // case "d": - // return "sourcecode.dtrace" - // case "defs", "mig": - // return "sourcecode.mig" - // case "m": - // return "sourcecode.c.objc" - // case "mm", "M": - // return "sourcecode.cpp.objcpp" - // case "metal": - // return "sourcecode.metal" - // case "l", "lm", "lmm", "lpp", "lp", "lxx": - // return "sourcecode.lex" - // case "swift": - // return "sourcecode.swift" - // case "y", "ym", "ymm", "ypp", "yp", "yxx": - // return "sourcecode.yacc" - - // case "xcassets": - // return "folder.assetcatalog" - // case "xcstrings": - // return "text.json.xcstrings" - // case "storyboard": - // return "file.storyboard" - // case "xib": - // return "file.xib" - - // case "xcframework": - // return "wrapper.xcframework" - - // default: - // return pathExtension.flatMap({ pathExtension in - // XCBuildFileType.allCases.first(where: ({ $0.fileTypes.contains(pathExtension) })) - // })?.fileTypeIdentifier ?? "file" - // } - // } -} - private struct UntypedTarget: Decodable { struct TargetContents: Decodable { let type: String diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 3025fa1..d57dad2 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -26,7 +26,7 @@ let programName = CommandLine.arguments.first! Example with build log: $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO > log.txt - $ \(programName) log.txt x.xcarchive + $ \(programName) log.txt x.xcarchive Example with pipe: $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ @@ -65,10 +65,15 @@ let programName = CommandLine.arguments.first! @Option(help: ArgumentHelp("Path to PIF cache. Use this in place of what is in the Xcode build log", visibility: .hidden)) var pifCachePath: URL? + @Option(help: ArgumentHelp("Specifiy a logging level. The --debug flag will override this", visibility: .hidden)) + var logLevel: LogLevelArgument? + mutating func validate() throws { // This will run before run() so set this here if debug { logger.logLevel = .debug + } else { + logger.logLevel = logLevel?.level ?? .info } if projectPath != nil { @@ -97,7 +102,8 @@ let programName = CommandLine.arguments.first! archive: xcarchivePath, level: logger.logLevel, dryRun: dryRun, - dumpDependencyGraph: dumpDependencyGraph + dumpDependencyGraph: dumpDependencyGraph, + pifCachePath: pifCachePath ) } @@ -238,3 +244,15 @@ extension URL: ExpressibleByArgument { self = argument.fileURL.absoluteURL } } + +struct LogLevelArgument: ExpressibleByArgument { + let level: Logger.Level + + init?(argument: String) { + // Convert the argument to lowercase and attempt to create a Logger.Level + guard let logLevel = Logger.Level(rawValue: argument.lowercased()) else { + return nil // Return nil if the argument is invalid + } + self.level = logLevel + } +} diff --git a/Sources/GenIR/OutputPostprocessor.swift b/Sources/GenIR/OutputPostprocessor.swift index fec6bce..03e4210 100644 --- a/Sources/GenIR/OutputPostprocessor.swift +++ b/Sources/GenIR/OutputPostprocessor.swift @@ -69,10 +69,10 @@ class OutputPostprocessor { // folder. Otherwise we will create an empty directory and that will contain the artifacts // of the dependency chain. if manager.directoryExists(at: buildDirectory) { - logger.debug("Copying \(node.value.guid) with name \(node.value.productName)") + logger.debug("Copying \(node.value.guid) with name \(node.value.productName)") try manager.copyItem(at: buildDirectory, to: irDirectory) } else { - logger.debug("Creating build directory for \(node.value.guid) with name \(node.value.productName)") + logger.debug("Creating build directory for \(node.value.guid) with name \(node.value.productName)") try manager.createDirectory(at: irDirectory, withIntermediateDirectories: false) } diff --git a/Sources/GenIR/Versions.swift b/Sources/GenIR/Versions.swift index f2c4935..c30da4b 100644 --- a/Sources/GenIR/Versions.swift +++ b/Sources/GenIR/Versions.swift @@ -8,5 +8,5 @@ import Foundation enum Versions { - static let version = "0.5.2" + static let version = "0.5.3" } diff --git a/Sources/GenIR/XcodeLogParser.swift b/Sources/GenIR/XcodeLogParser.swift index 78c7932..38c4622 100644 --- a/Sources/GenIR/XcodeLogParser.swift +++ b/Sources/GenIR/XcodeLogParser.swift @@ -69,6 +69,7 @@ class XcodeLogParser { /// Parse the lines from the build log func parseBuildLog() { var seenTargets = Set() + var commandsToLog = Set() // Track unique commands while let line = consumeLine() { if line.hasPrefix("Build description path: ") { @@ -92,7 +93,11 @@ class XcodeLogParser { let commands = parseCompilerCommands(target: target) commands.forEach { - logger.debug("Found \($0.command.compiler.rawValue) compiler command for target: \(target)") + let commandKey = "\($0.command.compiler.rawValue)-\(target)" + if (commandsToLog.insert(commandKey)).inserted { + // Log the compiler along with the target + logger.debug("Found \($0.command.compiler.rawValue) compiler command for target: \(target)") + } } commandLog.append(contentsOf: commands) From c41046bae12a68b81a3d49be15284d1ddb0d7340 Mon Sep 17 00:00:00 2001 From: davdres Date: Wed, 23 Apr 2025 07:27:45 -0700 Subject: [PATCH 17/24] SENG-9588 remove development release (#90) * SENG-9588 remove development release --- Documentation/releasing_an_update.md | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/Documentation/releasing_an_update.md b/Documentation/releasing_an_update.md index e8d1be8..1dffb35 100644 --- a/Documentation/releasing_an_update.md +++ b/Documentation/releasing_an_update.md @@ -9,20 +9,14 @@ When you have an update for `gen-ir`, there's a couple things that need to happe As mentioned in the [Branching Model](branching_model.md), features should be merged into the `develop` branch. You should never merge a feature directly to `main`. -To release a new version of `gen-ir`, create a release branch and open a merge request from the release branch (see the [Branching Model](branching_model.md)) to `main` at the commit point you're wanting to release and to `develop`. Allow any automated check, peer reviews, and - when approved - merge the request. +To release a new version of `gen-ir`, create a release branch and open a merge request from the release branch (see the [Branching Model](branching_model.md)) to `main`. Allow any automated check, peer reviews, and - when approved - merge the request. Release version descriptions mm.nn.pp stand for a 2 digit major version, 2 digit minor version, and 2 digit patch version. For example, `0.3.11` is a valid version. Then, on your local machine: - Change to `main` and pull the changes - `git checkout main && git pull` - Create the new tag for the release: - - `git tag -a 1.0.0 -m "Gen IR version: 1.0.0` - - `git push --tags` -- Change to `develop` and pull the changes - - `git checkout develop && git pull` -- Recreate the new `develop` tag for the release: - - `git tag -d develop && git push --delete origin develop` - - `git tag -a develop -m "Gen IR Develop version: ` + - `git tag -a mm.nn.pp -m "Gen IR version: mm.nn.pp"` - `git push --tags` Then, in the GitHub UI: @@ -30,18 +24,11 @@ Then, in the GitHub UI: - Go to the [Releases](https://github.com/veracode/gen-ir/releases) page - Click `Draft a new release` - Set the title to the version name -- From the drop down list, choose your newly created tag +- From the drop down list, choose your newly created tag from the main branch - Click the `Generate release notes` button to create a change log - Ensure `Set as the latest release` is checked - Click the `Publish` button -- Click `Draft a new release` -- Set the title to `develop` -- From the drop down list, choose your newly created `develop` tag -- Click the `Generate release notes` button to create a change log -- Ensure `Set as pre-release` is checked -- Click the `Publish` button - A release has been made, congratulations. However there's additional steps for distributing the release via `brew`. ## Distributing a release From fd8abb5f74d26456db7e05cac9c9d41f7d05e14d Mon Sep 17 00:00:00 2001 From: davdres Date: Thu, 24 Apr 2025 08:34:11 -0700 Subject: [PATCH 18/24] SSAST-10500 Warn if multiple builds in xcode log (#91) --- Sources/GenIR/XcodeLogParser.swift | 11 +++++++++- Tests/GenIRTests/XcodeLogParserTests.swift | 25 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 Tests/GenIRTests/XcodeLogParserTests.swift diff --git a/Sources/GenIR/XcodeLogParser.swift b/Sources/GenIR/XcodeLogParser.swift index 38c4622..c8d91d1 100644 --- a/Sources/GenIR/XcodeLogParser.swift +++ b/Sources/GenIR/XcodeLogParser.swift @@ -25,6 +25,9 @@ class XcodeLogParser { private(set) var buildCachePath: URL! private(set) var commandLog: [CommandEntry] = [] + // Gen-IR designed to parse one build at a time. + internal var buildCount: Int = 0 + enum Error: Swift.Error { case noCommandsFound(String) case noTargetsFound(String) @@ -64,6 +67,10 @@ class XcodeLogParser { if buildCachePath == nil { throw Error.noBuildCachePathFound("No build cache was found from the build log. Please report this as a bug.") } + + if buildCount > 1 { + logger.warning("\n\t ---- Multiple builds found in the log file, Gen-IR is designed to only parse one build at a time. ----\n") + } } /// Parse the lines from the build log @@ -76,6 +83,8 @@ class XcodeLogParser { buildCachePath = buildDescriptionPath(from: line) } else if line.hasPrefix("Build settings from command line:") { settings = parseBuildSettings() + } else if line.hasPrefix("** ARCHIVE SUCCEEDED **") { + buildCount += 1 } else { // Attempt to find a build task on this line that we are interested in. let task = line.split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)[0] @@ -111,7 +120,7 @@ class XcodeLogParser { /// Consume the next line from the log file and return it if we have not reached the end private func consumeLine() -> String? { - guard offset + 1 < log.endIndex else { return nil } + guard offset < log.endIndex else { return nil } defer { offset += 1 } return log[offset] diff --git a/Tests/GenIRTests/XcodeLogParserTests.swift b/Tests/GenIRTests/XcodeLogParserTests.swift new file mode 100644 index 0000000..6be2fac --- /dev/null +++ b/Tests/GenIRTests/XcodeLogParserTests.swift @@ -0,0 +1,25 @@ +import XCTest +import Foundation +import Testing +@testable import gen_ir + +@Test +func testWarnOnMultipleBuilds() throws { + let logContent: [String] = [ + "Build description path: /Users/ur/Library/Developer/Xcode/DrvdData/Exper1-etmk/Build/Intermediates.noindex/ArchiveIntermediates/Experimental1/IntermediatePath/XCBuildData/65828f.xcbuilddata", + "", + "SwiftDriver Experimental1 normal arm64 com.apple.xcode.tools.swift.compiler (in target 'Experimental1' from project 'Experimental1')", + " cd /p", + " builtin-SwiftDriver -- /swiftc build command", + "", + "** ARCHIVE SUCCEEDED **", + " ", + "Build description path: /Users/ur/Library/Developer/Xcode/DrvdData/Exper1-etmk/Build/Intermediates.noindex/ArchiveIntermediates/Experimental1/IntermediatePath/XCBuildData/65828f.xcbuilddata", + "", + "** ARCHIVE SUCCEEDED **" + ] + let logParser = XcodeLogParser(log: logContent) + try logParser.parse() + #expect(logParser.commandLog.count == 1) + #expect(logParser.buildCount == 2) +} From d7fb8ef5ccb32c7410b0a28f8cddc5e79f7a4a14 Mon Sep 17 00:00:00 2001 From: davdres Date: Mon, 2 Jun 2025 08:09:36 -0700 Subject: [PATCH 19/24] SSAST-10519 Add option to capture debug data (#92) A --capture option has been added to collect diagnostic data into a debug-data sub-folder of the IR directory. What data has been captured is written to the Gen-IR log. --- .gitignore | 2 +- PIF/.gitignore | 8 - Sources/DependencyGraph/DependencyGraph.swift | 12 +- .../DependencyGraphBuilder.swift | 2 +- Sources/GenIR/BuildCacheManipulator.swift | 10 +- Sources/GenIR/CompilerCommandRunner.swift | 24 +- Sources/GenIR/DebugData.swift | 206 ++++++++++++++++++ Sources/GenIR/GenIR.swift | 178 +++++++++++---- Sources/GenIR/OutputPostprocessor.swift | 16 +- Sources/GenIR/PIFCache.swift | 16 +- Sources/GenIR/Versions.swift | 9 +- Sources/GenIR/XcodeLogParser.swift | 10 +- Sources/LogHandlers/.gitignore | 8 - .../Sources/LogHandlers/FileLogHandler.swift | 33 +++ .../LogHandlers/GenIRLoggingDefinition.swift | 119 ++++++++++ .../LogHandlers/StdoutLogHandler.swift | 70 +----- .../SPMTest/MyBinaryDependency/.gitignore | 8 - .../SPMTest/MyCommonLibrary/.gitignore | 8 - .../PIFCaches/SPMTest/MyLibrary/.gitignore | 8 - .../SPMTest/MyTransitiveLibrary/.gitignore | 8 - 20 files changed, 545 insertions(+), 210 deletions(-) delete mode 100644 PIF/.gitignore create mode 100644 Sources/GenIR/DebugData.swift delete mode 100644 Sources/LogHandlers/.gitignore create mode 100644 Sources/LogHandlers/Sources/LogHandlers/FileLogHandler.swift create mode 100644 Sources/LogHandlers/Sources/LogHandlers/GenIRLoggingDefinition.swift delete mode 100644 TestAssets/PIFCaches/SPMTest/MyBinaryDependency/.gitignore delete mode 100644 TestAssets/PIFCaches/SPMTest/MyCommonLibrary/.gitignore delete mode 100644 TestAssets/PIFCaches/SPMTest/MyLibrary/.gitignore delete mode 100644 TestAssets/PIFCaches/SPMTest/MyTransitiveLibrary/.gitignore diff --git a/.gitignore b/.gitignore index 40915b2..15a43bf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ output/ /*.xcodeproj xcuserdata/ DerivedData/ -.swiftpm/config/registries.json +.swiftpm/configuration/registries.json .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .netrc .swiftpm diff --git a/PIF/.gitignore b/PIF/.gitignore deleted file mode 100644 index 0023a53..0000000 --- a/PIF/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/Sources/DependencyGraph/DependencyGraph.swift b/Sources/DependencyGraph/DependencyGraph.swift index 25296fd..02766df 100644 --- a/Sources/DependencyGraph/DependencyGraph.swift +++ b/Sources/DependencyGraph/DependencyGraph.swift @@ -38,7 +38,7 @@ public class DependencyGraph { /// - Returns: the chain of nodes, starting with the 'bottom' of the dependency subgraph public func chain(for value: Value) -> [Node] { guard let node = findNode(for: value) else { - logger.debug("Couldn't find node for value: \(value.valueName)") + GenIRLogger.logger.debug("Couldn't find node for value: \(value.valueName)") return [] } @@ -49,26 +49,26 @@ public class DependencyGraph { /// - Parameter node: the node whose children to search through /// - Returns: an array of nodes ordered by a depth-first search approach private func depthFirstSearch(startingAt node: Node) -> [Node] { - logger.debug("----\nSearching for: \(node.value.valueName)") + GenIRLogger.logger.debug("----\nSearching for: \(node.value.valueName)") var visited = Set() var chain = [Node]() /// Visits node dependencies and adds them to the chain from the bottom up /// - Parameter node: the node to search through func depthFirst(node: Node) { - logger.debug("inserting node: \(node.value.valueName)") + GenIRLogger.logger.debug("inserting node: \(node.value.valueName)") visited.insert(node) for edge in node.edges where edge.relationship == .dependency { if visited.insert(edge.to).inserted { - logger.debug("edge to: \(edge.to)") + GenIRLogger.logger.debug("edge to: \(edge.to)") depthFirst(node: edge.to) } else { - logger.debug("edge already in visited: \(visited)") + GenIRLogger.logger.debug("edge already in visited: \(visited)") } } - logger.debug("appending to chain: \(node.value.valueName)") + GenIRLogger.logger.debug("appending to chain: \(node.value.valueName)") chain.append(node) } diff --git a/Sources/DependencyGraph/DependencyGraphBuilder.swift b/Sources/DependencyGraph/DependencyGraphBuilder.swift index 74ee422..a0e9fad 100644 --- a/Sources/DependencyGraph/DependencyGraphBuilder.swift +++ b/Sources/DependencyGraph/DependencyGraphBuilder.swift @@ -47,7 +47,7 @@ public class DependencyGraphBuilder 1 { - logger.error( + GenIRLogger.logger.error( """ Found more than one possible folders matching 'debug' or 'veracode' configurations: \(filtered). Please ensure you build from a clean state. """ diff --git a/Sources/GenIR/CompilerCommandRunner.swift b/Sources/GenIR/CompilerCommandRunner.swift index fc52254..10ddbbd 100644 --- a/Sources/GenIR/CompilerCommandRunner.swift +++ b/Sources/GenIR/CompilerCommandRunner.swift @@ -54,24 +54,24 @@ struct CompilerCommandRunner { let totalCommands = commands .map { $0.value.count } .reduce(0, +) - logger.info("Total commands to run: \(totalCommands)") + GenIRLogger.logger.info("Total commands to run: \(totalCommands)") var totalModulesRun = 0 for target in targets { // Continue to the next target if no commands are found for the current target guard let targetCommands = commands[TargetKey(projectName: target.projectName, targetName: target.name)] else { - logger.debug("No commands found for target: \(target.name) in project: \(target.projectName)") + GenIRLogger.logger.debug("No commands found for target: \(target.name) in project: \(target.projectName)") continue } - logger.info("Operating on target: \(target.name). Total modules processed: \(totalModulesRun)") + GenIRLogger.logger.info("Operating on target: \(target.name). Total modules processed: \(totalModulesRun)") totalModulesRun += try run(commands: targetCommands, for: target.productName, at: output) } let uniqueModules = Set(try fileManager.files(at: output, withSuffix: ".bc")).count - logger.info("Finished compiling all targets. Unique modules: \(uniqueModules)") + GenIRLogger.logger.info("Finished compiling all targets. Unique modules: \(uniqueModules)") } /// Runs all commands for a given target @@ -85,12 +85,12 @@ struct CompilerCommandRunner { let targetDirectory = directory.appendingPathComponent(name) try fileManager.createDirectory(at: targetDirectory, withIntermediateDirectories: true) - logger.debug("Created target directory: \(targetDirectory)") + GenIRLogger.logger.debug("Created target directory: \(targetDirectory)") var targetModulesRun = 0 for (index, command) in commands.enumerated() { - logger.info( + GenIRLogger.logger.info( """ \(dryRun ? "Dry run of" : "Running") command (\(command.compiler.rawValue)) \(index + 1) of \(commands.count). \ Target modules processed: \(targetModulesRun) @@ -106,7 +106,7 @@ struct CompilerCommandRunner { do { result = try Process.runShell(executable, arguments: arguments, runInDirectory: directory) } catch { - logger.error( + GenIRLogger.logger.error( """ Couldn't create process for executable: \(executable) with arguments: \(arguments.joined(separator: " ")). \ This is likely a bug in parsing the build log. Please raise it as an issue. @@ -122,7 +122,7 @@ struct CompilerCommandRunner { continue } } - logger.error( + GenIRLogger.logger.error( """ Command finished: - code: \(result.code) @@ -141,7 +141,7 @@ struct CompilerCommandRunner { switch command.compiler { case .swiftc: guard let outputFileMap = try getOutputFileMap(from: arguments) else { - logger.error("Failed to find OutputFileMap for command \(command.command) ") + GenIRLogger.logger.error("Failed to find OutputFileMap for command \(command.command) ") break } @@ -151,7 +151,7 @@ struct CompilerCommandRunner { } if clangAdditionalModules == 0 && swiftAdditionalModules == 0 { - logger.error( + GenIRLogger.logger.error( """ No modules were produced from compiler, potential failure. Results: \n\n \ executable: \(executable)\n\n \ @@ -290,8 +290,8 @@ extension CompilerCommandRunner { let path = arguments[index + 1].fileURL guard fileManager.fileExists(atPath: path.filePath) else { - logger.error("Found an OutputFileMap, but it doesn't exist on disk? Please report this issue.") - logger.debug("OutputFileMap path: \(path)") + GenIRLogger.logger.error("Found an OutputFileMap, but it doesn't exist on disk? Please report this issue.") + GenIRLogger.logger.debug("OutputFileMap path: \(path)") return nil } diff --git a/Sources/GenIR/DebugData.swift b/Sources/GenIR/DebugData.swift new file mode 100644 index 0000000..0fa371b --- /dev/null +++ b/Sources/GenIR/DebugData.swift @@ -0,0 +1,206 @@ +import Foundation +import ArgumentParser // To use ValidationError +import LogHandlers +import Logging + +/// +/// This file contains the DebugData struct, which is responsible for capturing debug data during the execution of the program. +/// It includes methods for initializing the capture path and logging relevant information. The data is captured in a sub-directory +/// of the xcarchive and therefore will be included with the submission to the Veracode Platform. +/// +/// The struct is initialized with the xcarchive and a flag indicating whether debug data is to be captured. +/// The directory structure will be: +/// - xcarchive +/// - debug-data +/// - Gen-IR log output file. +/// - xcodebuild log which was input to Gen-IR +/// - PIF cache directory +/// - xcode-select ouput +/// - xcodebuild --version output +/// - swift --version output +/// - env | grep DEVELOPER_DIR output +/// - data.zip +/// +struct DebugData: Decodable { + + let capturePath: URL + let logDataPath: URL + + init (xcodeArchivePath: URL) throws { + + // Setup the capture path to hold the debug data. This path is a sub-directory of the xcarchive. + capturePath = xcodeArchivePath.appendingPathComponent("debug-data", isDirectory: true) + + // Make sure the directory to hold debug data exists and is empty + if !FileManager.default.directoryExists(at: capturePath) { + // It doesn't exist, so create it + try FileManager.default.createDirectory(at: capturePath, withIntermediateDirectories: true) + } + + // Create a subdirectory for the logs and add a file log handler to write the log there. + let zipLogPath = capturePath.appendingPathComponent("log") + try FileManager.default.createDirectory(at: zipLogPath, withIntermediateDirectories: true) + + logDataPath = zipLogPath.appendingPathComponent("genir-capture.log", isDirectory: false) + } + + /// + /// Tell the user what information will be captured. + /// + public func displayCaptureInfo() { + let captureInfo = Logger.Message( + """ + \n + \u{001B}[1m The Gen-IR capture option is enabled.\u{001B}[0m + The following data will be added to the xcarchive and sent to Veracode: + - Gen-IR log output file + - xcodebuild log which was input to Gen-IR + - PIF cache directory and its contents + - The location of the developer directory (e.g. /Applications/Xcode.app/Contents/Developer) + This is obtained via the xcode-select -p command and from the value of the DEVELOPER_DIR environment variable. + No other environment variables are captured. + - The xcodebuild version + - The swift-version + \n + """) + GenIRLogger.logger.info(captureInfo) + GenIRLogger.logger.info("Debug data will be captured to: \(capturePath)") + } + + /// + /// Capture the execution context: + /// This includes the xcodebuild log, the configured developer directory, the xcodebuild version, and the swift version. + /// + public func captureExecutionContext(logPath: URL) throws { + + // Capture the xcodebuild log + try FileManager.default.copyItem(at: logPath, to: capturePath.appendingPathComponent("xcodebuild.log")) + + // Capture the configured developer directory + let developerDir = try execShellCommand(command: "xcode-select", args: ["-p"]) + + // Capture a possible override of the developer directory + let developerDirOverride = ProcessInfo.processInfo.environment["DEVELOPER_DIR"] ?? "Not set" + + // Capture the xcodebuild version + let xcodeBuildVersion = try execShellCommand(command: "xcodebuild", args: ["-version"]) + + // Capture the swift version + let swiftVersion = try execShellCommand(command: "swift", args: ["-version"]) + + do { + let versionsUrl = capturePath.appendingPathComponent("versions.txt") + FileManager.default.createFile(atPath: versionsUrl.path, contents: nil) + let versionsFile = try FileHandle(forWritingTo: versionsUrl) + versionsFile.write(Data(""" + DEVELOPER_DIR: \(developerDir)\n + DEVELOPER_DIR_OVERRIDE: \(developerDirOverride)\n + XCODEBUILD_VERSION: \(xcodeBuildVersion)\n + SWIFT_VERSION: \(swiftVersion)\n + """.utf8)) + versionsFile.closeFile() + } catch { + GenIRLogger.logger.error("Debug data capture Error \(error) occurred creating the versions.txt file while capturing debug data.") + } + GenIRLogger.logger.info("Debug data capture execution context data captured.") + } + + /// + /// Capture the PIF cache: + /// This is a copy of the PIF cache from the location specified in the xcarchive. + /// The location is determined by the PIFCache.pifCachePath(in:) method. + /// + public func capturePIFCache(pifLocation: URL) throws { + + // Capture the PIF cache + let savedPif = capturePath.appendingPathComponent("pif-data") + do { + // Perform the copy operation and skip broken symlinks + try copyDirectorySkippingBrokenSymlinks(from: pifLocation, to: savedPif) + } catch { + GenIRLogger.logger.error("Debug data capture of PIF Cache error: \(error.localizedDescription)") + } + GenIRLogger.logger.info("Debug data capture PIF cache data captured.") + } + + /// + /// Do any final data captures and log the completion message. + /// + public func captureComplete(xcarchive: URL) throws { + GenIRLogger.logger.info("Debug data capture complete.") + } + + /// + /// Copy a directory and skip broken symlinks. + /// This is used to copy the PIF cache from the location based on the build cache path parsed from the xcode build log. + /// The location is determined by the PIFCache.pifCachePath(in:) method. + /// + private func copyDirectorySkippingBrokenSymlinks(from sourceURL: URL, to destinationURL: URL) throws { + + let fileManager = FileManager.default + let contents = try fileManager.contentsOfDirectory(at: sourceURL, includingPropertiesForKeys: [.isSymbolicLinkKey], options: []) + let sourceBaseName = sourceURL.path.hasSuffix("/") ? sourceURL.path : sourceURL.path + "/" + + for item in contents { + let resourceValues = try item.resourceValues(forKeys: [.isSymbolicLinkKey]) + + if resourceValues.isSymbolicLink == true { + // Check if the symlink target exists + let targetPath = try fileManager.destinationOfSymbolicLink(atPath: item.path) + if !fileManager.fileExists(atPath: targetPath) { + GenIRLogger.logger.info("Skipping broken symlink while copying PIFCache: \(item.path)") + continue + } + } + // Find the relative path of the item + let relativePart = item.path.replacingOccurrences(of: sourceBaseName, with: "") + + // Define destination path + let destinationItemURL = destinationURL.appendingPathComponent(relativePart) + let parentDestinationURL = destinationItemURL.deletingLastPathComponent() + do { + // Make sure the destination directory exists + try fileManager.createDirectory(at: parentDestinationURL, withIntermediateDirectories: true) + // Copy item + try fileManager.copyItem(at: item, to: destinationItemURL) + } catch { + GenIRLogger.logger.error("Error while copying a PIFCache item \(item) : \(error.localizedDescription)") + continue + } + } + } + + /// + /// Given a command string and it's arguments, invoke a shell to execute the command and return the command output. + /// + private func execShellCommand(command: String, args: [String]) throws -> String { + let result: Process.ReturnValue + do { + result = try Process.runShell(command, arguments: args, runInDirectory: FileManager.default.currentDirectoryPath.fileURL) + } catch { + GenIRLogger.logger.error( + """ + Debug data capture couldn't create process for command: \(command) with arguments: \(args.joined(separator: " ")). \ + Output will not be captured. + """ + ) + return "" + } + + if result.code != 0 { + GenIRLogger.logger.error( + """ + Debug data capture command finished with non-zero exit code. Output will not be captured. + - code: \(result.code) + - command: \(command) \(args.joined(separator: " ")) + - stdout: \(String(describing: result.stdout)) + - stderr: \(String(describing: result.stderr)) + """ + ) + + return "" + } + + return result.stdout ?? "" + } +} diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index d57dad2..b42f436 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -8,34 +8,58 @@ import LogHandlers /// The name of the program let programName = CommandLine.arguments.first! +struct DeprecatedOptions: ParsableArguments { + + /// Path to xcodeproj or xcworkspace file. This is hidden. Validation will notifiy the user if it is used. + @Option(help: ArgumentHelp("DEPRECATED: This Option is deprecated and will go away in a future version.", visibility: .hidden)) + var projectPath: URL? +} + +struct DebuggingOptions: ParsableArguments { + + @Option(help: ArgumentHelp("Path to PIF cache. Use this in place of what is in the Xcode build log", visibility: .hidden)) + var pifCachePath: URL? + + @Option(help: ArgumentHelp("Specifiy a logging level. The --debug flag will override this", visibility: .hidden)) + var logLevel: LogLevelArgument? + + @Flag(help: ArgumentHelp("Path to save a zip file containing debug data.", visibility: .hidden)) + var capture: Bool = false +} + /// Command to emit LLVM IR from an Xcode build log @main struct IREmitterCommand: ParsableCommand { + + // The following is formatted to about 100 characters per line static let configuration = CommandConfiguration( commandName: "", abstract: "Consumes an Xcode build log, and outputs LLVM IR, in the bitstream format, to the folder specified", discussion: """ - This can either be done via a file, or via stdin. You may have to redirect stderr to stdin before piping it to this \ + This can either be done via a file, or via stdin. You may have to redirect stderr to stdin before \npiping it to this \ tool. - This tool requires a full Xcode build log in order to capture all files in the project. If this is not provided, you may notice \ + This tool requires a full Xcode build log in order to capture all files in the project. If this is not \nprovided, you may notice \ that not all modules are emitted. To ensure this, run `xcodebuild clean` first before you `xcodebuild build` command. Example with build log: - $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ - DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO > log.txt + $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj \\\n\t\t-configuration Debug \\\n\t\t-scheme MyScheme \ + \\\n\t\tDEBUG_INFOMATION_FORMAT=dwarf-with-dsym \\\n\t\tENABLE_BITCODE=NO \\\n\t\t> log.txt $ \(programName) log.txt x.xcarchive Example with pipe: - $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj -configuration Debug -scheme MyScheme \ - DEBUG_INFOMATION_FORMAT=dwarf-with-dsym ENABLE_BITCODE=NO 2>&1 | \(programName) - x.xcarchive + $ xcodebuild clean && xcodebuild build -project MyProject.xcodeproj \\\n\t\t-configuration Debug \\\n\t\t-scheme MyScheme \ + \\\n\t\tDEBUG_INFOMATION_FORMAT=dwarf-with-dsym \\\n\t\tENABLE_BITCODE=NO \\\n\t\t2>&1 | \(programName) - x.xcarchive """, version: "v\(Versions.version)" ) + /// Optional variable to capture debug data, if requested. + var debugData: DebugData? + /// Path to an Xcode build log, or `-` if build log should be read from stdin @Argument(help: "Path to a full Xcode build log. If `-` is provided, stdin will be read") var logPath: String @@ -44,10 +68,6 @@ let programName = CommandLine.arguments.first! @Argument(help: "Path to the xcarchive associated with the build log") var xcarchivePath: URL - /// Path to xcodeproj or xcworkspace file - @Option(help: "DEPRECATED: This Option is deprecated and will go away in a future version.") - var projectPath: URL? - /// Enables enhanced debug logging @Flag(help: "Enables debug level logging") var debug = false @@ -56,30 +76,38 @@ let programName = CommandLine.arguments.first! @Flag(help: "Reduces log noise by suppressing xcodebuild output when reading from stdin") var quieter = false - @Flag(help: "Runs the tool without outputting IR to disk (i.e. leaving out the compiler command runner stage)") + @Flag(help: "Runs the tool without writing IR to disk (i.e. skips running compiler commands)") var dryRun = false @Flag(help: "Output the dependency graph as .dot files to the output directory - debug only") var dumpDependencyGraph = false - @Option(help: ArgumentHelp("Path to PIF cache. Use this in place of what is in the Xcode build log", visibility: .hidden)) - var pifCachePath: URL? + // Drop this in release 0.6 or greater + @OptionGroup var deprecatedOptions: DeprecatedOptions - @Option(help: ArgumentHelp("Specifiy a logging level. The --debug flag will override this", visibility: .hidden)) - var logLevel: LogLevelArgument? + // These options are hidden and will not be shown in the help text + @OptionGroup var debuggingOptions: DebuggingOptions mutating func validate() throws { - // This will run before run() so set this here - if debug { - logger.logLevel = .debug - } else { - logger.logLevel = logLevel?.level ?? .info + + try validateXcarchive() + + // Check if requested to capture debug data + // Logging is set to the default by the first reference to GenIRLogger.logger. When captureing debug data we also add a log handler + // to capture the log output to a file. + if debuggingOptions.capture { + debugData = try DebugData(xcodeArchivePath: xcarchivePath) } - if projectPath != nil { - logger.warning("--project-path has been deprecated and will go away in a future version. Please remove it from your invocation.") + // Initialize the logger + try initLogging() + + if deprecatedOptions.projectPath != nil { + GenIRLogger.logger.warning("\u{001B}[1m --project-path has been deprecated and will go away in a future version. \nPlease remove it from your invocation.\u{001B}[0m") } + } + mutating private func validateXcarchive() throws { // Version 0.2.x and below allowed the output folder to be any arbitrary folder. // Docs said to use 'IR' inside an xcarchive. For backwards compatibility, if we have an xcarchive path with an IR // folder, remove the IR portion @@ -94,40 +122,96 @@ let programName = CommandLine.arguments.first! if !FileManager.default.directoryExists(at: xcarchivePath) { throw ValidationError("Archive path doesn't exist: \(xcarchivePath.filePath)") } + + // Clean outpuf folders in the archive + let irPath = xcarchivePath.appendingPathComponent("IR") + if FileManager.default.directoryExists(at: irPath) { + do { + try FileManager.default.removeItem(at: irPath) + } catch { + GenIRLogger.logger.warning("Failed to remove existing IR folder at \(irPath.filePath): \(error)") + } + } + + let debugDataPath = xcarchivePath.appendingPathComponent("debug-data") + if FileManager.default.directoryExists(at: debugDataPath) { + do { + try FileManager.default.removeItem(at: debugDataPath) + } catch { + GenIRLogger.logger.warning("Failed to remove existing debug-data folder at \(debugDataPath.filePath): \(error)") + } + } + } + + mutating private func initLogging() throws { + // First, determine the requested log level + var logLevel: Logger.Level + if debug { + // If debug is set, we use the debug log level + logLevel = .debug + } else if let logLevelArg = debuggingOptions.logLevel?.level { + // If a log level was specified, use that + logLevel = logLevelArg + } else { + // Default to info level if no debug or log level is specified + logLevel = .info + } + + // Default handler is stdout + if debuggingOptions.capture { + // If capture is enabled, we create a file log handler to capture the log output + var captureLogHandler = FileLogHandler(filePath: debugData!.logDataPath) + var stdioLogHandler = StdIOStreamLogHandler() + captureLogHandler.logLevel = GenIRLogger.logger.logLevel + stdioLogHandler.logLevel = GenIRLogger.logger.logLevel + GenIRLogger.logger = Logger(label: "Gen-IR") { _ in MultiplexLogHandler([stdioLogHandler, captureLogHandler]) } + } else { + // Otherwise, we use the default StdIOStreamLogHandler + GenIRLogger.logger = Logger(label: "Gen-IR") { _ in StdIOStreamLogHandler() } + } + GenIRLogger.logger.logLevel = logLevel } mutating func run() throws { try run( log: logPath, archive: xcarchivePath, - level: logger.logLevel, + level: GenIRLogger.logger.logLevel, dryRun: dryRun, dumpDependencyGraph: dumpDependencyGraph, - pifCachePath: pifCachePath + pifCachePath: debuggingOptions.pifCachePath, + capture: debuggingOptions.capture ) } + // swiftlint:disable:next function_body_length mutating func run( log: String, archive: URL, - level: Logger.Level, - dryRun: Bool, - dumpDependencyGraph: Bool, - pifCachePath: URL? = nil + level: Logger.Level = .info, + dryRun: Bool = false, + dumpDependencyGraph: Bool = false, + pifCachePath: URL? = nil, + capture: Bool = false ) throws { - logger.logLevel = level - logger.info( - """ - - Gen-IR v\(IREmitterCommand.configuration.version) - log: \(log) - archive: \(archive.filePath) - level: \(level) - dryRun: \(dryRun) - dumpDependencyGraph: \(dumpDependencyGraph) - """) - let output = archive.appendingPathComponent("IR") + // Perform initial capture. + debugData?.displayCaptureInfo() + try debugData?.captureExecutionContext(logPath: log.fileURL) + + GenIRLogger.logger.info( + """ + + Gen-IR v\(IREmitterCommand.configuration.version) + log: \(log) + archive: \(archive.filePath) + level: \(level) + dryRun: \(dryRun) + dumpDependencyGraph: \(dumpDependencyGraph) + + """) + + let output = archive.appendingPathComponent("IR") let log = try logParser(for: log) try log.parse() @@ -135,13 +219,14 @@ let programName = CommandLine.arguments.first! guard let pifCachePath = pifCachePath ?? log.buildCachePath else { throw ValidationError("PIF cache path not found in log!") } - logger.debug("PIF location is: \(pifCachePath)") let pifCache = try PIFCache(buildCache: pifCachePath) + GenIRLogger.logger.debug("PIF location is: \(pifCache.pifCachePath)") + try debugData?.capturePIFCache(pifLocation: pifCache.pifCachePath) let targets = pifCache.projects.flatMap { project in project.targets.compactMap { Target(from: $0, in: project) } }.filter { !$0.isTest } - logger.debug("Project non-test targets: \(targets.count)") + GenIRLogger.logger.debug("Project non-test targets: \(targets.count)") let targetCommands = log.commandLog.reduce(into: [TargetKey: [CompilerCommand]]()) { commands, entry in commands[entry.target, default: []].append(entry.command) @@ -158,14 +243,14 @@ let programName = CommandLine.arguments.first! let tempDirectory = try FileManager.default.temporaryDirectory(named: "gen-ir-\(UUID().uuidString)") defer { try? FileManager.default.removeItem(at: tempDirectory) } - logger.info("Using temp directory as working directory: \(tempDirectory)") + GenIRLogger.logger.info("Using temp directory as working directory: \(tempDirectory)") let runner = CompilerCommandRunner( output: tempDirectory, buildCacheManipulator: buildCacheManipulator, dryRun: dryRun ) - logger.debug("Targets to run: \(targets.count)") + GenIRLogger.logger.debug("Targets to run: \(targets.count)") try runner.run(targets: targets, commands: targetCommands) let postprocessor = try OutputPostprocessor( @@ -175,7 +260,8 @@ let programName = CommandLine.arguments.first! ) try postprocessor.process() - logger.info("\n\n** Gen-IR SUCCEEDED **\n\n") + GenIRLogger.logger.info("\n\n** Gen-IR SUCCEEDED **\n\n") + try debugData?.captureComplete(xcarchive: archive) } private func buildDependencyGraph(targets: [Target], pifCache: PIFCache, output: URL, dumpGraph: Bool) -> DependencyGraph { @@ -194,7 +280,7 @@ let programName = CommandLine.arguments.first! .filePath ) } catch { - logger.error("toDot error: \(error)") + GenIRLogger.logger.error("toDot error: \(error)") } } return graph diff --git a/Sources/GenIR/OutputPostprocessor.swift b/Sources/GenIR/OutputPostprocessor.swift index 03e4210..2569ee8 100644 --- a/Sources/GenIR/OutputPostprocessor.swift +++ b/Sources/GenIR/OutputPostprocessor.swift @@ -69,10 +69,10 @@ class OutputPostprocessor { // folder. Otherwise we will create an empty directory and that will contain the artifacts // of the dependency chain. if manager.directoryExists(at: buildDirectory) { - logger.debug("Copying \(node.value.guid) with name \(node.value.productName)") + GenIRLogger.logger.debug("Copying \(node.value.guid) with name \(node.value.productName)") try manager.copyItem(at: buildDirectory, to: irDirectory) } else { - logger.debug("Creating build directory for \(node.value.guid) with name \(node.value.productName)") + GenIRLogger.logger.debug("Creating build directory for \(node.value.guid) with name \(node.value.productName)") try manager.createDirectory(at: irDirectory, withIntermediateDirectories: false) } @@ -88,7 +88,7 @@ class OutputPostprocessor { } for node in graph.chain(for: target) { - logger.debug("Processing Node: \(node.valueName)") + GenIRLogger.logger.debug("Processing Node: \(node.valueName)") // Do not copy dynamic dependencies guard dynamicDependencyToPath[node.value.productName] == nil else { continue } @@ -100,7 +100,7 @@ class OutputPostprocessor { do { try copyContentsOfDirectoryMergingDifferingFiles(at: buildDirectory, to: irDirectory) } catch { - logger.debug("Copy error: \(error)") + GenIRLogger.logger.debug("Copy error: \(error)") } } } @@ -125,7 +125,7 @@ class OutputPostprocessor { // Avoid overwriting existing files with the same name. let uniqueDestinationURL = manager.uniqueFilename(directory: destination.deletingLastPathComponent(), filename: source.lastPathComponent) - logger.debug("Copying source \(source) to destination: \(uniqueDestinationURL)") + GenIRLogger.logger.debug("Copying source \(source) to destination: \(uniqueDestinationURL)") try manager.copyItem(at: source, to: uniqueDestinationURL) } } @@ -135,7 +135,7 @@ class OutputPostprocessor { /// - Returns: a mapping of filename to filepath for dynamic objects in the provided path private func dynamicDependencies(in xcarchive: URL) -> [String: URL] { let searchPath = baseSearchPath(startingAt: xcarchive) - logger.debug("Using search path for dynamic dependencies: \(searchPath)") + GenIRLogger.logger.debug("Using search path for dynamic dependencies: \(searchPath)") let dynamicDependencyExtensions = ["framework", "appex", "app"] @@ -170,7 +170,7 @@ class OutputPostprocessor { } if contents.count > 1 { - logger.debug("Expected one folder at: \(path). Found \(contents.count). Selecting \(contents.first!)") + GenIRLogger.logger.debug("Expected one folder at: \(path). Found \(contents.count). Selecting \(contents.first!)") } return contents.first! @@ -182,7 +182,7 @@ class OutputPostprocessor { } } - logger.debug("Couldn't determine the base search path for the xcarchive, using: \(productsPath)") + GenIRLogger.logger.debug("Couldn't determine the base search path for the xcarchive, using: \(productsPath)") return productsPath } } diff --git a/Sources/GenIR/PIFCache.swift b/Sources/GenIR/PIFCache.swift index de9fcf9..536dba1 100644 --- a/Sources/GenIR/PIFCache.swift +++ b/Sources/GenIR/PIFCache.swift @@ -8,7 +8,7 @@ import LogHandlers /// This class is used in conjunction with `PIFDependencyProvider` to enable building dependency relationships between the various targets class PIFCache { /// The path to the PIF Cache - private let pifCachePath: URL + public let pifCachePath: URL /// The most recent `PIF.Workspace` in the cache private let workspace: PIF.Workspace @@ -35,7 +35,7 @@ class PIFCache { pifCachePath = try Self.pifCachePath(in: buildCache) do { - let cache = try PIFCacheParser(cachePath: pifCachePath, logger: logger) + let cache = try PIFCacheParser(cachePath: pifCachePath, logger: GenIRLogger.logger) workspace = cache.workspace } catch { throw Error.pifError(error) @@ -45,7 +45,7 @@ class PIFCache { guidToTargets = targets.reduce(into: [PIF.GUID: PIF.BaseTarget]()) { partial, target in partial[target.guid] = target } - logger.debug("Project targets: \(targets.count) reduced to \(guidToTargets.count)") + GenIRLogger.logger.debug("Project targets: \(targets.count) reduced to \(guidToTargets.count)") } func target(guid: PIF.GUID) -> PIF.BaseTarget? { @@ -98,7 +98,7 @@ class PIFCache { case let group as PIF.Group: resolveChildren(starting: group.children) default: - logger.debug("Unhandled reference type: \(child)") + GenIRLogger.logger.debug("Unhandled reference type: \(child)") } } } @@ -205,19 +205,19 @@ struct PIFDependencyProvider: DependencyProviding { if productUnderlyingTargets.isEmpty && !productTargetDependencies.isEmpty { // We likely have a stub target here (i.e. a precompiled framework) // see https://github.com/apple/swift-package-manager/issues/6069 for more - logger.debug("Resolving Swift Package (\(productName) - \(packageProductGUID)) resulted in no targets. Possible stub target in: \(productTargetDependencies)") + GenIRLogger.logger.debug("Resolving Swift Package (\(productName) - \(packageProductGUID)) resulted in no targets. Possible stub target in: \(productTargetDependencies)") return nil } else if productUnderlyingTargets.isEmpty && productTargetDependencies.isEmpty { - logger.debug("Resolving Swift Package (\(productName) - \(packageProductGUID)) resulted in no targets. Likely a prebuilt dependency") + GenIRLogger.logger.debug("Resolving Swift Package (\(productName) - \(packageProductGUID)) resulted in no targets. Likely a prebuilt dependency") return nil } guard productTargetDependencies.count == 1, let target = productTargetDependencies.first else { - logger.debug("Expecting one matching package target - found \(productTargetDependencies.count): \(productTargetDependencies). Returning first match if it exists") + GenIRLogger.logger.debug("Expecting one matching package target - found \(productTargetDependencies.count): \(productTargetDependencies). Returning first match if it exists") return productTargetDependencies.first?.targetGUID } - logger.debug("\(packageProductGUID) resolves to \(target.targetGUID)") + GenIRLogger.logger.debug("\(packageProductGUID) resolves to \(target.targetGUID)") return target.targetGUID } diff --git a/Sources/GenIR/Versions.swift b/Sources/GenIR/Versions.swift index c30da4b..0d64883 100644 --- a/Sources/GenIR/Versions.swift +++ b/Sources/GenIR/Versions.swift @@ -4,9 +4,14 @@ // // Created by Thomas Hedderwick on 12/09/2022. // - +// History: +// 2025-nn-nn - 0.5.4 -- Update release doc; warn multiple builds; capture debug data +// 2025-04-18 - 0.5.3 -- PIF Tracing; log unique compiler commands +// 2025-04-09 - 0.5.2 -- PIF sort workspace; log instead of throw +// 2024-09-17 - 0.5.1 +// 2024-09-16 - 0.5.0 -- Process based on the PIF cache instead of project files. import Foundation enum Versions { - static let version = "0.5.3" + static let version = "0.5.4" } diff --git a/Sources/GenIR/XcodeLogParser.swift b/Sources/GenIR/XcodeLogParser.swift index c8d91d1..d3b8600 100644 --- a/Sources/GenIR/XcodeLogParser.swift +++ b/Sources/GenIR/XcodeLogParser.swift @@ -45,7 +45,7 @@ class XcodeLogParser { parseBuildLog() if commandLog.isEmpty { - logger.debug("Found no targets in log") + GenIRLogger.logger.debug("Found no targets in log") throw Error.noTargetsFound( """ @@ -55,7 +55,7 @@ class XcodeLogParser { } if commandLog.count == 0 { - logger.debug("Found no commands in log") + GenIRLogger.logger.debug("Found no commands in log") throw Error.noCommandsFound( """ @@ -69,7 +69,7 @@ class XcodeLogParser { } if buildCount > 1 { - logger.warning("\n\t ---- Multiple builds found in the log file, Gen-IR is designed to only parse one build at a time. ----\n") + GenIRLogger.logger.warning("\n\t ---- Multiple builds found in the log file, Gen-IR is designed to only parse one build at a time. ----\n") } } @@ -96,7 +96,7 @@ class XcodeLogParser { } if seenTargets.insert(target).inserted { - logger.debug("Found target: \(target)") + GenIRLogger.logger.debug("Found target: \(target)") } let commands = parseCompilerCommands(target: target) @@ -105,7 +105,7 @@ class XcodeLogParser { let commandKey = "\($0.command.compiler.rawValue)-\(target)" if (commandsToLog.insert(commandKey)).inserted { // Log the compiler along with the target - logger.debug("Found \($0.command.compiler.rawValue) compiler command for target: \(target)") + GenIRLogger.logger.debug("Found \($0.command.compiler.rawValue) compiler command for target: \(target)") } } diff --git a/Sources/LogHandlers/.gitignore b/Sources/LogHandlers/.gitignore deleted file mode 100644 index 0023a53..0000000 --- a/Sources/LogHandlers/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/Sources/LogHandlers/Sources/LogHandlers/FileLogHandler.swift b/Sources/LogHandlers/Sources/LogHandlers/FileLogHandler.swift new file mode 100644 index 0000000..b3cf7f2 --- /dev/null +++ b/Sources/LogHandlers/Sources/LogHandlers/FileLogHandler.swift @@ -0,0 +1,33 @@ +// +// FileLogHandler.swift +// + +import Foundation +import Logging + +public struct FileLogHandler: GenIRLogHandler { + + private let fileStream: GenIrIoTextStream + + public var metadata: Logging.Logger.Metadata = [:] + public var logLevel: Logging.Logger.Level = .info + + public init(filePath: URL) { + fileStream = GenIrIoTextStream(file: fopen(filePath.path, "w")) + } + + // periphery:ignore:parameters count + // swiftlint:disable:next function_parameter_count + public func log( + level: Logger.Level, + message: Logger.Message, + metadata: Logger.Metadata?, + source: String, + file: String, + function: String, + line: UInt + ) { + let lineInfo = lineInfo(for: level, file: file, function: function, line: line) + fileStream.write("\(timestamp)\(lineInfo)\(levelPrefix)\(message)\n") + } +} diff --git a/Sources/LogHandlers/Sources/LogHandlers/GenIRLoggingDefinition.swift b/Sources/LogHandlers/Sources/LogHandlers/GenIRLoggingDefinition.swift new file mode 100644 index 0000000..84309f3 --- /dev/null +++ b/Sources/LogHandlers/Sources/LogHandlers/GenIRLoggingDefinition.swift @@ -0,0 +1,119 @@ +import Foundation +import Logging + +/// All module logger (yes because swift-log hasn't really solved for setting level globally without passing an instance around everywhere) +public class GenIRLogger { + private static var internalLogger: Logger? + + /// The logger for the GenIR module. This is a singleton instance that can be used to log messages throughout the module. + public static var logger: Logger { + get { + return internalLogger ?? Logger(label: "Gen-IR") + } + set {internalLogger = newValue } + } +} + +/// A protocol that defines a logging handler for GenIR. +public protocol GenIRLogHandler: LogHandler { + + var levelPrefix: String { get } + + var timestamp: String { get } + + func lineInfo(for level: Logger.Level, file: String, function: String, line: UInt) -> String + + // swiftlint:disable:next function_parameter_count + func log( + level: Logger.Level, + message: Logger.Message, + metadata: Logger.Metadata?, + source: String, + file: String, + function: String, + line: UInt + ) +} + +extension GenIRLogHandler { + + /// Add, change, or remove metadata for this handler. Metadata is a dictionary of key-value pairs which can be + /// used to add additional information to log messages. + public subscript(metadataKey key: String) -> Logging.Logger.Metadata.Value? { + get { metadata[key] } + set(newValue) { metadata[key] = newValue } + } + + /// Convert a log level to a string prefix for the log message. + public var levelPrefix: String { + switch logLevel { + case .trace: + return "[TRACE] " + case .debug: + return "[DEBUG] " + case .info: + return "" + case .notice, .warning: + return "[~] " + case .error: + return "[!] " + case .critical: + return "[!!!] " + } + } + + /// Add a timestamp to the log message based on the log level. + public var timestamp: String { + switch logLevel { + case .trace, .debug, .notice, .warning, .error, .critical: + return "\(Date.now) " + case .info: + return "" + } + } + + /// Add line information to the log message based on the log level. + public func lineInfo(for level: Logger.Level, file: String, function: String, line: UInt) -> String { + switch level { + case .trace, .debug, .notice, .warning, .error, .critical: + return "[\(file):\(line) \(function)] " + case .info: + return "" + } + } + + // swiftlint:disable function_parameter_count + /// Log a message with the specified log level, message, metadata, source, file, function, and line number. + public func log( + level: Logger.Level, + message: Logger.Message, + metadata: Logger.Metadata?, + source: String, + file: String, + function: String, + line: UInt + ) { + let lineInfo = lineInfo(for: level, file: file, function: function, line: line) + print("\(timestamp)\(lineInfo)\(levelPrefix)\(message)\n") + } + // swiftlint:enable function_parameter_count +} + +/// A custom text output stream that writes to a file. +struct GenIrIoTextStream: TextOutputStream { + + let file: UnsafeMutablePointer + + func write(_ string: String) { + var string = string + string.makeContiguousUTF8() + string.utf8.withContiguousStorageIfAvailable { bytes in + flockfile(file) + defer { funlockfile(file) } + + fwrite(bytes.baseAddress!, 1, bytes.count, file) + + fflush(file) + } + } +} diff --git a/Sources/LogHandlers/Sources/LogHandlers/StdoutLogHandler.swift b/Sources/LogHandlers/Sources/LogHandlers/StdoutLogHandler.swift index 1cd36d3..c11b2c0 100644 --- a/Sources/LogHandlers/Sources/LogHandlers/StdoutLogHandler.swift +++ b/Sources/LogHandlers/Sources/LogHandlers/StdoutLogHandler.swift @@ -8,38 +8,8 @@ import Foundation import Logging -/// All module logger (yes because swift-log hasn't really solved for setting level globally without passing an instance around everywhere) -public var logger = Logger(label: "LogHandler", factory: StdIOStreamLogHandler.init) - -struct StdIOTextStream: TextOutputStream { - static let stdout = StdIOTextStream(file: Darwin.stdout) - static let stderr = StdIOTextStream(file: Darwin.stderr) - - let file: UnsafeMutablePointer - - func write(_ string: String) { - var string = string - string.makeContiguousUTF8() - string.utf8.withContiguousStorageIfAvailable { bytes in - flockfile(file) - defer { funlockfile(file) } - - fwrite(bytes.baseAddress!, 1, bytes.count, file) - - fflush(file) - } - } -} - -public struct StdIOStreamLogHandler: LogHandler { - internal typealias SendableTextOutputStream = TextOutputStream & Sendable - - private let stdout = StdIOTextStream.stdout - - public subscript(metadataKey key: String) -> Logging.Logger.Metadata.Value? { - get { metadata[key] } - set(newValue) { metadata[key] = newValue } - } +public struct StdIOStreamLogHandler: GenIRLogHandler { + let stdout = GenIrIoTextStream(file: Darwin.stdout) public var metadata: Logging.Logger.Metadata = [:] public var logLevel: Logging.Logger.Level = .info @@ -60,42 +30,6 @@ public struct StdIOStreamLogHandler: LogHandler { line: UInt ) { let lineInfo = lineInfo(for: level, file: file, function: function, line: line) - stdout.write("\(timestamp)\(lineInfo)\(levelPrefix)\(message)\n") } - - private var levelPrefix: String { - switch logLevel { - case .trace: - return "[TRACE] " - case .debug: - return "[DEBUG] " - case .info: - return "" - case .notice, .warning: - return "[~] " - case .error: - return "[!] " - case .critical: - return "[!!!] " - } - } - - private var timestamp: String { - switch logLevel { - case .trace, .debug, .notice, .warning, .error, .critical: - return "\(Date.now) " - case .info: - return "" - } - } - - private func lineInfo(for level: Logger.Level, file: String, function: String, line: UInt) -> String { - switch level { - case .trace, .debug, .notice, .warning, .error, .critical: - return "[\(file):\(line) \(function)] " - case .info: - return "" - } - } } diff --git a/TestAssets/PIFCaches/SPMTest/MyBinaryDependency/.gitignore b/TestAssets/PIFCaches/SPMTest/MyBinaryDependency/.gitignore deleted file mode 100644 index 0023a53..0000000 --- a/TestAssets/PIFCaches/SPMTest/MyBinaryDependency/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/TestAssets/PIFCaches/SPMTest/MyCommonLibrary/.gitignore b/TestAssets/PIFCaches/SPMTest/MyCommonLibrary/.gitignore deleted file mode 100644 index 0023a53..0000000 --- a/TestAssets/PIFCaches/SPMTest/MyCommonLibrary/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/TestAssets/PIFCaches/SPMTest/MyLibrary/.gitignore b/TestAssets/PIFCaches/SPMTest/MyLibrary/.gitignore deleted file mode 100644 index 0023a53..0000000 --- a/TestAssets/PIFCaches/SPMTest/MyLibrary/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/TestAssets/PIFCaches/SPMTest/MyTransitiveLibrary/.gitignore b/TestAssets/PIFCaches/SPMTest/MyTransitiveLibrary/.gitignore deleted file mode 100644 index 0023a53..0000000 --- a/TestAssets/PIFCaches/SPMTest/MyTransitiveLibrary/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc From 51cb602b22a98cc7448d80d666cb3d19c38ebecc Mon Sep 17 00:00:00 2001 From: davdres Date: Thu, 31 Jul 2025 14:11:42 -0700 Subject: [PATCH 20/24] SSAST-10900 Update help for debug data capture. (#93) --- Sources/GenIR/GenIR.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index b42f436..c8a141a 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -23,7 +23,7 @@ struct DebuggingOptions: ParsableArguments { @Option(help: ArgumentHelp("Specifiy a logging level. The --debug flag will override this", visibility: .hidden)) var logLevel: LogLevelArgument? - @Flag(help: ArgumentHelp("Path to save a zip file containing debug data.", visibility: .hidden)) + @Flag(help: ArgumentHelp("If true, add captured debug data to the xcarchive.", visibility: .hidden)) var capture: Bool = false } From be30b573ea3b791914d41e5c357d755f1db4b496 Mon Sep 17 00:00:00 2001 From: Boy Baukema Date: Mon, 3 Nov 2025 11:55:24 +0100 Subject: [PATCH 21/24] Install instructions cannot be executed as is, improve install instructions to make them executable --- README.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8913a3c..105d659 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,18 @@ To **install and run** the tool, you'll need Homebrew, Xcode, and macOS 12 or gr ## Install ```bash -# If you don't have brew installed, install it: https://brew.sh/ - -# Add the brew tap to your local machine -brew tap veracode/tap - -# Install the tool -brew install gen-ir +if ! command -v brew >/dev/null 2>&1; then + echo "Homebrew is not installed. Visit https://brew.sh/ to install it." + return 1 2>/dev/null || true +else + echo "Installing gen-ir using Homebrew" && + brew tap veracode/tap && + brew install gen-ir && + + echo "gen-ir installed successfully." + echo "For usage instructions, see:" + echo " https://github.com/veracode/gen-ir#readme" +fi ``` ## Update (if previously installed) From a1dbe58d9a98dea6202ce30a0205d145d39c547c Mon Sep 17 00:00:00 2001 From: davdres Date: Mon, 17 Nov 2025 10:06:13 -0800 Subject: [PATCH 22/24] Feature/ssast 10888 (#96) * release/0.5.4 changes merged into main but not on develop * SSAST-10888 don't copy dependent modules but save them for pp to reconstruct. --- .github/workflows/build.yml | 2 +- Sources/DependencyGraph/DependencyGraph.swift | 22 +- Sources/GenIR/CompilerCommandRunner.swift | 4 +- Sources/GenIR/GenIR.swift | 4 +- Sources/GenIR/OutputPostprocessor.swift | 39 +- Sources/GenIR/Versions.swift | 5 +- TestAssets/DependencyChaseFilter/README.txt | 53 +++ .../contents.xcworkspacedata | 20 + .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../xcshareddata/swiftpm/Package.resolved | 231 ++++++++++ .../TestApp77.xcodeproj/project.pbxproj | 420 +++++++++++++++++ .../contents.xcworkspacedata | 7 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 35 ++ .../TestApp77/Assets.xcassets/Contents.json | 6 + .../TestApp77/TestApp77/ContentView.swift | 31 ++ .../Preview Assets.xcassets/Contents.json | 6 + .../TestApp77/TestApp77-Bridging-Header.h | 14 + .../TestApp77/TestApp77/TestApp77App.swift | 17 + .../TestLibraryA.xcodeproj/project.pbxproj | 396 ++++++++++++++++ .../contents.xcworkspacedata | 7 + .../TestLibraryA/TestLibraryA/TestLibraryA.h | 19 + .../TestLibraryA/VersionPrinter.h | 17 + .../TestLibraryA/VersionPrinter.m | 19 + .../TestLibraryB.xcodeproj/project.pbxproj | 436 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../TestLibraryB/TestLibraryB/TestLibraryB.h | 18 + .../TestLibraryB/VersionPrinterB.h | 17 + .../TestLibraryB/VersionPrinterB.m | 16 + .../TestLibraryC.xcodeproj/project.pbxproj | 372 +++++++++++++++ .../contents.xcworkspacedata | 7 + .../TestLibraryC/TestLibraryC/TestLibraryC.h | 19 + .../TestLibraryC/VersionPrinterC.h | 15 + .../TestLibraryC/VersionPrinterC.m | 17 + .../DependencyChaseFilterTests.swift | 44 ++ Tests/GenIRTests/WorkspaceTests.swift | 1 + 36 files changed, 2344 insertions(+), 15 deletions(-) create mode 100644 TestAssets/DependencyChaseFilter/README.txt create mode 100644 TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/contents.xcworkspacedata create mode 100644 TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.pbxproj create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/Contents.json create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77/ContentView.swift create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77-Bridging-Header.h create mode 100644 TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77App.swift create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.pbxproj create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/TestLibraryA.h create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.h create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.m create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.pbxproj create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/TestLibraryB.h create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.h create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.m create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.pbxproj create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/TestLibraryC.h create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.h create mode 100644 TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.m create mode 100644 Tests/GenIRTests/DependencyChaseFilterTests.swift diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f071396..e9c226f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: '16.2.0' # Specify the desired Xcode version + xcode-version: '16.4.0' # Specify the desired Xcode version - uses: actions/checkout@v4 diff --git a/Sources/DependencyGraph/DependencyGraph.swift b/Sources/DependencyGraph/DependencyGraph.swift index 02766df..a83fb7f 100644 --- a/Sources/DependencyGraph/DependencyGraph.swift +++ b/Sources/DependencyGraph/DependencyGraph.swift @@ -37,18 +37,31 @@ public class DependencyGraph { /// - Parameter value: the associated value for a node to start the search with /// - Returns: the chain of nodes, starting with the 'bottom' of the dependency subgraph public func chain(for value: Value) -> [Node] { + let noFilter: Set = [] + return chainWithFilter(for: value, filter: noFilter) + } + + /// Returns the dependency 'chain' for the value associated with a node in the graph using a depth-first search + /// while filtering dynamic dependencies. + /// - Parameter value: the associated value for a node to start the search with + /// - Parameter value: a set whose keys indicate node values which will not be chased further. + /// - Returns: the chain of nodes, starting with the 'bottom' of the dependency subgraph + public func chainWithFilter(for value: Value, filter dynamicDependencyFilter: Set) -> [Node] { guard let node = findNode(for: value) else { GenIRLogger.logger.debug("Couldn't find node for value: \(value.valueName)") return [] } - return depthFirstSearch(startingAt: node) + return depthFirstSearchWithFilter(startingAt: node, filter: dynamicDependencyFilter) } /// Perform a depth-first search starting at the provided node /// - Parameter node: the node whose children to search through + /// - Parameter filter: A set of String. If a dependency relationship in the graph is contained in + /// the Set, then add that edge to the chain and continue with the next edge without descending + /// further down the graph. /// - Returns: an array of nodes ordered by a depth-first search approach - private func depthFirstSearch(startingAt node: Node) -> [Node] { + private func depthFirstSearchWithFilter(startingAt node: Node, filter dynamicDependencyFilter: Set) -> [Node] { GenIRLogger.logger.debug("----\nSearching for: \(node.value.valueName)") var visited = Set() var chain = [Node]() @@ -60,6 +73,11 @@ public class DependencyGraph { visited.insert(node) for edge in node.edges where edge.relationship == .dependency { + if dynamicDependencyFilter.contains(edge.to.valueName) { + GenIRLogger.logger.debug("\tskipping dependency: \(edge.to.valueName)") + chain.append(edge.to) + continue + } if visited.insert(edge.to).inserted { GenIRLogger.logger.debug("edge to: \(edge.to)") depthFirst(node: edge.to) diff --git a/Sources/GenIR/CompilerCommandRunner.swift b/Sources/GenIR/CompilerCommandRunner.swift index 10ddbbd..dc453de 100644 --- a/Sources/GenIR/CompilerCommandRunner.swift +++ b/Sources/GenIR/CompilerCommandRunner.swift @@ -65,7 +65,7 @@ struct CompilerCommandRunner { continue } - GenIRLogger.logger.info("Operating on target: \(target.name). Total modules processed: \(totalModulesRun)") + GenIRLogger.logger.debug("Operating on target: \(target.name). Total modules processed: \(totalModulesRun)") totalModulesRun += try run(commands: targetCommands, for: target.productName, at: output) } @@ -90,7 +90,7 @@ struct CompilerCommandRunner { var targetModulesRun = 0 for (index, command) in commands.enumerated() { - GenIRLogger.logger.info( + GenIRLogger.logger.debug( """ \(dryRun ? "Dry run of" : "Running") command (\(command.compiler.rawValue)) \(index + 1) of \(commands.count). \ Target modules processed: \(targetModulesRun) diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index c8a141a..10d7fe7 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -107,7 +107,7 @@ struct DebuggingOptions: ParsableArguments { } } - mutating private func validateXcarchive() throws { + mutating private func validateXcarchive() throws { // Version 0.2.x and below allowed the output folder to be any arbitrary folder. // Docs said to use 'IR' inside an xcarchive. For backwards compatibility, if we have an xcarchive path with an IR // folder, remove the IR portion @@ -226,7 +226,7 @@ struct DebuggingOptions: ParsableArguments { let targets = pifCache.projects.flatMap { project in project.targets.compactMap { Target(from: $0, in: project) } }.filter { !$0.isTest } - GenIRLogger.logger.debug("Project non-test targets: \(targets.count)") + GenIRLogger.logger.debug("Project non-test targets: \(targets.count)") let targetCommands = log.commandLog.reduce(into: [TargetKey: [CompilerCommand]]()) { commands, entry in commands[entry.target, default: []].append(entry.command) diff --git a/Sources/GenIR/OutputPostprocessor.swift b/Sources/GenIR/OutputPostprocessor.swift index 2569ee8..223d0d6 100644 --- a/Sources/GenIR/OutputPostprocessor.swift +++ b/Sources/GenIR/OutputPostprocessor.swift @@ -56,6 +56,7 @@ class OutputPostprocessor { try manager.createDirectory(at: output, withIntermediateDirectories: false) for node in nodes { + var targetDependencies: [String: [String]] = [:] let dependers = node.edges.filter { $0.relationship == .depender } guard dynamicDependencyToPath[node.value.productName] != nil || (dependers.count == 0 && !node.value.isSwiftPackage) else { @@ -78,22 +79,33 @@ class OutputPostprocessor { // Copy over this target's static dependencies var processed: Set = [] - try copyDependencies(for: node.value, to: irDirectory, processed: &processed) + try copyDependencies(for: node.value, to: irDirectory, processed: &processed, savedDependencies: &targetDependencies) + + // Persist the dependency map for this target + try persistDynamicDependencies(map: targetDependencies, to: irDirectory.appendingPathComponent("savedDependencies.json")) } } - private func copyDependencies(for target: Target, to irDirectory: URL, processed: inout Set) throws { + private func copyDependencies(for target: Target, to irDirectory: URL, processed: inout Set, savedDependencies: inout [String: [String]]) throws { guard processed.insert(target).inserted else { return } - for node in graph.chain(for: target) { - GenIRLogger.logger.debug("Processing Node: \(node.valueName)") + for node in graph.chainWithFilter(for: target, filter: Set(dynamicDependencyToPath.keys)) { + GenIRLogger.logger.debug("Processing Node with product: \(node.value.productName) and value: \(node.valueName)") // Do not copy dynamic dependencies - guard dynamicDependencyToPath[node.value.productName] == nil else { continue } + guard dynamicDependencyToPath[node.value.productName] == nil else { + // Skip this directory for any dynamic dependency that is not the current one being processed. During preprocessing on the + // platform the modules for this dependency will be retrieved and added to this module. + if irDirectory.lastPathComponent != node.value.productName { + savedDependencies[irDirectory.lastPathComponent, default: []].append(node.value.productName) + } + GenIRLogger.logger.debug(" ---> Skipping dynamic dependency: \(node.value.productName)") + continue + } - try copyDependencies(for: node.value, to: irDirectory, processed: &processed) + try copyDependencies(for: node.value, to: irDirectory, processed: &processed, savedDependencies: &savedDependencies) let buildDirectory = build.appendingPathComponent(node.value.productName) if manager.directoryExists(at: buildDirectory) { @@ -185,4 +197,19 @@ class OutputPostprocessor { GenIRLogger.logger.debug("Couldn't determine the base search path for the xcarchive, using: \(productsPath)") return productsPath } + + /// Persist the dynamic dependecies in the IR folder. The preprocessor will use this data to build modules + /// for BCA. + private func persistDynamicDependencies(map dynamicDependencyToPath: [String: [String]], to destination: URL) throws { + // Convert URL to string for serialization + let serializableDict = dynamicDependencyToPath.mapValues { $0 } + + // JSON encode + let encoder = JSONEncoder() + encoder.outputFormatting = [.sortedKeys, .prettyPrinted] + let data = try encoder.encode(serializableDict) + + // Write to file + try data.write(to: URL(fileURLWithPath: destination.filePath)) + } } diff --git a/Sources/GenIR/Versions.swift b/Sources/GenIR/Versions.swift index 0d64883..e41a483 100644 --- a/Sources/GenIR/Versions.swift +++ b/Sources/GenIR/Versions.swift @@ -5,7 +5,8 @@ // Created by Thomas Hedderwick on 12/09/2022. // // History: -// 2025-nn-nn - 0.5.4 -- Update release doc; warn multiple builds; capture debug data +// 2025-nn-nn - 1.0.0 -- Don't chase through Dynamic Dependencies +// 2025-09-19 - 0.5.4 -- Update release doc; warn multiple builds; capture debug data // 2025-04-18 - 0.5.3 -- PIF Tracing; log unique compiler commands // 2025-04-09 - 0.5.2 -- PIF sort workspace; log instead of throw // 2024-09-17 - 0.5.1 @@ -13,5 +14,5 @@ import Foundation enum Versions { - static let version = "0.5.4" + static let version = "1.0.0" } diff --git a/TestAssets/DependencyChaseFilter/README.txt b/TestAssets/DependencyChaseFilter/README.txt new file mode 100644 index 0000000..dc5f4ee --- /dev/null +++ b/TestAssets/DependencyChaseFilter/README.txt @@ -0,0 +1,53 @@ +Test project in TestApp77.xcworkspace (built originally with Xcode 16.1). + + +TestApp77 (app target) depends on TestLibraryA (framework target) and TestLibraryC (framework target) + +TestLibraryA (framework target) depends on TestLibraryB (framework target) + +TestLibraryB (framework target) depends on the opentelemetry-swift package. + +TestLibraryC (framework target) has no dependencies. + + + +Generated archive is in build/test.xcarchive. + + +--- +See that the IR files from the opentelemetry-swift package (e.g., ZipkinBaggagePropagator.bc) appear in all targets, +except for TestLibraryC (which doesn't have a transitive dependency on opentelemetry-swift). + +However, the files should only appear in IR/TestLibraryB, which is the target that references the package. You can +check that only Products/Applications/TestApp77.app/Frameworks/TestLibraryB.framework/TestLibraryB contains symbols +from opentelemetry-swift (e.g., using the `nm` utility). + +Why is this a problem? The size of the IR folder is bloating the app: + +$ du -chd 1 build/test.xcarchive/IR + 26M build/test.xcarchive/IR/TestApp77.app + 26M build/test.xcarchive/IR/TestLibraryB.framework +4.0K build/test.xcarchive/IR/TestLibraryC.framework + 26M build/test.xcarchive/IR/TestLibraryA.framework + 78M build/test.xcarchive/IR + 78M total + + +This app has no actual contents: only TestLibraryB should have anything of +significance from the opentelemetry-swift package (26M), and everything else +should be ~4K. However, we're getting the 26M from opentelemetry-swift multiplied +across all transitive dependencies, which for a big app with ~200 frameworks, can +be multiple gigabytes of extra space. + +In particular, we're seeing our zipped app archive go above the 2GiB upload limit! + + +--- +Build command: + +rm -rf ./build && xcodebuild clean -workspace TestApp77.xcworkspace -scheme TestApp77 -derivedDataPath ./build && xcodebuild archive -derivedDataPath ./build -workspace TestApp77.xcworkspace -scheme TestApp77 -configuration Debug -destination generic/platform=iOS -archivePath build/test.xcarchive > build_log.txt + + +Gen-IR command: + +gen-ir build_log.txt build/test.xcarchive --debug > gen_ir_log.txt diff --git a/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/contents.xcworkspacedata b/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..dc40679 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/swiftpm/Package.resolved b/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..3778260 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,231 @@ +{ + "originHash" : "2c128f8da131b6f688d204a82023ec45f28617c47a0244f3e088ec8d96d23e95", + "pins" : [ + { + "identity" : "grpc-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/grpc/grpc-swift.git", + "state" : { + "revision" : "a56a157218877ef3e9625f7e1f7b2cb7e46ead1b", + "version" : "1.26.1" + } + }, + { + "identity" : "opentelemetry-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/open-telemetry/opentelemetry-swift", + "state" : { + "revision" : "7a68865d9cc571cbe62c4d4902ccc0d902881eab", + "version" : "2.1.0" + } + }, + { + "identity" : "opentelemetry-swift-core", + "kind" : "remoteSourceControl", + "location" : "https://github.com/open-telemetry/opentelemetry-swift-core.git", + "state" : { + "revision" : "6aebc7734e154cd221ea9fb76bd4f611262be962", + "version" : "2.1.1" + } + }, + { + "identity" : "opentracing-objc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/undefinedlabs/opentracing-objc", + "state" : { + "revision" : "18c1a35ca966236cee0c5a714a51a73ff33384c1", + "version" : "0.5.2" + } + }, + { + "identity" : "swift-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-algorithms.git", + "state" : { + "revision" : "87e50f483c54e6efd60e885f7f5aa946cee68023", + "version" : "1.2.1" + } + }, + { + "identity" : "swift-asn1", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-asn1.git", + "state" : { + "revision" : "f70225981241859eb4aa1a18a75531d26637c8cc", + "version" : "1.4.0" + } + }, + { + "identity" : "swift-async-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-async-algorithms.git", + "state" : { + "revision" : "042e1c4d9d19748c9c228f8d4ebc97bb1e339b0b", + "version" : "1.0.4" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-certificates", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-certificates.git", + "state" : { + "revision" : "4b092f15164144c24554e0a75e080a960c5190a6", + "version" : "1.14.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "8c0c0a8b49e080e54e5e328cc552821ff07cd341", + "version" : "1.2.1" + } + }, + { + "identity" : "swift-crypto", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-crypto.git", + "state" : { + "revision" : "d1c6b70f7c5f19fb0b8750cb8dcdf2ea6e2d8c34", + "version" : "3.15.0" + } + }, + { + "identity" : "swift-http-structured-headers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-http-structured-headers.git", + "state" : { + "revision" : "1625f271afb04375bf48737a5572613248d0e7a0", + "version" : "1.4.0" + } + }, + { + "identity" : "swift-http-types", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-http-types.git", + "state" : { + "revision" : "a0a57e949a8903563aba4615869310c0ebf14c03", + "version" : "1.4.0" + } + }, + { + "identity" : "swift-log", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-log.git", + "state" : { + "revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2", + "version" : "1.6.4" + } + }, + { + "identity" : "swift-metrics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-metrics.git", + "state" : { + "revision" : "0743a9364382629da3bf5677b46a2c4b1ce5d2a6", + "version" : "2.7.1" + } + }, + { + "identity" : "swift-nio", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio.git", + "state" : { + "revision" : "1c30f0f2053b654e3d1302492124aa6d242cdba7", + "version" : "2.86.0" + } + }, + { + "identity" : "swift-nio-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-extras.git", + "state" : { + "revision" : "a55c3dd3a81d035af8a20ce5718889c0dcab073d", + "version" : "1.29.0" + } + }, + { + "identity" : "swift-nio-http2", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-http2.git", + "state" : { + "revision" : "5e9e99ec96c53bc2c18ddd10c1e25a3cd97c55e5", + "version" : "1.38.0" + } + }, + { + "identity" : "swift-nio-ssl", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-ssl.git", + "state" : { + "revision" : "737e550e607d82bf15bdfddf158ec61652ce836f", + "version" : "2.34.0" + } + }, + { + "identity" : "swift-nio-transport-services", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-transport-services.git", + "state" : { + "revision" : "e645014baea2ec1c2db564410c51a656cf47c923", + "version" : "1.25.1" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics.git", + "state" : { + "revision" : "bbadd4b853a33fd78c4ae977d17bb2af15eb3f2a", + "version" : "1.1.0" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "2547102afd04fe49f1b286090f13ebce07284980", + "version" : "1.31.1" + } + }, + { + "identity" : "swift-service-lifecycle", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swift-server/swift-service-lifecycle.git", + "state" : { + "revision" : "e7187309187695115033536e8fc9b2eb87fd956d", + "version" : "2.8.0" + } + }, + { + "identity" : "swift-system", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-system.git", + "state" : { + "revision" : "395a77f0aa927f0ff73941d7ac35f2b46d47c9db", + "version" : "1.6.3" + } + }, + { + "identity" : "thrift-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/undefinedlabs/Thrift-Swift", + "state" : { + "revision" : "18ff09e6b30e589ed38f90a1af23e193b8ecef8e", + "version" : "1.1.2" + } + } + ], + "version" : 3 +} diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.pbxproj b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c09e8b7 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.pbxproj @@ -0,0 +1,420 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 13EF34552E7DF71C00F2EE87 /* TestLibraryA.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13EF34532E7DF6A200F2EE87 /* TestLibraryA.framework */; }; + 13EF34562E7DF71C00F2EE87 /* TestLibraryA.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 13EF34532E7DF6A200F2EE87 /* TestLibraryA.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 13EF349E2E7DF7EA00F2EE87 /* TestLibraryB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13EF349D2E7DF7EA00F2EE87 /* TestLibraryB.framework */; }; + 13EF349F2E7DF7EA00F2EE87 /* TestLibraryB.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 13EF349D2E7DF7EA00F2EE87 /* TestLibraryB.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 13EF34C52E81D33700F2EE87 /* TestLibraryC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13EF34C42E81D33700F2EE87 /* TestLibraryC.framework */; }; + 13EF34C62E81D33700F2EE87 /* TestLibraryC.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 13EF34C42E81D33700F2EE87 /* TestLibraryC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 13EF34522E7DF6A200F2EE87 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 13EF344C2E7DF6A200F2EE87 /* TestLibraryA.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 13EF34372E7DF58A00F2EE87; + remoteInfo = TestLibraryA; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 13EF34572E7DF71C00F2EE87 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 13EF34562E7DF71C00F2EE87 /* TestLibraryA.framework in Embed Frameworks */, + 13EF34C62E81D33700F2EE87 /* TestLibraryC.framework in Embed Frameworks */, + 13EF349F2E7DF7EA00F2EE87 /* TestLibraryB.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 13EF341C2E7DF54400F2EE87 /* TestApp77.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestApp77.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 13EF344C2E7DF6A200F2EE87 /* TestLibraryA.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TestLibraryA.xcodeproj; path = ../TestLibraryA/TestLibraryA.xcodeproj; sourceTree = ""; }; + 13EF349D2E7DF7EA00F2EE87 /* TestLibraryB.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TestLibraryB.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 13EF34C42E81D33700F2EE87 /* TestLibraryC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TestLibraryC.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 13EF341E2E7DF54400F2EE87 /* TestApp77 */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = TestApp77; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 13EF34192E7DF54400F2EE87 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 13EF34552E7DF71C00F2EE87 /* TestLibraryA.framework in Frameworks */, + 13EF34C52E81D33700F2EE87 /* TestLibraryC.framework in Frameworks */, + 13EF349E2E7DF7EA00F2EE87 /* TestLibraryB.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 13EF34132E7DF54400F2EE87 = { + isa = PBXGroup; + children = ( + 13EF341E2E7DF54400F2EE87 /* TestApp77 */, + 13EF344B2E7DF6A200F2EE87 /* Frameworks */, + 13EF341D2E7DF54400F2EE87 /* Products */, + ); + sourceTree = ""; + }; + 13EF341D2E7DF54400F2EE87 /* Products */ = { + isa = PBXGroup; + children = ( + 13EF341C2E7DF54400F2EE87 /* TestApp77.app */, + ); + name = Products; + sourceTree = ""; + }; + 13EF344B2E7DF6A200F2EE87 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 13EF34C42E81D33700F2EE87 /* TestLibraryC.framework */, + 13EF349D2E7DF7EA00F2EE87 /* TestLibraryB.framework */, + 13EF344C2E7DF6A200F2EE87 /* TestLibraryA.xcodeproj */, + ); + name = Frameworks; + sourceTree = ""; + }; + 13EF344D2E7DF6A200F2EE87 /* Products */ = { + isa = PBXGroup; + children = ( + 13EF34532E7DF6A200F2EE87 /* TestLibraryA.framework */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 13EF341B2E7DF54400F2EE87 /* TestApp77 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13EF342A2E7DF54500F2EE87 /* Build configuration list for PBXNativeTarget "TestApp77" */; + buildPhases = ( + 13EF34182E7DF54400F2EE87 /* Sources */, + 13EF34192E7DF54400F2EE87 /* Frameworks */, + 13EF341A2E7DF54400F2EE87 /* Resources */, + 13EF34572E7DF71C00F2EE87 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 13EF341E2E7DF54400F2EE87 /* TestApp77 */, + ); + name = TestApp77; + packageProductDependencies = ( + ); + productName = TestApp77; + productReference = 13EF341C2E7DF54400F2EE87 /* TestApp77.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 13EF34142E7DF54400F2EE87 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1610; + LastUpgradeCheck = 2600; + TargetAttributes = { + 13EF341B2E7DF54400F2EE87 = { + CreatedOnToolsVersion = 16.1; + }; + }; + }; + buildConfigurationList = 13EF34172E7DF54400F2EE87 /* Build configuration list for PBXProject "TestApp77" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 13EF34132E7DF54400F2EE87; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 13EF341D2E7DF54400F2EE87 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 13EF344D2E7DF6A200F2EE87 /* Products */; + ProjectRef = 13EF344C2E7DF6A200F2EE87 /* TestLibraryA.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 13EF341B2E7DF54400F2EE87 /* TestApp77 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 13EF34532E7DF6A200F2EE87 /* TestLibraryA.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = TestLibraryA.framework; + remoteRef = 13EF34522E7DF6A200F2EE87 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 13EF341A2E7DF54400F2EE87 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 13EF34182E7DF54400F2EE87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 13EF34282E7DF54500F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/TestLibraryA"; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/TestApp77/TestApp77-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 13EF34292E7DF54500F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/TestLibraryA"; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/TestApp77/TestApp77-Bridging-Header.h"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 13EF342B2E7DF54500F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_ASSET_PATHS = "\"TestApp77/Preview Content\""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestApp77; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 13EF342C2E7DF54500F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_ASSET_PATHS = "\"TestApp77/Preview Content\""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestApp77; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 13EF34172E7DF54400F2EE87 /* Build configuration list for PBXProject "TestApp77" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF34282E7DF54500F2EE87 /* Debug */, + 13EF34292E7DF54500F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 13EF342A2E7DF54500F2EE87 /* Build configuration list for PBXNativeTarget "TestApp77" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF342B2E7DF54500F2EE87 /* Debug */, + 13EF342C2E7DF54500F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 13EF34142E7DF54400F2EE87 /* Project object */; +} diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AccentColor.colorset/Contents.json b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AppIcon.appiconset/Contents.json b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/Contents.json b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/ContentView.swift b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/ContentView.swift new file mode 100644 index 0000000..b474510 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/ContentView.swift @@ -0,0 +1,31 @@ +// +// ContentView.swift +// TestApp77 +// +// Created by Keith Johnson on 9/19/25. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack { + Image(systemName: "globe") + .imageScale(.large) + .foregroundStyle(.tint) + Text("Hello, world!") + } + .padding() + .onAppear { + // printVersionInfo prints TestLibraryA's info. TestLibraryA in turn prints TestLibraryB's info + VersionPrinter.printVersionInfo() + + // Now print TestLibraryC's info + VersionPrinterC.printVersionInfoC() + } + } +} + +#Preview { + ContentView() +} diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Preview Content/Preview Assets.xcassets/Contents.json b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77-Bridging-Header.h b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77-Bridging-Header.h new file mode 100644 index 0000000..ada2d69 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77-Bridging-Header.h @@ -0,0 +1,14 @@ +// +// TestApp77-Bridging-Header.h +// TestApp77 +// +// Created by David Dresser on 10/21/25. +// + +#ifndef TestApp77_Bridging_Header_h +#define TestApp77_Bridging_Header_h + +#import // For Objective-C +#import // For Objective-C + +#endif /* TestApp77_Bridging_Header_h */ diff --git a/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77App.swift b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77App.swift new file mode 100644 index 0000000..a9894bd --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestApp77/TestApp77/TestApp77App.swift @@ -0,0 +1,17 @@ +// +// TestApp77App.swift +// TestApp77 +// +// Created by Keith Johnson on 9/19/25. +// + +import SwiftUI + +@main +struct TestApp77App: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.pbxproj b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8368128 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.pbxproj @@ -0,0 +1,396 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 13EF349A2E7DF7E000F2EE87 /* TestLibraryB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13EF34992E7DF7E000F2EE87 /* TestLibraryB.framework */; }; + A906D2282EA80285007DC512 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A906D2272EA80285007DC512 /* Foundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 13EF34372E7DF58A00F2EE87 /* TestLibraryA.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TestLibraryA.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 13EF34992E7DF7E000F2EE87 /* TestLibraryB.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = TestLibraryB.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A906D2272EA80285007DC512 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 13EF343C2E7DF58A00F2EE87 /* Exceptions for "TestLibraryA" folder in "TestLibraryA" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + publicHeaders = ( + TestLibraryA.h, + VersionPrinter.h, + ); + target = 13EF34362E7DF58A00F2EE87 /* TestLibraryA */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 13EF34392E7DF58A00F2EE87 /* TestLibraryA */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 13EF343C2E7DF58A00F2EE87 /* Exceptions for "TestLibraryA" folder in "TestLibraryA" target */, + ); + path = TestLibraryA; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 13EF34342E7DF58A00F2EE87 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A906D2282EA80285007DC512 /* Foundation.framework in Frameworks */, + 13EF349A2E7DF7E000F2EE87 /* TestLibraryB.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 13EF342D2E7DF58A00F2EE87 = { + isa = PBXGroup; + children = ( + 13EF34392E7DF58A00F2EE87 /* TestLibraryA */, + 13EF34982E7DF7E000F2EE87 /* Frameworks */, + 13EF34382E7DF58A00F2EE87 /* Products */, + ); + sourceTree = ""; + }; + 13EF34382E7DF58A00F2EE87 /* Products */ = { + isa = PBXGroup; + children = ( + 13EF34372E7DF58A00F2EE87 /* TestLibraryA.framework */, + ); + name = Products; + sourceTree = ""; + }; + 13EF34982E7DF7E000F2EE87 /* Frameworks */ = { + isa = PBXGroup; + children = ( + A906D2272EA80285007DC512 /* Foundation.framework */, + 13EF34992E7DF7E000F2EE87 /* TestLibraryB.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 13EF34322E7DF58A00F2EE87 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 13EF34362E7DF58A00F2EE87 /* TestLibraryA */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13EF343D2E7DF58A00F2EE87 /* Build configuration list for PBXNativeTarget "TestLibraryA" */; + buildPhases = ( + 13EF34322E7DF58A00F2EE87 /* Headers */, + 13EF34332E7DF58A00F2EE87 /* Sources */, + 13EF34342E7DF58A00F2EE87 /* Frameworks */, + 13EF34352E7DF58A00F2EE87 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 13EF34392E7DF58A00F2EE87 /* TestLibraryA */, + ); + name = TestLibraryA; + packageProductDependencies = ( + ); + productName = TestLibraryA; + productReference = 13EF34372E7DF58A00F2EE87 /* TestLibraryA.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 13EF342E2E7DF58A00F2EE87 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 2600; + TargetAttributes = { + 13EF34362E7DF58A00F2EE87 = { + CreatedOnToolsVersion = 16.1; + }; + }; + }; + buildConfigurationList = 13EF34312E7DF58A00F2EE87 /* Build configuration list for PBXProject "TestLibraryA" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 13EF342D2E7DF58A00F2EE87; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 13EF34382E7DF58A00F2EE87 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 13EF34362E7DF58A00F2EE87 /* TestLibraryA */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 13EF34352E7DF58A00F2EE87 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 13EF34332E7DF58A00F2EE87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 13EF343E2E7DF58A00F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestLibraryA; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 13EF343F2E7DF58A00F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestLibraryA; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 13EF34402E7DF58A00F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 9EPD44Q626; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 13EF34412E7DF58A00F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 9EPD44Q626; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 13EF34312E7DF58A00F2EE87 /* Build configuration list for PBXProject "TestLibraryA" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF34402E7DF58A00F2EE87 /* Debug */, + 13EF34412E7DF58A00F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 13EF343D2E7DF58A00F2EE87 /* Build configuration list for PBXNativeTarget "TestLibraryA" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF343E2E7DF58A00F2EE87 /* Debug */, + 13EF343F2E7DF58A00F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 13EF342E2E7DF58A00F2EE87 /* Project object */; +} diff --git a/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/TestLibraryA.h b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/TestLibraryA.h new file mode 100644 index 0000000..89fd998 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/TestLibraryA.h @@ -0,0 +1,19 @@ +// +// TestLibraryA.h +// TestLibraryA +// +// Created by Keith Johnson on 9/19/25. +// + +#import + +//! Project version number for TestLibraryA. +FOUNDATION_EXPORT double TestLibraryAVersionNumber; + +//! Project version string for TestLibraryA. +FOUNDATION_EXPORT const unsigned char TestLibraryAVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import +#import diff --git a/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.h b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.h new file mode 100644 index 0000000..a61f46f --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.h @@ -0,0 +1,17 @@ +// +// VersionPrinter.h +// TestLibraryA +// +// Created by David Dresser on 10/21/25. +// + +#ifndef VersionPrinter_h +#define VersionPrinter_h + +#import + +@interface VersionPrinter : NSObject ++ (void)printVersionInfo; +@end + +#endif /* VersionPrinter_h */ diff --git a/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.m b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.m new file mode 100644 index 0000000..e48f687 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryA/TestLibraryA/VersionPrinter.m @@ -0,0 +1,19 @@ +// +// VersionPrinter.m +// TestLibraryA +// +// Created by David Dresser on 10/21/25. +// + +#import "VersionPrinter.h" +#import "TestLibraryA.h" + +@implementation VersionPrinter ++ (void)printVersionInfo { + NSLog(@"Version Number: %f", TestLibraryAVersionNumber); + NSLog(@"Version String: %s", TestLibraryAVersionString); + + NSLog(@"Test LibraryB Version Info"); + [VersionPrinterB printVersionInfoB]; +} +@end diff --git a/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.pbxproj b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.pbxproj new file mode 100644 index 0000000..85daf08 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.pbxproj @@ -0,0 +1,436 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 13EF34A92E7DF8A500F2EE87 /* NetworkStatus in Frameworks */ = {isa = PBXBuildFile; productRef = 13EF34A82E7DF8A500F2EE87 /* NetworkStatus */; }; + A906D2262EA80241007DC512 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A906D2252EA80241007DC512 /* Foundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 13EF347F2E7DF7A900F2EE87 /* TestLibraryB.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TestLibraryB.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A906D2252EA80241007DC512 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 13EF34842E7DF7A900F2EE87 /* Exceptions for "TestLibraryB" folder in "TestLibraryB" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + publicHeaders = ( + TestLibraryB.h, + VersionPrinterB.h, + ); + target = 13EF347E2E7DF7A900F2EE87 /* TestLibraryB */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 13EF34812E7DF7A900F2EE87 /* TestLibraryB */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 13EF34842E7DF7A900F2EE87 /* Exceptions for "TestLibraryB" folder in "TestLibraryB" target */, + ); + path = TestLibraryB; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 13EF347C2E7DF7A900F2EE87 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A906D2262EA80241007DC512 /* Foundation.framework in Frameworks */, + 13EF34A92E7DF8A500F2EE87 /* NetworkStatus in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 13EF34752E7DF7A900F2EE87 = { + isa = PBXGroup; + children = ( + 13EF34812E7DF7A900F2EE87 /* TestLibraryB */, + A906D2242EA80241007DC512 /* Frameworks */, + 13EF34802E7DF7A900F2EE87 /* Products */, + ); + sourceTree = ""; + }; + 13EF34802E7DF7A900F2EE87 /* Products */ = { + isa = PBXGroup; + children = ( + 13EF347F2E7DF7A900F2EE87 /* TestLibraryB.framework */, + ); + name = Products; + sourceTree = ""; + }; + A906D2242EA80241007DC512 /* Frameworks */ = { + isa = PBXGroup; + children = ( + A906D2252EA80241007DC512 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 13EF347A2E7DF7A900F2EE87 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 13EF347E2E7DF7A900F2EE87 /* TestLibraryB */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13EF34852E7DF7A900F2EE87 /* Build configuration list for PBXNativeTarget "TestLibraryB" */; + buildPhases = ( + 13EF347A2E7DF7A900F2EE87 /* Headers */, + 13EF347B2E7DF7A900F2EE87 /* Sources */, + 13EF347C2E7DF7A900F2EE87 /* Frameworks */, + 13EF347D2E7DF7A900F2EE87 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 13EF34812E7DF7A900F2EE87 /* TestLibraryB */, + ); + name = TestLibraryB; + packageProductDependencies = ( + 13EF34A22E7DF8A500F2EE87 /* BaggagePropagationProcessor */, + 13EF34A42E7DF8A500F2EE87 /* InMemoryExporter */, + 13EF34A62E7DF8A500F2EE87 /* JaegerExporter */, + 13EF34A82E7DF8A500F2EE87 /* NetworkStatus */, + 13EF34AA2E7DF8A500F2EE87 /* OTelSwiftLog */, + ); + productName = TestLibraryB; + productReference = 13EF347F2E7DF7A900F2EE87 /* TestLibraryB.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 13EF34762E7DF7A900F2EE87 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1610; + TargetAttributes = { + 13EF347E2E7DF7A900F2EE87 = { + CreatedOnToolsVersion = 16.1; + }; + }; + }; + buildConfigurationList = 13EF34792E7DF7A900F2EE87 /* Build configuration list for PBXProject "TestLibraryB" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 13EF34752E7DF7A900F2EE87; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + 13EF34A12E7DF8A500F2EE87 /* XCRemoteSwiftPackageReference "opentelemetry-swift" */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = 13EF34802E7DF7A900F2EE87 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 13EF347E2E7DF7A900F2EE87 /* TestLibraryB */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 13EF347D2E7DF7A900F2EE87 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 13EF347B2E7DF7A900F2EE87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 13EF34862E7DF7A900F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9EPD44Q626; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestLibraryB; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 13EF34872E7DF7A900F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9EPD44Q626; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestLibraryB; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 13EF34882E7DF7A900F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 13EF34892E7DF7A900F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 13EF34792E7DF7A900F2EE87 /* Build configuration list for PBXProject "TestLibraryB" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF34882E7DF7A900F2EE87 /* Debug */, + 13EF34892E7DF7A900F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 13EF34852E7DF7A900F2EE87 /* Build configuration list for PBXNativeTarget "TestLibraryB" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF34862E7DF7A900F2EE87 /* Debug */, + 13EF34872E7DF7A900F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 13EF34A12E7DF8A500F2EE87 /* XCRemoteSwiftPackageReference "opentelemetry-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/open-telemetry/opentelemetry-swift"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.1.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 13EF34A22E7DF8A500F2EE87 /* BaggagePropagationProcessor */ = { + isa = XCSwiftPackageProductDependency; + package = 13EF34A12E7DF8A500F2EE87 /* XCRemoteSwiftPackageReference "opentelemetry-swift" */; + productName = BaggagePropagationProcessor; + }; + 13EF34A42E7DF8A500F2EE87 /* InMemoryExporter */ = { + isa = XCSwiftPackageProductDependency; + package = 13EF34A12E7DF8A500F2EE87 /* XCRemoteSwiftPackageReference "opentelemetry-swift" */; + productName = InMemoryExporter; + }; + 13EF34A62E7DF8A500F2EE87 /* JaegerExporter */ = { + isa = XCSwiftPackageProductDependency; + package = 13EF34A12E7DF8A500F2EE87 /* XCRemoteSwiftPackageReference "opentelemetry-swift" */; + productName = JaegerExporter; + }; + 13EF34A82E7DF8A500F2EE87 /* NetworkStatus */ = { + isa = XCSwiftPackageProductDependency; + package = 13EF34A12E7DF8A500F2EE87 /* XCRemoteSwiftPackageReference "opentelemetry-swift" */; + productName = NetworkStatus; + }; + 13EF34AA2E7DF8A500F2EE87 /* OTelSwiftLog */ = { + isa = XCSwiftPackageProductDependency; + package = 13EF34A12E7DF8A500F2EE87 /* XCRemoteSwiftPackageReference "opentelemetry-swift" */; + productName = OTelSwiftLog; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 13EF34762E7DF7A900F2EE87 /* Project object */; +} diff --git a/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/TestLibraryB.h b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/TestLibraryB.h new file mode 100644 index 0000000..67d8eeb --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/TestLibraryB.h @@ -0,0 +1,18 @@ +// +// TestLibraryB.h +// TestLibraryB +// +// Created by Keith Johnson on 9/19/25. +// + +#import + +//! Project version number for TestLibraryB. +FOUNDATION_EXPORT double TestLibraryBVersionNumber; + +//! Project version string for TestLibraryB. +FOUNDATION_EXPORT const unsigned char TestLibraryBVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import diff --git a/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.h b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.h new file mode 100644 index 0000000..b18f691 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.h @@ -0,0 +1,17 @@ +// +// VersionPrinter.h +// TestLibraryA +// +// Created by David Dresser on 10/21/25. +// + +#ifndef VersionPrinterB_h +#define VersionPrinterB_h + +#import + +@interface VersionPrinterB : NSObject ++ (void)printVersionInfoB; +@end + +#endif /* VersionPrinter_h */ diff --git a/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.m b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.m new file mode 100644 index 0000000..7cbcbf5 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryB/TestLibraryB/VersionPrinterB.m @@ -0,0 +1,16 @@ +// +// VersionPrinter.m +// TestLibraryB +// +// Created by David Dresser on 10/21/25. +// + +#import "VersionPrinterB.h" +#import "TestLibraryB.h" + +@implementation VersionPrinterB ++ (void)printVersionInfoB { + NSLog(@"Version Number: %f", TestLibraryBVersionNumber); + NSLog(@"Version String: %s", TestLibraryBVersionString); +} +@end diff --git a/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.pbxproj b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7eb9f8d --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.pbxproj @@ -0,0 +1,372 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXFileReference section */ + 13EF34B72E81D31800F2EE87 /* TestLibraryC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TestLibraryC.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 13EF34BC2E81D31800F2EE87 /* Exceptions for "TestLibraryC" folder in "TestLibraryC" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + publicHeaders = ( + TestLibraryC.h, + VersionPrinterC.h, + ); + target = 13EF34B62E81D31800F2EE87 /* TestLibraryC */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 13EF34B92E81D31800F2EE87 /* TestLibraryC */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 13EF34BC2E81D31800F2EE87 /* Exceptions for "TestLibraryC" folder in "TestLibraryC" target */, + ); + path = TestLibraryC; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 13EF34B42E81D31800F2EE87 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 13EF34AD2E81D31800F2EE87 = { + isa = PBXGroup; + children = ( + 13EF34B92E81D31800F2EE87 /* TestLibraryC */, + 13EF34B82E81D31800F2EE87 /* Products */, + ); + sourceTree = ""; + }; + 13EF34B82E81D31800F2EE87 /* Products */ = { + isa = PBXGroup; + children = ( + 13EF34B72E81D31800F2EE87 /* TestLibraryC.framework */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 13EF34B22E81D31800F2EE87 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 13EF34B62E81D31800F2EE87 /* TestLibraryC */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13EF34BD2E81D31800F2EE87 /* Build configuration list for PBXNativeTarget "TestLibraryC" */; + buildPhases = ( + 13EF34B22E81D31800F2EE87 /* Headers */, + 13EF34B32E81D31800F2EE87 /* Sources */, + 13EF34B42E81D31800F2EE87 /* Frameworks */, + 13EF34B52E81D31800F2EE87 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 13EF34B92E81D31800F2EE87 /* TestLibraryC */, + ); + name = TestLibraryC; + packageProductDependencies = ( + ); + productName = TestLibraryC; + productReference = 13EF34B72E81D31800F2EE87 /* TestLibraryC.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 13EF34AE2E81D31800F2EE87 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1610; + TargetAttributes = { + 13EF34B62E81D31800F2EE87 = { + CreatedOnToolsVersion = 16.1; + }; + }; + }; + buildConfigurationList = 13EF34B12E81D31800F2EE87 /* Build configuration list for PBXProject "TestLibraryC" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 13EF34AD2E81D31800F2EE87; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 13EF34B82E81D31800F2EE87 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 13EF34B62E81D31800F2EE87 /* TestLibraryC */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 13EF34B52E81D31800F2EE87 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 13EF34B32E81D31800F2EE87 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 13EF34BE2E81D31800F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9EPD44Q626; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestLibraryC; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 13EF34BF2E81D31800F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9EPD44Q626; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.epic.keijohns.sizing.TestLibraryC; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 13EF34C02E81D31800F2EE87 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 13EF34C12E81D31800F2EE87 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 13EF34B12E81D31800F2EE87 /* Build configuration list for PBXProject "TestLibraryC" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF34C02E81D31800F2EE87 /* Debug */, + 13EF34C12E81D31800F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 13EF34BD2E81D31800F2EE87 /* Build configuration list for PBXNativeTarget "TestLibraryC" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13EF34BE2E81D31800F2EE87 /* Debug */, + 13EF34BF2E81D31800F2EE87 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 13EF34AE2E81D31800F2EE87 /* Project object */; +} diff --git a/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/TestLibraryC.h b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/TestLibraryC.h new file mode 100644 index 0000000..a63577e --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/TestLibraryC.h @@ -0,0 +1,19 @@ +// +// TestLibraryC.h +// TestLibraryC +// +// Created by Keith Johnson on 9/22/25. +// + +#import + +//! Project version number for TestLibraryC. +FOUNDATION_EXPORT double TestLibraryCVersionNumber; + +//! Project version string for TestLibraryC. +FOUNDATION_EXPORT const unsigned char TestLibraryCVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import + diff --git a/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.h b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.h new file mode 100644 index 0000000..3908a39 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.h @@ -0,0 +1,15 @@ +// +// VersionPrinterC.h +// TestLibraryC +// +// Created by David Dresser on 10/21/25. +// + +#ifndef VersionPrinterC_h +#define VersionPrinterC_h + +@interface VersionPrinterC : NSObject ++ (void)printVersionInfoC; +@end + +#endif /* VersionPrinterC_h */ diff --git a/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.m b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.m new file mode 100644 index 0000000..d3ac047 --- /dev/null +++ b/TestAssets/DependencyChaseFilter/TestLibraryC/TestLibraryC/VersionPrinterC.m @@ -0,0 +1,17 @@ +// +// VersionPrinterC.m +// TestLibraryC +// +// Created by David Dresser on 10/21/25. +// + +#import +#import "VersionPrinterC.h" +#import "TestLibraryC.h" + +@implementation VersionPrinterC ++ (void)printVersionInfoC { + NSLog(@"Version Number TestLibraryC: %f", TestLibraryCVersionNumber); + NSLog(@"Version String TestLibraryC: %s", TestLibraryCVersionString); +} +@end diff --git a/Tests/GenIRTests/DependencyChaseFilterTests.swift b/Tests/GenIRTests/DependencyChaseFilterTests.swift new file mode 100644 index 0000000..93fc94e --- /dev/null +++ b/Tests/GenIRTests/DependencyChaseFilterTests.swift @@ -0,0 +1,44 @@ +import XCTest +@testable import gen_ir + +final class DependencyChaseFilterTests: XCTestCase { + let testPath: URL = { + TestContext.testAssetPath + .appendingPathComponent("DependencyChaseFilter") + .appendingPathComponent("TestApp77.xcworkspace") + }() + let scheme = "TestApp77" + + func testDependencyChaseFilter() throws { + let context = TestContext() + try context.build(test: testPath, scheme: scheme) + + var runner = IREmitterCommand() + try runner.run( + log: context.buildLog.filePath, + archive: context.archive, + level: .debug, + dryRun: false, + dumpDependencyGraph: false + ) + + // Verify that the dependency chase filter worked as expected + // Root of the IR should have 4 directories + let irPath = context.archive.appendingPathComponent("IR") + let files = try FileManager.default.contentsOfDirectory(at: irPath, includingPropertiesForKeys: [.isDirectoryKey], options: []) + XCTAssertEqual(files.count, 4, "DependencyChaseFilterTests: Expected 4 IR directories to be generated") + + // Validate the contents of each root directory in the IR folder. + try validateDirContents(context: context, dirName: "TestApp77.app", expectedCount: 4) + try validateDirContents(context: context, dirName: "TestLibraryA.framework", expectedCount: 3) + try validateDirContents(context: context, dirName: "TestLibraryB.framework", expectedCount: 368) + try validateDirContents(context: context, dirName: "TestLibraryC.framework", expectedCount: 3) + } + + private func validateDirContents(context: TestContext, dirName: String, expectedCount: Int) throws { + // dirName should have expectedCount files + let libPath = context.archive.appendingPathComponent("IR").appendingPathComponent(dirName) + let files = try FileManager.default.contentsOfDirectory(at: libPath, includingPropertiesForKeys: nil) + XCTAssertEqual(files.count, expectedCount, "DependencyChaseFilterTests: Expected \(expectedCount) \(dirName) files to be generated") + } +} diff --git a/Tests/GenIRTests/WorkspaceTests.swift b/Tests/GenIRTests/WorkspaceTests.swift index 2ae6cfd..f660b8f 100644 --- a/Tests/GenIRTests/WorkspaceTests.swift +++ b/Tests/GenIRTests/WorkspaceTests.swift @@ -15,6 +15,7 @@ final class WorkspaceTests: XCTestCase { static let frameworkIRFiles: Set = ["Framework.bc", "Framework_vers.bc"] static let sfSafeSymbolsIRFiles: Set = [ "NSImageExtension.bc", + "savedDependencies.json", "SFSymbol+1.0.bc", "SFSymbol+1.1.bc", "SFSymbol+2.0.bc", From b8ecdc06da88bda2978dd5049777c9043813dae6 Mon Sep 17 00:00:00 2001 From: davdres Date: Mon, 22 Dec 2025 07:00:52 -0800 Subject: [PATCH 23/24] SSAST-13151 Use info logging to give user a progress indication. (#99) --- Sources/GenIR/CompilerCommandRunner.swift | 2 +- Sources/GenIR/GenIR.swift | 3 ++- Sources/GenIR/Versions.swift | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Sources/GenIR/CompilerCommandRunner.swift b/Sources/GenIR/CompilerCommandRunner.swift index dc453de..bf2148f 100644 --- a/Sources/GenIR/CompilerCommandRunner.swift +++ b/Sources/GenIR/CompilerCommandRunner.swift @@ -65,7 +65,7 @@ struct CompilerCommandRunner { continue } - GenIRLogger.logger.debug("Operating on target: \(target.name). Total modules processed: \(totalModulesRun)") + GenIRLogger.logger.info("Operating on target: \(target.name). Total modules processed: \(totalModulesRun)") totalModulesRun += try run(commands: targetCommands, for: target.productName, at: output) } diff --git a/Sources/GenIR/GenIR.swift b/Sources/GenIR/GenIR.swift index 10d7fe7..fc3cdbd 100644 --- a/Sources/GenIR/GenIR.swift +++ b/Sources/GenIR/GenIR.swift @@ -213,6 +213,7 @@ struct DebuggingOptions: ParsableArguments { let output = archive.appendingPathComponent("IR") let log = try logParser(for: log) + GenIRLogger.logger.info("Processing the xcodebuild log.") try log.parse() // Find and parse the PIF cache @@ -250,7 +251,7 @@ struct DebuggingOptions: ParsableArguments { buildCacheManipulator: buildCacheManipulator, dryRun: dryRun ) - GenIRLogger.logger.debug("Targets to run: \(targets.count)") + GenIRLogger.logger.info("Targets to process: \(targets.count)") try runner.run(targets: targets, commands: targetCommands) let postprocessor = try OutputPostprocessor( diff --git a/Sources/GenIR/Versions.swift b/Sources/GenIR/Versions.swift index e41a483..8c75e08 100644 --- a/Sources/GenIR/Versions.swift +++ b/Sources/GenIR/Versions.swift @@ -5,7 +5,8 @@ // Created by Thomas Hedderwick on 12/09/2022. // // History: -// 2025-nn-nn - 1.0.0 -- Don't chase through Dynamic Dependencies +// 2025-nn-nn - 1.0.1 -- Use info logging to allow user to monitor progress. +// 2025-12-01 - 1.0.0 -- Don't chase through Dynamic Dependencies // 2025-09-19 - 0.5.4 -- Update release doc; warn multiple builds; capture debug data // 2025-04-18 - 0.5.3 -- PIF Tracing; log unique compiler commands // 2025-04-09 - 0.5.2 -- PIF sort workspace; log instead of throw @@ -14,5 +15,5 @@ import Foundation enum Versions { - static let version = "1.0.0" + static let version = "1.0.1" } From 52bef87300ad335f27474ebf619c793df7daa01e Mon Sep 17 00:00:00 2001 From: davdres Date: Mon, 5 Jan 2026 11:26:46 -0800 Subject: [PATCH 24/24] Release/1.0.1 (#101) * Release/0.5.2 (#87) * Issue #81 log unrequired targets instead of failing. * Issue #81 PIF workspace sort * Release/0.5.3 (#89) ENG-55520 * On sourceTree decode error, log & continue * SourceTree: refactor to class * Release/0.5.4 (#95) * Handle targets with same name but in different projects * Issue #81 log unrequired targets instead of failing. * Issue #81 log PIF location & missing commands. * Issue #81 PIF workspace sort * Issue #81 Update version; add some logging Co-authored-by: NinjaLikesCheez * Update PIF/Sources/PIFSupport/PIFSupport.swift Co-authored-by: NinjaLikesCheez * Issue #81 Address linter & review issues. * Issue #81 Test unwrap of optional pif cache location. * ENG-55520: On sourceTree decode error, log & continue (#88) ENG-55520 * On sourceTree decode error, log & continue * SourceTree: refactor to class * SENG-9588 remove development release (#90) * SENG-9588 remove development release * SSAST-10500 Warn if multiple builds in xcode log (#91) * SSAST-10519 Add option to capture debug data (#92) A --capture option has been added to collect diagnostic data into a debug-data sub-folder of the IR directory. What data has been captured is written to the Gen-IR log. * SSAST-10900 Update help for debug data capture. (#93) * SSAST-11687 fix type fixing merge conflicts * SSAST-11687 fix swiftlint error-no error locally * Update build.yml Update to match my local version. The tests run locally. --------- Co-authored-by: bmxav <5422569+bmxav@users.noreply.github.com> Co-authored-by: NinjaLikesCheez * Release/1.0.0 (#98) * Handle targets with same name but in different projects * Ignore test bundles when generating bitcode * Issue #81 log unrequired targets instead of failing. * Issue #81 PIF workspace sort ENG-55520 * On sourceTree decode error, log & continue * SourceTree: refactor to class * SENG-9588 remove development release * SSAST-10500 Warn if multiple builds in xcode log (#91) * SSAST-10519 A --capture option has been added to collect diagnostic data into a debug-data sub-folder of the IR directory. What data has been captured is written to the Gen-IR log. * Install instructions cannot be executed as is, improve install instructions to make them executable * Feature/ssast 10888 (#96) * SSAST-10888 don't copy dependent modules but save them for pp to reconstruct. --------- Co-authored-by: bmxav <5422569+bmxav@users.noreply.github.com> Co-authored-by: NinjaLikesCheez Co-authored-by: Boy Baukema --------- Co-authored-by: Bryan Xavier <5422569+bmxav@users.noreply.github.com> Co-authored-by: NinjaLikesCheez Co-authored-by: Boy Baukema