Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support background indexing when cross-compiling #1923

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

kabiroberai
Copy link
Contributor

Previously, if you selected a Swift SDK via the swiftPM.swiftSDK configuration option, background indexing would fail because the swift build --experimental-prepare-for-indexing invocation did not pass along the --swift-sdk argument. This PR fixes this by passing along that flag (+ other relevant cross-compilation flags) to swift build.

Best I can tell, the reason this was previously missing is simply that the PRs that added these two features (background indexing and Swift SDK support) were being worked on in parallel and didn't end up accounting for each other. Fortunately it's a trivial fix.

@kabiroberai kabiroberai requested a review from ahoppen as a code owner January 16, 2025 04:32
@kabiroberai
Copy link
Contributor Author

Would be nice to add tests for this but as far as I can tell BackgroundIndexingTests are all integration-type tests so we'd need a real Swift SDK fixture to test with. Any suggestions on approaches I could take? A few options come to mind:

  • Use the implicit Darwin SDKs that are available on macOS (--swift-sdk arm64-apple-ios), though this would require the tests to be gated by #if os(macOS)
  • Create a complete Swift SDK fixture, but this feels like a lot of boilerplate
  • Make this more of a unit test than an integration test — i.e. just check that we're passing along --swift-sdk foo to swift build. Unsure how best to fit this into the existing set of tests for the background indexing feature though.

@ahoppen
Copy link
Member

ahoppen commented Jan 16, 2025

Thank you @kabiroberai. Looks like I indeed just missed passing those options through. Regarding a test case: If you can conjure one up with the iOS SDK, that would be great. To account for Xcode installations that might not include an iOS SDK, I think we should guard it behind a SkipUnless that check if a basic package can be compiled withswift build --triple arm64-apple-ios. That should give us sufficient coverage.

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test looks great. Thanks for adding it. I have two suggestions that should allow us to reduce the code in SkipUnless a little further.

Comment on lines 492 to 506
let project = try await SwiftPMTestProject(
files: [
"Lib/MyFile.swift": """
public func foo() {}
""",
],
manifest: """
let package = Package(
name: "MyLibrary",
targets: [
.target(name: "Lib"),
]
)
"""
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should be able to reduce this a little bit further to

Suggested change
let project = try await SwiftPMTestProject(
files: [
"Lib/MyFile.swift": """
public func foo() {}
""",
],
manifest: """
let package = Package(
name: "MyLibrary",
targets: [
.target(name: "Lib"),
]
)
"""
)
let project = try await SwiftPMTestProject(
files: [
"MyFile.swift": """
public func foo() {}
"""
)

Comment on lines 508 to 519
var arguments = [
try swift.filePath, "build", "--package-path", try project.scratchDirectory.filePath, "--target", "Lib",
"--swift-sdk", "arm64-apple-ios",
]
if let globalModuleCache = try globalModuleCache {
arguments += ["-Xswiftc", "-module-cache-path", "-Xswiftc", try globalModuleCache.filePath]
}
let status = try await Process.run(arguments: arguments, workingDirectory: nil)
guard case .terminated(code: 0) = status.exitStatus else {
let error = (try? String(decoding: status.stderrOutput.get(), as: UTF8.self)) ?? "unknown error"
return .featureUnsupported(skipMessage: "Cannot build for iOS: \(error)")
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be the following?

Suggested change
var arguments = [
try swift.filePath, "build", "--package-path", try project.scratchDirectory.filePath, "--target", "Lib",
"--swift-sdk", "arm64-apple-ios",
]
if let globalModuleCache = try globalModuleCache {
arguments += ["-Xswiftc", "-module-cache-path", "-Xswiftc", try globalModuleCache.filePath]
}
let status = try await Process.run(arguments: arguments, workingDirectory: nil)
guard case .terminated(code: 0) = status.exitStatus else {
let error = (try? String(decoding: status.stderrOutput.get(), as: UTF8.self)) ?? "unknown error"
return .featureUnsupported(skipMessage: "Cannot build for iOS: \(error)")
}
try await SwiftPMTestProject.build(at: try project.scratchDirectory, extraArguments: ["--swift-sdk", "arm64-apple-ios"])

@kabiroberai
Copy link
Contributor Author

Good callouts, ty!

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Looks good.

@ahoppen
Copy link
Member

ahoppen commented Jan 16, 2025

@swift-ci Please test

@ahoppen ahoppen enabled auto-merge (squash) January 16, 2025 18:49
@ahoppen
Copy link
Member

ahoppen commented Jan 16, 2025

Could you format your changes? (https://github.com/swiftlang/sourcekit-lsp/blob/main/CONTRIBUTING.md#formatting)

Also looks like the new test failed on Linux, though I’m not sure why the skipping wouldn’t work. Could you take a look?

@kabiroberai
Copy link
Contributor Author

Can format, my bad! As for the test not being skipped on Linux, it looks like skipUnlessSupported intentionally no-ops on CI by default:

} else if ProcessEnv.block["SWIFTCI_USE_LOCAL_DEPS"] != nil && !allowSkippingInCI {
// In general, don't skip tests in CI. Toolchain should be up-to-date
checkResult = .featureSupported

Looks like we can override this with allowSkippingInCI: true though; I'll go ahead and do that. There's an argument to be made that we should pass allowSkippingInCI: false on macOS, but I'm not sure whether the CI setup always includes the iOS SDK so will be conservative with this for now.

auto-merge was automatically disabled January 17, 2025 04:43

Head branch was pushed to by a user without write access

Feedback

More cleanup

Allow skipping canSwiftPMCompileForIOS on CI

Format
@kabiroberai
Copy link
Contributor Author

Formatted and fixed the CI issue. I think we should be good now!

@ahoppen
Copy link
Member

ahoppen commented Jan 17, 2025

Ah, completely forgot about allowSkippingInCI. Thanks for finding it. I think it’s good enough to skip it on macOS because the iOS SDK might not be installed in Xcode either (not that I would expect this on Swift CI nodes but who knows).

@ahoppen
Copy link
Member

ahoppen commented Jan 17, 2025

@swift-ci Please test

@ahoppen ahoppen enabled auto-merge January 17, 2025 16:25
@kabiroberai
Copy link
Contributor Author

@ahoppen Linux + macOS CI is green, do we need to request a Windows run?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants