rules_xcodeproj
rules_xcodeproj copied to clipboard
Feature Request: Rule argument for the bazel build config
In some cases it is useful to specify the configuration only for building from Xcode. It would be useful to have something like this:
xcodeproj(
name = "xcodeproj",
project_name = "App",
bazel_build_config = "rules_xcodeproj"
...
)
And if this argument is specified, it will be passed to all calls to bazel.
For example for the build call in BazelDependencies: bazel build --config=rules_xcodeproj ...
Note: Now we can achieve the same behavior by setting a custom bazel_path to the wrapper script, which will add the config as a parameter. But this is not really convenient.
Because bazel configs can't be applied via a transition, doing this would require the same config to be applied when calling bazel run (or you will encounter this bug).
Right now the recommended solution is to apply the config in a bazel wrapper, to ensure that it's applied when generating the project and when Xcode calls into the wrapper (set via the bazel attribute).
Figuring out a wholistic solution to this is the goal of a future milestone. We will most likely create a script to invoke bazel run (or a script to create a script...) to allow us to apply things on both ends. Then instead of using an attribute on xcodeproj, we would set a value on a starlark build setting.
Is there an example for a wrapper script? It looks like bazel_path requires either an absolute path or an executable that's on $PATH. What should I set if I want to use a script that's checked into the workspace?
bazel_path is invoked from $SRCROOT, which is the root of the workspace, so a relative path should work. You might need to prefix it with ./.
Okay, I got further with a ./ prefix but I'm still stuck. Here's a minimal repro: https://github.com/jfirebaugh/rules_xcode_reduction/tree/454cf9eef2e7c5464147f43b6e75ade1bcd3911c.
When I run ./wrapper.sh run :xcodeproj && open open app.xcodeproj/ and then build in Xcode, I get:
error: Bazel didn't generate the correct files (it should have generated outputs for output group "generated_inputs darwin-dbg", but the timestamp for "bazel info --compilation_mode=dbg --color=no --experimental_convenience_symlinks=ignore --symlink_prefix=/ --bes_backend= --bes_results_url= output_path
Figured out that that's caused by the echo in the wrapper.
Now the issue I have is that when I open the Xcode project, something generates a directory named --compilation_mode=dbg/ with what looks like the contents of a Bazel output directory (execroot, server, DO_NOT_BUILD_HERE, etc.).
I assume something is invoking the wrapper with some unexpected initial argument, but it's difficult to figure out what or how I should write the wrapper instead.
https://github.com/jfirebaugh/rules_xcode_reduction/tree/86491746e9ae87d6b1f640050e40f887948796fb
I don't reproduce that error. There was a build error, but uses the latest on main fixed that:
Btw, --compilation_mode=dbg won't do anything, as there is a transition that forces compilation_mode to a certain value (dbg in this case). Here are the values that you can't change right now: https://github.com/buildbuddy-io/rules_xcodeproj/blob/51e4361f1f4acef2bed2b062ec433e8d38455044/xcodeproj/internal/xcodeproj_rule.bzl#L401-L419
Also, if you do get error: Bazel didn't generate the correct files, it might be because you changed the wrapper and need to re-generate the project.
I eventually got the minimized test case working with:
case "$1" in
build | run | test)
args=("$@")
bazel "${args[0]}" --compilation_mode=dbg "${args[@]:1}"
;;
*)
bazel "$@"
;;
esac
I still haven't got it working in the real-world project though. I do get the "Bazel didn't generate the correct files" error. sudo rm -rf ~/Library/Developer/Xcode/DerivedData/* && rm -rf app.xcodeproj/ && bazel clean && bazel shutdown doesn't help. Unfortunately all my attempts to create a minimal test case wind up working.
(--compilation_mode=dbg was just an example, the real-world project uses --config=debug which sets a variety of flags via .bazelrc.)
The Bazel didn't generate the correct files error means that the effective bazel envionment used during project generation (./wrapper.sh run) differs from when bazel_path is called inside of Xcode. That very much includes ./wrapper.sh info as well (which your above version excludes).
It still happens if I change the wrapper to build | run | test | info).
The type of change you are applying then can't be done this way. Something about it is causing the configuration for targets to be different when Xcode is invoking the wrapper versus when you invoke the wrapper on the command line.
So this is mostly done. The rules_xcodeproj and rules_xcodeproj_* configs are defined and can be extended in your .bazelrc file: https://github.com/buildbuddy-io/rules_xcodeproj/blob/cf20e53117780eb0912a3314948bccc83af872bf/xcodeproj/internal/bazel_integration_files/xcodeproj.bazelrc
I'm not closing this yet though, as I feel this issue can represent the desire to have per-xcodeproj configuration, which isn't currently supported.