Skip to content

Commit cec0b74

Browse files
Add apple.swizzle_absolute_xcttestsourcelocation feature (#878)
When this feature is enabled, the `@build_bazel_apple_support//lib:swizzle_absolute_xcttestsourcelocation` target is linked into `swift_test` targets.
1 parent 469db13 commit cec0b74

File tree

3 files changed

+175
-1
lines changed

3 files changed

+175
-1
lines changed

doc/rules.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,13 @@ swift_test(
491491
You can also disable this feature for all the tests in a package by applying it
492492
to your BUILD file's `package()` declaration instead of the individual targets.
493493

494+
If integrating with Xcode, the relative paths in test binaries can prevent the
495+
Issue navigator from working for test failures. To work around this, you can
496+
have the paths made absolute via swizzling by enabling the
497+
`"apple.swizzle_absolute_xcttestsourcelocation"` feature. You'll also need to
498+
set the `BAZEL_WORKSPACE_DIRECTORY` environment variable in your scheme to the
499+
root of your workspace (i.e. `$(SRCROOT)`).
500+
494501

495502
**ATTRIBUTES**
496503

swift/internal/BUILD

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2+
load("@bazel_skylib//lib:selects.bzl", "selects")
23

34
licenses(["notice"])
45

@@ -404,6 +405,145 @@ bzl_library(
404405
srcs = ["build_settings.bzl"],
405406
)
406407

408+
# `config_setting`s to allow for `swizzle_absolute_xcttestsourcelocation` to
409+
# only resolve to an `objc_library` on Apple platforms
410+
411+
config_setting(
412+
name = "catalyst_x86_64",
413+
values = {"cpu": "catalyst_x86_64"},
414+
)
415+
416+
config_setting(
417+
name = "darwin",
418+
values = {"cpu": "darwin"},
419+
)
420+
421+
config_setting(
422+
name = "darwin_x86_64",
423+
values = {"cpu": "darwin_x86_64"},
424+
)
425+
426+
config_setting(
427+
name = "darwin_arm64",
428+
values = {"cpu": "darwin_arm64"},
429+
)
430+
431+
config_setting(
432+
name = "ios_i386",
433+
values = {"cpu": "ios_i386"},
434+
)
435+
436+
config_setting(
437+
name = "ios_x86_64",
438+
values = {"cpu": "ios_x86_64"},
439+
)
440+
441+
config_setting(
442+
name = "ios_armv7",
443+
values = {"cpu": "ios_armv7"},
444+
)
445+
446+
config_setting(
447+
name = "ios_armv7s",
448+
values = {"cpu": "ios_armv7s"},
449+
)
450+
451+
config_setting(
452+
name = "ios_arm64",
453+
values = {"cpu": "ios_arm64"},
454+
)
455+
456+
config_setting(
457+
name = "ios_arm64e",
458+
values = {"cpu": "ios_arm64e"},
459+
)
460+
461+
config_setting(
462+
name = "ios_sim_arm64",
463+
values = {"cpu": "ios_sim_arm64"},
464+
)
465+
466+
config_setting(
467+
name = "watchos_arm64",
468+
values = {"cpu": "watchos_arm64"},
469+
)
470+
471+
config_setting(
472+
name = "watchos_arm64_32",
473+
values = {"cpu": "watchos_arm64_32"},
474+
)
475+
476+
config_setting(
477+
name = "watchos_armv7k",
478+
values = {"cpu": "watchos_armv7k"},
479+
)
480+
481+
config_setting(
482+
name = "watchos_i386",
483+
values = {"cpu": "watchos_i386"},
484+
)
485+
486+
config_setting(
487+
name = "watchos_x86_64",
488+
values = {"cpu": "watchos_x86_64"},
489+
)
490+
491+
config_setting(
492+
name = "tvos_arm64",
493+
values = {"cpu": "tvos_arm64"},
494+
)
495+
496+
config_setting(
497+
name = "tvos_sim_arm64",
498+
values = {"cpu": "tvos_sim_arm64"},
499+
)
500+
501+
config_setting(
502+
name = "tvos_x86_64",
503+
values = {"cpu": "tvos_x86_64"},
504+
)
505+
506+
selects.config_setting_group(
507+
name = "apple",
508+
match_any = [
509+
":catalyst_x86_64",
510+
":darwin",
511+
":darwin_arm64",
512+
":darwin_x86_64",
513+
":ios_arm64",
514+
":ios_arm64e",
515+
":ios_armv7",
516+
":ios_armv7s",
517+
":ios_i386",
518+
":ios_sim_arm64",
519+
":ios_x86_64",
520+
":watchos_arm64",
521+
":watchos_arm64_32",
522+
":watchos_armv7k",
523+
":watchos_i386",
524+
":watchos_x86_64",
525+
":tvos_arm64",
526+
":tvos_sim_arm64",
527+
":tvos_x86_64",
528+
],
529+
)
530+
531+
# Indirection needed to prevent using `objc_library` outside of macOS
532+
alias(
533+
name = "swizzle_absolute_xcttestsourcelocation",
534+
actual = select({
535+
":apple": (
536+
"@build_bazel_apple_support//lib:swizzle_absolute_xcttestsourcelocation"
537+
),
538+
"//conditions:default": ":dummy_swizzle_absolute_xcttestsourcelocation",
539+
}),
540+
visibility = ["//visibility:public"],
541+
)
542+
543+
cc_library(
544+
name = "dummy_swizzle_absolute_xcttestsourcelocation",
545+
)
546+
407547
# Consumed by Bazel integration tests.
408548
filegroup(
409549
name = "for_bazel_tests",

swift/internal/swift_binary_test.bzl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ def _swift_linking_rule_impl(
145145
binary_path,
146146
feature_configuration,
147147
swift_toolchain,
148+
extra_link_deps = [],
148149
linkopts = []):
149150
"""The shared implementation function for `swift_{binary,test}`.
150151
@@ -155,6 +156,8 @@ def _swift_linking_rule_impl(
155156
`swift_common.configure_features`.
156157
swift_toolchain: The `SwiftToolchainInfo` provider of the toolchain
157158
being used to build the target.
159+
extra_link_deps: Additional dependencies that should be linked into the
160+
binary.
158161
linkopts: Additional rule-specific flags that should be passed to the
159162
linker.
160163
@@ -248,7 +251,7 @@ def _swift_linking_rule_impl(
248251
cc_feature_configuration = cc_feature_configuration,
249252
# This is already collected from `linking_context`.
250253
compilation_outputs = None,
251-
deps = ctx.attr.deps,
254+
deps = ctx.attr.deps + extra_link_deps,
252255
grep_includes = ctx.file._grep_includes,
253256
name = binary_path,
254257
output_type = "executable",
@@ -354,9 +357,21 @@ def _swift_test_impl(ctx):
354357
xctest_bundle_binary = "{0}.xctest/Contents/MacOS/{0}".format(ctx.label.name)
355358
binary_path = xctest_bundle_binary if is_bundled else ctx.label.name
356359

360+
# `swift_common.is_enabled` isn't used, as it requires the prefix of the
361+
# feature to start with `swift.`
362+
swizzle_absolute_xcttestsourcelocation = (
363+
"apple.swizzle_absolute_xcttestsourcelocation" in
364+
feature_configuration._enabled_features
365+
)
366+
367+
extra_link_deps = []
368+
if swizzle_absolute_xcttestsourcelocation:
369+
extra_link_deps.append(ctx.attr._swizzle_absolute_xcttestsourcelocation)
370+
357371
_, linking_outputs, providers = _swift_linking_rule_impl(
358372
ctx,
359373
binary_path = binary_path,
374+
extra_link_deps = extra_link_deps,
360375
feature_configuration = feature_configuration,
361376
linkopts = linkopts,
362377
swift_toolchain = swift_toolchain,
@@ -438,6 +453,11 @@ swift_test = rule(
438453
"@build_bazel_apple_support//tools:coverage_support",
439454
),
440455
),
456+
"_swizzle_absolute_xcttestsourcelocation": attr.label(
457+
default = Label(
458+
"@build_bazel_rules_swift//swift/internal:swizzle_absolute_xcttestsourcelocation",
459+
),
460+
),
441461
"_xctest_runner_template": attr.label(
442462
allow_single_file = True,
443463
default = Label(
@@ -478,6 +498,13 @@ swift_test(
478498
479499
You can also disable this feature for all the tests in a package by applying it
480500
to your BUILD file's `package()` declaration instead of the individual targets.
501+
502+
If integrating with Xcode, the relative paths in test binaries can prevent the
503+
Issue navigator from working for test failures. To work around this, you can
504+
have the paths made absolute via swizzling by enabling the
505+
`"apple.swizzle_absolute_xcttestsourcelocation"` feature. You'll also need to
506+
set the `BAZEL_WORKSPACE_DIRECTORY` environment variable in your scheme to the
507+
root of your workspace (i.e. `$(SRCROOT)`).
481508
""",
482509
executable = True,
483510
fragments = ["cpp"],

0 commit comments

Comments
 (0)