[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PoCv2 04/15] build-sys: add a cargo-wrapper script
From: |
marcandre . lureau |
Subject: |
[PoCv2 04/15] build-sys: add a cargo-wrapper script |
Date: |
Mon, 12 Oct 2020 00:35:02 +0400 |
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Introduce a script to help calling cargo from Rust.
Cargo is the most convenient way to build Rust code, with various
crates, and has many features that meson lacks in general for Rust.
Trying to convert projects to meson automatically is an option I
considered (see for ex https://github.com/badboy/bygge for ninja
conversion), but the complexity of the task and the need of build.rs
mechanism in various crates makes this endeavour out of scope at this
point.
This script will help to invoke cargo in different ways. For now, it
supports building static libraries. It sets up a common environment, run
the compiler and grep its output for the linker flags. Finally it copies
the built library to the expected meson output directory, and create a
file with the linker arguments.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
meson.build | 1 +
scripts/cargo_wrapper.py | 101 +++++++++++++++++++++++++++++++++++++++
2 files changed, 102 insertions(+)
create mode 100644 scripts/cargo_wrapper.py
diff --git a/meson.build b/meson.build
index d8526dc999..c30bb290c5 100644
--- a/meson.build
+++ b/meson.build
@@ -75,6 +75,7 @@ endif
with_rust = 'CONFIG_WITH_RUST' in config_host
cargo = find_program('cargo', required: with_rust)
+cargo_wrapper = find_program('scripts/cargo_wrapper.py')
if with_rust
rs_target_triple = config_host['CONFIG_WITH_RUST_TARGET']
diff --git a/scripts/cargo_wrapper.py b/scripts/cargo_wrapper.py
new file mode 100644
index 0000000000..164fad5123
--- /dev/null
+++ b/scripts/cargo_wrapper.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020 Red Hat, Inc.
+#
+# Author:
+# Marc-André Lureau <marcandre.lureau@gmail.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+import argparse
+import configparser
+import distutils.file_util
+import glob
+import os
+import os.path
+import re
+import subprocess
+import sys
+from typing import List
+
+
+def get_cargo_target_dir(args: argparse.Namespace) -> str:
+ # avoid conflict with qemu "target" directory
+ return os.path.join(args.build_dir, "rs-target")
+
+
+def get_manifest_path(args: argparse.Namespace) -> str:
+ return os.path.join(args.src_dir, "Cargo.toml")
+
+
+def build_lib(args: argparse.Namespace) -> None:
+ target_dir = get_cargo_target_dir(args)
+ manifest_path = get_manifest_path(args)
+ # let's pretend it's an INI file to avoid extra dependency
+ config = configparser.ConfigParser()
+ config.read(manifest_path)
+ package_name = config["package"]["name"].strip('"')
+ liba = os.path.join(
+ target_dir, args.target_triple, args.build_type, "lib" + package_name
+ ".a"
+ )
+ libargs = os.path.join(args.build_dir, "lib" + package_name + ".args")
+
+ env = {}
+ env["MESON_CURRENT_BUILD_DIR"] = args.build_dir
+ env["MESON_BUILD_ROOT"] = args.build_root
+ env["WINAPI_NO_BUNDLED_LIBRARIES"] = "1"
+ cargo_cmd = [
+ "cargo",
+ "rustc",
+ "--target-dir",
+ target_dir,
+ "--manifest-path",
+ manifest_path,
+ ]
+ if args.target_triple:
+ cargo_cmd += ["--target", args.target_triple]
+ if args.build_type == "release":
+ cargo_cmd += ["--release"]
+ cargo_cmd += ["--", "--print", "native-static-libs"]
+ cargo_cmd += args.EXTRA
+ try:
+ out = subprocess.check_output(
+ cargo_cmd,
+ env=dict(os.environ, **env),
+ stderr=subprocess.STDOUT,
+ universal_newlines=True,
+ )
+ native_static_libs = re.search(r"native-static-libs:(.*)", out)
+ link_args = native_static_libs.group(1)
+ with open(libargs, "w") as f:
+ print(link_args, file=f)
+
+ distutils.file_util.copy_file(liba, args.build_dir, update=True)
+ except subprocess.CalledProcessError as e:
+ print(
+ "Environment: " + " ".join(["{}={}".format(k, v) for k, v in
env.items()])
+ )
+ print("Command: " + " ".join(cargo_cmd))
+ print(e.output)
+ sys.exit(1)
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("command")
+ parser.add_argument("build_dir")
+ parser.add_argument("src_dir")
+ parser.add_argument("build_root")
+ parser.add_argument("build_type")
+ parser.add_argument("target_triple")
+ parser.add_argument("EXTRA", nargs="*")
+ args = parser.parse_args()
+
+ if args.command == "build-lib":
+ build_lib(args)
+ else:
+ raise argparse.ArgumentTypeError("Unknown command: %s" % args.command)
+
+
+if __name__ == "__main__":
+ main()
--
2.28.0
- [PoCv2 00/15] Rust binding for QAPI (qemu-ga only, for now), marcandre . lureau, 2020/10/11
- [PoCv2 01/15] mingw: fix error __USE_MINGW_ANSI_STDIO redefined, marcandre . lureau, 2020/10/11
- [PoCv2 02/15] scripts/qapi: teach c_param_type() to return const argument type, marcandre . lureau, 2020/10/11
- [PoCv2 03/15] build-sys: add --with-rust{-target} & basic build infrastructure, marcandre . lureau, 2020/10/11
- [PoCv2 04/15] build-sys: add a cargo-wrapper script,
marcandre . lureau <=
- [PoCv2 05/15] qga/rust: build and link an empty static library, marcandre . lureau, 2020/10/11
- [PoCv2 06/15] rust: provide a common crate for QEMU, marcandre . lureau, 2020/10/11
- [PoCv2 07/15] scripts/qapi: add Rust sys bindings generation, marcandre . lureau, 2020/10/11
- [PoCv2 08/15] qga/rust: generate QGA QAPI sys bindings, marcandre . lureau, 2020/10/11
- [PoCv2 09/15] scripts/qapi: add generation of Rust bindings for types, marcandre . lureau, 2020/10/11
- [PoCv2 10/15] qga/rust: build Rust types, marcandre . lureau, 2020/10/11
- [PoCv2 11/15] qga: add qmp! macro helper, marcandre . lureau, 2020/10/11
- [PoCv2 12/15] qga: implement get-host-name in Rust, marcandre . lureau, 2020/10/11
- [PoCv2 13/15] qga: implement {get,set}-vcpus in Rust, marcandre . lureau, 2020/10/11
- [PoCv2 14/15] travis: add Rust, marcandre . lureau, 2020/10/11