217 lines
6.4 KiB
Python
Executable File
217 lines
6.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from argparse import ArgumentParser
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
parser = ArgumentParser("Cargo wrapper")
|
|
|
|
parser.add_argument(
|
|
"--command",
|
|
required=True,
|
|
choices=["cbuild", "test", "build"],
|
|
help="Cargo command",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--cargo", required=True, type=Path, help="Path to the cargo executable"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--manifest-path", required=True, type=Path, help="Path to Cargo.toml"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--current-build-dir",
|
|
required=True,
|
|
type=Path,
|
|
help="Value from meson.current_build_dir()",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--current-source-dir",
|
|
required=True,
|
|
type=Path,
|
|
help="Value from meson.current_source_dir()",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--project-build-root",
|
|
required=True,
|
|
type=Path,
|
|
help="Value from meson.project_build_root()",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--toolchain-version", help="Rust Toolchain Version if needed"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--target", help="Target triplet"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--build-triplet", help="Build toolchain triplet (for cross builds using specific toolchain version)"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--avif", action="store_true", help="Enable AVIF support"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--pixbuf", action="store_true", help="Enable GDK-Pixbuf support"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--packages",
|
|
nargs="*",
|
|
default=[],
|
|
help='Rust packages to build (names for "cargo cbuild/build -p")',
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--prefix", type=Path, required=True, help="Value of get_option('prefix')"
|
|
)
|
|
|
|
parser.add_argument("--libdir", required=True, help="Value of get_option('libdir')")
|
|
|
|
g = parser.add_argument_group("Outputs")
|
|
group = parser.add_mutually_exclusive_group(required=False)
|
|
group.add_argument(
|
|
"--extension", help="filename extension for the library (so, a, dll, lib, dylib)",
|
|
)
|
|
group.add_argument("--bin", help="Name of binary to build")
|
|
|
|
g = parser.add_argument_group("Optimizations")
|
|
g.add_argument(
|
|
"--release", action="store_true", help="Build artifacts in release mode"
|
|
)
|
|
g.add_argument(
|
|
'--optimization', choices=['0', '1', '2', '3', 's'], help="Set optimization level"
|
|
)
|
|
g.add_argument(
|
|
'--lto', choices=['fat', 'thin'], help="Set optimization level"
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.toolchain_version is not None and args.target is None and args.build_triplet is None:
|
|
raise ValueError('--target and/or --build-triplet argument required if --toolchain-version is specified')
|
|
|
|
if args.command == 'test':
|
|
if args.extension or args.bin:
|
|
raise ValueError('Cargo test does not take --extension or --bin')
|
|
|
|
cargo_target_dir = Path(args.project_build_root) / "target"
|
|
|
|
# The final rsvg-convert executable will be found in cargo_target_dir/$(TARGET_TRIPLET)
|
|
# if a target triplet is specified
|
|
if args.target:
|
|
cargo_target_output_dir = cargo_target_dir / args.target
|
|
else:
|
|
cargo_target_output_dir = cargo_target_dir
|
|
|
|
env = os.environ.copy()
|
|
pkg_config_path = [i for i in env.get("PKG_CONFIG_PATH", "").split(os.pathsep) if i]
|
|
pkg_config_path.insert(
|
|
0, (Path(args.project_build_root) / "meson-uninstalled").as_posix()
|
|
)
|
|
env["PKG_CONFIG_PATH"] = os.pathsep.join(pkg_config_path)
|
|
|
|
features = []
|
|
|
|
if args.avif:
|
|
features.append('avif')
|
|
|
|
if args.pixbuf:
|
|
features.append('pixbuf')
|
|
|
|
cargo_prefixes = [
|
|
"--prefix",
|
|
Path(args.prefix).as_posix(),
|
|
"--libdir",
|
|
(Path(args.prefix) / args.libdir).as_posix(),
|
|
]
|
|
|
|
cargo_cmd = [Path(args.cargo).as_posix()]
|
|
|
|
if args.toolchain_version is not None:
|
|
if args.build_triplet is not None:
|
|
cargo_cmd.extend(["+%s-%s" % (args.toolchain_version, args.build_triplet)])
|
|
else:
|
|
cargo_cmd.extend(["+%s-%s" % (args.toolchain_version, args.target)])
|
|
|
|
if args.command == "cbuild":
|
|
cargo_cmd.extend(["cbuild", "--locked"])
|
|
library_type = "staticlib" if args.extension in ("a", "lib") else "cdylib"
|
|
cargo_cmd.extend(cargo_prefixes)
|
|
cargo_cmd.extend(["--library-type", library_type])
|
|
elif args.command == "test":
|
|
cargo_cmd.extend(["test", "--locked", "--no-fail-fast", "--color=always"])
|
|
if 'librsvg' in args.packages:
|
|
# These are required for librsvg itself
|
|
# If doing an unqualified cargo build, they'll be called up
|
|
# by rsvg-convert
|
|
# https://github.com/rust-lang/cargo/issues/2911
|
|
features.extend(["capi", "test-utils"])
|
|
else:
|
|
cargo_cmd.extend(["build", "--locked"])
|
|
if args.bin:
|
|
cargo_cmd.extend(["--bin", args.bin])
|
|
|
|
cargo_cmd.extend(["--manifest-path", Path(args.manifest_path).as_posix()])
|
|
cargo_cmd.extend(["--target-dir", cargo_target_dir.as_posix()])
|
|
|
|
if args.release:
|
|
buildtype = 'release'
|
|
cargo_cmd.extend(['--release'])
|
|
else:
|
|
buildtype = 'debug'
|
|
|
|
if args.optimization:
|
|
env[f'CARGO_PROFILE_{buildtype.upper()}_OPT_LEVEL'] = args.optimization
|
|
if args.lto:
|
|
env[f'CARGO_PROFILE_{buildtype.upper()}_CODEGEN_UNITS'] = '1'
|
|
env[f'CARGO_PROFILE_{buildtype.upper()}_LTO'] = args.lto
|
|
|
|
if args.target:
|
|
cargo_cmd.extend(['--target', args.target])
|
|
|
|
if features:
|
|
cargo_cmd.extend(["--features", ",".join(features)])
|
|
|
|
for p in args.packages:
|
|
cargo_cmd.extend(["-p", p])
|
|
|
|
if args.command == "test":
|
|
cargo_cmd.extend(["--", "--include-ignored"])
|
|
|
|
k = {k: v for k, v in env.items() if k.startswith('CARGO_PROFILE')}
|
|
print(f"command: {cargo_cmd}, env: {k}")
|
|
subprocess.run(cargo_cmd, env=env, check=True)
|
|
|
|
if args.command in ["cbuild", "build"]:
|
|
# Copy so/dll/etc files to build dir
|
|
if args.extension:
|
|
for f in cargo_target_dir.glob(f"**/{buildtype}/*.{args.extension}"):
|
|
shutil.copy(f, args.current_build_dir)
|
|
# Copy binary and, if applicable, the corresponding .pdb file, to build dir
|
|
else:
|
|
binary = Path(cargo_target_output_dir / buildtype / args.bin)
|
|
is_windows_target = False
|
|
if args.target is None and sys.platform == "win32":
|
|
is_windows_target = True
|
|
elif args.target is not None and args.target.split('-')[2] == 'windows':
|
|
is_windows_target = True
|
|
if is_windows_target:
|
|
exe_name = args.bin.replace('rsvg-convert', 'rsvg_convert')
|
|
pdb_src = Path(cargo_target_output_dir / buildtype / exe_name).with_suffix(".pdb")
|
|
pdb_dest = Path(args.current_build_dir / args.bin).with_suffix('.pdb')
|
|
if pdb_src.exists():
|
|
shutil.copy(pdb_src, pdb_dest)
|
|
binary = binary.with_suffix(".exe")
|
|
shutil.copy(binary, args.current_build_dir)
|