rules_xcodeproj builds targets in its own output base, separate from the primary Bazel output base. It does this to prevent project generation — and other Bazel commands you run in your terminal — from polluting the analysis cache that Xcode depends on. Because of this isolation, running plainDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/MobileNativeFoundation/rules_xcodeproj/llms.txt
Use this file to discover all available pages before exploring further.
bazel build or bazel clean in your terminal operates in a different environment than what Xcode uses.
The command-line API bridges that gap. It lets you run any Bazel command in the exact same environment — same output base, same configs, same transitions — that rules_xcodeproj uses when Xcode invokes Bazel.
Running
bazel clean in your terminal will not affect the rules_xcodeproj output base. Use bazel run //:xcodeproj -- clean to clean the rules_xcodeproj environment instead.Basic invocation
Assuming yourxcodeproj target is at //:xcodeproj, the general form is:
-- is handled by the rules_xcodeproj runner. The command_string is a Bazel command plus any Bazel flags, quoted as a single shell argument when it contains spaces. Options (prefixed with - or --) go before the command string.
Commands
The API supports all standard Bazel commands. Startup options are not supported through the API; use the workspacexcodeproj.bazelrc for those instead.
build
Building by label through the API builds the correct, fully-transitioned version of your targets — the same version Xcode builds. If you specify a raw label, you may get a differently-configured artifact (different cache key, different transition hash).
The recommended approach is to use --generator_output_groups (described in the Options section) rather than a raw label:
clean
Use the API’s clean command to clean the rules_xcodeproj output base:
bazel clean in your terminal cleans the primary output base but leaves the rules_xcodeproj output base untouched. bazel clean --expunge does wipe both, since it removes the entire output root.
query / cquery / aquery
For query you may be able to run it without the API (depending on your config), but it is recommended to use the API to avoid fetching external dependencies in the primary output base. For cquery and aquery, always use the API to ensure targets are properly configured with the correct transitions:
Options
Options are placed before the command string (but after--).
-v / --verbose
Prints the exact Bazel command that was constructed and executed. Useful for debugging configuration issues or verifying which configs and flags are active.
--config
Overrides the Bazel config that is applied. Valid values:
| Value | Config used |
|---|---|
build | rules_xcodeproj (default when --config is not set) |
indexbuild | rules_xcodeproj_indexbuild |
swiftuipreviews | rules_xcodeproj_swiftuipreviews |
config attribute on xcodeproj), the project-level equivalent is used instead.
--generator_output_groups
When the command is build, this option instructs the runner to build the specified generator output groups and adds the same additional flags that Xcode’s bazel build invocation applies (e.g. --remote_download_regex).
Available output groups:
all_targets— builds every target listed intop_level_targets. Ideal for cache-warming jobs.
--download_intermediates
When --generator_output_groups is used, intermediate outputs (generated files, index stores, etc.) are not downloaded by default if --remote_download_toplevel or --remote_download_minimal is active. This is intentional for CI cache-warming jobs that do not want to download anything.
Pass --download_intermediates to make the behavior match a normal Xcode build, which does download intermediates:
Substitutions
The runner expands certain variables in your command string before executing it:| Variable | Expands to |
|---|---|
$_GENERATOR_LABEL_ | The label of the internal generator target (e.g. @@_main~internal~rules_xcodeproj_generated//generator/xcodeproj). Useful for aquery commands targeting the generator itself. |