Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
60068ee
Improve Xcode selection diagnostics (#644)
erikkerber Oct 17, 2026
d4595d8
Return native `XcodeProperties` from `xcode_config` on Bazel 8 (#669)
thii Oct 19, 2026
6599e08
Use direct indexing for required outputs in the Xcode path-substituti…
tamird Oct 22, 2026
24856d3
Accept Label values in Xcode threshold references (#678)
tamird Oct 22, 2026
e0c31aa
Use the arm64 simulator for the default visionOS test split (#679)
tamird Oct 26, 2026
94b7636
Use the visionOS platform type directly (#673)
tamird Oct 26, 2026
cd8c22b
Call the selected genrule action API directly (#675)
tamird Oct 26, 2026
436e9b7
Handle developer-directory Xcode versions in threshold conditions (#672)
tamird Oct 26, 2026
348b796
Use the Xcode configuration resolver for execution info (#674)
tamird Oct 26, 2026
4a3d6e6
Fix http_dmg's 7-Zip downloads on Windows (#671)
UebelAndre Oct 26, 2026
b11f5c4
Fix PLATFORM_FRAMEWORKS without transition (#680)
keith Oct 26, 2026
5e91381
Fix incremental archive creation with ar q (#670)
psalaberria002 Oct 26, 2026
373df5a
Preserve strings in generated Apple toolchain configuration (#677)
tamird Oct 26, 2026
6cc66ee
Make the tool map public (#681)
ma-oli Oct 27, 2026
0d7f093
Keep string executables out of action tools (#684)
tamird Oct 29, 2026
37301c6
Accept depset inputs in lipo.create (#683)
tamird Oct 29, 2026
3b692bc
fix(toolchain): keep version suffixes out of the clang target triple …
ma-oli Nov 2, 2026
df816ca
Describe Apple platform and action contracts
tamird Oct 29, 2026
48ced23
Check Apple type contracts with sty
tamird Oct 29, 2026
f373bbd
Move crosstool contracts beside their implementations
tamird Nov 3, 2026
913948d
Declare Xcode and 7-Zip helper types in source
tamird Nov 3, 2026
d975571
Explain the source annotation limits
tamird Nov 3, 2026
579ca88
Reference sty by release tag
tamird Nov 3, 2026
6e47ac0
Select the strict sty rules as a group
tamird Nov 3, 2026
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: 2 additions & 0 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ tasks:
- test/shell/layering_check_test.sh
- test/shell/header_parsing_test.sh
- test/shell/coverage_test.sh
- test/shell/toolchain_flags_test.sh

macos_latest_shell_scripts_toolchain_off:
name: "Shell tests (rules toolchain off)"
Expand All @@ -210,6 +211,7 @@ tasks:
- 'BAZEL_EXTRA_ARGS="--repo_env=APPLE_SUPPORT_RULES_BASED_TOOLCHAIN=0" test/shell/layering_check_test.sh'
- 'BAZEL_EXTRA_ARGS="--repo_env=APPLE_SUPPORT_RULES_BASED_TOOLCHAIN=0" test/shell/header_parsing_test.sh'
- 'BAZEL_EXTRA_ARGS="--repo_env=APPLE_SUPPORT_RULES_BASED_TOOLCHAIN=0" test/shell/coverage_test.sh'
- 'BAZEL_EXTRA_ARGS="--repo_env=APPLE_SUPPORT_RULES_BASED_TOOLCHAIN=0" test/shell/toolchain_flags_test.sh'

macos_last_green:
name: "Last Green Bazel"
Expand Down
7 changes: 7 additions & 0 deletions .github/sty/rules_cc.MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# TODO(https://github.com/bazelbuild/rules_cc/pull/940): Remove this override once
# the selected rules_cc release annotates framework_includes and compilation_context.
single_version_override(
module_name = "rules_cc",
patch_strip = 1,
patches = ["//:.github/sty/rules_cc.patch"],
)
20 changes: 20 additions & 0 deletions .github/sty/rules_cc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
diff --git a/cc/private/cc_common.bzl b/cc/private/cc_common.bzl
index 4533f7f..2d005ec 100644
--- a/cc/private/cc_common.bzl
+++ b/cc/private/cc_common.bzl
@@ -253,3 +253,5 @@ def _create_compilation_context(
quote_includes = None,
- framework_includes = None,
+ # TODO(https://github.com/bazelbuild/bazel/issues/32021): make this an
+ # annotation when supported Bazel versions expose element-typed depsets.
+ framework_includes = None, # type: depset[str] | None
defines = None,
diff --git a/cc/private/cc_info.bzl b/cc/private/cc_info.bzl
index 76eca95..7d6a599 100644
--- a/cc/private/cc_info.bzl
+++ b/cc/private/cc_info.bzl
@@ -322,3 +322,3 @@ def _create_cc_info(
*,
- compilation_context = None,
+ compilation_context = None, # type: CcCompilationContextInfo | None
linking_context = None,
71 changes: 71 additions & 0 deletions .github/workflows/sty.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Starlark types

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
sty:
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Prepare C++ annotations
env:
USE_BAZEL_VERSION: '9.3.0'
shell: bash
run: |
expected=rules_cc@0.2.26
selected=$(bazelisk mod show_repo rules_cc --output=streamed_jsonproto | jq -r .moduleKey)
if [[ "$selected" != "$expected" ]]; then
echo "The advisory annotations cover $expected; Bazel selected $selected." >&2
exit 1
fi
cat .github/sty/rules_cc.MODULE.bazel >> MODULE.bazel
- uses: tamird/sty@sty-action-v0.2.0
with:
audit-loads: true
advisory-pathspecs: '*.bzl'
bazel-version: '9.3.0'
files: |
@bazel_skylib//lib:shell.bzl
configs/platforms.bzl
crosstool/osx_cc_configure.bzl
crosstool/setup.bzl
crosstool/setup_internal.bzl
crosstool/universal_exec_tool.bzl
lib/missing_platform_fallback_users.bzl
lib/private/toolchain_flags.bzl
lib/providers.bzl
lib/xcode_support.bzl
rules/apple_genrule.bzl
rules/private/apple_genrule.bzl
rules/rules.doc.bzl
rules/toolchain_substitution.bzl
rules/universal_binary.bzl
test/apple_support_test.bzl
test/binary_tests.bzl
test/rules/apple_verification_test.bzl
test/test_data/framework_includes_provider.bzl
test/universal_binary_test.bzl
toolchain/dynamic_toolchain_info.bzl
toolchain/toolchain_env.bzl
tools/http_dmg/http_dmg.bzl
tools/http_dmg/private/tests/http_dmg_test_deps.bzl
tools/http_dmg/private/tests/http_dmg_test_extensions.bzl
tools/http_dmg/private/zip7.bzl
xcode/available_xcodes.bzl
xcode/private/providers.bzl
xcode/xcode_configure.bzl
xcode/xcode_sdk_variant.bzl
xcode/xcode_version.bzl
9 changes: 9 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ bazel_dep(name = "protobuf", version = "33.0", dev_dependency = True)

http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "sty_bazel_tools",
dev_dependency = True,
integrity = "sha256-FayMMyMk37REW96xvJXMY1fYcWXBban9QgFAZUB+Kr0=",
strip_prefix = "sty-2ab74c830937d3ca85165ca0e9a02a42400ad9e5/crates/starpls_bazel/data/bazel_tools",
urls = ["https://github.com/tamird/sty/archive/2ab74c830937d3ca85165ca0e9a02a42400ad9e5.tar.gz"],
)

http_archive(
name = "swift_linux_toolchain",
build_file = "//test/linux_toolchain:swift_toolchain.BUILD",
Expand All @@ -55,6 +63,7 @@ dmg_arc_test_deps = use_extension("//tools/http_dmg/private/tests:http_dmg_test_
use_repo(
dmg_arc_test_deps,
"http_dmg_test_firefox",
"http_dmg_test_firefox_patched",
"http_dmg_test_firefox_strip_prefix",
"http_dmg_test_krita",
"http_dmg_test_krita_strip_prefix",
Expand Down
6 changes: 6 additions & 0 deletions crosstool/libtool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,12 @@ void processArCreateArgs(
flags_consumer("-D"); // NOTE: Always added for hermiticity
flags_consumer("-o");
flags_consumer(args[1]);
// libtool creates a new archive, whereas ar q appends to an existing one.
// Include the previous archive so batched callers such as cc-rs retain it.
if (args[0].find('q') != std::string::npos &&
std::filesystem::exists(args[1])) {
flags_consumer(args[1]);
}
}

std::vector<std::string> expandResponseFiles(
Expand Down
48 changes: 27 additions & 21 deletions crosstool/osx_cc_configure.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
# limitations under the License.
"""Configuring the C++ toolchain on macOS."""

load(
"@bazel_tools//tools/cpp:lib_cc_configure.bzl",
"escape_string",
)
load("//lib/private:toolchain_flags.bzl", "get_starlark_list", "quote_starlark_string")
load("//xcode:xcode_configure.bzl", "run_xcode_locator", "watch_selected_xcode")

def _get_copts_env_var(repository_ctx, name, default = ""):
# type: (repository_ctx, str, str) -> list[str]
"""Get an environment variable and split it on ":" to be used as copts.

Args:
Expand All @@ -36,6 +34,7 @@ def _get_copts_env_var(repository_ctx, name, default = ""):
return _split_escaped(default, ":")

def _split_escaped(string, delimiter):
# type: (str, str) -> list[str]
"""Split string on the delimiter unless %-escaped.

Examples:
Expand Down Expand Up @@ -66,7 +65,7 @@ def _split_escaped(string, delimiter):

i = 0
result = []
accumulator = []
accumulator = [] # type: list[str]
length = len(string)
delimiter_length = len(delimiter)

Expand All @@ -86,7 +85,7 @@ def _split_escaped(string, delimiter):
i += 1 + delimiter_length
elif i + delimiter_length <= length and string[i:i + delimiter_length] == delimiter:
result.append("".join(accumulator))
accumulator = []
accumulator = [] # type: list[str]
i += delimiter_length
else:
accumulator.append(string[i])
Expand All @@ -96,13 +95,14 @@ def _split_escaped(string, delimiter):
result.append("".join(accumulator))
return result

def _get_starlark_list(values):
"""Convert a list of string into a string that can be passed to a rule attribute."""
if not values:
return ""
return "\"" + "\",\n \"".join(values) + "\""
# TODO(https://github.com/bazelbuild/bazel/pull/30373): Use a native alias when
# Bazel 8.8 is the minimum supported version.
# type _DeveloperDirectory = struct[{"developer_dir": str}, ...]

def _get_escaped_xcode_cxx_inc_directories(repository_ctx, xcode_toolchains):
def _get_xcode_cxx_inc_directories(repository_ctx, xcode_toolchains):
# type: (repository_ctx, Collection[_DeveloperDirectory]) -> list[str]
# TODO(https://github.com/bazelbuild/bazel/issues/32020): Use a native
# signature when supported Bazel versions expose repository_ctx.
"""Compute the list of default C++ include paths on Xcode-enabled darwin.

Args:
Expand All @@ -127,11 +127,14 @@ def _get_escaped_xcode_cxx_inc_directories(repository_ctx, xcode_toolchains):

# Include extra Xcode paths in case they're installed on other volumes
for toolchain in xcode_toolchains:
include_dirs.append(escape_string(toolchain.developer_dir))
include_dirs.append(toolchain.developer_dir)

return include_dirs

def _succeeds(repository_ctx, *args):
# type: (repository_ctx, *str) -> bool
# TODO(https://github.com/bazelbuild/bazel/issues/32020): make this an
# annotation when supported Bazel versions expose a repository context type.
env = repository_ctx.os.environ
result = repository_ctx.execute([
"env",
Expand All @@ -145,9 +148,13 @@ def _succeeds(repository_ctx, *args):
return result.return_code == 0

def _copy_file(repository_ctx, src, dest):
# type: (repository_ctx, str | Label | path, str | path) -> None
# TODO(https://github.com/bazelbuild/bazel/issues/32020): annotate repository_ctx
# when supported Bazel versions expose a repository context type.
repository_ctx.file(dest, content = repository_ctx.read(src))

def configure_osx_toolchain(repository_ctx):
# type: (repository_ctx) -> tuple[bool, str | None]
"""Configure C++ toolchain on macOS.

Args:
Expand All @@ -165,7 +172,7 @@ def configure_osx_toolchain(repository_ctx):
cc_toolchain_config = Label("@apple_support//crosstool:cc_toolchain_config.bzl")
build_template = Label("@apple_support//crosstool:BUILD.tpl")

xcode_toolchains = []
xcode_toolchains = [] # type: Collection[_DeveloperDirectory]
xcodeloc_err = ""
allow_non_applications_xcode = "BAZEL_ALLOW_NON_APPLICATIONS_XCODE" in repository_ctx.os.environ and repository_ctx.os.environ["BAZEL_ALLOW_NON_APPLICATIONS_XCODE"] == "1"
if allow_non_applications_xcode:
Expand Down Expand Up @@ -193,10 +200,9 @@ def configure_osx_toolchain(repository_ctx):
if _succeeds(repository_ctx, "ld", "-reproducible", "-v"):
features.append("reproducible_linker_flag")

escaped_include_paths = _get_escaped_xcode_cxx_inc_directories(repository_ctx, xcode_toolchains)
escaped_cxx_include_directories = []
for path in escaped_include_paths:
escaped_cxx_include_directories.append((" \"%s\"," % path))
for path in _get_xcode_cxx_inc_directories(repository_ctx, xcode_toolchains):
escaped_cxx_include_directories.append(" %s," % quote_starlark_string(path))
if xcodeloc_err:
escaped_cxx_include_directories.append(" # Error: " + xcodeloc_err)

Expand All @@ -209,13 +215,13 @@ def configure_osx_toolchain(repository_ctx):
"BUILD",
build_template,
{
"%{c_flags}": _get_starlark_list(c_opts),
"%{conly_flags}": _get_starlark_list(conly_opts),
"%{c_flags}": get_starlark_list(c_opts),
"%{conly_flags}": get_starlark_list(conly_opts),
"%{cxx_builtin_include_directories}": "\n".join(escaped_cxx_include_directories),
"%{cxx_flags}": _get_starlark_list(cxx_opts),
"%{cxx_flags}": get_starlark_list(cxx_opts),
"%{features}": "\n".join([' "{}",'.format(x) for x in features]),
"%{layering_check_modulemap}": "\"@apple_support//crosstool:exec_layering_check_modulemap\"," if enable_layering_check else "",
"%{link_flags}": _get_starlark_list(link_opts),
"%{link_flags}": get_starlark_list(link_opts),
"%{placeholder_modulemap}": "\"@apple_support//crosstool:module.modulemap\"" if enable_layering_check else "None",
"%{tool_paths_overrides}": ",\n ".join(
['"%s": "%s"' % (k, v) for k, v in tool_paths.items()],
Expand Down
3 changes: 3 additions & 0 deletions crosstool/setup.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ load("@bazel_features//:features.bzl", "bazel_features")
load(":setup_internal.bzl", "apple_cc_autoconf", "apple_cc_autoconf_toolchains")

def _apple_cc_configure_extension_impl(module_ctx):
# type: (module_ctx) -> extension_metadata | None
# TODO(https://github.com/bazelbuild/bazel/issues/32020): make this an
# annotation when supported Bazel versions expose context and metadata types.
apple_cc_autoconf_toolchains(name = "local_config_apple_cc_toolchains")
apple_cc_autoconf(name = "local_config_apple_cc")
if bazel_features.external_deps.extension_metadata_has_reproducible:
Expand Down
4 changes: 4 additions & 0 deletions crosstool/setup_internal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ _OLD_DISABLE_ENV_VAR = "BAZEL_USE_CPP_ONLY_TOOLCHAIN"
_NEW_TOOLCHAIN_VAR = "APPLE_SUPPORT_RULES_BASED_TOOLCHAIN"

def _apple_cc_autoconf_toolchains_impl(repository_ctx):
# type: (...) -> repo_metadata | None
# TODO(https://github.com/bazelbuild/bazel/issues/32020): make this an
# annotation when supported Bazel versions expose metadata types.
"""Generate BUILD file with 'toolchain' targets for the local host C++ toolchain.

Args:
Expand Down Expand Up @@ -55,6 +58,7 @@ apple_cc_autoconf_toolchains = repository_rule(
)

def _apple_cc_autoconf_impl(repository_ctx):
# type: (...) -> repo_metadata | None
env = repository_ctx.os.environ
should_disable = _DISABLE_ENV_VAR in env and env[_DISABLE_ENV_VAR] == "1"
old_should_disable = _OLD_DISABLE_ENV_VAR in env and env[_OLD_DISABLE_ENV_VAR] == "1"
Expand Down
9 changes: 9 additions & 0 deletions crosstool/universal_exec_tool.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
load("//rules:apple_genrule.bzl", "apple_genrule")

def _force_exec_impl(ctx):
# type: (...) -> list[DefaultInfo]
default_into = ctx.attr.target[DefaultInfo]

return [
Expand All @@ -24,7 +25,15 @@ force_exec = rule(
exec_compatible_with = ["@platforms//os:macos"],
)

# TODO(https://github.com/bazelbuild/bazel/issues/32021): Use native annotations
# once supported Bazel versions expose depset element types.
# type _Labels = Collection[Label | str] | depset[Label | str]

# TODO(https://github.com/tamird/sty/blob/sty-action-v0.2.0/docs/type-interfaces.md#selectors):
# Use a native parameter annotation when Bazel can describe configurable srcs
# whose selected value can be a list, a depset, or None.
def universal_exec_tool(*, name, out, srcs):
# type: (str, Label | str, _Labels | select[_Labels | None] | None) -> None
apple_genrule(
name = name + ".target_config",
srcs = srcs,
Expand Down
15 changes: 8 additions & 7 deletions doc/xcode_version_at_least.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Creates a `config_setting` target that matches when Xcode is at least `minimum_x

The condition compares the resolved Xcode version, including when Xcode is
selected by default without an explicit `--xcode_version` flag. It does not
match if the resolved configuration has no Xcode version.
match if the resolved configuration has no Xcode version. A developer
directory is assumed to represent a recent Xcode and matches any minimum.

For example, enable a definition with Xcode 26.4 or newer:

Expand Down Expand Up @@ -70,11 +71,11 @@ With Xcode 27 or newer, both conditions match, but the more specialized
`xcode_27_or_newer` branch wins. Without `after`, different values for these
overlapping conditions would make the `select()` ambiguous.

Declare lower thresholds before higher thresholds and use local target names
or `:name` labels to inherit a same-package `after` chain transitively. For
cross-package or fully qualified references, list every lower threshold in
the chain explicitly. Each threshold must be strictly higher than those in
its `after` list.
Declare lower thresholds before higher thresholds to inherit a same-package
`after` chain transitively, whether references are strings or `Label` objects.
For cross-package references, list every lower threshold in the chain
explicitly. Each threshold must be strictly higher than those in its `after`
list.


**PARAMETERS**
Expand All @@ -84,7 +85,7 @@ its `after` list.
| :------------- | :------------- | :------------- |
| <a id="xcode_version_at_least-name"></a>name | The name of the `config_setting` target to create. A companion feature flag target named `<name>_flag` will also be created. | none |
| <a id="xcode_version_at_least-minimum_xcode_version"></a>minimum_xcode_version | The minimum Xcode version to match (inclusive), such as `"26.4"`, `"26.4.1"`, or `"27.0.0.27A5228h"`. | none |
| <a id="xcode_version_at_least-after"></a>after | An optional list of lower-version `xcode_version_at_least` target names or labels that this condition should refine when used together in the same `select()` expression. If a referenced target is in the same package, any lower thresholds it already refines are inherited transitively. | `None` |
| <a id="xcode_version_at_least-after"></a>after | An optional list of lower-version `xcode_version_at_least` target names or labels that this condition should refine when used together in the same `select()` expression. If a referenced target is in the same package, any lower thresholds it already refines are inherited transitively, whether the reference is a string or a `Label` object. | `None` |
| <a id="xcode_version_at_least-visibility"></a>visibility | The visibility of the generated targets. | `None` |
| <a id="xcode_version_at_least-kwargs"></a>kwargs | Additional keyword arguments (such as `tags` or `constraint_values`) forwarded to `native.config_setting`. `tags` is also forwarded to the companion `<name>_flag` target. | none |

Expand Down
7 changes: 6 additions & 1 deletion lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ package(

exports_files(glob(["*.bzl"]))

exports_files([
"apple_support.bzli",
"lipo.bzli",
"transitions.bzli",
])

# This target is mainly for use by rules_apple and rules_swift.
# When this target is linked into an XCTest binary, and the
# `BUILD_WORKSPACE_DIRECTORY` environment variable is set, the relative paths of
Expand Down Expand Up @@ -37,7 +43,6 @@ bzl_library(
":missing_platform_fallback_users",
":providers",
"//lib/private:providers",
"@bazel_skylib//lib:types",
],
)

Expand Down
Loading
Loading