diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 84ad2ed95c9..3a1d9be50ea 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -35,10 +35,10 @@ jobs: # linux_build_command: 'swift run --build-system ${{ matrix.executableTargetBuildSystem }} swift-build --build-tests --build-system ${{ matrix.buildSystem}} && swift run --build-system ${{ matrix.executableTargetBuildSystem }} swift-test --parallel --build-system ${{ matrix.buildSystem}}' windows_swift_versions: '["nightly-main"]' windows_pre_build_command: 'Invoke-Program .\.github\scripts\prebuild.ps1' - windows_build_command: 'Invoke-Program swift run -Xlinker /ignore:4217 --configuration release --build-system ${{ matrix.executableTargetBuildSystem }} swift-build --build-tests -Xlinker /ignore:4217 --build-system ${{ matrix.buildSystem}}' + windows_build_command: 'Invoke-Program swift run -Xlinker /ignore:4217 --build-system ${{ matrix.executableTargetBuildSystem }} swift-build --build-tests -Xlinker /ignore:4217 --build-system ${{ matrix.buildSystem}}' # windows_build_command: 'Invoke-Program swift run -Xlinker /ignore:4217 --build-system ${{ matrix.executableTargetBuildSystem }} swift-build --build-tests -Xlinker /ignore:4217 --build-system ${{ matrix.buildSystem}}; Invoke-Program swift run --build-system ${{ matrix.executableTargetBuildSystem }} -Xlinker /ignore:4217 swift-test -Xlinker /ignore:4217 --parallel --build-system ${{ matrix.buildSystem}}' enable_windows_checks: true - enable_ios_checks: false + enable_ios_checks: true enable_macos_checks: true macos_exclude_xcode_versions: "[{\"xcode_version\": \"16.3\"}, {\"xcode_version\": \"16.4\"}]" macos_build_command: 'swift run --build-system ${{ matrix.executableTargetBuildSystem }} swift-build --build-tests --build-system ${{ matrix.buildSystem}}' @@ -64,7 +64,7 @@ jobs: windows_swift_versions: '["nightly-main"]' windows_pre_build_command: 'Invoke-Program .\.github\scripts\prebuild.ps1' windows_build_command: 'Invoke-Program swift run --build-system ${{ matrix.executableTargetBuildSystem }} swift-build --build-tests --build-system ${{ matrix.buildSystem }}' - enable_ios_checks: false + enable_ios_checks: true enable_macos_checks: true macos_exclude_xcode_versions: "[{\"xcode_version\": \"16.3\"}, {\"xcode_version\": \"16.4\"}]" macos_build_command: 'swift run --build-system ${{ matrix.executableTargetBuildSystem }} swift-build --build-tests --build-system ${{ matrix.buildSystem }}' diff --git a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/Package.swift b/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/Package.swift deleted file mode 100644 index 732dcf06f87..00000000000 --- a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/Package.swift +++ /dev/null @@ -1,16 +0,0 @@ -// swift-tools-version: 6.0 - -import PackageDescription - -let package = Package( - name: "Simple", - products: [ - .library(name: "Simple", type: .static, targets: ["Simple"]), - ], - targets: [ - .target( - name: "Simple", - path: "." - ), - ] -) diff --git a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/build.sh b/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/build.sh deleted file mode 100644 index edf7a80e69e..00000000000 --- a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/build.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# currently only used for Windows - -rm -fr .build -swift build --arch arm64 -c release -swift build --arch x86_64 -c release - -cd dist -rm -fr windows -mkdir windows -cd windows -cp ../../.build/arm64-unknown-windows-msvc/release/libSimple.a Simple_arm64.lib -cp ../../.build/x86_64-unknown-windows-msvc/release/libSimple.a Simple_x86_64.lib diff --git a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/dist/windows/Simple_arm64.lib b/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/dist/windows/Simple_arm64.lib deleted file mode 100644 index 4ff9ddafd62..00000000000 Binary files a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/dist/windows/Simple_arm64.lib and /dev/null differ diff --git a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/dist/windows/Simple_x86_64.lib b/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/dist/windows/Simple_x86_64.lib deleted file mode 100644 index dcd5f2069c3..00000000000 Binary files a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/dist/windows/Simple_x86_64.lib and /dev/null differ diff --git a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/info.json b/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/info.json index f170563d013..96fed2184ac 100644 --- a/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/info.json +++ b/Fixtures/BinaryLibraries/Static/Package1/Simple.artifactbundle/info.json @@ -28,24 +28,7 @@ "headerPaths": ["include"], "moduleMapPath": "include/simple.modulemap" } - }, - { - "path": "dist/windows/Simple_arm64.lib", - "supportedTriples": ["aarch64-unknown-windows-msvc"], - "staticLibraryMetadata": { - "headerPaths": ["include"], - "moduleMapPath": "include/simple.modulemap" - } - }, - { - "path": "dist/windows/Simple_x86_64.lib", - "supportedTriples": ["x86_64-unknown-windows-msvc"], - "staticLibraryMetadata": { - "headerPaths": ["include"], - "moduleMapPath": "include/simple.modulemap" - } - }, - + } ] } } diff --git a/Sources/Basics/Concurrency/AsyncProcess.swift b/Sources/Basics/Concurrency/AsyncProcess.swift index cf824adb8ec..f18dff34719 100644 --- a/Sources/Basics/Concurrency/AsyncProcess.swift +++ b/Sources/Basics/Concurrency/AsyncProcess.swift @@ -678,8 +678,7 @@ package final class AsyncProcess { resolvedArgs[0] = executablePath.pathString } let argv = CStringArray(resolvedArgs) - let envValues = environment.map { "\($0.0)=\($0.1)" } - let env = CStringArray(envValues) + let env = CStringArray(environment.map { "\($0.0)=\($0.1)" }) let rv = posix_spawnp(&self.processID, argv.cArray[0]!, &fileActions, &attributes, argv.cArray, env.cArray) guard rv == 0 else { diff --git a/Sources/Build/BuildPlan/BuildPlan+Product.swift b/Sources/Build/BuildPlan/BuildPlan+Product.swift index ae08e63886d..b290f9e3fd3 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Product.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Product.swift @@ -56,9 +56,6 @@ extension BuildPlan { buildProduct.additionalFlags += ["-framework", binaryPath.basenameWithoutExt] } else if binaryPath.basename.starts(with: "lib") { buildProduct.additionalFlags += ["-l\(binaryPath.basenameWithoutExt.dropFirst(3))"] - } else if binaryPath.extension == "lib" { - // Static libraries on Windows - buildProduct.additionalFlags += ["-l\(binaryPath.basenameWithoutExt)"] } else { self.observabilityScope.emit(error: "unexpected binary name at \(binaryPath). Static libraries should be prefixed with lib") } diff --git a/Sources/SPMBuildCore/Plugins/PluginInvocation.swift b/Sources/SPMBuildCore/Plugins/PluginInvocation.swift index 8c31dcf1e89..30b73883e84 100644 --- a/Sources/SPMBuildCore/Plugins/PluginInvocation.swift +++ b/Sources/SPMBuildCore/Plugins/PluginInvocation.swift @@ -705,8 +705,7 @@ fileprivate func collectAccessibleTools( } // For an executable target we create a `builtTool`. else if executableOrBinaryModule.type == .executable { - let exeName = executableOrBinaryModule.name + hostTriple.executableExtension - return try [.builtTool(name: builtToolName, path: RelativePath(validating: exeName))] + return try [.builtTool(name: builtToolName, path: RelativePath(validating: executableOrBinaryModule.name))] } else { return [] diff --git a/Sources/SwiftBuildSupport/PackagePIFBuilder.swift b/Sources/SwiftBuildSupport/PackagePIFBuilder.swift index 47026ac3015..269a941787b 100644 --- a/Sources/SwiftBuildSupport/PackagePIFBuilder.swift +++ b/Sources/SwiftBuildSupport/PackagePIFBuilder.swift @@ -392,10 +392,8 @@ public final class PackagePIFBuilder { init(from pifProductType: ProjectModel.Target.ProductType) { self = switch pifProductType { case .application: .application - case .commonStaticArchive: .staticArchive case .staticArchive: .staticArchive case .commonObject: .commonObject - case .objectFile: .commonObject case .dynamicLibrary: .dynamicLibrary case .framework: .framework case .executable: .executable diff --git a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift index d3af792e33d..020cddf85a9 100644 --- a/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift +++ b/Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Modules.swift @@ -263,10 +263,7 @@ extension PackagePIFProjectBuilder { productType = .framework } - case .staticLibrary: - productType = .commonStaticArchive - - case .executable: + case .staticLibrary, .executable: productType = .commonObject case .macro: diff --git a/Tests/BuildTests/PluginInvocationTests.swift b/Tests/BuildTests/PluginInvocationTests.swift index 175c07c55e8..4d97913bc41 100644 --- a/Tests/BuildTests/PluginInvocationTests.swift +++ b/Tests/BuildTests/PluginInvocationTests.swift @@ -120,10 +120,10 @@ final class PluginInvocationTests: XCTestCase { buildPlanResult.checkTargetsCount(5) // Note: plugins are not included here. buildPlanResult.check(destination: .target, for: "Foo") - + buildPlanResult.check(destination: .host, for: "FooTool") buildPlanResult.check(destination: .target, for: "FooTool") - + buildPlanResult.check(destination: .host, for: "FooToolLib") buildPlanResult.check(destination: .target, for: "FooToolLib") } @@ -135,7 +135,7 @@ final class PluginInvocationTests: XCTestCase { return try UserToolchain.default.targetTriple } } - + func compilePluginScript( sourceFiles: [AbsolutePath], pluginName: String, @@ -150,7 +150,7 @@ final class PluginInvocationTests: XCTestCase { completion(.failure(StringError("unimplemented"))) } } - + func runPluginScript( sourceFiles: [AbsolutePath], pluginName: String, @@ -175,7 +175,7 @@ final class PluginInvocationTests: XCTestCase { callbackQueue.sync { delegate.handleOutput(data: Data("Hello Plugin!".utf8)) } - + // Pretend it emitted a warning. try callbackQueue.sync { let message = Data(""" @@ -264,7 +264,7 @@ final class PluginInvocationTests: XCTestCase { XCTAssertEqual(evalFirstCommand.configuration.arguments, ["-c", "/Foo/Sources/Foo/SomeFile.abc"]) XCTAssertEqual(evalFirstCommand.configuration.environment, ["X": "Y"]) XCTAssertEqual(evalFirstCommand.configuration.workingDirectory, AbsolutePath("/Foo/Sources/Foo")) - XCTAssertEqual(evalFirstCommand.inputFiles, [builtToolsDir.appending("FooTool" + ProcessInfo.exeSuffix)]) + XCTAssertEqual(evalFirstCommand.inputFiles, [builtToolsDir.appending("FooTool")]) XCTAssertEqual(evalFirstCommand.outputFiles, []) XCTAssertEqual(evalFirstResult.diagnostics.count, 1) @@ -275,7 +275,7 @@ final class PluginInvocationTests: XCTestCase { XCTAssertEqual(evalFirstResult.textOutput, "Hello Plugin!") } - + func testCompilationDiagnostics() async throws { try await testWithTemporaryDirectory { tmpPath in // Create a sample package with a library target and a plugin. @@ -300,13 +300,13 @@ final class PluginInvocationTests: XCTestCase { ] ) """) - + let myLibraryTargetDir = packageDir.appending(components: "Sources", "MyLibrary") try localFileSystem.createDirectory(myLibraryTargetDir, recursive: true) try localFileSystem.writeFileContents(myLibraryTargetDir.appending("library.swift"), string: """ public func Foo() { } """) - + let myPluginTargetDir = packageDir.appending(components: "Plugins", "MyPlugin") try localFileSystem.createDirectory(myPluginTargetDir, recursive: true) try localFileSystem.writeFileContents(myPluginTargetDir.appending("plugin.swift"), string: """ @@ -329,7 +329,7 @@ final class PluginInvocationTests: XCTestCase { customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), delegate: MockWorkspaceDelegate() ) - + // Load the root manifest. let rootInput = PackageGraphRootInput(packages: [packageDir], dependencies: []) let rootManifests = try await workspace.loadRootManifests( @@ -345,7 +345,7 @@ final class PluginInvocationTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) XCTAssert(packageGraph.packages.count == 1, "\(packageGraph.packages)") - + // Find the build tool plugin. let buildToolPlugin = try XCTUnwrap(packageGraph.packages.first?.modules.map(\.underlying).first{ $0.name == "MyPlugin" } as? PluginModule) XCTAssertEqual(buildToolPlugin.name, "MyPlugin") @@ -358,10 +358,10 @@ final class PluginInvocationTests: XCTestCase { cacheDir: pluginCacheDir, toolchain: try UserToolchain.default ) - + // Define a plugin compilation delegate that just captures the passed information. class Delegate: PluginScriptCompilerDelegate { - var commandLine: [String]? + var commandLine: [String]? var environment: Environment? var compiledResult: PluginCompilationResult? var cachedResult: PluginCompilationResult? @@ -406,7 +406,7 @@ final class PluginInvocationTests: XCTestCase { XCTAssertNotNil(delegate.environment) XCTAssertEqual(delegate.compiledResult, result) XCTAssertNil(delegate.cachedResult) - + // Check the serialized diagnostics. We should have an error. let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile) let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents) @@ -431,7 +431,7 @@ final class PluginInvocationTests: XCTestCase { } } """) - + // Try to compile the fixed plugin. let firstExecModTime: Date do { @@ -573,7 +573,7 @@ final class PluginInvocationTests: XCTestCase { XCTAssertNotNil(delegate.environment) XCTAssertEqual(delegate.compiledResult, result) XCTAssertNil(delegate.cachedResult) - + // Check that the diagnostics no longer have a warning. let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile) let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents) @@ -627,7 +627,7 @@ final class PluginInvocationTests: XCTestCase { XCTAssertNotNil(delegate.environment) XCTAssertEqual(delegate.compiledResult, result) XCTAssertNil(delegate.cachedResult) - + // Check the diagnostics. We should have a different error than the original one. let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile) let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents) @@ -896,7 +896,7 @@ final class PluginInvocationTests: XCTestCase { } } """) - + let artifactVariants = [try UserToolchain.default.targetTriple].map { """ { "path": "Y", "supportedTriples": ["\($0.tripleString)"] } @@ -1124,7 +1124,7 @@ final class PluginInvocationTests: XCTestCase { let diags = result.flatMap(\.value.results).flatMap(\.diagnostics) testDiagnostics(diags) { result in - let msg = "a prebuild command cannot use executables built from source, including executable target '\("Y" + ProcessInfo.exeSuffix)'" + let msg = "a prebuild command cannot use executables built from source, including executable target 'Y'" result.check(diagnostic: .contains(msg), severity: .error) } } @@ -1243,7 +1243,7 @@ final class PluginInvocationTests: XCTestCase { ) throws -> [Command] { } } """) - + // Create a valid swift interface file that can be detected via `canImport()`. let fakeExtraModulesDir = tmpPath.appending("ExtraModules") try localFileSystem.createDirectory(fakeExtraModulesDir, recursive: true) @@ -1252,7 +1252,7 @@ final class PluginInvocationTests: XCTestCase { // swift-interface-format-version: 1.0 // swift-module-flags: -module-name ModuleFoundViaExtraSearchPaths """) - + ///////// // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() @@ -1589,5 +1589,5 @@ extension BuildPlanResult { $0.module.name == target && $0.destination == destination } XCTAssertEqual(targets.count, 1, file: file, line: line) - } + } } diff --git a/Tests/CommandsTests/APIDiffTests.swift b/Tests/CommandsTests/APIDiffTests.swift index 1f45c3ca94e..15cd185c307 100644 --- a/Tests/CommandsTests/APIDiffTests.swift +++ b/Tests/CommandsTests/APIDiffTests.swift @@ -256,7 +256,7 @@ struct APIDiffTests { arguments: SupportedBuildSystemOnAllPlatforms ) func testAPIDiffOfModuleWithCDependency(buildSystem: BuildSystemProvider.Kind) async throws { - try await withKnownIssue("https://github.com/swiftlang/swift/issues/82394", isIntermittent: true) { + try await withKnownIssue("https://github.com/swiftlang/swift/issues/82394") { try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in let packageRoot = fixturePath.appending("CTargetDep") // Overwrite the existing decl. @@ -293,7 +293,7 @@ struct APIDiffTests { arguments: SupportedBuildSystemOnAllPlatforms ) func testAPIDiffOfVendoredCDependency(buildSystem: BuildSystemProvider.Kind) async throws { - try await withKnownIssue("https://github.com/swiftlang/swift/issues/82394", isIntermittent: true) { + try await withKnownIssue("https://github.com/swiftlang/swift/issues/82394") { try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in let packageRoot = fixturePath.appending("CIncludePath") let (output, _) = try await execute(["diagnose-api-breaking-changes", "main"], packagePath: packageRoot, buildSystem: buildSystem) @@ -533,4 +533,20 @@ struct APIDiffTests { #expect(error.stdout.contains("`swift package experimental-api-diff` has been renamed to `swift package diagnose-api-breaking-changes`")) } } + + @Test(.requiresAPIDigester, arguments: SupportedBuildSystemOnAllPlatforms) + func testBrokenAPIDiff(buildSystem: BuildSystemProvider.Kind) async throws { + try await fixture(name: "Miscellaneous/APIDiff/") { fixturePath in + let packageRoot = fixturePath.appending("BrokenPkg") + await expectThrowsCommandExecutionError(try await execute(["diagnose-api-breaking-changes", "1.2.3"], packagePath: packageRoot, buildSystem: buildSystem)) { error in + let expectedError: String + if buildSystem == .swiftbuild { + expectedError = "error: Build failed" + } else { + expectedError = "baseline for Swift2 contains no symbols, swift-api-digester output" + } + #expect(error.stderr.contains(expectedError)) + } + } + } } diff --git a/Tests/FunctionalTests/PluginTests.swift b/Tests/FunctionalTests/PluginTests.swift index 3fe4a712535..3ab39d798fd 100644 --- a/Tests/FunctionalTests/PluginTests.swift +++ b/Tests/FunctionalTests/PluginTests.swift @@ -380,6 +380,7 @@ struct PluginTests { @Test( .issue("https://github.com/swiftlang/swift-package-manager/issues/9215", relationship: .verifies), .requiresSwiftConcurrencySupport, + .disabled("rdar://162053979"), arguments: [BuildSystemProvider.Kind.native, .swiftbuild] ) func testUseOfVendedBinaryTool(buildSystem: BuildSystemProvider.Kind) async throws { diff --git a/Tests/FunctionalTests/StaticBinaryLibrary.swift b/Tests/FunctionalTests/StaticBinaryLibrary.swift index e0eec6a6bc3..329438f24d2 100644 --- a/Tests/FunctionalTests/StaticBinaryLibrary.swift +++ b/Tests/FunctionalTests/StaticBinaryLibrary.swift @@ -32,19 +32,23 @@ struct StaticBinaryLibraryTests { func staticLibrary( buildData: BuildData, ) async throws { - try await fixture(name: "BinaryLibraries") { fixturePath in - let (stdout, _) = try await executeSwiftRun( - fixturePath.appending("Static").appending("Package1"), - "Example", - configuration: buildData.config, - extraArgs: ["--experimental-prune-unused-dependencies"], - buildSystem: buildData.buildSystem, - ) - #expect(stdout == """ - 42 - 42 + try await withKnownIssue(isIntermittent: true) { + try await fixture(name: "BinaryLibraries") { fixturePath in + let (stdout, _) = try await executeSwiftRun( + fixturePath.appending("Static").appending("Package1"), + "Example", + configuration: buildData.config, + extraArgs: ["--experimental-prune-unused-dependencies"], + buildSystem: buildData.buildSystem, + ) + #expect(stdout == """ + 42 + 42 - """) + """) + } + } when: { + ProcessInfo.hostOperatingSystem == .windows } } }