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
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
buildForTesting = "NO"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "NO"
buildForArchiving = "YES"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
Expand Down
15 changes: 14 additions & 1 deletion test/fixtures/generator/bwb_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,20 @@
"configuration": "darwin_x86_64-fastbuild-ST-1b9bd654f600",
"custom_xcode_schemes": [
{
"build_action": null,
"build_action": {
"targets": [
{
"build_for": {
"analyzing": "unspecified",
"archiving": "enabled",
"profiling": "unspecified",
"running": "unspecified",
"testing": "unspecified"
},
"label": "//tools/generator:generator"
}
]
},
"launch_action": {
"args": [],
"build_configuration_name": "Debug",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
buildForTesting = "NO"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "NO"
buildForArchiving = "YES"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
Expand Down
15 changes: 14 additions & 1 deletion test/fixtures/generator/bwx_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,20 @@
"configuration": "darwin_x86_64-fastbuild-ST-1b9bd654f600",
"custom_xcode_schemes": [
{
"build_action": null,
"build_action": {
"targets": [
{
"build_for": {
"analyzing": "unspecified",
"archiving": "enabled",
"profiling": "unspecified",
"running": "unspecified",
"testing": "unspecified"
},
"label": "//tools/generator:generator"
}
]
},
"launch_action": {
"args": [],
"build_configuration_name": "Debug",
Expand Down
85 changes: 82 additions & 3 deletions test/internal/xcode_schemes/model_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,91 @@ def _scheme_test(ctx):

scheme_test = unittest.make(_scheme_test)

def _build_action_test(ctx):
def _build_target_test(ctx):
env = unittest.begin(ctx)

targets = ["//Sources/Foo"]
actual = xcode_schemes.build_target("//Sources/Foo")
expected = struct(
label = bazel_labels.normalize("//Sources/Foo"),
build_for = None,
)
asserts.equals(env, expected, actual, "no build_for")

actual = xcode_schemes.build_target(
"//Sources/Foo",
xcode_schemes.build_for(),
)
expected = struct(
label = bazel_labels.normalize("//Sources/Foo"),
build_for = xcode_schemes.build_for(),
)
asserts.equals(env, expected, actual, "with build_for")

return unittest.end(env)

build_target_test = unittest.make(_build_target_test)

def _build_for_test(ctx):
env = unittest.begin(ctx)

actual = xcode_schemes.build_for()
expected = struct(
running = xcode_schemes.build_for_values.UNSPECIFIED,
testing = xcode_schemes.build_for_values.UNSPECIFIED,
profiling = xcode_schemes.build_for_values.UNSPECIFIED,
archiving = xcode_schemes.build_for_values.UNSPECIFIED,
analyzing = xcode_schemes.build_for_values.UNSPECIFIED,
)
asserts.equals(env, expected, actual, "default")

actual = xcode_schemes.build_for(
running = True,
testing = True,
profiling = True,
archiving = True,
analyzing = True,
)
expected = struct(
running = xcode_schemes.build_for_values.ENABLED,
testing = xcode_schemes.build_for_values.ENABLED,
profiling = xcode_schemes.build_for_values.ENABLED,
archiving = xcode_schemes.build_for_values.ENABLED,
analyzing = xcode_schemes.build_for_values.ENABLED,
)
asserts.equals(env, expected, actual, "all true")

actual = xcode_schemes.build_for(
running = False,
testing = True,
profiling = False,
archiving = True,
analyzing = False,
)
expected = struct(
running = xcode_schemes.build_for_values.DISABLED,
testing = xcode_schemes.build_for_values.ENABLED,
profiling = xcode_schemes.build_for_values.DISABLED,
archiving = xcode_schemes.build_for_values.ENABLED,
analyzing = xcode_schemes.build_for_values.DISABLED,
)
asserts.equals(env, expected, actual, "mix it up")

return unittest.end(env)

build_for_test = unittest.make(_build_for_test)

def _build_action_test(ctx):
env = unittest.begin(ctx)

targets = [
xcode_schemes.build_target("//Sources/Foo"),
]
actual = xcode_schemes.build_action(targets)

expected = struct(
targets = [bazel_labels.normalize(t) for t in targets],
targets = [
xcode_schemes.build_target(bazel_labels.normalize("//Sources/Foo")),
],
)
asserts.equals(env, expected, actual)

Expand Down Expand Up @@ -115,6 +192,8 @@ def model_test_suite(name):
return unittest.suite(
name,
scheme_test,
build_target_test,
build_for_test,
build_action_test,
test_action_test,
launch_action_test,
Expand Down
2 changes: 1 addition & 1 deletion tools/generator/src/Generator/XcodeScheme+BuildFor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ extension XcodeScheme {
}

extension XcodeScheme.BuildFor {
enum Value: Equatable, Hashable, Decodable {
enum Value: String, Equatable, Hashable, Decodable {
case unspecified
case enabled
case disabled
Expand Down
9 changes: 9 additions & 0 deletions tools/generator/xcodeproj_targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ def get_xcode_schemes():
return [
xcode_schemes.scheme(
name = "generator",
# The build_action in this example is not necessary for the scheme
# to work. It is here to test that customized build_for settings
# propagate properly.
build_action = xcode_schemes.build_action([
xcode_schemes.build_target(
_APP_TARGET,
xcode_schemes.build_for(archiving = True),
),
]),
launch_action = xcode_schemes.launch_action(_APP_TARGET),
test_action = xcode_schemes.test_action([_TEST_TARGET]),
),
Expand Down
38 changes: 21 additions & 17 deletions xcodeproj/internal/xcode_schemes.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ def _focus_schemes(schemes, focused_targets):
build_action = scheme.build_action
if build_action:
build_targets = [
label
for label in build_action.targets
if sets.contains(focused_targets, label)
build_target
for build_target in build_action.targets
if sets.contains(focused_targets, build_target.label)
]
if build_targets:
build_action = xcode_schemes_internal.build_action(
Expand Down Expand Up @@ -98,9 +98,9 @@ def _unfocus_schemes(schemes, unfocused_targets):
build_action = scheme.build_action
if build_action:
build_targets = [
label
for label in build_action.targets
if not sets.contains(unfocused_targets, label)
build_target
for build_target in build_action.targets
if not sets.contains(unfocused_targets, build_target.label)
]
if build_targets:
build_action = xcode_schemes_internal.build_action(
Expand Down Expand Up @@ -155,20 +155,21 @@ def make_xcode_schemes(bazel_labels):
A `struct` that can be used as a `bazel_labels` module.
"""

def _build_action(targets):
"""Constructs a build action for an Xcode scheme.
def _build_target(label, build_for = None):
"""Constructs a build target for an Xcode scheme's build action.

Args:
targets: A `sequence` of target labels as `string` values.
label: A target label as a `string` value.
build_for: Optional. The settings that dictate when Xcode will build
the target. It is a `struct` as returned by
`xcode_schemes.build_for`.

Return:
A `struct` representing a build action.
Returns:
A `struct` representing a build target.
"""
return xcode_schemes_internal.build_action(
targets = [
bazel_labels.normalize(t)
for t in targets
],
return xcode_schemes_internal.build_target(
label = bazel_labels.normalize(label),
build_for = build_for,
)

def _test_action(targets):
Expand Down Expand Up @@ -217,7 +218,10 @@ def make_xcode_schemes(bazel_labels):

return struct(
scheme = xcode_schemes_internal.scheme,
build_action = _build_action,
build_action = xcode_schemes_internal.build_action,
build_target = _build_target,
build_for = xcode_schemes_internal.build_for,
build_for_values = xcode_schemes_internal.build_for_values,
test_action = _test_action,
launch_action = _launch_action,
focus_schemes = _focus_schemes,
Expand Down
80 changes: 79 additions & 1 deletion xcodeproj/internal/xcode_schemes_internal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def _build_action(targets):
"""Constructs a build action for an Xcode scheme.

Args:
targets: A `sequence` of target labels as `string` values.
targets: A `sequence` of `struct` values as created by
`xcode_schemes.build_target`.

Return:
A `struct` representing a build action.
Expand All @@ -39,6 +40,74 @@ def _build_action(targets):
targets = targets,
)

def _build_target(label, build_for = None):
"""Constructs a build target for an Xcode scheme's build action.

Args:
label: A target label as a `string` value.
build_for: Optional. The settings that dictate when Xcode will build
the target. It is a `struct` as returned by
`xcode_schemes.build_for`.

Returns:
A `struct` representing a build target.
"""
return struct(
label = label,
build_for = build_for,
)

def _build_for_value(bool_value):
"""Converts an optional `bool` value to an appropriate `build_for` setting.

Args:
bool_value: Optional. A `bool` value.

Returns:
A `string` value representing the `build_for` value to use.
"""
if bool_value == None:
return build_for_values.UNSPECIFIED
elif bool_value == True:
return build_for_values.ENABLED
elif bool_value == False:
return build_for_values.DISABLED
fail("Unrecognized build_for value: {bool_value}".format(
bool_value = bool_value,
))

def _build_for(
running = None,
testing = None,
profiling = None,
archiving = None,
analyzing = None):
"""Construct a `struct` representing the settings that dictate when Xcode \
will build a target.

Args:
running: Optional. A `bool` specifying whether to build for the running
phase.
testing: Optional. A `bool` specifying whether to build for the testing
phase.
profiling: Optional. A `bool` specifying whether to build for the
profiling phase.
archiving: Optional. A `bool` specifying whether to build for the
archiving phase.
analyzing: Optional. A `bool` specifying whether to build for the
analyzing phase.

Returns:
A `struct`.
"""
return struct(
running = _build_for_value(running),
testing = _build_for_value(testing),
profiling = _build_for_value(profiling),
archiving = _build_for_value(archiving),
analyzing = _build_for_value(analyzing),
)

def _test_action(targets, build_configuration_name):
"""Constructs a test action for an Xcode scheme.

Expand Down Expand Up @@ -85,9 +154,18 @@ def _launch_action(
working_directory = working_directory,
)

build_for_values = struct(
UNSPECIFIED = "unspecified",
ENABLED = "enabled",
DISABLED = "disabled",
)

xcode_schemes_internal = struct(
scheme = _scheme,
build_action = _build_action,
build_target = _build_target,
build_for = _build_for,
build_for_values = build_for_values,
test_action = _test_action,
launch_action = _launch_action,
)