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
2 changes: 1 addition & 1 deletion docs/bazel.md
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ Defines the test options for a custom scheme.
| :------------- | :------------- | :------------- |
| <a id="xcschemes.test_options-app_language"></a>app_language | Language to set in scheme.<br><br>Defaults to system settings if not set. | `None` |
| <a id="xcschemes.test_options-app_region"></a>app_region | Region to set in scheme.<br><br>Defaults to system settings if not set. | `None` |
| <a id="xcschemes.test_options-code_coverage"></a>code_coverage | Whether to enable code coverage.<br><br>If `True`, code coverage will be enabled. | `False` |
| <a id="xcschemes.test_options-code_coverage"></a>code_coverage | Whether to enable code coverage.<br><br>If `True`, code coverage will be enabled. Note that out-of-the-box support for inline code coverage UI in Xcode when using Build with Bazel mode requires [apple_support](https://github.com/bazelbuild/apple_support) 2.0.0 or later, and [rules_swift](https://github.com/bazelbuild/rules_swift) 3.4.1 or later. | `False` |


<a id="xcschemes.test_target"></a>
Expand Down
29 changes: 29 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [`rules_xcodeproj_generator`](#rules_xcodeproj_generator)
- [`rules_xcodeproj_indexbuild`](#rules_xcodeproj_indexbuild)
- [`rules_xcodeproj_swiftuipreviews`](#rules_xcodeproj_swiftuipreviews)
- [`rules_xcodeproj_coverage`](#rules_xcodeproj_coverage)
- [Project-level configs](#project-level-configs)
- [Extra config flags](#extra-config-flags)
- [`.bazelrc` files](#bazelrc-files)
Expand Down Expand Up @@ -119,6 +120,34 @@ SwiftUI Preview build.
You shouldn’t need to adjust this config. The default config applies the needed
build adjusting flags.

### `rules_xcodeproj_coverage`

> [!NOTE]
> Code coverage in Xcode with Bazel requires [apple_support](https://github.com/bazelbuild/apple_support) 2.0.0 or later and [rules_swift](https://github.com/bazelbuild/rules_swift) 3.4.1 or later.

The `rules_xcodeproj_coverage` config is used when building the project tests
inside of Xcode when code coverage is enabled. This config sets the needed
features inside apple_support and rules_swift to generate coverage data with
absolute paths to sources so Xcode can map them correctly.

By default, code coverage is **disabled** for test actions of schemes. You can
enable code coverage in Xcode by setting `code_coverage = True` on an
[`xcschemes.test_options`](/doc/bazel.md#xcschemes.test_options-code_coverage)
declaration, or by enabling the "Gather coverage data" option in the scheme editor.

> [!WARNING]
> Enabling code coverage will cause tests to be built for coverage, which is a
> distinct configuration mode from normal test builds. For building in Xcode
> in particular, this results in build outputs that are inherently non-hermetic
> as they contain absolute paths to source files. This will result in poor
> cache hit rates for these builds. This does not impact `coverage` builds run
> using the [command-line API](#command-line-api) or normal `bazel test` runs.
>
> It is recommended to only enable code coverage inside of Xcode when actively
> using it for development, and to use tool sets like
> [lcov](https://registry.bazel.build/modules/lcov) to produce coverage reports
> from normal `bazel` test runs.

## Project-level configs

Each `xcodeproj` can specify a set of configs which inherit from the
Expand Down
2 changes: 1 addition & 1 deletion examples/integration/xcodeproj_targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ XCSCHEMES = [
test_options = xcschemes.test_options(
app_language = "en",
app_region = "US",
code_coverage = False,
code_coverage = True,
),
test_targets = [
"//iOSApp/Test/SwiftUnitTests:iOSAppSwiftUnitTests",
Expand Down
4 changes: 4 additions & 0 deletions xcodeproj/internal/templates/generate_bazel_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ if [ "$ACTION" == "indexbuild" ]; then
apply_sanitizers=0
elif [ "${ENABLE_PREVIEWS:-}" == "YES" ]; then
readonly config="${BAZEL_CONFIG}_swiftuipreviews"
elif [ "${ENABLE_CODE_COVERAGE:-}" == "YES" ]; then
readonly config="${BAZEL_CONFIG}_coverage"

echo "warning: Code coverage is enabled. In order to maintain compatibility with Xcode, the instrumented build is not hermetic. Remote cache performance will be affected." >&2
else
readonly config="_${BAZEL_CONFIG}_build"
fi
Expand Down
27 changes: 27 additions & 0 deletions xcodeproj/internal/templates/xcodeproj.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,33 @@ common:rules_xcodeproj_indexbuild --config=rules_xcodeproj
# Disable BES for Index Builds, as it runs a lot, and isn't user invoked
common:rules_xcodeproj_indexbuild --bes_backend= --bes_results_url=

### `--config=rules_xcodeproj_coverage`
#
# Used when doing building for code coverage.

common:rules_xcodeproj_coverage --config=rules_xcodeproj

# Enable features that allow for building for instrumentation.
#
# Of particular note are the (swift./)_coverage_prefix_map_absolute_sources_non_hermetic
# features, which remap the execroot during the build as the absolute, canonical path
# to the source root.
#
# This approach breaks remote caching when building for testing and codeCoverageEnabled
# is set to YES, but does not affect other builds (for running, or for testing without
# coverage).
common:rules_xcodeproj_coverage --features=coverage
common:rules_xcodeproj_coverage --features=llvm_coverage_map_format
common:rules_xcodeproj_coverage --features=_coverage_prefix_map_absolute_sources_non_hermetic
common:rules_xcodeproj_coverage --features=swift.coverage
common:rules_xcodeproj_coverage --features=swift._coverage_prefix_map_absolute_sources_non_hermetic

# Disable features that interfere with (swift./)_coverage_prefix_map_absolute_sources_non_hermetic
common:rules_xcodeproj_coverage --features=-coverage_prefix_map
common:rules_xcodeproj_coverage --features=-file_prefix_map
common:rules_xcodeproj_coverage --features=-swift.coverage_prefix_map
common:rules_xcodeproj_coverage --features=-swift.file_prefix_map

### `--config=rules_xcodeproj_swiftuipreviews`
#
# Used when doing a Xcode Previews build.
Expand Down
2 changes: 2 additions & 0 deletions xcodeproj/internal/xcodeproj_runner.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ common:{config}_generator --config=rules_xcodeproj_generator
common:{config}_generator --config={config}
common:{config}_indexbuild --config=rules_xcodeproj_indexbuild
common:{config}_indexbuild --config={config}
common:{config}_coverage --config=rules_xcodeproj_coverage
common:{config}_coverage --config={config}
common:{config}_swiftuipreviews --config=rules_xcodeproj_swiftuipreviews
common:{config}_swiftuipreviews --config={config}
common:{config}_asan --config=rules_xcodeproj_asan
Expand Down
5 changes: 4 additions & 1 deletion xcodeproj/xcschemes.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,10 @@ def _test_options(
Defaults to system settings if not set.
code_coverage: Whether to enable code coverage.

If `True`, code coverage will be enabled.
If `True`, code coverage will be enabled. Note that out-of-the-box support for inline
code coverage UI in Xcode when using Build with Bazel mode requires
[apple_support](https://github.com/bazelbuild/apple_support) 2.0.0 or later, and
[rules_swift](https://github.com/bazelbuild/rules_swift) 3.4.1 or later.
"""

return struct(
Expand Down