Skip to main content

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

By default, rules_xcodeproj auto-generates an Xcode scheme for every buildable target in your project. This is convenient for getting started, but for production projects you typically need more control: grouping targets into a single scheme, setting launch arguments, customizing the test action, or suppressing schemes for internal library targets. The xcschemes module gives you that full control by letting you define every aspect of an Xcode scheme directly in your BUILD file.

Scheme autogeneration modes

The scheme_autogeneration_mode attribute on the xcodeproj rule controls whether Xcode schemes are automatically generated alongside any custom schemes you define.
ValueBehaviour
"auto"(Default) If no custom schemes are provided via xcschemes, a scheme is created for every buildable target. If any custom schemes are provided, no autogenerated schemes are created.
"none"No schemes are automatically generated, regardless of whether custom schemes are provided.
"all"A scheme is generated for every buildable target even if custom schemes are provided.
Use "none" together with xcschemes to have complete, explicit control over what appears in the scheme menu.

A full working example

BUILD
load("@rules_xcodeproj//xcodeproj:top_level_target.bzl", "top_level_target")
load("@rules_xcodeproj//xcodeproj:xcodeproj.bzl", "xcodeproj")
load("@rules_xcodeproj//xcodeproj:xcschemes.bzl", "xcschemes")

xcodeproj(
    name = "xcodeproj",
    project_name = "App",
    top_level_targets = [
        top_level_target(":App", target_environments = ["device", "simulator"]),
        ":Tests",
    ],
    xcschemes = [
        xcschemes.scheme(
            name = "App",
            run = xcschemes.run(
                launch_target = xcschemes.launch_target(":App"),
            ),
            test = xcschemes.test(
                test_targets = [
                    xcschemes.test_target(":Tests"),
                ],
            ),
        ),
    ],
    scheme_autogeneration_mode = "none",
)
This produces a single scheme named “App” that launches :App and runs :Tests, suppressing all autogenerated schemes.

Scheme actions

A scheme can include up to three actions, each configured with its own constructor:
xcschemes.run defines the Run (and Debug) action. The most important field is launch_target, which must be a value from xcschemes.launch_target or xcschemes.launch_path.
xcschemes.run(
    launch_target = xcschemes.launch_target(
        ":App",
        target_environment = "simulator",
    ),
)

Arguments and environment variables

Use xcschemes.arg and xcschemes.env_value to set command-line arguments and environment variables for any action.
BUILD
load("@rules_xcodeproj//xcodeproj:xcschemes.bzl", "xcschemes")

xcschemes.scheme(
    name = "App",
    run = xcschemes.run(
        launch_target = xcschemes.launch_target(":App"),
        args = [
            "-FIRDebugEnabled",
            xcschemes.arg("-MyOptionalFlag", enabled = False),
        ],
        env = {
            "MY_ENV_VAR": "some_value",
            "DISABLED_VAR": xcschemes.env_value("other_value", enabled = False),
        },
    ),
)
xcschemes.arg accepts:
  • value — the argument string (required)
  • enabled — whether the checkbox is checked in Xcode (default True)
  • literal_string — if True, spaces in value are escaped so the whole string is treated as one argument (default True)
xcschemes.env_value accepts:
  • value — the environment variable value (required)
  • enabled — whether the checkbox is checked in Xcode (default True)

Pre- and post-actions

You can run shell scripts before or after the Build or Run/Test/Profile phase using the xcschemes.pre_post_actions namespace.
BUILD
load("@rules_xcodeproj//xcodeproj:xcschemes.bzl", "xcschemes")

xcschemes.scheme(
    name = "App",
    run = xcschemes.run(
        launch_target = xcschemes.launch_target(
            ":App",
            pre_actions = [
                xcschemes.pre_post_actions.build_script(
                    title = "Print Build Start",
                    script_text = "echo 'Build starting…'",
                ),
                xcschemes.pre_post_actions.launch_script(
                    title = "Print Run Start",
                    script_text = "echo 'Launching app…'",
                ),
            ],
        ),
    ),
)
ConstructorWhere it appears in Xcode
xcschemes.pre_post_actions.build_scriptPre/Post-actions of the Build section
xcschemes.pre_post_actions.launch_scriptPre/Post-actions of the Run, Test, or Profile section
Both constructors accept:
  • title — displayed name in Xcode (default "Run Script")
  • script_text — the shell script body (required)
  • order — optional integer controlling relative ordering among actions
Scripts run in Bazel’s execution root, not the source directory. Add cd "$SRCROOT" at the top of your script if you need to reference workspace-relative paths.

Diagnostics

Enable runtime sanitizers for a scheme’s Run or Test action using xcschemes.diagnostics:
BUILD
xcschemes.run(
    launch_target = xcschemes.launch_target(":App"),
    diagnostics = xcschemes.diagnostics(
        address_sanitizer = True,
    ),
)
Available flags: address_sanitizer, thread_sanitizer, undefined_behavior_sanitizer, main_thread_checker (default True), thread_performance_checker (default True). Note that address_sanitizer and thread_sanitizer are mutually exclusive.

Autogeneration config

For cases where you want autogenerated schemes but need to apply pre/post-actions or name filters globally, use xcschemes.autogeneration_config on the scheme_autogeneration_config attribute:
BUILD
xcodeproj(
    name = "xcodeproj",
    project_name = "App",
    top_level_targets = [":App", ":Tests"],
    scheme_autogeneration_config = xcschemes.autogeneration_config(
        scheme_name_exclude_patterns = [
            ".*Internal.*",
        ],
        run = xcschemes.autogeneration.run(
            pre_actions = [
                xcschemes.pre_post_actions.build_script(
                    title = "Build Start",
                    script_text = "echo build",
                ),
            ],
        ),
    ),
)
For the full API reference — including all parameters, defaults, and advanced options like xcschemes.top_level_anchor_target and xcschemes.test_options — see the xcschemes reference.

Build docs developers (and LLMs) love