Skip to content

Commit

Permalink
Draft: Build wheels for different Python interpreter
Browse files Browse the repository at this point in the history
Fromager now support building wheels for a different Python interpreter:

```shell
fromager --python-interpreter=/path/to/python ...
```

Fixes: #431
Signed-off-by: Christian Heimes <[email protected]>
  • Loading branch information
tiran committed Sep 18, 2024
1 parent d80da7c commit 3348a7c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
10 changes: 10 additions & 0 deletions src/fromager/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import logging
import pathlib
import sys

import click

Expand Down Expand Up @@ -127,6 +128,13 @@
help="Build sdist and wheen with network isolation (unshare -cn)",
show_default=True,
)
@click.option(
"--python-interpreter",
type=clickext.ClickPath(),
default=pathlib.Path(sys.executable),
help="Python interpreter to build wheels for",
show_default=True,
)
@click.pass_context
def main(
ctx: click.Context,
Expand All @@ -145,6 +153,7 @@ def main(
variant: str,
jobs: int | None,
network_isolation: bool,
python_interpreter: pathlib.Path,
) -> None:
# Set the overall logger level to debug and allow the handlers to filter
# messages at their own level.
Expand Down Expand Up @@ -211,6 +220,7 @@ def main(
network_isolation=network_isolation,
max_jobs=jobs,
settings_dir=settings_dir,
python_interpreter=python_interpreter,
)
wkctx.setup()
ctx.obj = wkctx
Expand Down
8 changes: 3 additions & 5 deletions src/fromager/build_environment.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import importlib.metadata
import logging
import pathlib
import platform
import re
import subprocess
import sys
import typing

from packaging.requirements import Requirement
Expand Down Expand Up @@ -75,7 +73,7 @@ def __init__(
build_requirements: typing.Iterable[Requirement] | None,
):
self._ctx = ctx
self.path = parent_dir / f"build-{platform.python_version()}"
self.path = parent_dir / f"build-{ctx.python_version()}"
self._build_requirements = build_requirements
self._createenv()

Expand All @@ -90,7 +88,7 @@ def _createenv(self) -> None:

logger.debug("creating build environment in %s", self.path)
external_commands.run(
[sys.executable, "-m", "virtualenv", str(self.path)],
[str(self._ctx.python_interpreter), "-m", "virtualenv", str(self.path)],
network_isolation=False,
)
logger.info("created build environment in %s", self.path)
Expand Down Expand Up @@ -258,7 +256,7 @@ def _safe_install(
logger.debug("installing %s %s", req_type, req)
external_commands.run(
[
sys.executable,
str(ctx.python_interpreter),
"-m",
"pip",
"-vvv",
Expand Down
20 changes: 20 additions & 0 deletions src/fromager/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import os
import pathlib
import sys
import typing
from urllib.parse import urlparse

Expand All @@ -13,6 +14,7 @@
from . import (
constraints,
dependency_graph,
external_commands,
packagesettings,
)

Expand All @@ -38,6 +40,7 @@ def __init__(
network_isolation: bool = False,
max_jobs: int | None = None,
settings_dir: pathlib.Path | None = None,
python_interpreter: pathlib.Path = pathlib.Path(sys.executable),
):
if active_settings is None:
active_settings = packagesettings.Settings(
Expand Down Expand Up @@ -69,6 +72,8 @@ def __init__(
self.variant = variant
self.network_isolation = network_isolation
self.settings_dir = settings_dir
self.python_interpreter = python_interpreter.absolute()
self._python_version: str | None = None

self._build_order_filename = self.work_dir / "build-order.json"
self._constraints_filename = self.work_dir / "constraints.txt"
Expand Down Expand Up @@ -165,6 +170,21 @@ def package_build_info(
name = package
return self.settings.package_build_info(name)

def python_version(self) -> str:
"""Return Python version of `python_interpreter` (major.minor.patch)
"""
if self._python_version is None:
out = external_commands.run(
[
str(self.python_interpreter),
"-c",
"import platform; print(platform.python_version())",
],
network_isolation=False,
)
self._python_version = out.split("\n", 1)[0].strip()
return self._python_version

def setup(self) -> None:
# The work dir must already exist, so don't try to create it.
# Use os.makedirs() to create the others in case the paths
Expand Down

0 comments on commit 3348a7c

Please sign in to comment.