From 6cf282c51e6ceb2bbcaef07ae99e32d5b12bdcc2 Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Mon, 27 May 2024 14:40:47 +0200 Subject: [PATCH] Add support for CMake builds These have different PIF cache locations in the build cache --- Sources/GenIR/BuildCacheManipulator.swift | 1 + .../GenIR/Extensions/Process+Extension.swift | 13 +++- Sources/GenIR/PIFCache.swift | 25 +++----- Sources/GenIR/XcodeLogParser.swift | 27 ++++++--- TestAssets/CMakeDiscoveryTest/CMakeLists.txt | 60 +++++++++++++++++++ .../CMakeDiscoveryTest/Source/App.swift | 10 ++++ Tests/GenIRTests/CMakeDiscoveryTests.swift | 54 +++++++++++++++++ Tests/GenIRTests/DependencyGraphTests.swift | 10 ++-- 8 files changed, 168 insertions(+), 32 deletions(-) create mode 100644 TestAssets/CMakeDiscoveryTest/CMakeLists.txt create mode 100644 TestAssets/CMakeDiscoveryTest/Source/App.swift create mode 100644 Tests/GenIRTests/CMakeDiscoveryTests.swift diff --git a/Sources/GenIR/BuildCacheManipulator.swift b/Sources/GenIR/BuildCacheManipulator.swift index b9a2e7a..43501db 100644 --- a/Sources/GenIR/BuildCacheManipulator.swift +++ b/Sources/GenIR/BuildCacheManipulator.swift @@ -38,6 +38,7 @@ struct BuildCacheManipulator { func manipulate() throws { if shouldDeploySkipInstallHack { let intermediatesPath = buildCachePath + .appendingPathComponent("Build") .appendingPathComponent("Intermediates.noindex") .appendingPathComponent("ArchiveIntermediates") diff --git a/Sources/GenIR/Extensions/Process+Extension.swift b/Sources/GenIR/Extensions/Process+Extension.swift index a5df895..7de2e80 100644 --- a/Sources/GenIR/Extensions/Process+Extension.swift +++ b/Sources/GenIR/Extensions/Process+Extension.swift @@ -54,7 +54,16 @@ extension Process { let process = Process() - let executable = command.replacingOccurrences(of: "\\", with: "") + let executable: String + let args: [String] + + if command.starts(with: ".") || command.starts(with: "/") { + executable = command.replacingOccurrences(of: "\\", with: "") + args = arguments + } else { + executable = "/usr/bin/env" + args = [command] + arguments + } if #available(macOS 10.13, *) { process.executableURL = executable.fileURL @@ -62,7 +71,7 @@ extension Process { process.launchPath = executable } - process.arguments = arguments.map { $0.replacingOccurrences(of: "\\", with: "") } + process.arguments = args.map { $0.replacingOccurrences(of: "\\", with: "") } process.standardOutput = stdoutPipe process.standardError = stderrPipe process.standardInput = FileHandle.nullDevice diff --git a/Sources/GenIR/PIFCache.swift b/Sources/GenIR/PIFCache.swift index 449b4e5..3325c3a 100644 --- a/Sources/GenIR/PIFCache.swift +++ b/Sources/GenIR/PIFCache.swift @@ -2,7 +2,6 @@ import Foundation import PIFSupport class PIFCache { - private let buildCache: URL private let pifCachePath: URL private let workspace: PIF.Workspace @@ -22,7 +21,6 @@ class PIFCache { } init(buildCache: URL) throws { - self.buildCache = buildCache self.pifCachePath = try Self.pifCachePath(in: buildCache) do { @@ -34,13 +32,12 @@ class PIFCache { } private static func pifCachePath(in buildCache: URL) throws -> URL { - // TODO: test this variation, because I haven't seen this personally let cmakePIFCachePath = buildCache - .deletingLastPathComponent() .appendingPathComponent("XCBuildData") .appendingPathComponent("PIFCache") let regularPIFCachePath = buildCache + .appendingPathComponent("Build") .appendingPathComponent("Intermediates.noindex") .appendingPathComponent("XCBuildData") .appendingPathComponent("PIFCache") @@ -111,12 +108,10 @@ extension PIF.BaseTarget: Hashable { } struct PIFDependencyProvider: DependencyProviding { - private let targets: [Target] private let cache: PIFCache private var guidToTargets: [PIF.GUID: Target] init(targets: [Target], cache: PIFCache) { - self.targets = targets self.cache = cache self.guidToTargets = targets @@ -168,24 +163,20 @@ struct PIFDependencyProvider: DependencyProviding { .compactMap { resolveSwiftPackage($0) } // Framework build phase dependencies - let frameworkBuildPhases = value + // NOTE: Previously we just cast this - all of a sudden with pods this is broken + // Not the end of the world - just as quick to do a dictionary lookup + let frameworkGUIDs = value .baseTarget .buildPhases - .compactMap { $0 as? PIF.FrameworksBuildPhase } - - let referenceGUIDs = frameworkBuildPhases .flatMap { $0.buildFiles } + // .compactMap { $0 as? PIF.FrameworksBuildPhase } .compactMap { switch $0.reference { - case .file(let guid): return guid - case .target: return nil // TODO: is this fine? I think so since we're looking for .framework file references here not targets which should be a dependency + case let .file(guid): return guid + case .target: return nil } } - - let frameworkGUIDs = referenceGUIDs - .compactMap { - cache.frameworks[$0]?.guid - } + .compactMap { cache.frameworks[$0]?.guid } let dependencyTargets = (dependencyTargetGUIDs + frameworkGUIDs).compactMap { guidToTargets[$0] } diff --git a/Sources/GenIR/XcodeLogParser.swift b/Sources/GenIR/XcodeLogParser.swift index ced8b74..2d2f0cb 100644 --- a/Sources/GenIR/XcodeLogParser.swift +++ b/Sources/GenIR/XcodeLogParser.swift @@ -92,14 +92,25 @@ class XcodeLogParser { guard let startIndex = line.firstIndex(of: ":") else { continue } let stripped = line[line.index(after: startIndex)..