From eed7c2161517f5cb97c9fd602ab0dacabdccadd0 Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Fri, 7 Mar 2025 08:00:28 -0500 Subject: [PATCH 1/7] Remove 32-bit libraries from RHEL sysroots built from containers - These are not needed, and the amazonlinux2 ones have broken symlinks that cause failures to generate the Swift SDK. --- .../Generator/SwiftSDKGenerator+Copy.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift index 5b9afae..1c0101f 100644 --- a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift +++ b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift @@ -91,6 +91,18 @@ extension SwiftSDKGenerator { } try await generator.createSymlink(at: sdkDirPath.appending("lib"), pointingTo: "usr/lib") + // Look for 32-bit libraries to remove from RHEL-based distros + // These are not needed, and the amazonlinux2 x86_64 symlinks are messed up + if case .rhel = targetDistribution { + for gccVersion in 7...13 { + let removePath = "gcc/x86_64-redhat-linux/\(gccVersion)/32" + if await doesFileExist(at: sdkUsrLibPath.appending(removePath)) { + logger.warning("Removing 32-bit libraries from RHEL imported sysroot", metadata: ["removePath": .stringConvertible(removePath)]) + try await removeRecursively(at: sdkUsrLibPath.appending(removePath)) + } + } + } + // Copy the ELF interpreter try await generator.copyFromDockerContainer( id: containerID, From 45a0614c5e6c16c06348ea9ea7fe06f8ca9ad7ae Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Fri, 7 Mar 2025 08:00:52 -0500 Subject: [PATCH 2/7] Update EndToEndTests to DRY out code a bit, add tests for amazonlinux2 and fedora39 --- .../EndToEndTests.swift | 139 ++++++++++++------ 1 file changed, 94 insertions(+), 45 deletions(-) diff --git a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift index 15b19c9..5dad60e 100644 --- a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift +++ b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift @@ -34,14 +34,12 @@ extension FileManager { try createDirectory(at: temporaryDirectory, withIntermediateDirectories: false) defer { // Best effort cleanup. - do { - if cleanup { - try removeItem(at: temporaryDirectory) - logger.info("Removed temporary directory") - } else { - logger.info("Keeping temporary directory") - } - } catch {} + if cleanup { + try? removeItem(at: temporaryDirectory) + logger.info("Removed temporary directory") + } else { + logger.info("Keeping temporary directory") + } } logger.info("Created temporary directory") @@ -58,7 +56,7 @@ func buildSDK(_ logger: Logger, scratchPath: String, withArguments runArguments: logger[metadataKey: "runArguments"] = "\"\(runArguments)\"" logger[metadataKey: "scratchPath"] = "\(scratchPath)" - logger.info("Building SDK") + logger.info("Building Swift SDK") var packageDirectory = FilePath(#filePath) packageDirectory.removeLastComponent() @@ -67,7 +65,7 @@ func buildSDK(_ logger: Logger, scratchPath: String, withArguments runArguments: let generatorOutput = try await Shell.readStdout( "cd \(packageDirectory) && swift run --scratch-path \"\(scratchPath)\" swift-sdk-generator make-linux-sdk \(runArguments)" ) - logger.info("Finished building SDK") + logger.info("Finished building Swift SDK") let installCommand = try XCTUnwrap(generatorOutput.split(separator: "\n").first { $0.contains("swift experimental-sdk install") @@ -78,16 +76,16 @@ func buildSDK(_ logger: Logger, scratchPath: String, withArguments runArguments: ).stem logger[metadataKey: "bundleName"] = "\(bundleName)" - logger.info("Checking installed SDKs") + logger.info("Checking installed Swift SDKs") let installedSDKs = try await Shell.readStdout("swift experimental-sdk list").components(separatedBy: "\n") // Make sure this bundle hasn't been installed already. if installedSDKs.contains(bundleName) { - logger.info("Removing existing SDK") + logger.info("Removing existing Swift SDK") try await Shell.run("swift experimental-sdk remove \(bundleName)") } - logger.info("Installing new SDK") + logger.info("Installing new Swift SDK") let installOutput = try await Shell.readStdout(String(installCommand)) XCTAssertTrue(installOutput.contains("successfully installed")) @@ -154,8 +152,12 @@ struct SDKConfiguration { var linuxDistributionVersion: String var architecture: String var withDocker: Bool + var containerImageSuffix: String? - var bundleName: String { "\(linuxDistributionName)_\(linuxDistributionVersion)_\(architecture)_\(swiftVersion)-RELEASE\(withDocker ? "_with-docker" : "")" } + var bundleName: String { + let sdkPrefix = containerImageSuffix ?? "\(linuxDistributionName)_\(linuxDistributionVersion)" + return "\(sdkPrefix)_\(architecture)_\(swiftVersion)-RELEASE\(withDocker ? "_with-docker" : "")" + } func withDocker(_ enabled: Bool = true) -> SDKConfiguration { var res = self @@ -163,6 +165,12 @@ struct SDKConfiguration { return res } + func withContainerImageSuffix(_ containerImageSuffix: String) -> SDKConfiguration { + var res = self + res.containerImageSuffix = containerImageSuffix + return res + } + func withArchitecture(_ arch: String) -> SDKConfiguration { var res = self res.architecture = arch @@ -175,14 +183,22 @@ struct SDKConfiguration { } var sdkGeneratorArguments: String { + // Build the container image tag + var containerImage: String? = nil + if let containerImageSuffix { + containerImage = "swift:\(swiftVersion)-\(containerImageSuffix)" + } + return [ "--sdk-name \(bundleName)", "--host-toolchain", withDocker ? "--with-docker" : nil, + containerImage != nil ? "--from-container-image" : nil, containerImage, "--swift-version \(swiftVersion)-RELEASE", testLinuxSwiftSDKs ? "--host \(hostArch!)-unknown-linux-gnu" : nil, "--target \(architecture)-unknown-linux-gnu", - "--linux-distribution-name \(linuxDistributionName)" + "--linux-distribution-name \(linuxDistributionName)", + "--linux-distribution-version \(linuxDistributionVersion)" ].compactMap{ $0 }.joined(separator: " ") } } @@ -273,6 +289,8 @@ func buildTestcase(_ logger: Logger, testcase: String, bundleName: String, tempD } func buildTestcases(config: SDKConfiguration) async throws { + try skipSlow() + var logger = Logger(label: "EndToEndTests") logger[metadataKey: "testcase"] = "testPackageInitExecutable" @@ -292,17 +310,26 @@ func buildTestcases(config: SDKConfiguration) async throws { try await buildSDK(logger, scratchPath: tempDir.path, withArguments: config.sdkGeneratorArguments) } - logger.info("Built SDK") + logger.info("Built Swift SDK") + + // Cleanup + let cleanupSdk: () async -> Void = { + logger.info("Removing Swift SDK to cleanup...") + try? await Shell.run("swift experimental-sdk remove \(bundleName)") + } for testcase in testcases { - try await FileManager.default.withTemporaryDirectory(logger: logger) { tempDir in - try await buildTestcase(logger, testcase: testcase, bundleName: bundleName, tempDir: tempDir) + do { + try await FileManager.default.withTemporaryDirectory(logger: logger) { tempDir in + try await buildTestcase(logger, testcase: testcase, bundleName: bundleName, tempDir: tempDir) + } + } catch { + await cleanupSdk() + throw error } } - // Cleanup - logger.info("Removing SDK to cleanup...") - try await Shell.run("swift experimental-sdk remove \(bundleName)") + await cleanupSdk() } final class Swift59_UbuntuEndToEndTests: XCTestCase { @@ -315,22 +342,18 @@ final class Swift59_UbuntuEndToEndTests: XCTestCase { ) func testAarch64Direct() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64Direct() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAarch64FromContainer() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) } func testX86_64FromContainer() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) } } @@ -345,22 +368,18 @@ final class Swift510_UbuntuEndToEndTests: XCTestCase { ) func testAarch64Direct() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64Direct() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAarch64FromContainer() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) } func testX86_64FromContainer() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) } } @@ -375,22 +394,18 @@ final class Swift60_UbuntuEndToEndTests: XCTestCase { ) func testAarch64Direct() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64Direct() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAarch64FromContainer() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) } func testX86_64FromContainer() async throws { - try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) } } @@ -405,13 +420,19 @@ final class Swift59_RHELEndToEndTests: XCTestCase { ) func testAarch64FromContainer() async throws { - try skipSlow() - try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) + try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64FromContainer() async throws { - try skipSlow() - try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) + try await buildTestcases(config: config.withArchitecture("x86_64")) + } + + func testAmazonLinux2Aarch64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("amazonlinux2")) + } + + func testAmazonLinux2X86_64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("amazonlinux2")) } } @@ -425,13 +446,27 @@ final class Swift510_RHELEndToEndTests: XCTestCase { ) func testAarch64FromContainer() async throws { - try skipSlow() - try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) + try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64FromContainer() async throws { - try skipSlow() - try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) + try await buildTestcases(config: config.withArchitecture("x86_64")) + } + + func testAmazonLinux2Aarch64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("amazonlinux2")) + } + + func testAmazonLinux2X86_64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("amazonlinux2")) + } + + func testFedora39Aarch64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("fedora39")) + } + + func testFedora39X86_64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("fedora39")) } } @@ -445,12 +480,26 @@ final class Swift60_RHELEndToEndTests: XCTestCase { ) func testAarch64FromContainer() async throws { - try skipSlow() - try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) + try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64FromContainer() async throws { - try skipSlow() - try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) + try await buildTestcases(config: config.withArchitecture("x86_64")) + } + + func testAmazonLinux2Aarch64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("amazonlinux2")) + } + + func testAmazonLinux2X86_64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("amazonlinux2")) + } + + func testFedora39Aarch64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("fedora39")) + } + + func testFedora39X86_64FromContainer() async throws { + try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("fedora39")) } } From ca2c787eaa4ebf06a750a100b4caeea0acd4ef2c Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Fri, 7 Mar 2025 08:41:13 -0500 Subject: [PATCH 3/7] Restore skipSlow() calls in each test case for configurability - Some tests may not be skipped in the future --- .../EndToEndTests.swift | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift index 5dad60e..f601af8 100644 --- a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift +++ b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift @@ -289,8 +289,6 @@ func buildTestcase(_ logger: Logger, testcase: String, bundleName: String, tempD } func buildTestcases(config: SDKConfiguration) async throws { - try skipSlow() - var logger = Logger(label: "EndToEndTests") logger[metadataKey: "testcase"] = "testPackageInitExecutable" @@ -342,18 +340,22 @@ final class Swift59_UbuntuEndToEndTests: XCTestCase { ) func testAarch64Direct() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64Direct() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) } func testX86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) } } @@ -368,18 +370,22 @@ final class Swift510_UbuntuEndToEndTests: XCTestCase { ) func testAarch64Direct() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64Direct() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) } func testX86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) } } @@ -394,18 +400,22 @@ final class Swift60_UbuntuEndToEndTests: XCTestCase { ) func testAarch64Direct() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64Direct() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withDocker()) } func testX86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withDocker()) } } @@ -420,18 +430,22 @@ final class Swift59_RHELEndToEndTests: XCTestCase { ) func testAarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAmazonLinux2Aarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("amazonlinux2")) } func testAmazonLinux2X86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("amazonlinux2")) } } @@ -446,26 +460,32 @@ final class Swift510_RHELEndToEndTests: XCTestCase { ) func testAarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAmazonLinux2Aarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("amazonlinux2")) } func testAmazonLinux2X86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("amazonlinux2")) } func testFedora39Aarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("fedora39")) } func testFedora39X86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("fedora39")) } } @@ -480,26 +500,32 @@ final class Swift60_RHELEndToEndTests: XCTestCase { ) func testAarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64")) } func testX86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64")) } func testAmazonLinux2Aarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("amazonlinux2")) } func testAmazonLinux2X86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("amazonlinux2")) } func testFedora39Aarch64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("aarch64").withContainerImageSuffix("fedora39")) } func testFedora39X86_64FromContainer() async throws { + try skipSlow() try await buildTestcases(config: config.withArchitecture("x86_64").withContainerImageSuffix("fedora39")) } } From a1ee33397dc3ce741376a15a82f62d23bc265d63 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 12 Mar 2025 10:46:31 +0000 Subject: [PATCH 4/7] Fix formatting in `EndToEndTests.swift` --- Tests/SwiftSDKGeneratorTests/EndToEndTests.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift index 7dbd4a3..d579dcd 100644 --- a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift +++ b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift @@ -345,7 +345,8 @@ func buildTestcases(config: SDKConfiguration) async throws { do { try await FileManager.default.withTemporaryDirectory(logger: logger) { tempDir in try await buildTestcase( - logger, testcase: testcase, bundleName: bundleName, tempDir: tempDir) + logger, testcase: testcase, bundleName: bundleName, tempDir: tempDir + ) } } catch { await cleanupSdk() From 7164b86ea009cb71f9dcec3f5590707107951f04 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 12 Mar 2025 11:05:59 +0000 Subject: [PATCH 5/7] Apply suggestions from code review --- Tests/SwiftSDKGeneratorTests/EndToEndTests.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift index d579dcd..b067fd7 100644 --- a/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift +++ b/Tests/SwiftSDKGeneratorTests/EndToEndTests.swift @@ -336,8 +336,8 @@ func buildTestcases(config: SDKConfiguration) async throws { logger.info("Built Swift SDK") // Cleanup - let cleanupSdk: () async -> Void = { - logger.info("Removing Swift SDK to cleanup...") + func cleanupSDK() async { + logger.info("Removing Swift SDK to clean up...") try? await Shell.run("swift experimental-sdk remove \(bundleName)") } @@ -349,12 +349,12 @@ func buildTestcases(config: SDKConfiguration) async throws { ) } } catch { - await cleanupSdk() + await cleanupSDK() throw error } } - await cleanupSdk() + await cleanupSDK() } final class Swift59_UbuntuEndToEndTests: XCTestCase { From eb5d33d9218137e441eb645665b8f30ac6104a19 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 12 Mar 2025 11:12:33 +0000 Subject: [PATCH 6/7] Fix formatting in `SwiftSDKGenerator+Copy.swift` --- .../SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift index b45e8c2..28334d5 100644 --- a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift +++ b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift @@ -97,7 +97,10 @@ extension SwiftSDKGenerator { for gccVersion in 7...13 { let removePath = "gcc/x86_64-redhat-linux/\(gccVersion)/32" if await doesFileExist(at: sdkUsrLibPath.appending(removePath)) { - logger.warning("Removing 32-bit libraries from RHEL imported sysroot", metadata: ["removePath": .stringConvertible(removePath)]) + logger.warning( + "Removing 32-bit libraries from RHEL imported sysroot", + metadata: ["removePath": .stringConvertible(removePath)] + ) try await removeRecursively(at: sdkUsrLibPath.appending(removePath)) } } From 984124f353d05db8add15810ae7a40feba3bf8d0 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 12 Mar 2025 11:14:15 +0000 Subject: [PATCH 7/7] Remove trailing whitespace in `SwiftSDKGenerator+Copy.swift` --- .../SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift index 28334d5..e1386ac 100644 --- a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift +++ b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift @@ -98,7 +98,7 @@ extension SwiftSDKGenerator { let removePath = "gcc/x86_64-redhat-linux/\(gccVersion)/32" if await doesFileExist(at: sdkUsrLibPath.appending(removePath)) { logger.warning( - "Removing 32-bit libraries from RHEL imported sysroot", + "Removing 32-bit libraries from RHEL imported sysroot", metadata: ["removePath": .stringConvertible(removePath)] ) try await removeRecursively(at: sdkUsrLibPath.appending(removePath))