From c0084468f6dc2e6964ce6fa5acd066a797b86b84 Mon Sep 17 00:00:00 2001 From: Zixu Wang Date: Tue, 31 Oct 2023 18:24:53 -0700 Subject: [PATCH 1/2] Add support for automatically emit API descriptor files --- Sources/SwiftDriver/Driver/Driver.swift | 28 ++++-- Tests/SwiftDriverTests/SwiftDriverTests.swift | 92 +++++++++++++++---- 2 files changed, 95 insertions(+), 25 deletions(-) diff --git a/Sources/SwiftDriver/Driver/Driver.swift b/Sources/SwiftDriver/Driver/Driver.swift index 642910ab5..b5cff7c62 100644 --- a/Sources/SwiftDriver/Driver/Driver.swift +++ b/Sources/SwiftDriver/Driver/Driver.swift @@ -957,14 +957,26 @@ public struct Driver { outputFileMap: self.outputFileMap, moduleName: moduleOutputInfo.name) - self.apiDescriptorFilePath = try Self.computeSupplementaryOutputPath( - &parsedOptions, type: .jsonAPIDescriptor, isOutputOptions: [], - outputPath: .emitApiDescriptorPath, - compilerOutputType: compilerOutputType, - compilerMode: compilerMode, - emitModuleSeparately: emitModuleSeparately, - outputFileMap: self.outputFileMap, - moduleName: moduleOutputInfo.name) + let apiDescriptorDirectory: VirtualPath? = if let apiDescriptorDirectoryEnvVar = env["TAPI_SDKDB_OUTPUT_PATH"] { + try VirtualPath(path: apiDescriptorDirectoryEnvVar) + } else if let ldTraceFileEnvVar = env["LD_TRACE_FILE"] { + try VirtualPath(path: ldTraceFileEnvVar).parentDirectory.appending(component: "SDKDB") + } else { nil } + + if let apiDescriptorDirectory { + self.apiDescriptorFilePath = apiDescriptorDirectory + .appending(component: "\(moduleOutputInfo.name).\(frontendTargetInfo.target.moduleTriple.triple).swift.sdkdb") + .intern() + } else { + self.apiDescriptorFilePath = try Self.computeSupplementaryOutputPath( + &parsedOptions, type: .jsonAPIDescriptor, isOutputOptions: [], + outputPath: .emitApiDescriptorPath, + compilerOutputType: compilerOutputType, + compilerMode: compilerMode, + emitModuleSeparately: emitModuleSeparately, + outputFileMap: self.outputFileMap, + moduleName: moduleOutputInfo.name) + } Self.validateDigesterArgs(&parsedOptions, moduleOutputInfo: moduleOutputInfo, diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index a5af8471d..c740e53ce 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7219,30 +7219,88 @@ final class SwiftDriverTests: XCTestCase { func testEmitAPIDescriptorEmitModule() throws { try withTemporaryDirectory { path in - let apiDescriptorPath = path.appending(component: "api.json").nativePathString(escaped: true) - var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift", - "-emit-module", "-module-name", "Test", - "-emit-api-descriptor-path", apiDescriptorPath]) + do { + let apiDescriptorPath = path.appending(component: "api.json").nativePathString(escaped: true) + var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift", + "-emit-module", "-module-name", "Test", + "-emit-api-descriptor-path", apiDescriptorPath]) - let jobs = try driver.planBuild().removingAutolinkExtractJobs() - let emitModuleJob = try jobs.findJob(.emitModule) - XCTAssert(emitModuleJob.commandLine.contains(.flag("-emit-api-descriptor-path"))) + let jobs = try driver.planBuild().removingAutolinkExtractJobs() + let emitModuleJob = try jobs.findJob(.emitModule) + XCTAssert(emitModuleJob.commandLine.contains(.flag("-emit-api-descriptor-path"))) + } + + do { + var env = ProcessEnv.vars + env["TAPI_SDKDB_OUTPUT_PATH"] = path.appending(component: "SDKDB").nativePathString(escaped: false) + var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift", + "-emit-module", "-module-name", "Test"], env: env) + let jobs = try driver.planBuild().removingAutolinkExtractJobs() + let emitModuleJob = try jobs.findJob(.emitModule) + XCTAssert(emitModuleJob.commandLine.contains(subsequence: [ + .flag("-emit-api-descriptor-path"), + .path(.absolute(path.appending(components: "SDKDB", "Test.\(driver.frontendTargetInfo.target.moduleTriple.triple).swift.sdkdb"))), + ])) + } + + do { + var env = ProcessEnv.vars + env["LD_TRACE_FILE"] = path.appending(component: ".LD_TRACE").nativePathString(escaped: false) + var driver = try Driver(args: ["swiftc", "foo.swift", "bar.swift", "baz.swift", + "-emit-module", "-module-name", "Test"], env: env) + let jobs = try driver.planBuild().removingAutolinkExtractJobs() + let emitModuleJob = try jobs.findJob(.emitModule) + XCTAssert(emitModuleJob.commandLine.contains(subsequence: [ + .flag("-emit-api-descriptor-path"), + .path(.absolute(path.appending(components: "SDKDB", "Test.\(driver.frontendTargetInfo.target.moduleTriple.triple).swift.sdkdb"))), + ])) + } } } func testEmitAPIDescriptorWholeModuleOptimization() throws { try withTemporaryDirectory { path in - let apiDescriptorPath = path.appending(component: "api.json").nativePathString(escaped: true) - var driver = try Driver(args: ["swiftc", "-whole-module-optimization", - "-driver-filelist-threshold=0", - "foo.swift", "bar.swift", "baz.swift", - "-module-name", "Test", "-emit-module", - "-emit-api-descriptor-path", apiDescriptorPath]) + do { + let apiDescriptorPath = path.appending(component: "api.json").nativePathString(escaped: true) + var driver = try Driver(args: ["swiftc", "-whole-module-optimization", + "-driver-filelist-threshold=0", + "foo.swift", "bar.swift", "baz.swift", + "-module-name", "Test", "-emit-module", + "-emit-api-descriptor-path", apiDescriptorPath]) - let jobs = try driver.planBuild().removingAutolinkExtractJobs() - let compileJob = try jobs.findJob(.compile) - let supplementaryOutputs = try XCTUnwrap(compileJob.commandLine.supplementaryOutputFilemap) - XCTAssertNotNil(supplementaryOutputs.entries.values.first?[.jsonAPIDescriptor]) + let jobs = try driver.planBuild().removingAutolinkExtractJobs() + let compileJob = try jobs.findJob(.compile) + let supplementaryOutputs = try XCTUnwrap(compileJob.commandLine.supplementaryOutputFilemap) + XCTAssertNotNil(supplementaryOutputs.entries.values.first?[.jsonAPIDescriptor]) + } + + do { + var env = ProcessEnv.vars + env["TAPI_SDKDB_OUTPUT_PATH"] = path.appending(component: "SDKDB").nativePathString(escaped: false) + var driver = try Driver(args: ["swiftc", "-whole-module-optimization", + "-driver-filelist-threshold=0", + "foo.swift", "bar.swift", "baz.swift", + "-module-name", "Test", "-emit-module"], env: env) + + let jobs = try driver.planBuild().removingAutolinkExtractJobs() + let compileJob = try jobs.findJob(.compile) + let supplementaryOutputs = try XCTUnwrap(compileJob.commandLine.supplementaryOutputFilemap) + XCTAssertNotNil(supplementaryOutputs.entries.values.first?[.jsonAPIDescriptor]) + } + + do { + var env = ProcessEnv.vars + env["LD_TRACE_FILE"] = path.appending(component: ".LD_TRACE").nativePathString(escaped: false) + var driver = try Driver(args: ["swiftc", "-whole-module-optimization", + "-driver-filelist-threshold=0", + "foo.swift", "bar.swift", "baz.swift", + "-module-name", "Test", "-emit-module"], env: env) + + let jobs = try driver.planBuild().removingAutolinkExtractJobs() + let compileJob = try jobs.findJob(.compile) + let supplementaryOutputs = try XCTUnwrap(compileJob.commandLine.supplementaryOutputFilemap) + XCTAssertNotNil(supplementaryOutputs.entries.values.first?[.jsonAPIDescriptor]) + } } } } From 13a3bbf73a4d6aae891891309fba476cf10b87aa Mon Sep 17 00:00:00 2001 From: Zixu Wang Date: Wed, 1 Nov 2023 15:16:21 -0700 Subject: [PATCH 2/2] Refactor to remove new language features for compatibility --- Sources/SwiftDriver/Driver/Driver.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/SwiftDriver/Driver/Driver.swift b/Sources/SwiftDriver/Driver/Driver.swift index b5cff7c62..257932d21 100644 --- a/Sources/SwiftDriver/Driver/Driver.swift +++ b/Sources/SwiftDriver/Driver/Driver.swift @@ -957,13 +957,13 @@ public struct Driver { outputFileMap: self.outputFileMap, moduleName: moduleOutputInfo.name) - let apiDescriptorDirectory: VirtualPath? = if let apiDescriptorDirectoryEnvVar = env["TAPI_SDKDB_OUTPUT_PATH"] { - try VirtualPath(path: apiDescriptorDirectoryEnvVar) + var apiDescriptorDirectory: VirtualPath? = nil + if let apiDescriptorDirectoryEnvVar = env["TAPI_SDKDB_OUTPUT_PATH"] { + apiDescriptorDirectory = try VirtualPath(path: apiDescriptorDirectoryEnvVar) } else if let ldTraceFileEnvVar = env["LD_TRACE_FILE"] { - try VirtualPath(path: ldTraceFileEnvVar).parentDirectory.appending(component: "SDKDB") - } else { nil } - - if let apiDescriptorDirectory { + apiDescriptorDirectory = try VirtualPath(path: ldTraceFileEnvVar).parentDirectory.appending(component: "SDKDB") + } + if let apiDescriptorDirectory = apiDescriptorDirectory { self.apiDescriptorFilePath = apiDescriptorDirectory .appending(component: "\(moduleOutputInfo.name).\(frontendTargetInfo.target.moduleTriple.triple).swift.sdkdb") .intern()