@@ -25,8 +25,6 @@ platform-specific repositories.
2525
2626load (
2727 "//python:versions.bzl" ,
28- "LINUX_NAME" ,
29- "MACOS_NAME" ,
3028 "PLATFORMS" ,
3129 "WINDOWS_NAME" ,
3230)
@@ -220,15 +218,15 @@ actions.""",
220218)
221219
222220def _host_toolchain_impl (rctx ):
223- logger = repo_utils .logger (rctx )
224221 rctx .file ("BUILD.bazel" , """\
225222 # Generated by python/private/toolchains_repo.bzl
226223
227224exports_files(["python"], visibility = ["//visibility:public"])
228225""" )
229226
230- (os_name , arch ) = _get_host_os_arch (rctx , logger )
231- host_platform = _get_host_platform (os_name , arch )
227+ os_name = repo_utils .get_platforms_os_name (rctx )
228+ cpu_name = repo_utils .get_platforms_cpu_name (rctx )
229+ host_platform = _get_host_platform (rctx , os_name , cpu_name , rctx .attr .platforms )
232230 repo = "@@{py_repository}_{host_platform}" .format (
233231 py_repository = rctx .attr .name [:- len ("_host" )],
234232 host_platform = host_platform ,
@@ -297,6 +295,7 @@ toolchain_aliases repo because referencing the `python` interpreter target from
297295this repo causes an eager fetch of the toolchain for the host platform.
298296 """ ,
299297 attrs = {
298+ "platforms" : attr .string_list (mandatory = True ),
300299 "_rule_name" : attr .string (default = "host_toolchain" ),
301300 "_rules_python_workspace" : attr .label (default = Label ("//:WORKSPACE" )),
302301 },
@@ -365,57 +364,47 @@ multi_toolchain_aliases = repository_rule(
365364def sanitize_platform_name (platform ):
366365 return platform .replace ("-" , "_" )
367366
368- def _get_host_platform (os_name , arch ):
367+ def _get_host_platform (rctx , os_name , cpu_name , platforms ):
369368 """Gets the host platform.
370369
371370 Args:
372- os_name: the host OS name.
373- arch: the host arch.
371+ rctx: {type}`repository_ctx`.
372+ os_name: {type}`str` the host OS name.
373+ cpu_name: {type}`str` the host CPU name.
374+ platforms: {type}`list[str]` the list of loaded platforms.
374375 Returns:
375376 The host platform.
376377 """
377- host_platform = None
378- for platform , meta in PLATFORMS .items ():
379- if "freethreaded" in platform :
380- continue
381-
382- if meta .os_name == os_name and meta .arch == arch :
383- host_platform = platform
384- if not host_platform :
385- fail ("No platform declared for host OS {} on arch {}" .format (os_name , arch ))
386- return host_platform
378+ candidates = []
379+ for platform in platforms :
380+ meta = PLATFORMS [platform ]
387381
388- def _get_host_os_arch ( rctx , logger ) :
389- """Infer the host OS name and arch from a repository context.
382+ if meta . os_name == os_name and meta . arch == cpu_name :
383+ candidates . append ( platform )
390384
391- Args:
392- rctx: Bazel's repository_ctx.
393- logger: Logger to use for operations.
385+ if len (candidates ) == 1 :
386+ return candidates [0 ]
394387
395- Returns:
396- A tuple with the host OS name and arch.
397- """
398- os_name = rctx .os .name
399-
400- # We assume the arch for Windows is always x86_64.
401- if "windows" in os_name .lower ():
402- arch = "x86_64"
403-
404- # Normalize the os_name. E.g. os_name could be "OS windows server 2019".
405- os_name = WINDOWS_NAME
406- else :
407- # This is not ideal, but bazel doesn't directly expose arch.
408- arch = repo_utils .execute_unchecked (
388+ if candidates :
389+ preference = repo_utils .getenv (
409390 rctx ,
410- op = "GetUname" ,
411- arguments = [repo_utils .which_checked (rctx , "uname" ), "-m" ],
412- logger = logger ,
413- ).stdout .strip ()
414-
415- # Normalize the os_name.
416- if "mac" in os_name .lower ():
417- os_name = MACOS_NAME
418- elif "linux" in os_name .lower ():
419- os_name = LINUX_NAME
420-
421- return (os_name , arch )
391+ "RULES_PYTHON_{}_{}_USE_HOST_PYTHON" .format (
392+ os_name .upper (),
393+ cpu_name .upper (),
394+ ),
395+ )
396+ if preference == None :
397+ candidates = sorted (candidates , lambda k : ("freethreaded" in k , k ))
398+ elif preference not in candidates :
399+ fail ("Please choose a prefrered interpreter out of the following platforms: {}" .format (candidates ))
400+ else :
401+ candidates = [preference ]
402+
403+ if candidates :
404+ return candidates [0 ]
405+
406+ fail ("Could not find a compatible 'host' python for '{os_name}', '{cpu_name}' from the loaded platforms: {platforms}" .format (
407+ os_name = os_name ,
408+ cpu_name = cpu_name ,
409+ platforms = platforms ,
410+ ))
0 commit comments