From 9c61dd1201344a361ca78112510cfbb7447cf561 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Wed, 21 Aug 2024 09:36:55 -0700 Subject: [PATCH 1/8] Tests: adjust tests for Darwin The Darwin toolchain is incomplete, missing `swift-autolink-extract`. Add a workaround for the missing tool to allow the tests to pass. This then uncovers another issue with ASi builds where the prebuilt NDK is only available on x86_64 hosts. While we could loosen the NDK lookup, we do still occassionally use some of the tools, so for now lets limit the test to x86_64. Fixes: #1682 --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index d074ceea0..8ed6e93ac 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7932,11 +7932,14 @@ final class SwiftDriverTests: XCTestCase { func testAndroidNDK() throws { try withTemporaryDirectory { path in + var env = ProcessEnv.vars + env["SWIFT_DRIVER_SWIFT_AUTOLINK_EXTRACT_EXEC"] = "/garbage/swift-autolink-extract" + do { let sysroot = path.appending(component: "sysroot") var driver = try Driver(args: [ "swiftc", "-target", "aarch64-unknown-linux-android", "-sysroot", sysroot.pathString, #file - ]) + ], env: env) let jobs = try driver.planBuild().removingAutolinkExtractJobs() let frontend = try XCTUnwrap(jobs.first) XCTAssertTrue(frontend.commandLine.contains(subsequence: [ @@ -7946,7 +7949,7 @@ final class SwiftDriverTests: XCTestCase { } do { - var env = ProcessEnv.vars + var env = env env["ANDROID_NDK_ROOT"] = path.appending(component: "ndk").nativePathString(escaped: false) let sysroot = path.appending(component: "sysroot") @@ -7961,10 +7964,12 @@ final class SwiftDriverTests: XCTestCase { ])) } + // The default NDK prebuilts are x86_64 hosts only currently as if r27. +#if arch(x86_64) do { let sysroot = path.appending(component: "ndk") - var env = ProcessEnv.vars + var env = env env["ANDROID_NDK_ROOT"] = sysroot.nativePathString(escaped: false) #if os(Windows) @@ -7980,11 +7985,13 @@ final class SwiftDriverTests: XCTestCase { ], env: env) let jobs = try driver.planBuild().removingAutolinkExtractJobs() let frontend = try XCTUnwrap(jobs.first) + print(frontend.commandLine) XCTAssertTrue(frontend.commandLine.contains(subsequence: [ .flag("-sysroot"), .path(.absolute(sysroot.appending(components: "toolchains", "llvm", "prebuilt", "\(os)-x86_64", "sysroot"))), ])) } +#endif } } From 088ac1df3ae661db2c9211f3256e2ec884a8bc2c Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Mon, 26 Aug 2024 12:51:32 +0530 Subject: [PATCH 2/8] Android: add the right suffix for the compiler-rt profiler library --- .../Jobs/GenericUnixToolchain+LinkerSupport.swift | 3 ++- Tests/SwiftDriverTests/SwiftDriverTests.swift | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift index 4b4a1bd3f..a774bd52a 100644 --- a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift @@ -285,9 +285,10 @@ extension GenericUnixToolchain { } if parsedOptions.hasArgument(.profileGenerate) { + let environment = (targetTriple.environment == .android) ? "-android" : "" let libProfile = VirtualPath.lookup(targetInfo.runtimeResourcePath.path) .appending(components: "clang", "lib", targetTriple.osName, - "libclang_rt.profile-\(targetTriple.archName).a") + "libclang_rt.profile-\(targetTriple.archName)\(environment).a") commandLine.appendPath(libProfile) // HACK: Hard-coded from llvm::getInstrProfRuntimeHookVarName() diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 8ed6e93ac..130c8534d 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -4416,15 +4416,19 @@ final class SwiftDriverTests: XCTestCase { // FIXME: This will fail when run on macOS, because // swift-autolink-extract is not present #if os(Linux) || os(Android) || os(Windows) - do { - var driver = try Driver(args: ["swiftc", "-profile-generate", "-target", "x86_64-unknown-linux-gnu", "test.swift"]) + for triple in ["aarch64-unknown-linux-android", "x86_64-unknown-linux-gnu"] { + var driver = try Driver(args: ["swiftc", "-profile-generate", "-target", triple, "test.swift"]) let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs() XCTAssertEqual(plannedJobs.count, 2) XCTAssertEqual(plannedJobs[0].kind, .compile) XCTAssertEqual(plannedJobs[1].kind, .link) - XCTAssert(plannedJobs[1].commandLine.containsPathWithBasename("libclang_rt.profile-x86_64.a")) + if triple == "aarch64-unknown-linux-android" { + XCTAssert(plannedJobs[1].commandLine.containsPathWithBasename("libclang_rt.profile-aarch64-android.a")) + } else { + XCTAssert(plannedJobs[1].commandLine.containsPathWithBasename("libclang_rt.profile-x86_64.a")) + } XCTAssert(plannedJobs[1].commandLine.contains { $0 == .flag("-u__llvm_profile_runtime") }) } #endif From 0c1c1067b2f9f98199c9016eaac30156840a393f Mon Sep 17 00:00:00 2001 From: James Dempsey Date: Fri, 30 Aug 2024 09:10:49 -0700 Subject: [PATCH 3/8] Update Options.swift with SE-0441 language-mode option Generated with https://github.com/swiftlang/swift/pull/75564 to include changes in PR to `Options.td` file. --- Sources/SwiftOptions/Options.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/SwiftOptions/Options.swift b/Sources/SwiftOptions/Options.swift index 6162fb5f1..a86c5f90d 100644 --- a/Sources/SwiftOptions/Options.swift +++ b/Sources/SwiftOptions/Options.swift @@ -584,6 +584,7 @@ extension Option { public static let json_: Option = Option("--json", .flag, alias: Option.json, attributes: [.noDriver], helpText: "Print output in JSON format.") public static let j: Option = Option("-j", .joinedOrSeparate, attributes: [.doesNotAffectIncrementalBuild], metaVar: "", helpText: "Number of commands to execute in parallel") public static let LEQ: Option = Option("-L=", .joined, alias: Option.L, attributes: [.frontend, .doesNotAffectIncrementalBuild, .argumentIsPath], group: .linkerOption) + public static let languageMode: Option = Option("-language-mode", .separate, alias: Option.swiftVersion, attributes: [.frontend, .moduleInterface], metaVar: "", helpText: "Interpret input according to a specific Swift language mode") public static let ldPath: Option = Option("-ld-path=", .joined, attributes: [.helpHidden, .doesNotAffectIncrementalBuild, .argumentIsPath], helpText: "Specifies the path to the linker to be used") public static let libc: Option = Option("-libc", .separate, attributes: [], helpText: "libc runtime library to use") public static let libraryLevelEQ: Option = Option("-library-level=", .joined, alias: Option.libraryLevel, attributes: [.helpHidden, .frontend, .moduleInterface], metaVar: "") @@ -1457,6 +1458,7 @@ extension Option { Option.json_, Option.j, Option.LEQ, + Option.languageMode, Option.ldPath, Option.libc, Option.libraryLevelEQ, From c31dd9ebea8a93b545fdd648fba344c30eadd8d4 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 4 Sep 2024 14:10:07 -0700 Subject: [PATCH 4/8] [android] fix the sysroot linker flag dashes --- .../SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift index a774bd52a..ffdf2a406 100644 --- a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift @@ -219,10 +219,10 @@ extension GenericUnixToolchain { if targetTriple.environment == .android { if let sysroot = parsedOptions.getLastArgument(.sysroot)?.asSingle { - commandLine.appendFlag("-sysroot") + commandLine.appendFlag("--sysroot") try commandLine.appendPath(VirtualPath(path: sysroot)) } else if let sysroot = AndroidNDK.getDefaultSysrootPath(in: self.env) { - commandLine.appendFlag("-sysroot") + commandLine.appendFlag("--sysroot") try commandLine.appendPath(VirtualPath(path: sysroot.pathString)) } } else if let path = targetInfo.sdkPath?.path { From e548e86dc5d6a4df3da1eda79746920143211c01 Mon Sep 17 00:00:00 2001 From: Egor Zhdan Date: Thu, 5 Sep 2024 15:42:35 +0100 Subject: [PATCH 5/8] [cxx-interop] Remove `-experimental-cxx-stdlib` flag This change is a counterpart of https://github.com/swiftlang/swift/pull/76280. --- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 3 --- .../Jobs/WindowsToolchain+LinkerSupport.swift | 4 ---- .../Toolchains/DarwinToolchain.swift | 9 -------- Sources/SwiftOptions/Options.swift | 2 -- Tests/SwiftDriverTests/SwiftDriverTests.swift | 21 ------------------- 5 files changed, 39 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 249faca09..87213f34a 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -136,9 +136,6 @@ extension Driver { // Add flags for C++ interop try commandLine.appendLast(.enableExperimentalCxxInterop, from: &parsedOptions) try commandLine.appendLast(.cxxInteroperabilityMode, from: &parsedOptions) - if let stdlibVariant = parsedOptions.getLastArgument(.experimentalCxxStdlib)?.asSingle { - appendXccFlag("-stdlib=\(stdlibVariant)") - } if isEmbeddedEnabled && parsedOptions.hasArgument(.enableLibraryEvolution) { diagnosticEngine.emit(.error_no_library_evolution_embedded) diff --git a/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift index 86d75f9b0..1bbb745ad 100644 --- a/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift @@ -202,10 +202,6 @@ extension WindowsToolchain { commandLine.appendPath(VirtualPath.lookup(sdkPath)) } - if let stdlib = parsedOptions.getLastArgument(.experimentalCxxStdlib) { - commandLine.appendFlag("-stdlib=\(stdlib.asSingle)") - } - // Pass down an optimization level if let optArg = mapOptimizationLevelToClangArg(from: &parsedOptions) { commandLine.appendFlag(optArg) diff --git a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift index f5a26e92d..390247fd0 100644 --- a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift +++ b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift @@ -165,7 +165,6 @@ public final class DarwinToolchain: Toolchain { case argumentNotSupported(String) case invalidDeploymentTargetForIR(platform: DarwinPlatform, version: Triple.Version, archName: String) case unsupportedTargetVariant(variant: Triple) - case darwinOnlySupportsLibCxx public var description: String { switch self { @@ -177,8 +176,6 @@ public final class DarwinToolchain: Toolchain { return "unsupported '\(variant.isiOS ? "-target-variant" : "-target")' value '\(variant.triple)'; use 'ios-macabi' instead" case .argumentNotSupported(let argument): return "\(argument) is no longer supported for Apple platforms" - case .darwinOnlySupportsLibCxx: - return "The only C++ standard library supported on Apple platforms is libc++" } } } @@ -211,12 +208,6 @@ public final class DarwinToolchain: Toolchain { if parsedOptions.hasArgument(.staticExecutable) { throw ToolchainValidationError.argumentNotSupported("-static-executable") } - // If a C++ standard library is specified, it has to be libc++. - if let cxxLib = parsedOptions.getLastArgument(.experimentalCxxStdlib) { - if cxxLib.asSingle != "libc++" { - throw ToolchainValidationError.darwinOnlySupportsLibCxx - } - } } public func getDefaultDwarfVersion(targetTriple: Triple) -> UInt8 { diff --git a/Sources/SwiftOptions/Options.swift b/Sources/SwiftOptions/Options.swift index 6162fb5f1..f38520804 100644 --- a/Sources/SwiftOptions/Options.swift +++ b/Sources/SwiftOptions/Options.swift @@ -478,7 +478,6 @@ extension Option { public static let experimentalAllowedReexportedModules: Option = Option("-experimental-allowed-reexported-modules=", .commaJoined, attributes: [.noDriver], helpText: "Allow reexporting symbols from the provided modules if they are themselves exported from the main module. This is a comma separated list of module names.") public static let experimentalCForeignReferenceTypes: Option = Option("-experimental-c-foreign-reference-types", .flag, attributes: [.helpHidden, .frontend, .moduleInterface], helpText: "Enable experimental C foreign references types (with reference counting).") public static let experimentalClangImporterDirectCc1Scan: Option = Option("-experimental-clang-importer-direct-cc1-scan", .flag, attributes: [.helpHidden, .frontend], helpText: "Enables swift driver to construct swift-frontend invocations using -direct-clang-cc1-module-build") - public static let experimentalCxxStdlib: Option = Option("-experimental-cxx-stdlib", .separate, attributes: [.helpHidden], helpText: "C++ standard library to use; forwarded to Clang's -stdlib flag") public static let emitModuleSeparately: Option = Option("-experimental-emit-module-separately", .flag, attributes: [.helpHidden], helpText: "Emit module files as a distinct job") public static let driverExperimentalExplicitModuleBuild: Option = Option("-experimental-explicit-module-build", .flag, alias: Option.driverExplicitModuleBuild, attributes: [.helpHidden], helpText: "Prebuild module dependencies to make them explicit") public static let forceWorkaroundBrokenModules: Option = Option("-experimental-force-workaround-broken-modules", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Attempt unsafe recovery for imported modules with broken modularization") @@ -1351,7 +1350,6 @@ extension Option { Option.experimentalAllowedReexportedModules, Option.experimentalCForeignReferenceTypes, Option.experimentalClangImporterDirectCc1Scan, - Option.experimentalCxxStdlib, Option.emitModuleSeparately, Option.driverExperimentalExplicitModuleBuild, Option.forceWorkaroundBrokenModules, diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 130c8534d..95d826bdd 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -4281,14 +4281,6 @@ final class SwiftDriverTests: XCTestCase { } } - XCTAssertThrowsError(try Driver(args: ["swiftc", "-c", "-target", "x86_64-apple-macosx10.14", "-experimental-cxx-stdlib", "libstdc++", - "foo.swift"])) { error in - guard case DarwinToolchain.ToolchainValidationError.darwinOnlySupportsLibCxx = error else { - XCTFail("Unexpected error: \(error)") - return - } - } - // Not actually a valid arch for tvOS, but we shouldn't fall into the iOS case by mistake and emit a message about iOS >= 11 not supporting armv7. XCTAssertNoThrow(try Driver(args: ["swiftc", "-c", "-target", "armv7-apple-tvos9.0", "foo.swift"])) @@ -6826,19 +6818,6 @@ final class SwiftDriverTests: XCTestCase { XCTAssertTrue(linkJob.commandLine.contains(.flag("-lc++"))) } } - do { - var driver = try Driver(args: ["swiftc", "-cxx-interoperability-mode=swift-5.9", - "-experimental-cxx-stdlib", "libc++", "foo.swift"]) - let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs() - XCTAssertEqual(plannedJobs.count, 2) - let compileJob = plannedJobs[0] - let linkJob = plannedJobs[1] - XCTAssertTrue(compileJob.commandLine.contains(.flag("-cxx-interoperability-mode=swift-5.9"))) - XCTAssertTrue(compileJob.commandLine.contains(.flag("-stdlib=libc++"))) - if driver.targetTriple.isDarwin { - XCTAssertTrue(linkJob.commandLine.contains(.flag("-lc++"))) - } - } } func testEmbeddedSwiftOptions() throws { From 8bc892792998c523fe979477f2038b20f6317258 Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Thu, 5 Sep 2024 16:00:27 -0700 Subject: [PATCH 6/8] [Tests] Remove all hard-coded macOS targets in explicit module tests Remove all the hard coded macOS tests for module scanning and planning. Feed stdlib and shims into the tests instead to support all targets for those tests. --- TestInputs/ExplicitModuleBuilds/CHeaders/G.h | 2 +- .../SwiftDriverTests/CachingBuildTests.swift | 20 ++++++++--- .../ExplicitModuleBuildTests.swift | 36 ++++++++++++++----- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/TestInputs/ExplicitModuleBuilds/CHeaders/G.h b/TestInputs/ExplicitModuleBuilds/CHeaders/G.h index e12e0c275..906f424aa 100644 --- a/TestInputs/ExplicitModuleBuilds/CHeaders/G.h +++ b/TestInputs/ExplicitModuleBuilds/CHeaders/G.h @@ -1,4 +1,4 @@ -#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000 +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000 #include "X.h" #endif diff --git a/Tests/SwiftDriverTests/CachingBuildTests.swift b/Tests/SwiftDriverTests/CachingBuildTests.swift index f449bb747..67ec92755 100644 --- a/Tests/SwiftDriverTests/CachingBuildTests.swift +++ b/Tests/SwiftDriverTests/CachingBuildTests.swift @@ -219,6 +219,7 @@ final class CachingBuildTests: XCTestCase { } func testCachingBuildJobs() throws { + let (stdlibPath, shimsPath, _, hostTriple) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let main = path.appending(component: "testCachingBuildJobs.swift") try localFileSystem.writeFileContents(main) { @@ -235,9 +236,10 @@ final class CachingBuildTests: XCTestCase { cHeadersPath.appending(component: "Bridging.h") let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] var driver = try Driver(args: ["swiftc", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-explicit-module-build", "-v", "-cache-compile-job", "-cas-path", casPath.nativePathString(escaped: true), "-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true), @@ -312,6 +314,12 @@ final class CachingBuildTests: XCTestCase { try checkCachingBuildJob(job: job, moduleId: .clang("_SwiftConcurrencyShims"), dependencyGraph: dependencyGraph) } + else if hostTriple.isMacOSX, + hostTriple.version(for: .macOS) < Triple.Version(11, 0, 0), + relativeOutputPathFileName.starts(with: "X-") { + try checkCachingBuildJob(job: job, moduleId: .clang("X"), + dependencyGraph: dependencyGraph) + } else { XCTFail("Unexpected module dependency build job output: \(outputFilePath)") } @@ -453,6 +461,7 @@ final class CachingBuildTests: XCTestCase { /// Test generation of explicit module build jobs for dependency modules when the driver /// is invoked with -explicit-module-build, -verify-emitted-module-interface and -enable-library-evolution. func testExplicitModuleVerifyInterfaceJobs() throws { + let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let main = path.appending(component: "testExplicitModuleVerifyInterfaceJobs.swift") try localFileSystem.writeFileContents(main) { @@ -470,9 +479,10 @@ final class CachingBuildTests: XCTestCase { let privateSwiftInterfacePath: AbsolutePath = path.appending(component: "testExplicitModuleVerifyInterfaceJobs.private.swiftinterface") let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] var driver = try Driver(args: ["swiftc", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-emit-module-interface-path", swiftInterfacePath.nativePathString(escaped: true), "-emit-private-module-interface-path", privateSwiftInterfacePath.nativePathString(escaped: true), "-explicit-module-build", "-verify-emitted-module-interface", @@ -769,12 +779,12 @@ final class CachingBuildTests: XCTestCase { // #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000 let expectedNumberOfDependencies: Int if driver.hostTriple.isMacOSX, - driver.hostTriple.version(for: .macOS) >= Triple.Version(11, 0, 0) { - expectedNumberOfDependencies = 11 + driver.hostTriple.version(for: .macOS) < Triple.Version(11, 0, 0) { + expectedNumberOfDependencies = 12 } else if driver.targetTriple.isWindows { expectedNumberOfDependencies = 14 } else { - expectedNumberOfDependencies = 12 + expectedNumberOfDependencies = 11 } // Dispatch several iterations in parallel diff --git a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift index fe54c38e5..73666ffa1 100644 --- a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift +++ b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift @@ -275,6 +275,7 @@ final class ExplicitModuleBuildTests: XCTestCase { } func testModuleDependencyBuildCommandUniqueDepFile() throws { + let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let source0 = path.appending(component: "testModuleDependencyBuildCommandUniqueDepFile1.swift") let source1 = path.appending(component: "testModuleDependencyBuildCommandUniqueDepFile2.swift") @@ -299,9 +300,10 @@ final class ExplicitModuleBuildTests: XCTestCase { .appending(component: "Swift") let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] var driver = try Driver(args: ["swiftc", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-explicit-module-build", "-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true), source0.nativePathString(escaped: true), @@ -331,6 +333,7 @@ final class ExplicitModuleBuildTests: XCTestCase { /// Test generation of explicit module build jobs for dependency modules when the driver /// is invoked with -explicit-module-build func testBridgingHeaderDeps() throws { + let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let main = path.appending(component: "testExplicitModuleBuildJobs.swift") try localFileSystem.writeFileContents(main, bytes: @@ -350,9 +353,10 @@ final class ExplicitModuleBuildTests: XCTestCase { .appending(component: "Swift") let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] var driver = try Driver(args: ["swiftc", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-explicit-module-build", "-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true), main.nativePathString(escaped: true)] + sdkArgumentsForTesting) @@ -492,6 +496,7 @@ final class ExplicitModuleBuildTests: XCTestCase { /// Test generation of explicit module build jobs for dependency modules when the driver /// is invoked with -explicit-module-build func testExplicitModuleBuildJobs() throws { + let (stdlibPath, shimsPath, _, hostTriple) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let main = path.appending(component: "testExplicitModuleBuildJobs.swift") try localFileSystem.writeFileContents(main, bytes: @@ -512,9 +517,10 @@ final class ExplicitModuleBuildTests: XCTestCase { .appending(component: "Swift") let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] var driver = try Driver(args: ["swiftc", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-explicit-module-build", "-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true), main.nativePathString(escaped: true)] + sdkArgumentsForTesting) @@ -589,6 +595,12 @@ final class ExplicitModuleBuildTests: XCTestCase { try checkExplicitModuleBuildJob(job: job, moduleId: .clang("_SwiftConcurrencyShims"), dependencyGraph: dependencyGraph) } + else if hostTriple.isMacOSX, + hostTriple.version(for: .macOS) < Triple.Version(11, 0, 0), + relativeOutputPathFileName.starts(with: "X-") { + try checkExplicitModuleBuildJob(job: job, moduleId: .clang("X"), + dependencyGraph: dependencyGraph) + } else { XCTFail("Unexpected module dependency build job output: \(outputFilePath)") } @@ -616,6 +628,7 @@ final class ExplicitModuleBuildTests: XCTestCase { /// Test generation of explicit module build jobs for dependency modules when the driver /// is invoked with -explicit-module-build, -verify-emitted-module-interface and -enable-library-evolution. func testExplicitModuleVerifyInterfaceJobs() throws { + let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let main = path.appending(component: "testExplicitModuleVerifyInterfaceJobs.swift") try localFileSystem.writeFileContents(main) { @@ -632,9 +645,10 @@ final class ExplicitModuleBuildTests: XCTestCase { let privateSwiftInterfacePath: AbsolutePath = path.appending(component: "testExplicitModuleVerifyInterfaceJobs.private.swiftinterface") let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] var driver = try Driver(args: ["swiftc", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-emit-module-interface-path", swiftInterfacePath.nativePathString(escaped: true), "-emit-private-module-interface-path", privateSwiftInterfacePath.nativePathString(escaped: true), "-explicit-module-build", "-verify-emitted-module-interface", @@ -748,6 +762,7 @@ final class ExplicitModuleBuildTests: XCTestCase { /// Test generation of explicit module build jobs for dependency modules when the driver /// is invoked with -explicit-module-build and -pch-output-dir func testExplicitModuleBuildPCHOutputJobs() throws { + let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let main = path.appending(component: "testExplicitModuleBuildPCHOutputJobs.swift") try localFileSystem.writeFileContents(main, bytes: @@ -769,9 +784,10 @@ final class ExplicitModuleBuildTests: XCTestCase { let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] let pchOutputDir: AbsolutePath = path var driver = try Driver(args: ["swiftc", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-explicit-module-build", "-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true), "-pch-output-dir", pchOutputDir.nativePathString(escaped: true), @@ -883,6 +899,7 @@ final class ExplicitModuleBuildTests: XCTestCase { } func testImmediateModeExplicitModuleBuild() throws { + let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning() try withTemporaryDirectory { path in let main = path.appending(component: "testExplicitModuleBuildJobs.swift") try localFileSystem.writeFileContents(main, bytes: "import C\n") @@ -895,9 +912,10 @@ final class ExplicitModuleBuildTests: XCTestCase { .appending(component: "Swift") let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] var driver = try Driver(args: ["swift", - "-target", "x86_64-apple-macosx11.0", "-I", cHeadersPath.nativePathString(escaped: true), "-I", swiftModuleInterfacesPath.nativePathString(escaped: true), + "-I", stdlibPath.nativePathString(escaped: true), + "-I", shimsPath.nativePathString(escaped: true), "-explicit-module-build", main.nativePathString(escaped: true)] + sdkArgumentsForTesting) @@ -1723,12 +1741,12 @@ final class ExplicitModuleBuildTests: XCTestCase { // #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000 let expectedNumberOfDependencies: Int if hostTriple.isMacOSX, - hostTriple.version(for: .macOS) >= Triple.Version(11, 0, 0) { - expectedNumberOfDependencies = 11 + hostTriple.version(for: .macOS) < Triple.Version(11, 0, 0) { + expectedNumberOfDependencies = 12 } else if driver.targetTriple.isWindows { expectedNumberOfDependencies = 14 } else { - expectedNumberOfDependencies = 12 + expectedNumberOfDependencies = 11 } // Dispatch several iterations in parallel From b4fcea85eac5c740318bce27b2aa30a4f73b0da8 Mon Sep 17 00:00:00 2001 From: Dmitrii Galimzianov Date: Sat, 3 Aug 2024 04:47:20 +0200 Subject: [PATCH 7/8] [Diagnostics] Support for all the flags of the warning treating group This commit adds support for the warning treating option group, including the following options: -warnings-as-errors, -no-warnings-as-errors, -Werror, and -Wwarning. Options in this group are now preserved as-is. It is forbidden to reorder or drop any of them. These changes reflect the modifications made to the frontend in https://github.com/swiftlang/swift/pull/74466. --- Sources/SwiftDriver/Driver/Driver.swift | 17 ++++-- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 6 ++- Sources/SwiftOptions/Options.swift | 13 ++++- Tests/SwiftDriverTests/SwiftDriverTests.swift | 52 +++++++++++++++++-- 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/Sources/SwiftDriver/Driver/Driver.swift b/Sources/SwiftDriver/Driver/Driver.swift index e5d272b02..55f3ce3c5 100644 --- a/Sources/SwiftDriver/Driver/Driver.swift +++ b/Sources/SwiftDriver/Driver/Driver.swift @@ -2929,10 +2929,19 @@ extension Diagnostic.Message { extension Driver { static func validateWarningControlArgs(_ parsedOptions: inout ParsedOptions, diagnosticEngine: DiagnosticsEngine) { - if parsedOptions.hasArgument(.suppressWarnings) && - parsedOptions.hasFlag(positive: .warningsAsErrors, negative: .noWarningsAsErrors, default: false) { - diagnosticEngine.emit(.error(Error.conflictingOptions(.warningsAsErrors, .suppressWarnings)), - location: nil) + if parsedOptions.hasArgument(.suppressWarnings) { + if parsedOptions.hasFlag(positive: .warningsAsErrors, negative: .noWarningsAsErrors, default: false) { + diagnosticEngine.emit(.error(Error.conflictingOptions(.warningsAsErrors, .suppressWarnings)), + location: nil) + } + if parsedOptions.hasArgument(.Wwarning) { + diagnosticEngine.emit(.error(Error.conflictingOptions(.Wwarning, .suppressWarnings)), + location: nil) + } + if parsedOptions.hasArgument(.Werror) { + diagnosticEngine.emit(.error(Error.conflictingOptions(.Werror, .suppressWarnings)), + location: nil) + } } } diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 249faca09..019cb0716 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -228,7 +228,11 @@ extension Driver { try commandLine.appendLast(.profileGenerate, from: &parsedOptions) try commandLine.appendLast(.profileUse, from: &parsedOptions) try commandLine.appendLast(.profileCoverageMapping, from: &parsedOptions) - try commandLine.appendLast(.warningsAsErrors, .noWarningsAsErrors, from: &parsedOptions) + try commandLine.appendAllExcept( + includeList: [.warningTreating], + excludeList: [], + from: &parsedOptions + ) try commandLine.appendLast(.sanitizeEQ, from: &parsedOptions) try commandLine.appendLast(.sanitizeRecoverEQ, from: &parsedOptions) try commandLine.appendLast(.sanitizeAddressUseOdrIndicator, from: &parsedOptions) diff --git a/Sources/SwiftOptions/Options.swift b/Sources/SwiftOptions/Options.swift index 6162fb5f1..6e51b1aae 100644 --- a/Sources/SwiftOptions/Options.swift +++ b/Sources/SwiftOptions/Options.swift @@ -640,7 +640,7 @@ extension Option { public static let noStrictImplicitModuleContext: Option = Option("-no-strict-implicit-module-context", .flag, attributes: [.helpHidden, .frontend], helpText: "Disable the strict forwarding of compilation context to downstream implicit module dependencies") public static let noToolchainStdlibRpath: Option = Option("-no-toolchain-stdlib-rpath", .flag, attributes: [.helpHidden, .doesNotAffectIncrementalBuild], helpText: "Do not add an rpath entry for the toolchain's standard library (default)") public static let noVerifyEmittedModuleInterface: Option = Option("-no-verify-emitted-module-interface", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Don't check that module interfaces emitted during compilation typecheck") - public static let noWarningsAsErrors: Option = Option("-no-warnings-as-errors", .flag, attributes: [.frontend], helpText: "Don't treat warnings as errors") + public static let noWarningsAsErrors: Option = Option("-no-warnings-as-errors", .flag, attributes: [.frontend], helpText: "Treat warnings as warnings", group: .warningTreating) public static let noWholeModuleOptimization: Option = Option("-no-whole-module-optimization", .flag, attributes: [.frontend, .noInteractive], helpText: "Disable optimizing input files together instead of individually") public static let driverScanDependenciesNonLib: Option = Option("-nonlib-dependency-scanner", .flag, attributes: [.helpHidden], helpText: "Use calls to `swift-frontend -scan-dependencies` instead of dedicated dependency scanning library") public static let nostartfiles: Option = Option("-nostartfiles", .flag, attributes: [.helpHidden, .frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Do not link in the Swift language startup routines") @@ -872,14 +872,16 @@ extension Option { public static let warnSwift3ObjcInferenceComplete: Option = Option("-warn-swift3-objc-inference-complete", .flag, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild], helpText: "Deprecated, has no effect") public static let warnSwift3ObjcInferenceMinimal: Option = Option("-warn-swift3-objc-inference-minimal", .flag, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild], helpText: "Deprecated, has no effect") public static let warnSwift3ObjcInference: Option = Option("-warn-swift3-objc-inference", .flag, alias: Option.warnSwift3ObjcInferenceComplete, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild]) - public static let warningsAsErrors: Option = Option("-warnings-as-errors", .flag, attributes: [.frontend], helpText: "Treat warnings as errors") + public static let warningsAsErrors: Option = Option("-warnings-as-errors", .flag, attributes: [.frontend], helpText: "Treat warnings as errors", group: .warningTreating) public static let weakLinkAtTarget: Option = Option("-weak-link-at-target", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Weakly link symbols for declarations that were introduced at the deployment target. Symbols introduced before the deployment target are still strongly linked.") + public static let Werror: Option = Option("-Werror", .separate, attributes: [.helpHidden, .frontend], metaVar: "", helpText: "Treat this warning group as error", group: .warningTreating) public static let wholeModuleOptimization: Option = Option("-whole-module-optimization", .flag, attributes: [.frontend, .noInteractive], helpText: "Optimize input files together instead of individually") public static let windowsSdkRoot: Option = Option("-windows-sdk-root", .separate, attributes: [.frontend, .argumentIsPath], metaVar: "", helpText: "Windows SDK Root") public static let windowsSdkVersion: Option = Option("-windows-sdk-version", .separate, attributes: [.frontend], metaVar: "", helpText: "Windows SDK Version") public static let wmo: Option = Option("-wmo", .flag, alias: Option.wholeModuleOptimization, attributes: [.helpHidden, .frontend, .noInteractive]) public static let workingDirectoryEQ: Option = Option("-working-directory=", .joined, alias: Option.workingDirectory) public static let workingDirectory: Option = Option("-working-directory", .separate, metaVar: "", helpText: "Resolve file paths relative to the specified directory") + public static let Wwarning: Option = Option("-Wwarning", .separate, attributes: [.helpHidden, .frontend], metaVar: "", helpText: "Treat this warning group as warning", group: .warningTreating) public static let Xcc: Option = Option("-Xcc", .separate, attributes: [.frontend], metaVar: "", helpText: "Pass to the C/C++/Objective-C compiler") public static let XclangLinker: Option = Option("-Xclang-linker", .separate, attributes: [.helpHidden], metaVar: "", helpText: "Pass to Clang when it is use for linking.") public static let Xfrontend: Option = Option("-Xfrontend", .separate, attributes: [.helpHidden], metaVar: "", helpText: "Pass to the Swift frontend") @@ -1747,12 +1749,14 @@ extension Option { Option.warnSwift3ObjcInference, Option.warningsAsErrors, Option.weakLinkAtTarget, + Option.Werror, Option.wholeModuleOptimization, Option.windowsSdkRoot, Option.windowsSdkVersion, Option.wmo, Option.workingDirectoryEQ, Option.workingDirectory, + Option.Wwarning, Option.Xcc, Option.XclangLinker, Option.Xfrontend, @@ -1774,6 +1778,7 @@ extension Option { case linkerOption case modes case pluginSearch + case warningTreating } } @@ -1798,6 +1803,8 @@ extension Option.Group { return "" case .pluginSearch: return "" + case .warningTreating: + return "" } } } @@ -1823,6 +1830,8 @@ extension Option.Group { return "MODES" case .pluginSearch: return nil + case .warningTreating: + return nil } } } diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index d57954e04..ae910d19c 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -5662,7 +5662,9 @@ final class SwiftDriverTests: XCTestCase { let plannedJobs = try driver.planBuild() XCTAssertEqual(plannedJobs.count, 1) let job = plannedJobs[0] - XCTAssertTrue(job.commandLine.contains(.flag("-warnings-as-errors"))) + XCTAssertTrue(job.commandLine.contains( + subsequence: [.flag("-no-warnings-as-errors"), .flag("-warnings-as-errors")] + )) } do { @@ -5670,7 +5672,9 @@ final class SwiftDriverTests: XCTestCase { let plannedJobs = try driver.planBuild() XCTAssertEqual(plannedJobs.count, 1) let job = plannedJobs[0] - XCTAssertTrue(job.commandLine.contains(.flag("-no-warnings-as-errors"))) + XCTAssertTrue(job.commandLine.contains( + subsequence: [.flag("-warnings-as-errors"), .flag("-no-warnings-as-errors")] + )) } do { @@ -5678,16 +5682,58 @@ final class SwiftDriverTests: XCTestCase { let plannedJobs = try driver.planBuild() XCTAssertEqual(plannedJobs.count, 1) let job = plannedJobs[0] - XCTAssertTrue(job.commandLine.contains(.flag("-no-warnings-as-errors"))) + XCTAssertTrue(job.commandLine.contains( + subsequence: [.flag("-warnings-as-errors"), .flag("-no-warnings-as-errors")] + )) XCTAssertTrue(job.commandLine.contains(.flag("-suppress-warnings"))) } + do { + var driver = try Driver(args: [ + "swift", + "-warnings-as-errors", + "-no-warnings-as-errors", + "-Werror", "A", + "-Wwarning", "B", + "-Werror", "C", + "-Wwarning", "C", + "foo.swift", + ]) + let plannedJobs = try driver.planBuild() + XCTAssertEqual(plannedJobs.count, 1) + let job = plannedJobs[0] + XCTAssertTrue(job.commandLine.contains(subsequence: [ + .flag("-warnings-as-errors"), + .flag("-no-warnings-as-errors"), + .flag("-Werror"), + .flag("A"), + .flag("-Wwarning"), + .flag("B"), + .flag("-Werror"), + .flag("C"), + .flag("-Wwarning"), + .flag("C"), + ])) + } + do { try assertDriverDiagnostics(args: ["swift", "-no-warnings-as-errors", "-warnings-as-errors", "-suppress-warnings", "foo.swift"]) { $1.expect(.error(Driver.Error.conflictingOptions(.warningsAsErrors, .suppressWarnings))) } } + do { + try assertDriverDiagnostics(args: ["swift", "-Wwarning", "test", "-suppress-warnings", "foo.swift"]) { + $1.expect(.error(Driver.Error.conflictingOptions(.Wwarning, .suppressWarnings))) + } + } + + do { + try assertDriverDiagnostics(args: ["swift", "-Werror", "test", "-suppress-warnings", "foo.swift"]) { + $1.expect(.error(Driver.Error.conflictingOptions(.Werror, .suppressWarnings))) + } + } + do { var driver = try Driver(args: ["swift", "-print-educational-notes", "foo.swift"]) let plannedJobs = try driver.planBuild() From 0155ae03cd329ca33b13b65ec50dd42a43a840ea Mon Sep 17 00:00:00 2001 From: Mirza Garibovic Date: Mon, 9 Sep 2024 21:56:09 -0700 Subject: [PATCH 8/8] Change swift-argument-parser dependency from 'upToNextMinor' to 'from'. upToNextMinor is no longer needed since swift-argument-parser reached 1.0. Unblocks downstream projects from adopting a newer swift-argument-parser. --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index dfb1cbe40..02cef3a3f 100644 --- a/Package.swift +++ b/Package.swift @@ -170,7 +170,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { // The 'swift-argument-parser' version declared here must match that // used by 'swift-package-manager' and 'sourcekit-lsp'. Please coordinate // dependency version changes here with those projects. - .package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMinor(from: "1.4.0")), + .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.4.0"), ] } else { package.dependencies += [