22
33load ("@bazel_skylib//rules:common_settings.bzl" , "BuildSettingInfo" )
44load ("//python/private:toolchain_types.bzl" , "TARGET_TOOLCHAIN_TYPE" )
5+ load (
6+ ":pep508_env.bzl" ,
7+ "env_aliases" ,
8+ "os_name_select_map" ,
9+ "platform_machine_aliases" ,
10+ "platform_machine_select_map" ,
11+ "platform_system_select_map" ,
12+ "sys_platform_select_map" ,
13+ )
514load (":pep508_evaluate.bzl" , "evaluate" )
615
7- # todo: copied from pep508_env.bzl
8- _os_name_select_map = {
9- # The "java" value is documented, but with Jython defunct,
10- # shouldn't occur in practice.
11- # The os.name value is technically a property of the runtime, not the
12- # targetted runtime OS, but the distinction shouldn't matter if
13- # things are properly configured.
14- "@platforms//os:windows" : "nt" ,
15- "//conditions:default" : "posix" ,
16- }
17-
18- # TODO @aignas 2025-04-29: this is copied from ./pep508_env.bzl
19- _platform_machine_aliases = {
20- # These pairs mean the same hardware, but different values may be used
21- # on different host platforms.
22- "amd64" : "x86_64" ,
23- "arm64" : "aarch64" ,
24- "i386" : "x86_32" ,
25- "i686" : "x86_32" ,
26- }
27-
28- # Taken from
29- # https://docs.python.org/3/library/sys.html#sys.platform
30- _sys_platform_select_map = {
31- # These values are decided by the sys.platform docs.
32- "@platforms//os:android" : "android" ,
33- "@platforms//os:emscripten" : "emscripten" ,
34- "@platforms//os:ios" : "ios" ,
35- "@platforms//os:linux" : "linux" ,
36- "@platforms//os:osx" : "darwin" ,
37- "@platforms//os:windows" : "win32" ,
38- "@platforms//os:wasi" : "wasi" ,
39- # NOTE: The below values are approximations. The sys.platform() docs
40- # don't have documented values for these OSes. Per docs, the
41- # sys.platform() value reflects the OS at the time Python was *built*
42- # instead of the runtime (target) OS value.
43- "@platforms//os:freebsd" : "freebsd" ,
44- "@platforms//os:openbsd" : "openbsd" ,
45- # For lack of a better option, use empty string. No standard doc/spec
46- # about sys_platform value.
47- "//conditions:default" : "" ,
48- }
49-
50- # todo: copied from pep508_env.bzl
51- # TODO: there are many cpus and unfortunately, it doesn't look like
52- # the value is directly accessible to starlark. It might be possible to
53- # get it via CcToolchain.cpu though.
54- _platform_machine_select_map = {
55- "@platforms//cpu:aarch32" : "aarch32" ,
56- "@platforms//cpu:aarch64" : "aarch64" ,
57- "@platforms//cpu:arm" : "arm" ,
58- "@platforms//cpu:arm64" : "arm64" ,
59- "@platforms//cpu:arm64_32" : "arm64_32" ,
60- "@platforms//cpu:arm64e" : "arm64e" ,
61- "@platforms//cpu:armv6-m" : "armv6-m" ,
62- "@platforms//cpu:armv7" : "armv7" ,
63- "@platforms//cpu:armv7-m" : "armv7-m" ,
64- "@platforms//cpu:armv7e-m" : "armv7e-m" ,
65- "@platforms//cpu:armv7e-mf" : "armv7e-mf" ,
66- "@platforms//cpu:armv7k" : "armv7k" ,
67- "@platforms//cpu:armv8-m" : "armv8-m" ,
68- "@platforms//cpu:cortex-r52" : "cortex-r52" ,
69- "@platforms//cpu:cortex-r82" : "cortex-r82" ,
70- "@platforms//cpu:i386" : "i386" ,
71- "@platforms//cpu:mips64" : "mips64" ,
72- "@platforms//cpu:ppc" : "ppc" ,
73- "@platforms//cpu:ppc32" : "ppc32" ,
74- "@platforms//cpu:ppc64le" : "ppc64le" ,
75- "@platforms//cpu:riscv32" : "riscv32" ,
76- "@platforms//cpu:riscv64" : "riscv64" ,
77- "@platforms//cpu:s390x" : "s390x" ,
78- "@platforms//cpu:wasm32" : "wasm32" ,
79- "@platforms//cpu:wasm64" : "wasm64" ,
80- "@platforms//cpu:x86_32" : "x86_32" ,
81- "@platforms//cpu:x86_64" : "x86_64" ,
82- # The value is empty string if it cannot be determined:
83- # https://docs.python.org/3/library/platform.html#platform.machine
84- "//conditions:default" : "" ,
85- }
86-
87- # todo: copied from pep508_env.bzl
88- _platform_system_select_map = {
89- # See https://peps.python.org/pep-0738/#platform
90- "@platforms//os:android" : "Android" ,
91- "@platforms//os:freebsd" : "FreeBSD" ,
92- # See https://peps.python.org/pep-0730/#platform
93- # NOTE: Per Pep 730, "iPadOS" is also an acceptable value
94- "@platforms//os:ios" : "iOS" ,
95- "@platforms//os:linux" : "Linux" ,
96- "@platforms//os:netbsd" : "NetBSD" ,
97- "@platforms//os:openbsd" : "OpenBSD" ,
98- "@platforms//os:osx" : "Darwin" ,
99- "@platforms//os:windows" : "Windows" ,
100- # The value is empty string if it cannot be determined:
101- # https://docs.python.org/3/library/platform.html#platform.machine
102- "//conditions:default" : "" ,
103- }
16+ # Use capitals to hint its not an actual boolean type.
17+ _ENV_MARKER_TRUE = "TRUE"
18+ _ENV_MARKER_FALSE = "FALSE"
10419
10520def env_marker_setting (* , name , expression , ** kwargs ):
10621 """Creates an env_marker setting.
10722
23+ Generated targets:
24+
25+ * `is_{name}_true`: config_setting that matches when the expression is true.
26+ * `{name}`: env marker target that evalutes the expression.
27+
10828 Args:
10929 name: {type}`str` target name
11030 expression: {type}`str` the environment marker string to evaluate
111- **kwargs: {type}`dict` additionally common kwargs.
31+ **kwargs: {type}`dict` additional common kwargs.
11232 """
33+ native .config_setting (
34+ name = "is_{}_true" .format (name ),
35+ flag_values = {
36+ ":{}" .format (name ): _ENV_MARKER_TRUE ,
37+ },
38+ ** kwargs
39+ )
11340 _env_marker_setting (
11441 name = name ,
11542 expression = expression ,
116- os_name = select (_os_name_select_map ),
117- sys_platform = select (_sys_platform_select_map ),
118- platform_machine = select (_platform_machine_select_map ),
119- platform_system = select (_platform_system_select_map ),
43+ os_name = select (os_name_select_map ),
44+ sys_platform = select (sys_platform_select_map ),
45+ platform_machine = select (platform_machine_select_map ),
46+ platform_system = select (platform_system_select_map ),
12047 ** kwargs
12148 )
12249
@@ -149,12 +76,13 @@ def _env_marker_setting_impl(ctx):
14976 env ["sys_platform" ] = ctx .attr .sys_platform
15077 env ["platform_machine" ] = ctx .attr .platform_machine
15178
152- # The `platform_python_implementation` marker value is supposed to come from
153- # `platform.python_implementation()`, however, PEP 421 introduced
154- # `sys.implementation.name` to replace it. There's now essentially just two
155- # possible values it might have: CPython or PyPy. Rather than add a field to
156- # the toolchain, we just special case the value from
157- # `sys.implementation.name`
79+ # The `platform_python_implementation` marker value is supposed to come
80+ # from `platform.python_implementation()`, however, PEP 421 introduced
81+ # `sys.implementation.name` and the `implementation_name` env marker to
82+ # replace it. Per the platform.python_implementation docs, there's now
83+ # essentially just two possible "registered" values: CPython or PyPy.
84+ # Rather than add a field to the toolchain, we just special case the value
85+ # from `sys.implementation.name` to handle the two documented values.
15886 platform_python_impl = runtime .implementation_name
15987 if platform_python_impl == "cpython" :
16088 platform_python_impl = "CPython"
@@ -170,21 +98,12 @@ def _env_marker_setting_impl(ctx):
17098 env ["platform_system" ] = ctx .attr .platform_system
17199 env ["platform_version" ] = _get_flag (ctx .attr ._platform_version_config_flag )
172100
173- # TODO @aignas 2025-04-29: figure out how to correctly share the aliases
174- # between the two. Maybe the select statements above should be part of the
175- # `pep508_env.bzl` file?
176- env = env | {
177- "_aliases" : {
178- "platform_machine" : _platform_machine_aliases ,
179- },
180- }
101+ env .update (env_aliases ())
181102
182103 if evaluate (ctx .attr .expression , env = env ):
183- # todo: better return value than "yes" and "no"
184- # matched/unmatched, satisfied/unsatisfied ?
185- value = "yes"
104+ value = _ENV_MARKER_TRUE
186105 else :
187- value = "no"
106+ value = _ENV_MARKER_FALSE
188107 return [config_common .FeatureFlagInfo (value = value )]
189108
190109_env_marker_setting = rule (
0 commit comments