|
1 | 1 | ""
|
2 | 2 |
|
3 |
| -load("//python:repositories.bzl", "STANDALONE_INTERPRETER_FILENAME") |
| 3 | +load("//python:repositories.bzl", "is_standalone_interpreter") |
4 | 4 | load("//python/pip_install:repositories.bzl", "all_requirements")
|
5 | 5 | load("//python/pip_install/private:srcs.bzl", "PIP_INSTALL_PY_SRCS")
|
6 | 6 |
|
@@ -66,35 +66,68 @@ def _resolve_python_interpreter(rctx):
|
66 | 66 | fail("python interpreter `{}` not found in PATH".format(python_interpreter))
|
67 | 67 | return python_interpreter
|
68 | 68 |
|
69 |
| -def _maybe_set_xcode_location_cflags(rctx, environment): |
70 |
| - """Patch environment with CPPFLAGS of xcode sdk location. |
| 69 | +def _get_xcode_location_cflags(rctx): |
| 70 | + """Query the xcode sdk location to update cflags |
71 | 71 |
|
72 | 72 | Figure out if this interpreter target comes from rules_python, and patch the xcode sdk location if so.
|
73 | 73 | Pip won't be able to compile c extensions from sdists with the pre built python distributions from indygreg
|
74 | 74 | otherwise. See https://github.com/indygreg/python-build-standalone/issues/103
|
75 | 75 | """
|
76 |
| - if ( |
77 |
| - rctx.os.name.lower().startswith("mac os") and |
78 |
| - rctx.attr.python_interpreter_target != None and |
79 |
| - # This is a rules_python provided toolchain. |
80 |
| - rctx.execute([ |
81 |
| - "ls", |
82 |
| - "{}/{}".format( |
83 |
| - rctx.path(Label("@{}//:WORKSPACE".format(rctx.attr.python_interpreter_target.workspace_name))).dirname, |
84 |
| - STANDALONE_INTERPRETER_FILENAME, |
85 |
| - ), |
86 |
| - ]).return_code == 0 and |
87 |
| - not environment.get(CPPFLAGS) |
88 |
| - ): |
89 |
| - xcode_sdk_location = rctx.execute(["xcode-select", "--print-path"]) |
90 |
| - if xcode_sdk_location.return_code == 0: |
91 |
| - xcode_root = xcode_sdk_location.stdout.strip() |
92 |
| - if COMMAND_LINE_TOOLS_PATH_SLUG not in xcode_root.lower(): |
93 |
| - # This is a full xcode installation somewhere like /Applications/Xcode13.0.app/Contents/Developer |
94 |
| - # so we need to change the path to to the macos specific tools which are in a different relative |
95 |
| - # path than xcode installed command line tools. |
96 |
| - xcode_root = "{}/Platforms/MacOSX.platform/Developer".format(xcode_root) |
97 |
| - environment[CPPFLAGS] = "-isysroot {}/SDKs/MacOSX.sdk".format(xcode_root) |
| 76 | + |
| 77 | + # Only run on MacOS hosts |
| 78 | + if not rctx.os.name.lower().startswith("mac os"): |
| 79 | + return [] |
| 80 | + |
| 81 | + # Only update the location when using a hermetic toolchain. |
| 82 | + if not is_standalone_interpreter(rctx, rctx.attr.python_interpreter_target): |
| 83 | + return [] |
| 84 | + |
| 85 | + # Locate xcode-select |
| 86 | + xcode_select = rctx.which("xcode-select") |
| 87 | + |
| 88 | + xcode_sdk_location = rctx.execute([xcode_select, "--print-path"]) |
| 89 | + if xcode_sdk_location.return_code != 0: |
| 90 | + return [] |
| 91 | + |
| 92 | + xcode_root = xcode_sdk_location.stdout.strip() |
| 93 | + if COMMAND_LINE_TOOLS_PATH_SLUG not in xcode_root.lower(): |
| 94 | + # This is a full xcode installation somewhere like /Applications/Xcode13.0.app/Contents/Developer |
| 95 | + # so we need to change the path to to the macos specific tools which are in a different relative |
| 96 | + # path than xcode installed command line tools. |
| 97 | + xcode_root = "{}/Platforms/MacOSX.platform/Developer".format(xcode_root) |
| 98 | + return [ |
| 99 | + "-isysroot {}/SDKs/MacOSX.sdk".format(xcode_root), |
| 100 | + ] |
| 101 | + |
| 102 | +def _get_toolchain_unix_cflags(rctx): |
| 103 | + """Gather cflags from a standalone toolchain for unix systems. |
| 104 | +
|
| 105 | + Pip won't be able to compile c extensions from sdists with the pre built python distributions from indygreg |
| 106 | + otherwise. See https://github.com/indygreg/python-build-standalone/issues/103 |
| 107 | + """ |
| 108 | + |
| 109 | + # Only run on Unix systems |
| 110 | + if not rctx.os.name.lower().startswith(("mac os", "linux")): |
| 111 | + return [] |
| 112 | + |
| 113 | + # Only update the location when using a standalone toolchain. |
| 114 | + if not is_standalone_interpreter(rctx, rctx.attr.python_interpreter_target): |
| 115 | + return [] |
| 116 | + |
| 117 | + er = rctx.execute([ |
| 118 | + rctx.path(rctx.attr.python_interpreter_target).realpath, |
| 119 | + "-c", |
| 120 | + "import sys; print(f'{sys.version_info[0]}.{sys.version_info[1]}')", |
| 121 | + ]) |
| 122 | + if er.return_code != 0: |
| 123 | + fail("could not get python version from interpreter (status {}): {}".format(er.return_code, er.stderr)) |
| 124 | + _python_version = er.stdout |
| 125 | + include_path = "{}/include/python{}".format( |
| 126 | + rctx.path(Label("@{}//:WORKSPACE".format(rctx.attr.python_interpreter_target.workspace_name))).dirname.realpath, |
| 127 | + _python_version, |
| 128 | + ) |
| 129 | + |
| 130 | + return ["-isystem {}".format(include_path)] |
98 | 131 |
|
99 | 132 | def _parse_optional_attrs(rctx, args):
|
100 | 133 | """Helper function to parse common attributes of pip_repository and whl_library repository rules.
|
@@ -152,10 +185,20 @@ def _create_repository_execution_environment(rctx):
|
152 | 185 |
|
153 | 186 | Args:
|
154 | 187 | rctx: The repository context.
|
155 |
| - Returns: Dictionary of envrionment variable suitable to pass to rctx.execute. |
| 188 | + Returns: |
| 189 | + Dictionary of environment variable suitable to pass to rctx.execute. |
156 | 190 | """
|
157 |
| - env = {"PYTHONPATH": _construct_pypath(rctx)} |
158 |
| - _maybe_set_xcode_location_cflags(rctx, env) |
| 191 | + |
| 192 | + # Gather any available CPPFLAGS values |
| 193 | + cppflags = [] |
| 194 | + cppflags.extend(_get_xcode_location_cflags(rctx)) |
| 195 | + cppflags.extend(_get_toolchain_unix_cflags(rctx)) |
| 196 | + |
| 197 | + env = { |
| 198 | + "PYTHONPATH": _construct_pypath(rctx), |
| 199 | + CPPFLAGS: " ".join(cppflags), |
| 200 | + } |
| 201 | + |
159 | 202 | return env
|
160 | 203 |
|
161 | 204 | _BUILD_FILE_CONTENTS = """\
|
|
0 commit comments