A proof-of-concept ruleset to (hopefully) improve cross-platform Python builds with Bazel.
Note: very much still experimental.
- A single lock file for all target platforms, thanks to Poetry
- Builds that happen in build actions, not during WORKSPACE initialization
- Standard Bazel
http_filerules used for fetching dependencies.pipis not a build-time dependency.
See the example.
The current Bazel rules for working with Python external dependencies have a couple of issues that make cross-platform usage difficult (see bazel-contrib/rules_python#260):
- they're based on
pipandpip-compilewhich do not generate cross-platform lock files. For example, IPython depends onappnopeonly on MacOS. Lock files generated bypip-compilewill differ based on whether they're created on Linux or MacOS. - They use
pip installduring theWORKSPACEphase to fetch and possibly build packages (including native libraries).WORKSPACEoperations lack many of the things that Bazel's build actions provide such as sandboxing and remote execution.
A pip install operation can be roughly broken down into these parts:
- determine the environment (OS and Python version/implementation)
- resolve the dependencies of the package to install, some of which may be platform-specific (optionally constrained by a pre-compiled lock file)
- figure out which files to download - either pre-built wheels matching the current platform or sdists to build locally
- download sdists and wheels
- build and install sdists; install wheels
rules_pycross attemps to deconstruct this operation into its constituent parts and glue them together with Bazel:
pycross_target_environmentis used to specify target environments ahead of time provided with ABI, platform, and implementation parameters (similar to pip's--abi,--platform, and--implementationflags). These environments are selected using Bazel's own platform/constraint system.pycross_lock_filegenerates a "lock".bzlfile from an inputpoetry.lock. This.bzlfile contains a mix ofhttp_filerepositories andpycross_*targets.pycross_wheel_buildbuildssdist.tar.gzarchives into Python wheels. This is a build action, not aWORKSPACEoperation.pycross_wheel_library"installs" (extracts) a Python wheel - either downloaded or built from an sdist - and provides it as apy_library.
See the generated docs.