rules_swift_package_manager
rules_swift_package_manager copied to clipboard
Public access to all targets declared in packages
In the latest release - 0.28.0 - the underlying targets declared by the packages were hidden. As I understand the change was introduced in https://github.com/cgrindel/rules_swift_package_manager/pull/883. I generally agree with the view that you need to rely on the library products rather than the underlying targets but not in all cases.
I use these rules to generate BUILD files for SPM packages, so I can wrap them in XCFrameworks and use them for internal distribution. To do this, access to the underlying targets is crucial. Thus my question, can we restore public access to these targets, perhaps under a feature toggle?
I don't feel strongly about the visibility of the generated targets.
@brentleyjones Do you have any thoughts?
The visibility is to enforce the same restriction that SPM has: you depend on the products of Swift packages, nothing else. So, in an SPM world, I don't believe you are able to do what you are trying to do, can you? If I'm wrong there, then yes, let's open them up. Or, if you can give a concrete example of how the current way fails, maybe there is a different solution than opening up the visibility.
If this is just because you need a product that is a subset of another product, you could patch the package to add that product in. But I have a feeling that's not the root issue here.
I don't believe you are able to do what you are trying to do, can you?
Agree. This is actually a bazel-only feature.
I can give some of my context of the usecase:
- AFAIK when using SPM is only supported to create dynamic frameworks from a swift package. But not static frameworks. I think the issue is very well explained here
- A workaround is to rewrite the dependency-tree with another system such as cocoapods/xcodegen that allows to obtain a xcodeproj, and use the usual scripts/carthage/xcodebuild to create a prebuilt framework. The problem is when the dependency-tree is so complex/big that rewriting it is unattainable effort (example: GRPC only supports SPM in recent versions)
- But thanks to
rules_swift_package_manager+ bazel, is possible to generate prebuilt dynamic/static framework from swift packages.rules_swift_package_manageris able to auto-generate the dependency-tree as bazel targets, and bazel is able to create prebuilt frameworks for them. So far I have not found any other tool that can do so
For extra context, this PR is based on the same usecase: need to disable library evolution in order to create the prebuilt frameworks
@acecilia described the problem very well. In short, a framework can contain only one module (aka SPM target), a product can depend on multiple targets. With only access to the product, I can't create all the necessary artifacts to distribute internally prebuilt binaries.
If this is just because you need a product that is a subset of another product, you could patch the package to add that product in. But I have a feeling that's not the root issue here.
This technically may work (manually creating products for all the targets), but it does not solve the problems with complex dependency trees that @acecilia mentioned (they need to be maintained).
Could you provide an example repro for what you are trying to do. It would help me fully wrap my head around this. In the end we might allow changing the visibility, but I want to make sure there isn't another option first.
I agree with @brentleyjones. If we proceed with adjusting the visibility, I would like to add it as an option set in MODULE.bazel. Also, we will want to document the option as "use at your own risk". After the 1.0 release, we should ensure that the publicly visible targets are stable. Anything that is not public by default is fair game to change without a major version bump.
@brentleyjones spm-to-xcframework, let me know if that helps.
That does help. I need to think on this more.
I think we can do this with a flag, preferably set per-package, with a disclaimer that the format of the labels can change between rules_swift_package_manager releases without us having to bump our major version (really that the targets themselves are an implementation detail), and that SPM counts those targets as non-public API as well.
@sewerynplazuk could you take on the work to implement this PR?
@brentleyjones Great, that should work for us. I'll prepare the change.