Skip to content

Build: pass through Embedded flag to link jobs #7304

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

Merged
merged 5 commits into from
Feb 21, 2024

Conversation

MaxDesiatov
Copy link
Contributor

Motivation:

Without passing this flag, Swift Driver links such products as if they're not built for embedded platforms at all, passing incorrect flags to the linker. This is not reproducible when using plain swiftc, as that combines both compile and link jobs by default, but SwiftPM prefers to run those separately, which requires this special handling.

Modifications:

Directly checking in ProductBuildDescription/linkArguments whether all of the product's targets are built in the embedded mode. If so, we're passing the embedded mode flag to Swift Driver.

Unfortunately, BuildSettings.AssignmentTable is formed too early in the build process right in PackageModel, while we still need to run checks specific build settings quite late in the build stage. Because of that, there's no clean way to check if Embedded flag is passed other than directly rendering BuildSettings.Scope to a string and running a substring check on that. In the future we should move BuildSettings out of PackageModel, ensuring that SwiftPM clients don't rely on this behavior anymore.

Result:

Products that have targets using Embedded Swift can be built with SwiftPM, assuming that Swift Driver handles other linker flags correctly.

@MaxDesiatov MaxDesiatov added bug build system Changes to interactions with build systems labels Jan 29, 2024
@MaxDesiatov MaxDesiatov requested a review from rauhul January 29, 2024 15:47
@MaxDesiatov MaxDesiatov self-assigned this Jan 29, 2024
@MaxDesiatov MaxDesiatov force-pushed the maxd/fix-embedded-linking branch 2 times, most recently from 6840d35 to 8fc6189 Compare January 29, 2024 15:50
@MaxDesiatov MaxDesiatov enabled auto-merge (squash) January 29, 2024 15:51
@MaxDesiatov
Copy link
Contributor Author

@swift-ci test

@neonichu
Copy link
Contributor

I think we should vend the used experimental/upcoming flags as a separate API at the model level instead of parsing the generated flags after the fact. Whenever we resorted to parsing flags like this in the past it only lead to future issues.

It also seems like we shouldn't limit this to one particular feature flag, adding special handling like that is the opposite of what the feature flags are supposed to accomplish. Can we just pass each of them to the link invocation?

@rauhul
Copy link
Member

rauhul commented Feb 3, 2024

Would it not be more prudent to pass the flags to the integrated driver? The swift-driver should be the source of truth. I would love to see the concept of "unsafe flags" removed entirely

@MaxDesiatov
Copy link
Contributor Author

Would it not be more prudent to pass the flags to the integrated driver?

I'm not sure we use the integrated driver in all cases, probably we don't use it by default at all, at least that was my understanding. Maybe @neonichu can clarify.

@neonichu
Copy link
Contributor

neonichu commented Feb 5, 2024

Yes, we're not using the integrated driver by default, IIRC the current integration is more of a prototype.

@MaxDesiatov
Copy link
Contributor Author

@swift-ci test

@MaxDesiatov
Copy link
Contributor Author

MaxDesiatov commented Feb 16, 2024

I think we should vend the used experimental/upcoming flags as a separate API at the model level instead of parsing the generated flags after the fact. Whenever we resorted to parsing flags like this in the past it only lead to future issues.

It also seems like we shouldn't limit this to one particular feature flag, adding special handling like that is the opposite of what the feature flags are supposed to accomplish. Can we just pass each of them to the link invocation?

@neonichu this is addressed now by storing a new property of type [TargetBuildSettingDescription.Setting] on Target from PackageModel, which we then process in func linkArguments() of ProductBuildDescription.

Ready for review.

Without passing this flag, Swift Driver links such products as if they're not built for embedded platforms at all, passing incorrect flags to the linker. This is not reproducible when using plain `swiftc`, as that combines both compile and link jobs by default, but SwiftPM prefers to run those separately, which requires this special handling.

### Modifications:

Directly checking in `ProductBuildDescription/linkArguments` whether all of the product's targets are built in the embedded mode. If so, we're passing the embedded mode flag to Swift Driver.

Unfortunately, `BuildSettings.AssignmentTable` is formed too early in the build process right in `PackageModel`, while we still need to run checks specific build settings quite late in the build stage. Because of that, there's no clean way to check if `Embedded` flag is passed other than directly rendering `BuildSettings.Scope` to a string and running a substring check on that. In the future we should move `BuildSettings` out of `PackageModel`, ensuring that SwiftPM clients don't rely on this behavior anymore.

### Result:

Products that have targets using Embedded Swift can be built with SwiftPM, assuming that Swift Driver handles other linker flags correctly.
@MaxDesiatov MaxDesiatov force-pushed the maxd/fix-embedded-linking branch from b47c2c7 to 4c2d55a Compare February 16, 2024 16:35
@MaxDesiatov
Copy link
Contributor Author

@swift-ci test

@MaxDesiatov
Copy link
Contributor Author

@swift-ci test windows

@MaxDesiatov
Copy link
Contributor Author

@swift-ci test

@MaxDesiatov
Copy link
Contributor Author

@swift-ci test windows

@MaxDesiatov
Copy link
Contributor Author

@swift-ci test

@MaxDesiatov
Copy link
Contributor Author

@swift-ci test windows

1 similar comment
@MaxDesiatov
Copy link
Contributor Author

@swift-ci test windows

// Pass experimental features to link jobs in addition to compile jobs. Preserve ordering while eliminating
// duplicates with `OrderedSet`.
var experimentalFeatures = OrderedSet<String>()
for target in self.product.targets {
Copy link
Member

@kateinoigakukun kateinoigakukun Feb 21, 2024

Choose a reason for hiding this comment

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

I'm not sure what is the semantically correct way, but should we collect features from transitive dependencies too? Or it's it fine to collect from only top-level targets as is now?

Either way, it would be better to cover transitive dependencies in test cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is tricky, in my testing the embedded mode doesn't even support multiple modules in the same product right now, or at least SwiftPM is not ready for that yet. When we unblock that in a future PR, we can look into transitive dependencies support too.

@MaxDesiatov MaxDesiatov merged commit c82304c into main Feb 21, 2024
@MaxDesiatov MaxDesiatov deleted the maxd/fix-embedded-linking branch February 21, 2024 10:53
furby-tm pushed a commit to wabiverse/swift-package-manager that referenced this pull request May 15, 2024
### Motivation:

Without passing this flag, Swift Driver links such products as if
they're not built for embedded platforms at all, passing incorrect flags
to the linker. This is not reproducible when using plain `swiftc`, as
that combines both compile and link jobs by default, but SwiftPM prefers
to run those separately, which requires this special handling.

### Modifications:

Directly checking in `ProductBuildDescription/linkArguments` whether all
of the product's targets are built in the embedded mode. If so, we're
passing the embedded mode flag to Swift Driver.

Unfortunately, `BuildSettings.AssignmentTable` is formed too early in
the build process right in `PackageModel`, while we still need to run
checks specific build settings quite late in the build stage. Because of
that, there's no clean way to check if `Embedded` flag is passed other
than directly rendering `BuildSettings.Scope` to a string and running a
substring check on that. In the future we should move `BuildSettings`
out of `PackageModel`, ensuring that SwiftPM clients don't rely on this
behavior anymore.

### Result:

Products that have targets using Embedded Swift can be built with
SwiftPM, assuming that Swift Driver handles other linker flags
correctly.
furby-tm pushed a commit to wabiverse/swift-package-manager that referenced this pull request May 15, 2024
### Motivation:

Without passing this flag, Swift Driver links such products as if
they're not built for embedded platforms at all, passing incorrect flags
to the linker. This is not reproducible when using plain `swiftc`, as
that combines both compile and link jobs by default, but SwiftPM prefers
to run those separately, which requires this special handling.

### Modifications:

Directly checking in `ProductBuildDescription/linkArguments` whether all
of the product's targets are built in the embedded mode. If so, we're
passing the embedded mode flag to Swift Driver.

Unfortunately, `BuildSettings.AssignmentTable` is formed too early in
the build process right in `PackageModel`, while we still need to run
checks specific build settings quite late in the build stage. Because of
that, there's no clean way to check if `Embedded` flag is passed other
than directly rendering `BuildSettings.Scope` to a string and running a
substring check on that. In the future we should move `BuildSettings`
out of `PackageModel`, ensuring that SwiftPM clients don't rely on this
behavior anymore.

### Result:

Products that have targets using Embedded Swift can be built with
SwiftPM, assuming that Swift Driver handles other linker flags
correctly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug build system Changes to interactions with build systems
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants