rules_xcodeproj icon indicating copy to clipboard operation
rules_xcodeproj copied to clipboard

Feature Request: Rule argument for the bazel build config

Open CognitiveDisson opened this issue 3 years ago • 11 comments

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.

CognitiveDisson avatar Jul 05 '22 09:07 CognitiveDisson

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.

brentleyjones avatar Jul 05 '22 12:07 brentleyjones

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?

jfirebaugh avatar Jul 27 '22 01:07 jfirebaugh

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 ./.

brentleyjones avatar Jul 27 '22 02:07 brentleyjones

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

jfirebaugh avatar Jul 27 '22 03:07 jfirebaugh

Figured out that that's caused by the echo in the wrapper.

jfirebaugh avatar Jul 27 '22 04:07 jfirebaugh

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

jfirebaugh avatar Jul 27 '22 04:07 jfirebaugh

I don't reproduce that error. There was a build error, but uses the latest on main fixed that:

CleanShot 2022-07-27 at 08 23 19@2x

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.

brentleyjones avatar Jul 27 '22 13:07 brentleyjones

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

jfirebaugh avatar Jul 27 '22 16:07 jfirebaugh

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

brentleyjones avatar Jul 27 '22 17:07 brentleyjones

It still happens if I change the wrapper to build | run | test | info).

jfirebaugh avatar Jul 27 '22 18:07 jfirebaugh

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.

brentleyjones avatar Jul 27 '22 18:07 brentleyjones

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.

brentleyjones avatar Sep 08 '22 21:09 brentleyjones