Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/bazel.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ load("@rules_xcodeproj//xcodeproj:xcodeproj.bzl", "xcodeproj")
load("@rules_xcodeproj//xcodeproj/internal/docs:xcodeproj.bzl", "xcodeproj")

xcodeproj(*, <a href="#xcodeproj-name">name</a>, <a href="#xcodeproj-associated_extra_files">associated_extra_files</a>, <a href="#xcodeproj-bazel_path">bazel_path</a>, <a href="#xcodeproj-bazel_env">bazel_env</a>, <a href="#xcodeproj-config">config</a>,
<a href="#xcodeproj-default_xcode_configuration">default_xcode_configuration</a>, <a href="#xcodeproj-extra_files">extra_files</a>, <a href="#xcodeproj-focused_targets">focused_targets</a>, <a href="#xcodeproj-import_index_build_indexstores">import_index_build_indexstores</a>,
<a href="#xcodeproj-install_directory">install_directory</a>, <a href="#xcodeproj-ios_device_cpus">ios_device_cpus</a>, <a href="#xcodeproj-ios_simulator_cpus">ios_simulator_cpus</a>, <a href="#xcodeproj-minimum_xcode_version">minimum_xcode_version</a>, <a href="#xcodeproj-post_build">post_build</a>,
<a href="#xcodeproj-pre_build">pre_build</a>, <a href="#xcodeproj-project_name">project_name</a>, <a href="#xcodeproj-project_options">project_options</a>, <a href="#xcodeproj-scheme_autogeneration_mode">scheme_autogeneration_mode</a>,
<a href="#xcodeproj-scheme_autogeneration_config">scheme_autogeneration_config</a>, <a href="#xcodeproj-target_name_mode">target_name_mode</a>, <a href="#xcodeproj-top_level_targets">top_level_targets</a>, <a href="#xcodeproj-tvos_device_cpus">tvos_device_cpus</a>,
<a href="#xcodeproj-tvos_simulator_cpus">tvos_simulator_cpus</a>, <a href="#xcodeproj-unfocused_targets">unfocused_targets</a>, <a href="#xcodeproj-visionos_device_cpus">visionos_device_cpus</a>, <a href="#xcodeproj-visionos_simulator_cpus">visionos_simulator_cpus</a>,
<a href="#xcodeproj-watchos_device_cpus">watchos_device_cpus</a>, <a href="#xcodeproj-watchos_simulator_cpus">watchos_simulator_cpus</a>, <a href="#xcodeproj-xcode_configurations">xcode_configurations</a>, <a href="#xcodeproj-xcschemes">xcschemes</a>, <a href="#xcodeproj-kwargs">**kwargs</a>)
<a href="#xcodeproj-default_xcode_configuration">default_xcode_configuration</a>, <a href="#xcodeproj-extra_files">extra_files</a>, <a href="#xcodeproj-focused_targets">focused_targets</a>, <a href="#xcodeproj-generator_bazel_env">generator_bazel_env</a>,
<a href="#xcodeproj-import_index_build_indexstores">import_index_build_indexstores</a>, <a href="#xcodeproj-install_directory">install_directory</a>, <a href="#xcodeproj-ios_device_cpus">ios_device_cpus</a>, <a href="#xcodeproj-ios_simulator_cpus">ios_simulator_cpus</a>,
<a href="#xcodeproj-minimum_xcode_version">minimum_xcode_version</a>, <a href="#xcodeproj-post_build">post_build</a>, <a href="#xcodeproj-pre_build">pre_build</a>, <a href="#xcodeproj-project_name">project_name</a>, <a href="#xcodeproj-project_options">project_options</a>,
<a href="#xcodeproj-scheme_autogeneration_mode">scheme_autogeneration_mode</a>, <a href="#xcodeproj-scheme_autogeneration_config">scheme_autogeneration_config</a>, <a href="#xcodeproj-target_name_mode">target_name_mode</a>,
<a href="#xcodeproj-top_level_targets">top_level_targets</a>, <a href="#xcodeproj-tvos_device_cpus">tvos_device_cpus</a>, <a href="#xcodeproj-tvos_simulator_cpus">tvos_simulator_cpus</a>, <a href="#xcodeproj-unfocused_targets">unfocused_targets</a>,
<a href="#xcodeproj-visionos_device_cpus">visionos_device_cpus</a>, <a href="#xcodeproj-visionos_simulator_cpus">visionos_simulator_cpus</a>, <a href="#xcodeproj-watchos_device_cpus">watchos_device_cpus</a>, <a href="#xcodeproj-watchos_simulator_cpus">watchos_simulator_cpus</a>,
<a href="#xcodeproj-xcode_configurations">xcode_configurations</a>, <a href="#xcodeproj-xcschemes">xcschemes</a>, <a href="#xcodeproj-kwargs">**kwargs</a>)
</pre>

Creates an `.xcodeproj` file in the workspace when run.
Expand Down Expand Up @@ -97,6 +98,7 @@ xcodeproj(
| <a id="xcodeproj-default_xcode_configuration"></a>default_xcode_configuration | Optional. The name of the the Xcode configuration to use when building, if not overridden by custom schemes.<br><br>If not set, the first Xcode configuration alphabetically will be used. Use [`xcode_configurations`](#xcodeproj-xcode_configurations) to adjust Xcode configurations. | `None` |
| <a id="xcodeproj-extra_files"></a>extra_files | Optional. A `list` of extra `File`s to be added to the project. | `[]` |
| <a id="xcodeproj-focused_targets"></a>focused_targets | Optional. A `list` of target labels as `string` values.<br><br>If specified, only these targets will be included in the generated project; all other targets will be excluded, as if they were listed explicitly in the `unfocused_targets` argument. The labels must match transitive dependencies of the targets specified in the `top_level_targets` argument. | `[]` |
| <a id="xcodeproj-generator_bazel_env"></a>generator_bazel_env | Optional. A `dict` of environment variables to set when invoking `bazel_path` during project generation only.<br><br>This behaves the same as `bazel_env`, but only applies to the generated runner's Bazel invocations while generating the project. These values are not written into the generated `.xcodeproj`, and they do not apply to Bazel builds launched later from Xcode. | `{}` |
| <a id="xcodeproj-import_index_build_indexstores"></a>import_index_build_indexstores | Optional. Whether to import the index stores generated by Index Build.<br><br>This is useful if you want to use the index stores generated by Index Build to speed up Xcode's indexing process. You may not want this enabled if the additional work (mainly disk IO) of importing the index stores is not worth it for your project. | `True` |
| <a id="xcodeproj-install_directory"></a>install_directory | Optional. The directory where the generated project will be written to.<br><br>The path is relative to the workspace root.<br><br>Defaults to the directory that the `xcodeproj` target is declared in (e.g. if the `xcodeproj` target is declared in `//foo/bar:BUILD` then the default value is `"foo/bar"`). Use `""` to have the project generated in the workspace root. | `None` |
| <a id="xcodeproj-ios_device_cpus"></a>ios_device_cpus | Optional. The value to use for `--ios_multi_cpus` when building the transitive dependencies of the targets specified in the `top_level_targets` argument with the `"device"` `target_environment`.<br><br>**Warning:** Changing this value will affect the Starlark transition hash of all transitive dependencies of the targets specified in the `top_level_targets` argument with the `"device"` `target_environment`, even if they aren't iOS targets. | `"arm64"` |
Expand Down
33 changes: 31 additions & 2 deletions xcodeproj/internal/xcodeproj_runner.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ load(":collections.bzl", "uniq")
load(":execution_root.bzl", "write_execution_root_file")
load(":providers.bzl", "XcodeProjRunnerOutputInfo")

# Null character is used to represent `None`, since `attr.string_dict`
# requires non-`None` values.
_NULL_BAZEL_ENV_VALUE = "\0"
_NULL_BAZEL_ENV_VALUE_LITERAL = "\\0"

def _process_extra_flags(*, attr, content, setting, config, config_suffix):
extra_flags = getattr(attr, setting)[BuildSettingInfo].value
if extra_flags:
Expand Down Expand Up @@ -272,6 +277,7 @@ def _write_runner(
execution_root_file,
extra_flags_bazelrc,
extra_generator_flags,
generator_bazel_env,
generator_build_file,
generator_defs_bzl,
install_path,
Expand All @@ -286,8 +292,10 @@ def _write_runner(
base_envs_values = []
collect_statements = []
for key, value in bazel_env.items():
if value == "\0":
base_def_env_values.append(' \\"{}\\": \\"\\\\0\\",'.format(key))
if value == _NULL_BAZEL_ENV_VALUE:
base_def_env_values.append(
' \\"{}\\": \\"{}\\",'.format(key, _NULL_BAZEL_ENV_VALUE_LITERAL),
)
collect_statements.append("""\
if [[ -n "${{{key}:-}}" ]]; then
envs+=("{key}=${key}")
Expand Down Expand Up @@ -323,6 +331,25 @@ fi
),
))

for key, value in generator_bazel_env.items():
if value == _NULL_BAZEL_ENV_VALUE:
collect_statements.append("""\
if [[ -n "${{{key}:-}}" ]]; then
envs+=("{key}=${key}")
fi
""".format(key = key))
else:
base_envs_values.append(" \"{}={}\"".format(
key,
(
value.replace(
# Escape double quotes for bash
"\"",
"\\\"",
)
),
))

collect_bazel_env = """\
envs=(
{base_envs_values}
Expand Down Expand Up @@ -439,6 +466,7 @@ def _xcodeproj_runner_impl(ctx):
extra_generator_flags = (
ctx.attr._extra_generator_flags[BuildSettingInfo].value
),
generator_bazel_env = ctx.attr.generator_bazel_env,
generator_build_file = generator_build_file,
generator_defs_bzl = generator_defs_bzl,
install_path = install_path,
Expand Down Expand Up @@ -475,6 +503,7 @@ xcodeproj_runner = rule(
"default_xcode_configuration": attr.string(),
"focused_labels": attr.string_list(default = []),
"generation_shard_count": attr.int(mandatory = True),
"generator_bazel_env": attr.string_dict(mandatory = True),
"import_index_build_indexstores": attr.bool(mandatory = True),
"install_directory": attr.string(mandatory = True),
"ios_device_cpus": attr.string(mandatory = True),
Expand Down
22 changes: 19 additions & 3 deletions xcodeproj/xcodeproj.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ load(
"xcscheme_labels",
)

# Null character is used to represent `None`, since `attr.string_dict`
# requires non-`None` values.
_NULL_BAZEL_ENV_VALUE = "\0"

def _normalize_build_setting(flag):
if flag.startswith("//command_line_option:"):
return flag
Expand All @@ -31,6 +35,7 @@ def xcodeproj(
default_xcode_configuration = None,
extra_files = [],
focused_targets = [],
generator_bazel_env = {},
import_index_build_indexstores = True,
install_directory = None,
ios_device_cpus = "arm64",
Expand Down Expand Up @@ -150,6 +155,13 @@ def xcodeproj(
listed explicitly in the `unfocused_targets` argument. The labels
must match transitive dependencies of the targets specified in the
`top_level_targets` argument.
generator_bazel_env: Optional. A `dict` of environment variables to
set when invoking `bazel_path` during project generation only.

This behaves the same as `bazel_env`, but only applies to the
generated runner's Bazel invocations while generating the project.
These values are not written into the generated `.xcodeproj`, and
they do not apply to Bazel builds launched later from Xcode.
import_index_build_indexstores: Optional. Whether to import the index
stores generated by Index Build.

Expand Down Expand Up @@ -365,6 +377,7 @@ def xcodeproj(
if not bazel_path:
bazel_path = "bazel"
bazel_env = dict(bazel_env) if bazel_env else {}
generator_bazel_env = dict(generator_bazel_env) if generator_bazel_env else {}
Comment thread
brentleyjones marked this conversation as resolved.
if "PATH" not in bazel_env:
bazel_env["PATH"] = "/bin:/usr/bin"
if "LANG" not in bazel_env:
Expand All @@ -386,11 +399,13 @@ def xcodeproj(
bazel_env["BAZELISK_SKIP_WRAPPER"] = None

bazel_env = {
# Null character is used to represent `None`, since `attr.string_dict`
# requires non-`None` values.
key: "\0" if value == None else value
key: _NULL_BAZEL_ENV_VALUE if value == None else value
for key, value in sorted(bazel_env.items())
}
generator_bazel_env = {
key: _NULL_BAZEL_ENV_VALUE if value == None else value
for key, value in sorted(generator_bazel_env.items())
}

if default_xcode_configuration and default_xcode_configuration not in xcode_configurations:
keys = sorted(xcode_configurations.keys())
Expand Down Expand Up @@ -530,6 +545,7 @@ for {configuration} ({new_keys}) do not match keys of other configurations \
config = config,
default_xcode_configuration = default_xcode_configuration,
focused_labels = focused_labels,
generator_bazel_env = generator_bazel_env,
generation_shard_count = generation_shard_count,
import_index_build_indexstores = import_index_build_indexstores,
install_directory = install_directory,
Expand Down
Loading