rules_swift_package_manager icon indicating copy to clipboard operation
rules_swift_package_manager copied to clipboard

Support for other resource file extensions such as `.stencil` and `.png`

Open tinder-cfuller opened this issue 1 year ago • 13 comments

How to include .stencil and .png resources in bundle?

Target resources are defined as resources: [.process("Resources")], and when building with SPM natively, all files are copied to bundle. I could be wrong, but I believe that .process() includes all files, regardless of file type/extension, while performing optimizations for specific types/extensions.

FWIW, resources: [.copy("Resources/Image.png")] is also not working.

In both cases, the following error is reported when running the executable target:

Generator/Generator.rspm_resource_bundle_accessor_ResourceBundleAccessor.swift:42: Fatal error: unable to find bundle

Any help or suggestions are welcome. Thank you!

tinder-cfuller avatar Apr 22 '24 00:04 tinder-cfuller

I just noticed Unable to find dependency labels for s in the log, is it related?

bazelisk run //:update_build_files
INFO: Analyzed target //:update_build_files (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:update_build_files up-to-date:
  bazel-bin/update_build_files-runner.bash
  bazel-bin/update_build_files
INFO: Elapsed time: 0.226s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/update_build_files
gazelle: Unable to find dependency labels for s

tinder-cfuller avatar Apr 22 '24 15:04 tinder-cfuller

I just noticed Unable to find dependency labels for s in the log, is it related?

Not sure.

resources: [.process("Resources")]

Is this in the Package.swift for one of your dependencies or is it in the Package.swift for your repository?

cgrindel avatar Apr 22 '24 22:04 cgrindel

@cgrindel Thank you for taking time to reply. Very much appreciated 👍

The resources are in one of the dependencies.

tinder-cfuller avatar Apr 22 '24 22:04 tinder-cfuller

By any chance is this dependency publicly available, it would be great to add a repro to one of the examples in this repository.

cgrindel avatar Apr 25 '24 00:04 cgrindel

Hi @cgrindel 👋

I published an example dependency for use in attempting to repro my issue:

https://github.com/tinder-cfuller/rspm-example

Since rules_swift_package_manager has been updated since I originally submitted my issue, I am attempting to repro with the latest version that has new instructions.

After following the latest instructions in the README, I am receiving the following error:

$ bazel run //:update_build_files
ERROR: no such package '@@[unknown repo 'swift_deps_info' requested from @@]//': The repository '@@[unknown repo 'swift_deps_info' requested from @@]' could not be resolved: No repository visible as '@swift_deps_info' from main repository
ERROR: /Users/christopherfuller/Downloads/rules_swift_package_manager_debugging/Executable/BUILD.bazel:25:8: no such package '@@[unknown repo 'swift_deps_info' requested from @@]//': The repository '@@[unknown repo 'swift_deps_info' requested from @@]' could not be resolved: No repository visible as '@swift_deps_info' from main repository and referenced by '//:update_build_files'
ERROR: Analysis of target '//:update_build_files' failed; build aborted: Analysis failed
INFO: Elapsed time: 0.150s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
ERROR: Build did NOT complete successfully
ERROR: Build failed. Not running target

If I manually add swift_deps_info to MODULE.bazel, the error of course is:

$ bazel run //:update_build_files
WARNING: /Users/christopherfuller/Downloads/rules_swift_package_manager_debugging/Executable/MODULE.bazel:5:27: The module extension swift_deps defined in @rules_swift_package_manager//:extensions.bzl reported incorrect imports of repositories via use_repo():

Imported, but not created by the extension (will cause the build to fail):
    swift_deps_info

Fix the use_repo calls by running 'bazel mod tidy'.
ERROR: Analysis of target '//:update_build_files' failed; build aborted: module extension "swift_deps" from "@@rules_swift_package_manager~//:extensions.bzl" does not generate repository "swift_deps_info", yet it is imported as "swift_deps_info" in the usage at /Users/christopherfuller/Downloads/rules_swift_package_manager_debugging/Executable/MODULE.bazel:5:27
INFO: Elapsed time: 0.190s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
ERROR: Build did NOT complete successfully
ERROR: Build failed. Not running target

I have attached my sample executable project:

Executable.zip

This can be executed via SPM directly with:

swift run example

Which will output:

Hello World

For reference, I ultimately expect to validate by executing:

bazel run //:example

May you please help me to fix the error I am receiving so I am then able to continue to repo my original issue. Thank you!

tinder-cfuller avatar Jul 20 '24 22:07 tinder-cfuller

@cgrindel Looking through the source code, I found usage of declare_swift_deps_info, which is not currently in the README instructions. Adding this has helped:

swift_deps.from_package(
    declare_swift_deps_info = True, # <- here
    resolved = "//:Package.resolved",
    swift = "//:Package.swift",
)

With this in place, I am able to execute:

bazel run //Sources/ExampleExecutable

But this fails with the same bundle error I reported:

ExampleLibrary/ExampleLibrary.rspm_resource_bundle_accessor_ResourceBundleAccessor.swift:42: Fatal error: unable to find bundle

Here is the up-to-date sample executable project:

Executable.zip

Now that we have a repro example in place, may you please help diagnose the resources issue? Thank you!

[!NOTE] The repro example is only setup for a .stencil file resource, but the reported issue affects other resource types including, but not limited to, png images.

As a reminder, I believe that .process() includes all files, regardless of file type/extension, while performing optimizations for specific types/extensions.

tinder-cfuller avatar Jul 21 '24 00:07 tinder-cfuller

Looking through the source code, I found usage of declare_swift_deps_info, which is not currently in the README instructions. Adding this has helped:

I just put up #1185 to clarify when one needs to specify that attribute. Can you review and let me know if that helps?

Regarding the resource issue, I will take a look now that we have a repro. Thanks!

cgrindel avatar Jul 29 '24 20:07 cgrindel

@cgrindel Thank you!

tinder-cfuller avatar Jul 29 '24 20:07 tinder-cfuller

Hi @cgrindel 👋

I am kindly checking in to see whether you can please look into this issue?

tinder-cfuller avatar Aug 21 '24 22:08 tinder-cfuller

Sorry for the delay, @tinder-cfuller. I am a bit behind on my open-source work. I'll try to look at it this weekend.

cgrindel avatar Aug 21 '24 23:08 cgrindel

There are a couple of issues.

First, to use resources with Bazel-built Apple applications, you must use a rules_apple rule that supports resources (e.g. macos_application, ios_application). This means that you need to change the example so that ExampleExecutable is a macos_application instead of a swift_binary.

Second: However, as @tinder-cfuller rightly points out, SPM allows you to create a command-line application that can access resources. Unfortunately, macos_command_line_application does not. In theory, I think that we need to update rules_apple to support resources. Then, the example could be defined as

load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
load("@rules_apple//apple:macos.bzl", "macos_command_line_application")
load(
    "@rules_apple//apple:versioning.bzl",
    "apple_bundle_version",
)

swift_library(
    name = "ExampleExecutableLib",
    srcs = ["ExampleExecutable.swift"],
    module_name = "ExampleExecutable",
    visibility = ["//visibility:public"],
    deps = ["@swiftpkg_rspm_example//:ExampleLibrary"],
)

apple_bundle_version(
    name = "CommandLineSwiftVersion",
    build_version = "1.0",
)

macos_command_line_application(
    name = "ExampleExecutable",
    bundle_id = "com.example.command-line-swift",
    infoplists = [":Info.plist"],
    minimum_os_version = "10.13",
    version = ":CommandLineSwiftVersion",
    deps = [":ExampleExecutableLib"],
) 

@brentleyjones @luispadron Do you have thoughts on adding resource bundle support to macos_command_line_application?

cgrindel avatar Aug 24 '24 22:08 cgrindel

Thank you @cgrindel 👍 Very much appreciated!

And just for my own Bazel learning, may you please clarify, would the example Bazel config you provided ultimately be code generated just like the swift_binary one is today? Asking since I was considering adopting rules_swift_package_manager as a way to avoid manually creating and maintaining BUILD files.

Also, are we sure that macos_command_line_application would be required? I would very much like to see a Bazel solution that matches how SPM works as apposed to xcodebuild for example. This would result in the same bundle format and without the property list, etc. And I am not familiar enough the resulting binary formats, but I would guess that the SPM format is different. Ultimately, if I have some consumers that consume this executable via SPM and some via Bazel, I would expect that the executable and bundle formats are the same.

tinder-cfuller avatar Aug 25 '24 01:08 tinder-cfuller

would the example Bazel config you provided ultimately be code generated just like the swift_binary one is today?

Yes and no. It will generate the swift_binary as you saw. However, if you change it to a swift_library, it should respect that and apply any future changes to the swift_library. The gazelle plugin does not support any of the rules_apple targets, at this time.

Asking since I was considering adopting rules_swift_package_manager as a way to avoid manually creating and maintaining BUILD files.

Great. FYI. Per a request from the community, I am working to separate the Gazelle plugin from the rules_swift_package_manager. In the coming months, they will be two separate projects.

are we sure that macos_command_line_application would be required?

Well, all of the Apple bundle support is implemented in rules_apple rules. The Bazel rules try to separate Swift from the Apple-specific functionality. Swift Package Manager does not.

I would expect that the executable and bundle formats are the same.

By any change, did you try your example on Linux? Did it work? If so, that could be a good argument for adding the resource bundling to the Swift Bazel rules. 🤷‍♂️ @brentleyjones @luispadron Do you have any thoughts on this?

cgrindel avatar Aug 25 '24 14:08 cgrindel