pyodide/pyodide_build/buildall.py

167 lines
4.9 KiB
Python
Raw Normal View History

2018-06-20 18:54:47 +00:00
#!/usr/bin/env python3
"""
Build all of the packages in a given directory.
"""
2018-06-20 18:54:47 +00:00
import argparse
import json
2018-08-03 16:48:22 +00:00
from pathlib import Path
2018-06-20 18:54:47 +00:00
import shutil
from . import common
from . import buildpkg
2018-06-20 18:54:47 +00:00
2018-08-06 14:01:28 +00:00
def build_package(pkgname, dependencies, packagesdir, outputdir, args):
reqs = dependencies[pkgname]
# Make sure all of the package's requirements are built first
2018-06-20 18:54:47 +00:00
for req in reqs:
2018-08-06 14:01:28 +00:00
build_package(req, dependencies, packagesdir, outputdir, args)
buildpkg.build_package(packagesdir / pkgname / "meta.yaml", args)
2018-06-20 18:54:47 +00:00
shutil.copyfile(
packagesdir / pkgname / "build" / (pkgname + ".data"),
outputdir / (pkgname + ".data"),
)
2018-06-20 18:54:47 +00:00
shutil.copyfile(
packagesdir / pkgname / "build" / (pkgname + ".js"),
outputdir / (pkgname + ".js"),
)
2018-06-20 18:54:47 +00:00
2018-08-06 14:01:28 +00:00
def build_packages(packagesdir, outputdir, args):
# We have to build the packages in the correct order (dependencies first),
# so first load in all of the package metadata and build a dependency map.
2018-06-20 18:54:47 +00:00
dependencies = {}
import_name_to_package_name = {}
included_packages = common._parse_package_subset(args.only)
if included_packages is not None:
# check that the specified packages exist
for name in included_packages:
if not (packagesdir / name).exists():
raise ValueError(
f"package name {name} does not exist. "
f"The value of PYODIDE_PACKAGES is likely incorrect."
)
2018-08-03 16:48:22 +00:00
for pkgdir in packagesdir.iterdir():
if included_packages is not None and pkgdir.name not in included_packages:
print(
2020-07-13 19:46:20 +00:00
f"Warning: skipping build of {pkgdir.name} due "
f"to specified PYODIDE_PACKAGES"
)
continue
pkgpath = pkgdir / "meta.yaml"
2018-08-03 16:48:22 +00:00
if pkgdir.is_dir() and pkgpath.is_file():
2018-06-20 18:54:47 +00:00
pkg = common.parse_package(pkgpath)
name = pkg["package"]["name"]
reqs = pkg.get("requirements", {}).get("run", [])
2018-06-20 18:54:47 +00:00
dependencies[name] = reqs
imports = pkg.get("test", {}).get("imports", [name])
for imp in imports:
import_name_to_package_name[imp] = name
2018-06-20 18:54:47 +00:00
for pkgname in dependencies.keys():
2018-08-06 14:01:28 +00:00
build_package(pkgname, dependencies, packagesdir, outputdir, args)
2018-06-20 18:54:47 +00:00
2018-07-18 13:26:18 +00:00
# The "test" package is built in a different way, so we hardcode its
# existence here.
dependencies["test"] = []
2018-07-18 13:26:18 +00:00
# This is done last so the Makefile can use it as a completion token.
with open(outputdir / "packages.json", "w") as fd:
json.dump(
{
"dependencies": dependencies,
"import_name_to_package_name": import_name_to_package_name,
},
fd,
)
2018-06-20 18:54:47 +00:00
def make_parser(parser):
parser.description = (
"Build all of the packages in a given directory\n\n"
"Unless the --only option is provided"
)
parser.add_argument(
"dir",
type=str,
nargs=1,
help="Input directory containing a tree of package definitions",
)
parser.add_argument(
"output",
type=str,
nargs=1,
help="Output directory in which to put all built packages",
)
parser.add_argument(
"--package_abi",
type=int,
required=True,
help="The ABI number for the packages to be built",
)
2018-06-20 19:05:13 +00:00
parser.add_argument(
"--cflags",
type=str,
nargs="?",
default=common.DEFAULTCFLAGS,
help="Extra compiling flags",
)
2018-06-20 19:05:13 +00:00
parser.add_argument(
"--ldflags",
type=str,
nargs="?",
default=common.DEFAULTLDFLAGS,
help="Extra linking flags",
)
2018-06-20 19:05:13 +00:00
parser.add_argument(
"--host",
type=str,
nargs="?",
default=common.HOSTPYTHON,
help="The path to the host Python installation",
)
2018-06-20 19:05:13 +00:00
parser.add_argument(
"--target",
type=str,
nargs="?",
default=common.TARGETPYTHON,
help="The path to the target Python installation",
)
parser.add_argument(
"--install-dir",
type=str,
nargs="?",
default="",
help=(
"Directory for installing built host packages. Defaults to setup.py "
"default. Set to 'skip' to skip installation. Installation is "
"needed if you want to build other packages that depend on this one."
),
)
parser.add_argument(
"--only",
type=str,
nargs="?",
default=None,
help=(
"Only build the specified packages, provided as a comma " "separated list"
),
)
return parser
2018-06-20 18:54:47 +00:00
def main(args):
2018-08-03 16:48:22 +00:00
packagesdir = Path(args.dir[0]).resolve()
outputdir = Path(args.output[0]).resolve()
2018-08-06 14:01:28 +00:00
build_packages(packagesdir, outputdir, args)
2018-06-20 18:54:47 +00:00
if __name__ == "__main__":
parser = make_parser(argparse.ArgumentParser())
args = parser.parse_args()
2018-06-20 18:54:47 +00:00
main(args)