1515"""Create the toolchain defs in a BUILD.bazel file."""
1616
1717load ("@bazel_skylib//lib:selects.bzl" , "selects" )
18+ load ("@platforms//host:constraints.bzl" , "HOST_CONSTRAINTS" )
1819load (":text_util.bzl" , "render" )
1920load (
2021 ":toolchain_types.bzl" ,
@@ -95,9 +96,15 @@ def py_toolchain_suite(
9596 runtime_repo_name = user_repository_name ,
9697 target_settings = target_settings ,
9798 target_compatible_with = target_compatible_with ,
99+ exec_compatible_with = [],
98100 )
99101
100- def _internal_toolchain_suite (prefix , runtime_repo_name , target_compatible_with , target_settings ):
102+ def _internal_toolchain_suite (
103+ prefix ,
104+ runtime_repo_name ,
105+ target_compatible_with ,
106+ target_settings ,
107+ exec_compatible_with ):
101108 native .toolchain (
102109 name = "{prefix}_toolchain" .format (prefix = prefix ),
103110 toolchain = "@{runtime_repo_name}//:python_runtimes" .format (
@@ -106,6 +113,7 @@ def _internal_toolchain_suite(prefix, runtime_repo_name, target_compatible_with,
106113 toolchain_type = TARGET_TOOLCHAIN_TYPE ,
107114 target_settings = target_settings ,
108115 target_compatible_with = target_compatible_with ,
116+ exec_compatible_with = exec_compatible_with ,
109117 )
110118
111119 native .toolchain (
@@ -116,6 +124,7 @@ def _internal_toolchain_suite(prefix, runtime_repo_name, target_compatible_with,
116124 toolchain_type = PY_CC_TOOLCHAIN_TYPE ,
117125 target_settings = target_settings ,
118126 target_compatible_with = target_compatible_with ,
127+ exec_compatible_with = exec_compatible_with ,
119128 )
120129
121130 native .toolchain (
@@ -142,7 +151,13 @@ def _internal_toolchain_suite(prefix, runtime_repo_name, target_compatible_with,
142151 # call in python/repositories.bzl. Bzlmod doesn't need anything; it will
143152 # register `:all`.
144153
145- def define_local_toolchain_suites (name , version_aware_repo_names , version_unaware_repo_names ):
154+ def define_local_toolchain_suites (
155+ name ,
156+ version_aware_repo_names ,
157+ version_unaware_repo_names ,
158+ repo_exec_compatible_with ,
159+ repo_target_compatible_with ,
160+ repo_target_settings ):
146161 """Define toolchains for `local_runtime_repo` backed toolchains.
147162
148163 This generates `toolchain` targets that can be registered using `:all`. The
@@ -156,24 +171,60 @@ def define_local_toolchain_suites(name, version_aware_repo_names, version_unawar
156171 version-aware toolchains defined.
157172 version_unaware_repo_names: `list[str]` of the repo names that will have
158173 version-unaware toolchains defined.
174+ repo_target_settings: {type}`dict[str, list[str]]` mapping of repo names
175+ to string labels that are added to the `target_settings` for the
176+ respective repo's toolchain.
177+ repo_target_compatible_with: {type}`dict[str, list[str]]` mapping of repo names
178+ to string labels that are added to the `target_compatible_with` for
179+ the respective repo's toolchain.
180+ repo_exec_compatible_with: {type}`dict[str, list[str]]` mapping of repo names
181+ to string labels that are added to the `exec_compatible_with` for
182+ the respective repo's toolchain.
159183 """
184+
160185 i = 0
161186 for i , repo in enumerate (version_aware_repo_names , start = i ):
162- prefix = render .left_pad_zero (i , 4 )
187+ target_settings = ["@{}//:is_matching_python_version" .format (repo )]
188+
189+ if repo_target_settings .get (repo ):
190+ selects .config_setting_group (
191+ name = "_{}_user_guard" .format (repo ),
192+ match_all = repo_target_settings .get (repo , []) + target_settings ,
193+ )
194+ target_settings = ["_{}_user_guard" .format (repo )]
163195 _internal_toolchain_suite (
164- prefix = prefix ,
196+ prefix = render . left_pad_zero ( i , 4 ) ,
165197 runtime_repo_name = repo ,
166- target_compatible_with = ["@{}//:os" .format (repo )],
167- target_settings = ["@{}//:is_matching_python_version" .format (repo )],
198+ target_compatible_with = _get_local_toolchain_target_compatible_with (
199+ repo ,
200+ repo_target_compatible_with ,
201+ ),
202+ target_settings = target_settings ,
203+ exec_compatible_with = repo_exec_compatible_with .get (repo , []),
168204 )
169205
170206 # The version unaware entries must go last because they will match any Python
171207 # version.
172208 for i , repo in enumerate (version_unaware_repo_names , start = i + 1 ):
173- prefix = render .left_pad_zero (i , 4 )
174209 _internal_toolchain_suite (
175- prefix = prefix ,
210+ prefix = render . left_pad_zero ( i , 4 ) + "_default" ,
176211 runtime_repo_name = repo ,
177- target_settings = [],
178- target_compatible_with = ["@{}//:os" .format (repo )],
212+ target_compatible_with = _get_local_toolchain_target_compatible_with (
213+ repo ,
214+ repo_target_compatible_with ,
215+ ),
216+ # We don't call _get_local_toolchain_target_settings because that
217+ # will add the version matching condition by default.
218+ target_settings = repo_target_settings .get (repo , []),
219+ exec_compatible_with = repo_exec_compatible_with .get (repo , []),
179220 )
221+
222+ def _get_local_toolchain_target_compatible_with (repo , repo_target_compatible_with ):
223+ if repo in repo_target_compatible_with :
224+ target_compatible_with = repo_target_compatible_with [repo ]
225+ if "HOST_CONSTRAINTS" in target_compatible_with :
226+ target_compatible_with .remove ("HOST_CONSTRAINTS" )
227+ target_compatible_with .extend (HOST_CONSTRAINTS )
228+ else :
229+ target_compatible_with = ["@{}//:os" .format (repo )]
230+ return target_compatible_with
0 commit comments