Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions Lib/sysconfig/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,12 +665,10 @@ def get_platform():

For other non-POSIX platforms, currently just returns :data:`sys.platform`."""
if os.name == 'nt':
if 'amd64' in sys.version.lower():
return 'win-amd64'
if '(arm)' in sys.version.lower():
return 'win-arm32'
if '(arm64)' in sys.version.lower():
return 'win-arm64'
import _sysconfig
platform = _sysconfig.get_platform()
if platform:
return platform
return sys.platform

if os.name != "posix" or not hasattr(os, 'uname'):
Expand Down
21 changes: 9 additions & 12 deletions Lib/test/test_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import shutil
import json
import textwrap
from unittest.mock import patch
from copy import copy

from test import support
Expand Down Expand Up @@ -247,19 +248,15 @@ def test_get_platform(self):
self.assertIsInstance(actual_platform, str)
self.assertTrue(actual_platform)

# windows XP, 32bits
# Windows
os.name = 'nt'
sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
'[MSC v.1310 32 bit (Intel)]')
sys.platform = 'win32'
self.assertEqual(get_platform(), 'win32')

# windows XP, amd64
os.name = 'nt'
sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) '
'[MSC v.1310 32 bit (Amd64)]')
sys.platform = 'win32'
self.assertEqual(get_platform(), 'win-amd64')
with patch('_sysconfig.get_platform', create=True, return_value='win32'):
self.assertEqual(get_platform(), 'win32')
with patch('_sysconfig.get_platform', create=True, return_value='win-amd64'):
self.assertEqual(get_platform(), 'win-amd64')
sys.platform = 'test-plaform'
with patch('_sysconfig.get_platform', create=True, return_value=None):
self.assertEqual(get_platform(), 'test-plaform')

# macbook
os.name = 'posix'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
On Windows, :func:`sysconfig.get_platform` now gets the platform from the
``_sysconfig`` module instead of parsing :data:`sys.version` string. Patch
by Victor Stinner.
37 changes: 37 additions & 0 deletions Modules/_sysconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,48 @@ _sysconfig_config_vars_impl(PyObject *module)
return config;
}

#ifdef MS_WINDOWS
/*[clinic input]
_sysconfig.get_platform

Return a string that identifies the current platform.
[clinic start generated code]*/

static PyObject *
_sysconfig_get_platform_impl(PyObject *module)
/*[clinic end generated code: output=4ecbbe2b77633f3e input=c0b43abda44f9a01]*/
{
#ifdef MS_WIN64
# if defined(_M_X64) || defined(_M_AMD64)
# define SYSCONFIG_PLATFORM "win-amd64"
# elif defined(_M_ARM64)
# define SYSCONFIG_PLATFORM "win-arm64"
# endif
#endif

#if defined(MS_WIN32) && !defined(MS_WIN64)
# if defined(_M_IX86)
# define SYSCONFIG_PLATFORM "win32"
# elif defined(_M_ARM)
# define SYSCONFIG_PLATFORM "win-arm32"
# endif
#endif

#ifdef SYSCONFIG_PLATFORM
return PyUnicode_FromString(SYSCONFIG_PLATFORM);
#else
Py_RETURN_NONE;
#endif
}
#endif // MS_WINDOWS


PyDoc_STRVAR(sysconfig__doc__,
"A helper for the sysconfig module.");

static struct PyMethodDef sysconfig_methods[] = {
_SYSCONFIG_CONFIG_VARS_METHODDEF
_SYSCONFIG_GET_PLATFORM_METHODDEF
{NULL, NULL}
};

Expand Down
28 changes: 27 additions & 1 deletion Modules/clinic/_sysconfig.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 73 additions & 17 deletions Platforms/emscripten/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ def get_build_paths(cross_build_dir=None, emsdk_cache=None):
LOCAL_SETUP_MARKER = b"# Generated by Platforms/wasm/emscripten.py\n"


@functools.cache
def validate_emsdk_version(emsdk_cache):
"""Validate that the emsdk cache contains the required emscripten version."""
if emsdk_cache is None:
print("Build will use EMSDK from current environment.")
return
required_version = required_emscripten_version()
emsdk_env = emsdk_activate_path(emsdk_cache)
Expand Down Expand Up @@ -530,7 +532,6 @@ def configure_emscripten_python(context, working_dir):
@subdir("host_dir")
def make_emscripten_python(context, working_dir):
"""Run `make` for the emscripten/host build."""
validate_emsdk_version(context.emsdk_cache)
call(
["make", "--jobs", str(cpu_count()), "all"],
env=updated_env({}, context.emsdk_cache),
Expand All @@ -541,6 +542,22 @@ def make_emscripten_python(context, working_dir):
subprocess.check_call([exec_script, "--version"])


def run_emscripten_python(context):
"""Run the built emscripten Python."""
host_dir = context.build_paths["host_dir"]
exec_script = host_dir / "python.sh"
if not exec_script.is_file():
print("Emscripten not built", file=sys.stderr)
sys.exit(1)

args = context.args
# Strip the "--" separator if present
if args and args[0] == "--":
args = args[1:]

os.execv(str(exec_script), [str(exec_script)] + args)


def build_target(context):
"""Build one or more targets."""
steps = []
Expand Down Expand Up @@ -581,15 +598,31 @@ def clean_contents(context):
print(f"🧹 Deleting generated {LOCAL_SETUP} ...")


def add_cross_build_dir_option(subcommand):
subcommand.add_argument(
"--cross-build-dir",
action="store",
default=os.environ.get("CROSS_BUILD_DIR"),
dest="cross_build_dir",
help=(
"Path to the cross-build directory "
f"(default: {DEFAULT_CROSS_BUILD_DIR}). "
"Can also be set with the CROSS_BUILD_DIR environment variable.",
),
)


def main():
default_host_runner = "node"

parser = argparse.ArgumentParser()
subcommands = parser.add_subparsers(dest="subcommand")

install_emscripten_cmd = subcommands.add_parser(
"install-emscripten",
help="Install the appropriate version of Emscripten",
)

build = subcommands.add_parser("build", help="Build everything")
build.add_argument(
"target",
Expand All @@ -605,24 +638,46 @@ def main():
configure_build = subcommands.add_parser(
"configure-build-python", help="Run `configure` for the build Python"
)

make_mpdec_cmd = subcommands.add_parser(
"make-mpdec",
help="Clone mpdec repo, configure and build it for emscripten",
)

make_libffi_cmd = subcommands.add_parser(
"make-libffi",
help="Clone libffi repo, configure and build it for emscripten",
)

make_build = subcommands.add_parser(
"make-build-python", help="Run `make` for the build Python"
)

configure_host = subcommands.add_parser(
"configure-host",
help="Run `configure` for the host/emscripten (pydebug builds are inferred from the build Python)",
help=(
"Run `configure` for the host/emscripten "
"(pydebug builds are inferred from the build Python)"
),
)

make_host = subcommands.add_parser(
"make-host", help="Run `make` for the host/emscripten"
)

run = subcommands.add_parser(
"run",
help="Run the built emscripten Python",
)
run.add_argument(
"args",
nargs=argparse.REMAINDER,
help=(
"Arguments to pass to the emscripten Python "
"(use '--' to separate from run options)",
)
)
add_cross_build_dir_option(run)
clean = subcommands.add_parser(
"clean", help="Delete files and directories created by this script"
)
Expand Down Expand Up @@ -651,26 +706,26 @@ def main():
subcommand.add_argument(
"--quiet",
action="store_true",
default=False,
default="QUIET" in os.environ,
dest="quiet",
help="Redirect output from subprocesses to a log file",
)
subcommand.add_argument(
"--cross-build-dir",
action="store",
default=None,
dest="cross_build_dir",
help="Path to the cross-build directory "
f"(default: {DEFAULT_CROSS_BUILD_DIR})",
help=(
"Redirect output from subprocesses to a log file. "
"Can also be set with the QUIET environment variable."
),
)
add_cross_build_dir_option(subcommand)
subcommand.add_argument(
"--emsdk-cache",
action="store",
default=None,
default=os.environ.get("EMSDK_CACHE"),
dest="emsdk_cache",
help="Path to emsdk cache directory. If provided, validates that "
"the required emscripten version is installed.",
help=(
"Path to emsdk cache directory. If provided, validates that "
"the required emscripten version is installed. "
"Can also be set with the EMSDK_CACHE environment variable."
),
)

for subcommand in configure_build, configure_host:
subcommand.add_argument(
"--clean",
Expand All @@ -679,10 +734,12 @@ def main():
dest="clean",
help="Delete any relevant directories before building",
)

for subcommand in build, configure_build, configure_host:
subcommand.add_argument(
"args", nargs="*", help="Extra arguments to pass to `configure`"
)

for subcommand in build, configure_host:
subcommand.add_argument(
"--host-runner",
Expand All @@ -699,8 +756,6 @@ def main():

if context.emsdk_cache:
context.emsdk_cache = Path(context.emsdk_cache).absolute()
else:
print("Build will use EMSDK from current environment.")

context.build_paths = get_build_paths(
context.cross_build_dir, context.emsdk_cache
Expand All @@ -715,6 +770,7 @@ def main():
"configure-host": configure_emscripten_python,
"make-host": make_emscripten_python,
"build": build_target,
"run": run_emscripten_python,
"clean": clean_contents,
}

Expand Down
Loading