rules_swift_package_manager icon indicating copy to clipboard operation
rules_swift_package_manager copied to clipboard

Public access to all targets declared in packages

Open sewerynplazuk opened this issue 1 year ago • 11 comments

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?

sewerynplazuk avatar Feb 21 '24 08:02 sewerynplazuk

I don't feel strongly about the visibility of the generated targets.

@brentleyjones Do you have any thoughts?

cgrindel avatar Feb 21 '24 13:02 cgrindel

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.

brentleyjones avatar Feb 21 '24 13:02 brentleyjones

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.

brentleyjones avatar Feb 21 '24 13:02 brentleyjones

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_manager is 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 avatar Feb 21 '24 15:02 acecilia

@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).

sewerynplazuk avatar Feb 21 '24 17:02 sewerynplazuk

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.

brentleyjones avatar Feb 21 '24 19:02 brentleyjones

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.

cgrindel avatar Feb 21 '24 20:02 cgrindel

@brentleyjones spm-to-xcframework, let me know if that helps.

sewerynplazuk avatar Feb 22 '24 16:02 sewerynplazuk

That does help. I need to think on this more.

brentleyjones avatar Feb 23 '24 19:02 brentleyjones

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 avatar Feb 23 '24 19:02 brentleyjones

@brentleyjones Great, that should work for us. I'll prepare the change.

sewerynplazuk avatar Feb 25 '24 07:02 sewerynplazuk