-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add cxx interop support to symbolgraph-extract #7610
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
Conversation
98ef23c
to
0cd1433
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind adding a test to make sure this doesn't regress in the future/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic mostly duplicates the existing solution that forwards the C++ interop compat version flag to the test discovery target: https://github.com/apple/swift-package-manager/blob/8d419298fe880c44692a757c92ee5ab5d3b6d6f3/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift#L555-L574
I think it's worth extracting and reusing it.
} | ||
} | ||
if cxxInterop { | ||
commandLine += ["-cxx-interoperability-mode=default"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some projects use a non-default compat version (e.g. swift-5.9
), we should forward the actual version here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont see anything in SwiftPM that currents sets a non-"default" value and based on the PackageModel I dont see how a user can even select a "non-default compat version"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this support was removed in #6583
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is still possible to pass a custom C++ interop compat version, for example:
swiftSettings: [
.unsafeFlags(["-cxx-interoperability-mode=upcoming-swift"])
]
345fe41
to
f9bb69f
Compare
@MaxDesiatov @egorzhdan @daniel-grumberg I've refactored this with (a lot of) guidance from @neonichu, please take another look |
Using:
Via:
I am able to properly generate docs. Running based on
When running I think both of these issues are unrelated to my change here and should be handled independently. |
In order to extract symbol graphs for modules with transitive imports on cxx modules we need parse headers in cxx mode using the option: `-cxx-interoperability-mode=default`. This commit updates `swift-symbolgraph-extract` to pass the option when there is a Cxx module in the import graph. This option is a new addition to `swift-symbolgraph-extract` added in swiftlang/swift#73963. Prior to this option's introduction, extracting the symbol graph for cxx dependent modules would fail with an error similar to: "unknown type name 'namespace'". With this SwiftPM commit and `swift-symbolgraph-extract` _prior_ to 73963, users will instead see an argument parsing error like: "unknown option -cxx-interoperability-mode". With this change and `swift-symbolgraph-extract` 73963, the symbol graph is extracted properly.
4dcd4e4
to
9e5cfa2
Compare
/// If the current module or any of its linked dependencies requires cxx | ||
/// interop, cxx interop will be enabled on the current module. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually want to implicitly enable C++ interop for anything other than the test discovery target or the symbolgraph target.
One of the reasons for that is that C++ interop is incompatible with Swift's library evolution. If a dependency of your project uses C++ internally, without re-exporting any C++ symbols, you don't need to enable C++ interop and can keep library evolution enabled.
try XCTAssertMatch( | ||
result.target(for: "swiftLib2").swiftTarget().compileArguments(), | ||
[.anySequence, "-cxx-interoperability-mode=default", "-Xcc", "-std=c++20", .anySequence] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assertion needs to be reversed: unless the Swift target explicitly enables C++ interop, we should not pass these flags to the compiler.
@swift-ci test |
@swift-ci smoke test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM from the perspective of C++ interop.
I would probably wait for someone from the SwiftPM side of things to give a thumbs up as well before merging 😉
var args = [String]() | ||
args += try self.cxxInteroperabilityModeArguments( | ||
propagateFromCurrentModuleOtherSwiftFlags: true) | ||
return args |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be simplified to just return self.cxxInteroperabilityModeArguments(propagateFromCurrentModuleOtherSwiftFlags: true)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A follow up PR adds to args so I'd like to leave this as is
|
||
/// Determines the arguments needed to run `swift-symbolgraph-extract` for | ||
/// this module. | ||
public func symbolGraphExtractArguments() throws -> [String] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public func symbolGraphExtractArguments() throws -> [String] { | |
package func symbolGraphExtractArguments() throws -> [String] { |
|
||
/// Determines the arguments needed to run `swift-symbolgraph-extract` for | ||
/// this module. | ||
public func symbolGraphExtractArguments() throws -> [String] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public func symbolGraphExtractArguments() throws -> [String] { | |
package func symbolGraphExtractArguments() throws -> [String] { |
@@ -207,6 +207,20 @@ public final class ClangTargetBuildDescription { | |||
} | |||
} | |||
|
|||
/// Determines the arguments needed to run `swift-symbolgraph-extract` for | |||
/// this module. | |||
public func symbolGraphExtractArguments() throws -> [String] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public func symbolGraphExtractArguments() throws -> [String] { | |
package func symbolGraphExtractArguments() throws -> [String] { |
@MaxDesiatov do you mind if I fix the |
func cxxInteroperabilityModeAndStandard( | ||
for module: ResolvedModule | ||
) -> [String]? { | ||
let scope = self.buildParameters.createScope(for: module) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct to use buildParameters
of the context here for dependency scopes? What if if this i.e. executable target that has a plugin or a macro dependency and that in turn has other dependencies, we'd use "destination" parameters for their scope, which seems counter-intuitive?
It seems like we need to avoid adding new uses of recursiveTargetDependencies()
in this context when build parameters are involved, because they are strongly connected to a destination, and instead traverse a build plan graph and use TargetDependencyDescription
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not change this logic in this PR, im simply moving the existing code such that symbol graph can use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'm mentioning this because of the comment - Move logic from PackageBuilder here.
, I don't think that would be possible to do because of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the point of that comment is to say, we should not throw away the typed interop information at that layer and try to recover it here by parsing flags, we should instead determine the flags at this layer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could do the same thing as .SWIFT_VERSION
and add a new declaration for assigments like that which means that you won't need to deal with prefixes here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mean it has to be in this PR, just an idea how to avoid having to prefix match things...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditional onpackage
changes Max suggested.
In order to extract symbol graphs for modules with transitive imports on C++ modules we need parse headers in C++ interop mode using the option: `-cxx-interoperability-mode=default`. This commit updates `swift-symbolgraph-extract` to pass the option when there is a C++ module in the import graph. This option is a new addition to `swift-symbolgraph-extract` added in swiftlang/swift#73963. Prior to this option's introduction, extracting the symbol graph for C++ dependent modules would fail with an error similar to: "unknown type name 'namespace'". With this SwiftPM commit and `swift-symbolgraph-extract` _prior_ to swiftlang/swift#73963, users will instead see an argument parsing error like: "unknown option -cxx-interoperability-mode". With this change and `swift-symbolgraph-extract` change in swiftlang/swift#73963, the symbol graph is extracted properly.
In order to extract symbol graphs for modules with transitive imports on C++ modules we need parse headers in C++ interop mode using the option: `-cxx-interoperability-mode=default`. This commit updates `swift-symbolgraph-extract` to pass the option when there is a C++ module in the import graph. This option is a new addition to `swift-symbolgraph-extract` added in swiftlang/swift#73963. Prior to this option's introduction, extracting the symbol graph for C++ dependent modules would fail with an error similar to: "unknown type name 'namespace'". With this SwiftPM commit and `swift-symbolgraph-extract` _prior_ to swiftlang/swift#73963, users will instead see an argument parsing error like: "unknown option -cxx-interoperability-mode". With this change and `swift-symbolgraph-extract` change in swiftlang/swift#73963, the symbol graph is extracted properly.
In order to extract symbol graphs for modules with transitive imports on C++ modules we need parse headers in C++ interop mode using the option:
-cxx-interoperability-mode=default
. This commit updatesswift-symbolgraph-extract
to pass the option when there is a C++ module in the import graph.This option is a new addition to
swift-symbolgraph-extract
added in swiftlang/swift#73963.Prior to this option's introduction, extracting the symbol graph for C++ dependent modules would fail with an error similar to: "unknown type name 'namespace'".
With this SwiftPM commit and
swift-symbolgraph-extract
prior to swiftlang/swift#73963, users will instead see an argument parsing error like: "unknown option -cxx-interoperability-mode".With this change and
swift-symbolgraph-extract
change in swiftlang/swift#73963, the symbol graph is extracted properly.