mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-24 06:56:26 +00:00
This adds `gstdump` and `gst-dots-viewer` server, see the README for more details about what those tools do. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7999>
204 lines
7.5 KiB
Python
204 lines
7.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import glob
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import shlex
|
|
from argparse import ArgumentParser
|
|
from pathlib import Path as P
|
|
|
|
PARSER = ArgumentParser()
|
|
PARSER.add_argument("command", choices=["build", "test"])
|
|
PARSER.add_argument("build_dir", type=P)
|
|
PARSER.add_argument("src_dir", type=P)
|
|
PARSER.add_argument("root_dir", type=P)
|
|
PARSER.add_argument("target", choices=["release", "debug"])
|
|
PARSER.add_argument("prefix", type=P)
|
|
PARSER.add_argument("libdir", type=P)
|
|
PARSER.add_argument("--version", default=None)
|
|
PARSER.add_argument("--bin", default=None, type=P)
|
|
PARSER.add_argument("--features", nargs="+", default=[])
|
|
PARSER.add_argument("--packages", nargs="+", default=[])
|
|
PARSER.add_argument("--examples", nargs="+", default=[])
|
|
PARSER.add_argument("--lib-suffixes", nargs="+", default=[])
|
|
PARSER.add_argument("--exe-suffix")
|
|
PARSER.add_argument("--depfile")
|
|
PARSER.add_argument("--disable-doc", action="store_true", default=False)
|
|
|
|
|
|
def shlex_join(args):
|
|
if hasattr(shlex, "join"):
|
|
return shlex.join(args)
|
|
return " ".join([shlex.quote(arg) for arg in args])
|
|
|
|
|
|
def generate_depfile_for(fpath):
|
|
file_stem = fpath.parent / fpath.stem
|
|
depfile_content = ""
|
|
with open(f"{file_stem}.d", "r") as depfile:
|
|
for line in depfile.readlines():
|
|
if line.startswith(str(file_stem)):
|
|
# We can't blindly split on `:` because on Windows that's part
|
|
# of the drive letter. Lucky for us, the format of the dep file
|
|
# is one of:
|
|
#
|
|
# /path/to/output: /path/to/src1 /path/to/src2
|
|
# /path/to/output:
|
|
#
|
|
# So we parse these two cases specifically
|
|
if line.endswith(":"):
|
|
output = line[:-1]
|
|
srcs = ""
|
|
else:
|
|
output, srcs = line.split(": ", maxsplit=2)
|
|
|
|
all_deps = []
|
|
for src in srcs.split(" "):
|
|
all_deps.append(src)
|
|
src = P(src)
|
|
if src.name == "lib.rs":
|
|
# `rustc` doesn't take `Cargo.toml` into account
|
|
# but we need to
|
|
cargo_toml = src.parent.parent / "Cargo.toml"
|
|
if cargo_toml.exists():
|
|
all_deps.append(str(cargo_toml))
|
|
|
|
depfile_content += f"{output}: {' '.join(all_deps)}\n"
|
|
|
|
return depfile_content
|
|
|
|
|
|
if __name__ == "__main__":
|
|
opts = PARSER.parse_args()
|
|
logdir = opts.root_dir / "meson-logs"
|
|
logfile_path = logdir / f"{opts.src_dir.name}-cargo-wrapper.log"
|
|
logfile = open(logfile_path, mode="w", buffering=1)
|
|
|
|
print(opts, file=logfile)
|
|
cargo_target_dir = opts.build_dir / "target"
|
|
|
|
env = os.environ.copy()
|
|
if "PKG_CONFIG_PATH" in env:
|
|
pkg_config_path = env["PKG_CONFIG_PATH"].split(os.pathsep)
|
|
else:
|
|
pkg_config_path = []
|
|
pkg_config_path.append(str(opts.root_dir / "meson-uninstalled"))
|
|
env["PKG_CONFIG_PATH"] = os.pathsep.join(pkg_config_path)
|
|
|
|
if "NASM" in env:
|
|
env["PATH"] = os.pathsep.join([os.path.dirname(env["NASM"]), env["PATH"]])
|
|
|
|
rustc_target = None
|
|
if "RUSTC" in env:
|
|
rustc_cmdline = shlex.split(env["RUSTC"])
|
|
# grab target from RUSTFLAGS
|
|
rust_flags = rustc_cmdline[1:] + shlex.split(env.get("RUSTFLAGS", ""))
|
|
if "--target" in rust_flags:
|
|
rustc_target_idx = rust_flags.index("--target")
|
|
_ = rust_flags.pop(rustc_target_idx) # drop '--target'
|
|
rustc_target = rust_flags.pop(rustc_target_idx)
|
|
env["RUSTFLAGS"] = shlex_join(rust_flags)
|
|
env["RUSTC"] = rustc_cmdline[0]
|
|
|
|
features = opts.features
|
|
if opts.command == "build":
|
|
cargo_cmd = ["cargo"]
|
|
if opts.bin or opts.examples:
|
|
cargo_cmd += ["build"]
|
|
else:
|
|
cargo_cmd += ["cbuild"]
|
|
if not opts.disable_doc:
|
|
features += ["doc"]
|
|
if opts.target == "release":
|
|
cargo_cmd.append("--release")
|
|
elif opts.command == "test":
|
|
# cargo test
|
|
cargo_cmd = ["cargo", "ctest", "--no-fail-fast", "--color=always"]
|
|
else:
|
|
print("Unknown command:", opts.command, file=logfile)
|
|
sys.exit(1)
|
|
|
|
if rustc_target:
|
|
cargo_cmd += ["--target", rustc_target]
|
|
if features:
|
|
cargo_cmd += ["--features", ",".join(features)]
|
|
cargo_cmd += ["--target-dir", cargo_target_dir]
|
|
cargo_cmd += ["--manifest-path", opts.src_dir / "Cargo.toml"]
|
|
if opts.bin:
|
|
cargo_cmd.extend(["--bin", opts.bin.name])
|
|
else:
|
|
if not opts.examples:
|
|
cargo_cmd.extend(
|
|
["--prefix", opts.prefix, "--libdir", opts.prefix / opts.libdir]
|
|
)
|
|
for p in opts.packages:
|
|
cargo_cmd.extend(["-p", p])
|
|
for e in opts.examples:
|
|
cargo_cmd.extend(["--example", e])
|
|
|
|
def run(cargo_cmd, env):
|
|
print(cargo_cmd, env, file=logfile)
|
|
try:
|
|
subprocess.run(cargo_cmd, env=env, cwd=opts.src_dir, check=True)
|
|
except subprocess.SubprocessError:
|
|
sys.exit(1)
|
|
|
|
run(cargo_cmd, env)
|
|
|
|
if opts.command == "build":
|
|
target_dir = cargo_target_dir / "**" / opts.target
|
|
if opts.bin:
|
|
exe = glob.glob(
|
|
str(target_dir / opts.bin) + opts.exe_suffix, recursive=True
|
|
)[0]
|
|
shutil.copy2(exe, opts.build_dir)
|
|
depfile_content = generate_depfile_for(P(exe))
|
|
else:
|
|
# Copy so files to build dir
|
|
depfile_content = ""
|
|
for suffix in opts.lib_suffixes:
|
|
for f in glob.glob(str(target_dir / f"*.{suffix}"), recursive=True):
|
|
libfile = P(f)
|
|
|
|
depfile_content += generate_depfile_for(libfile)
|
|
|
|
copied_file = opts.build_dir / libfile.name
|
|
try:
|
|
if copied_file.stat().st_mtime == libfile.stat().st_mtime:
|
|
print(f"{copied_file} has not changed.", file=logfile)
|
|
continue
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
print(f"Copying {copied_file}", file=logfile)
|
|
shutil.copy2(f, opts.build_dir)
|
|
# Copy examples to builddir
|
|
for example in opts.examples:
|
|
example_glob = str(target_dir / "examples" / example) + opts.exe_suffix
|
|
exe = glob.glob(example_glob, recursive=True)[0]
|
|
shutil.copy2(exe, opts.build_dir)
|
|
depfile_content += generate_depfile_for(P(exe))
|
|
|
|
with open(opts.depfile, "w") as depfile:
|
|
depfile.write(depfile_content)
|
|
|
|
# Copy generated pkg-config files
|
|
for f in glob.glob(str(target_dir / "*.pc"), recursive=True):
|
|
shutil.copy(f, opts.build_dir)
|
|
|
|
# Move -uninstalled.pc to meson-uninstalled
|
|
uninstalled = opts.build_dir / "meson-uninstalled"
|
|
os.makedirs(uninstalled, exist_ok=True)
|
|
|
|
for f in opts.build_dir.glob("*-uninstalled.pc"):
|
|
# move() does not allow us to update the file so remove it if it already exists
|
|
dest = uninstalled / P(f).name
|
|
if dest.exists():
|
|
dest.unlink()
|
|
# move() takes paths from Python3.9 on
|
|
if (sys.version_info.major >= 3) and (sys.version_info.minor >= 9):
|
|
shutil.move(f, uninstalled)
|
|
else:
|
|
shutil.move(str(f), str(uninstalled))
|