in Sources/XCRemoteCache/Commands/Swiftc/Swiftc.swift [93:200]
func mockCompilation() throws -> SwiftCResult {
let rcModeEnabled = markerReader.canRead()
guard rcModeEnabled else {
infoLog("Swiftc marker doesn't exist")
return .forceFallback
}
let inputFilesInputs = try inputFileListReader.listFilesURLs()
let markerAllowedFiles = try markerReader.listFilesURLs()
let allDependencies = Set(markerAllowedFiles + inputFilesInputs)
let cachedDependenciesWriterFactory = CachedFileDependenciesWriterFactory(
dependencies: Array(allDependencies),
fileManager: fileManager,
writerFactory: dependenciesWriterFactory
)
// Verify all input files to be present in a marker fileList
let disallowedInputs = try inputFilesInputs.filter { file in
try !allowedFilesListScanner.contains(file) &&
!allowedInputDeterminer.allowedNonDependencyInput(file: file)
}
if !disallowedInputs.isEmpty {
// New file (disallowedFile) added without modifying the rest of the feature. Fallback to swiftc and
// ensure that compilation from source will be forced up until next merge/rebase with "primary" branch
infoLog("Swiftc new input file \(disallowedInputs)")
// Deleting marker to indicate that the remote cached artifact cannot be used
try markerWriter.disable()
// Save custom prebuild discovery content to make sure that the following prebuild
// phase will not try to reuse cached artifact (if present)
// In other words: let prebuild know that it should not try to reenable cache
// until the next merge with primary
switch context.mode {
case .consumer(commit: .available(let remoteCommit)):
let prebuildDiscoveryURL = context.tempDir.appendingPathComponent(context.prebuildDependenciesPath)
let prebuildDiscoverWriter = dependenciesWriterFactory(prebuildDiscoveryURL, fileManager)
try prebuildDiscoverWriter.write(skipForSha: remoteCommit)
case .consumer, .producer, .producerFast:
// Never skip prebuild phase and fallback to the swiftc compilation for:
// 1) Not enabled remote cache, 2) producer(s)
break
}
return .forceFallback
}
let artifactLocation = artifactOrganizer.getActiveArtifactLocation()
// Read swiftmodule location from XCRemoteCache
// arbitrary format swiftmodule/${arch}/${moduleName}.swift{module|doc|sourceinfo}
let moduleName = context.moduleName
let allCompilations = try inputFilesReader.read()
let artifactSwiftmoduleDir = artifactLocation
.appendingPathComponent("swiftmodule")
.appendingPathComponent(context.arch)
let artifactSwiftmoduleBase = artifactSwiftmoduleDir.appendingPathComponent(moduleName)
let artifactSwiftmoduleFiles = Dictionary(
uniqueKeysWithValues: SwiftmoduleFileExtension.SwiftmoduleExtensions
.map { ext, _ in
(ext, artifactSwiftmoduleBase.appendingPathExtension(ext.rawValue))
}
)
// emit module (if requested)
if let emitModule = context.steps.emitModule {
// Build -Swift.h location from XCRemoteCache arbitrary format include/${arch}/${target}-Swift.h
let artifactSwiftModuleObjCDir = artifactLocation
.appendingPathComponent("include")
.appendingPathComponent(context.arch)
.appendingPathComponent(context.moduleName)
// Move cached xxxx-Swift.h to the location passed in arglist
// Alternatively, artifactSwiftModuleObjCFile could be built as a first .h
// file in artifactSwiftModuleObjCDir
let artifactSwiftModuleObjCFile = artifactSwiftModuleObjCDir
.appendingPathComponent(emitModule.objcHeaderOutput.lastPathComponent)
_ = try productsGenerator.generateFrom(
artifactSwiftModuleFiles: artifactSwiftmoduleFiles,
artifactSwiftModuleObjCFile: artifactSwiftModuleObjCFile
)
}
try plugins.forEach {
try $0.generate(for: allCompilations)
}
// Save individual .d and touch .o for each .swift file
for compilation in allCompilations.files {
if let object = compilation.object {
// Touching .o is required to invalidate already existing .a or linked library
let touch = touchFactory(object, fileManager)
try touch.touch()
}
if let individualDeps = compilation.dependencies {
// swiftc product should be invalidated if any of dependencies file has changed
try cachedDependenciesWriterFactory.generate(output: individualDeps)
}
}
// Save .d for the entire module (might not be required in the `swift-frontend -c` mode)
if let swiftDependencies = allCompilations.info.swiftDependencies {
try cachedDependenciesWriterFactory.generate(output: swiftDependencies)
}
// Generate .d file with all deps in the "-master.d" (e.g. for WMO)
if let wmoDeps = allCompilations.info.dependencies {
try cachedDependenciesWriterFactory.generate(output: wmoDeps)
}
infoLog("Swiftc noop for \(context.target)")
return .success
}