gdnative_python/platforms/SConscript

110 lines
3.8 KiB
Python

import os
import re
from uuid import uuid4
from io import BytesIO
from zipfile import ZipFile
from urllib.request import urlopen, HTTPError
from SCons.Errors import UserError
Import("env")
def resolve_pandemonium_download_url(major, minor, patch, extra, platform):
#version = f"{major}.{minor}.{patch}" if patch != 0 else f"{major}.{minor}"
#if extra == "stable":
# return f"https://downloads.tuxfamily.org/godotengine/{version}/Pandemonium_v{version}-{extra}_{platform}.zip"
#else:
# return f"https://downloads.tuxfamily.org/godotengine/{version}/{extra}/Pandemonium_v{version}-{extra}_{platform}.zip"
return ""
def resolve_pandemonium_binary_name(major, minor, patch, extra, platform):
version = f"{major}.{minor}.{patch}" if patch != 0 else f"{major}.{minor}"
return f"Pandemonium_v{version}-{extra}_{platform}"
SConscript([f"{env['platform']}/SConscript"])
# Platform-dependant variables
assert "bits" in env
assert "pandemonium_binary_download_platform" in env
assert "cpython_build" in env
assert "cpython_build_dir" in env
assert "DIST_SITE_PACKAGES" in env
# Cython modules need to link against libpython.so
env.AppendUnique(CYTHON_COMPILE_DEPS=[env["cpython_build"]])
### Install CPython build into dist ###
# Installing cpython build into dist cannot be simply done by a
# `env.InstallAs("$DIST_PLATFORM", cypthon_build)` rule given it would
# conflict with the rules that install libpythonscript&godot modules.
# To solve this we represent the installation of the build by a virtual target.
cpython_build_install_marker = env.File("cpython_build_installed_in_dist.marker")
env.VirtualTargetCommand(
marker=cpython_build_install_marker,
condition=lambda env: os.path.exists(env.Dir("$DIST_PLATFORM").abspath),
source=env["cpython_build"], # Note we don't use `cpython_build_dir` !
action=[Delete("$DIST_PLATFORM"), Copy("$DIST_PLATFORM", env["cpython_build_dir"])],
)
# Replace default Install command to always depend on cpython build install
env.VanillaInstall = env.Install
env.VanillaInstallAs = env.InstallAs
def install(env, target, source):
out = env.VanillaInstall(target, source)
env.Depends(out, cpython_build_install_marker)
return out
def install_as(env, target, source):
out = env.VanillaInstallAs(target, source)
env.Depends(out, cpython_build_install_marker)
return out
env.AddMethod(install, "Install")
env.AddMethod(install_as, "InstallAs")
### Pandemonium binary (to run tests) ###
if not env["pandemonium_binary"]:
pandemonium_download_url = resolve_pandemonium_download_url(
*env["pandemonium_binary_download_version"], env["pandemonium_binary_download_platform"]
)
pandemonium_binary_name = resolve_pandemonium_binary_name(
*env["pandemonium_binary_download_version"], env["pandemonium_binary_download_platform"]
)
env["pandemonium_binary"] = File(pandemonium_binary_name)
pandemonium_binary_zip_path = env.get("pandemonium_binary_download_zip_path", pandemonium_binary_name)
def download_and_extract(target, source, env):
try:
with urlopen(pandemonium_download_url) as rep:
zipfile = ZipFile(BytesIO(rep.read()))
except HTTPError as exc:
# It seems SCons swallows HTTPError, so we have to wrap it
raise UserError(exc) from exc
if pandemonium_binary_zip_path not in zipfile.namelist():
raise UserError(f"Archive doesn't contain {pandemonium_binary_zip_path}")
with open(target[0].abspath, "wb") as fd:
fd.write(zipfile.open(pandemonium_binary_zip_path).read())
if env["HOST_OS"] != "win32":
os.chmod(target[0].abspath, 0o755)
env.Command(
env["pandemonium_binary"],
None,
Action(download_and_extract, f"Download&extract {pandemonium_download_url}"),
)
env.NoClean(env["pandemonium_binary"])