From: "Alex Bennée" <alex.bennee@linaro.org>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: "Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
qemu-devel@nongnu.org, "Mads Ynddal" <mads@ynddal.dk>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Zhao Liu" <zhao1.liu@intel.com>,
"Gustavo Romero" <gustavo.romero@linaro.org>,
"Pierrick Bouvier" <pierrick.bouvier@linaro.org>,
"John Snow" <jsnow@redhat.com>, "Cleber Rosa" <crosa@redhat.com>
Subject: Re: [RFC PATCH v1 1/6] build-sys: Add rust feature option
Date: Tue, 11 Jun 2024 15:19:59 +0100 [thread overview]
Message-ID: <87wmmvy31s.fsf@draig.linaro.org> (raw)
In-Reply-To: <20240610192517.GA350256@fedora> (Stefan Hajnoczi's message of "Mon, 10 Jun 2024 15:25:17 -0400")
Stefan Hajnoczi <stefanha@redhat.com> writes:
> On Mon, Jun 10, 2024 at 09:22:36PM +0300, Manos Pitsidianakis wrote:
>> Add options for Rust in meson_options.txt, meson.build, configure to
>> prepare for adding Rust code in the followup commits.
>>
>> `rust` is a reserved meson name, so we have to use an alternative.
>> `with_rust` was chosen.
>>
>> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>> ---
>> The cargo wrapper script hardcodes some rust target triples. This is
>> just temporary.
>> ---
>> .gitignore | 2 +
>> configure | 12 +++
>> meson.build | 11 ++
>> meson_options.txt | 4 +
>> scripts/cargo_wrapper.py | 211 +++++++++++++++++++++++++++++++++++++++
>> 5 files changed, 240 insertions(+)
>> create mode 100644 scripts/cargo_wrapper.py
>>
>> diff --git a/.gitignore b/.gitignore
>> index 61fa39967b..f42b0d937e 100644
>> --- a/.gitignore
>> +++ b/.gitignore
>> @@ -2,6 +2,8 @@
>> /build/
>> /.cache/
>> /.vscode/
>> +/target/
>> +rust/**/target
>
> Are these necessary since the cargo build command-line below uses
> --target-dir <meson-build-dir>?
>
> Adding new build output directories outside build/ makes it harder to
> clean up the source tree and ensure no state from previous builds
> remains.
Indeed my tree looks like:
$SRC
/builds
/buildA
/buildB
etc. So I would expect the rust build stuff to be in the builddir
because I have multiple configurations.
>
>> *.pyc
>> .sdk
>> .stgit-*
>> diff --git a/configure b/configure
>> index 38ee257701..c195630771 100755
>> --- a/configure
>> +++ b/configure
>> @@ -302,6 +302,9 @@ else
>> objcc="${objcc-${cross_prefix}clang}"
>> fi
>>
>> +with_rust="auto"
>> +with_rust_target_triple=""
>> +
>> ar="${AR-${cross_prefix}ar}"
>> as="${AS-${cross_prefix}as}"
>> ccas="${CCAS-$cc}"
>> @@ -760,6 +763,12 @@ for opt do
>> ;;
>> --gdb=*) gdb_bin="$optarg"
>> ;;
>> + --enable-rust) with_rust=enabled
>> + ;;
>> + --disable-rust) with_rust=disabled
>> + ;;
>> + --rust-target-triple=*) with_rust_target_triple="$optarg"
>> + ;;
>> # everything else has the same name in configure and meson
>> --*) meson_option_parse "$opt" "$optarg"
>> ;;
>> @@ -1796,6 +1805,9 @@ if test "$skip_meson" = no; then
>> test -n "${LIB_FUZZING_ENGINE+xxx}" && meson_option_add "-Dfuzzing_engine=$LIB_FUZZING_ENGINE"
>> test "$plugins" = yes && meson_option_add "-Dplugins=true"
>> test "$tcg" != enabled && meson_option_add "-Dtcg=$tcg"
>> + test "$with_rust" != enabled && meson_option_add "-Dwith_rust=$with_rust"
>> + test "$with_rust" != enabled && meson_option_add "-Dwith_rust=$with_rust"
>
> Duplicate line.
>
>> + test "$with_rust_target_triple" != "" && meson_option_add "-Dwith_rust_target_triple=$with_rust_target_triple"
>> run_meson() {
>> NINJA=$ninja $meson setup "$@" "$PWD" "$source_path"
>> }
>> diff --git a/meson.build b/meson.build
>> index a9de71d450..3533889852 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -290,6 +290,12 @@ foreach lang : all_languages
>> endif
>> endforeach
>>
>> +cargo = not_found
>> +if get_option('with_rust').allowed()
>> + cargo = find_program('cargo', required: get_option('with_rust'))
>> +endif
>> +with_rust = cargo.found()
>> +
>> # default flags for all hosts
>> # We use -fwrapv to tell the compiler that we require a C dialect where
>> # left shift of signed integers is well defined and has the expected
>> @@ -2066,6 +2072,7 @@ endif
>>
>> config_host_data = configuration_data()
>>
>> +config_host_data.set('CONFIG_WITH_RUST', with_rust)
>> audio_drivers_selected = []
>> if have_system
>> audio_drivers_available = {
>> @@ -4190,6 +4197,10 @@ if 'objc' in all_languages
>> else
>> summary_info += {'Objective-C compiler': false}
>> endif
>> +summary_info += {'Rust support': with_rust}
>> +if with_rust and get_option('with_rust_target_triple') != ''
>> + summary_info += {'Rust target': get_option('with_rust_target_triple')}
>> +endif
>> option_cflags = (get_option('debug') ? ['-g'] : [])
>> if get_option('optimization') != 'plain'
>> option_cflags += ['-O' + get_option('optimization')]
>> diff --git a/meson_options.txt b/meson_options.txt
>> index 4c1583eb40..223491b731 100644
>> --- a/meson_options.txt
>> +++ b/meson_options.txt
>> @@ -366,3 +366,7 @@ option('qemu_ga_version', type: 'string', value: '',
>>
>> option('hexagon_idef_parser', type : 'boolean', value : true,
>> description: 'use idef-parser to automatically generate TCG code for the Hexagon frontend')
>> +option('with_rust', type: 'feature', value: 'auto',
>> + description: 'Enable Rust support')
>> +option('with_rust_target_triple', type : 'string', value: '',
>> + description: 'Rust target triple')
>> diff --git a/scripts/cargo_wrapper.py b/scripts/cargo_wrapper.py
>> new file mode 100644
>> index 0000000000..d338effdaa
>> --- /dev/null
>> +++ b/scripts/cargo_wrapper.py
>> @@ -0,0 +1,211 @@
>> +#!/usr/bin/env python3
>> +# Copyright (c) 2020 Red Hat, Inc.
>> +# Copyright (c) 2023 Linaro Ltd.
>> +#
>> +# Authors:
>> +# Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>> +# Marc-André Lureau <marcandre.lureau@redhat.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 json
>> +import logging
>> +import os
>> +import os.path
>> +import re
>> +import subprocess
>> +import sys
>> +import pathlib
>> +import shutil
>> +import tomllib
>> +
>> +from pathlib import Path
>> +from typing import Any, Dict, List, Tuple
>> +
>> +RUST_TARGET_TRIPLES = (
>> + "aarch64-unknown-linux-gnu",
>> + "x86_64-unknown-linux-gnu",
>> + "x86_64-apple-darwin",
>> + "aarch64-apple-darwin",
>> +)
>
> Is this hardcoded to avoid calling `rustc --print target-list`?
>
> Or is this the support matrix? In that case it would be interesting to
> figure out the target triples for all host OSes and CPUs that QEMU is
> supported on.
>
>> +
>> +
>> +def cfg_name(name: str) -> str:
>> + if (
>> + name.startswith("CONFIG_")
>> + or name.startswith("TARGET_")
>> + or name.startswith("HAVE_")
>> + ):
>> + return name
>> + return ""
>> +
>> +
>> +def generate_cfg_flags(header: str) -> List[str]:
>> + with open(header, encoding="utf-8") as cfg:
>> + config = [l.split()[1:] for l in cfg if l.startswith("#define")]
>> +
>> + cfg_list = []
>> + for cfg in config:
>> + name = cfg_name(cfg[0])
>> + if not name:
>> + continue
>> + if len(cfg) >= 2 and cfg[1] != "1":
>> + continue
>> + cfg_list.append("--cfg")
>> + cfg_list.append(name)
>> + return cfg_list
>> +
>> +
>> +def cargo_target_dir(args: argparse.Namespace) -> pathlib.Path:
>> + return args.meson_build_dir
>> +
>> +
>> +def manifest_path(args: argparse.Namespace) -> pathlib.Path:
>> + return args.crate_dir / "Cargo.toml"
>> +
>> +
>> +def get_cargo_rustc(args: argparse.Namespace) -> tuple[Dict[str, Any], List[str]]:
>> + # See https://doc.rust-lang.org/cargo/reference/environment-variables.html
>> + # Item `CARGO_ENCODED_RUSTFLAGS — A list of custom flags separated by
>> + # 0x1f (ASCII Unit Separator) to pass to all compiler invocations that Cargo
>> + # performs`
>> + cfg = chr(0x1F).join(
>> + [c for h in args.config_headers for c in generate_cfg_flags(h)]
>> + )
>> + target_dir = cargo_target_dir(args)
>> + cargo_path = manifest_path(args)
>> +
>> + cargo_cmd = [
>> + "cargo",
>> + "build",
>> + "--target-dir",
>> + str(target_dir),
>> + "--manifest-path",
>> + str(cargo_path),
>> + ]
>> + if args.target_triple:
>> + cargo_cmd += ["--target", args.target_triple]
>> + if args.profile == "release":
>> + cargo_cmd += ["--release"]
>> +
>> + env = os.environ
>> + env["CARGO_ENCODED_RUSTFLAGS"] = cfg
>> +
>> + return (env, cargo_cmd)
>> +
>> +
>> +def run_cargo(env: Dict[str, Any], cargo_cmd: List[str]) -> str:
>> + envlog = " ".join(["{}={}".format(k, v) for k, v in env.items()])
>> + cmdlog = " ".join(cargo_cmd)
>> + logging.debug("Running %s %s", envlog, cmdlog)
>> + try:
>> + out = subprocess.check_output(
>> + cargo_cmd,
>> + env=dict(os.environ, **env),
>> + stderr=subprocess.STDOUT,
>> + universal_newlines=True,
>> + )
>> + except subprocess.CalledProcessError as err:
>> + print("Environment: " + envlog)
>> + print("Command: " + cmdlog)
>> + print(err.output)
>> + sys.exit(1)
>> +
>> + return out
>> +
>> +
>> +def build_lib(args: argparse.Namespace) -> None:
>> + logging.debug("build-lib")
>> + target_dir = cargo_target_dir(args)
>> + cargo_toml_path = manifest_path(args)
>> +
>> + with open(cargo_toml_path, "rb") as f:
>> + config = tomllib.load(f)
>> +
>> + package_name = config["package"]["name"].strip('"').replace("-", "_")
>> +
>> + liba_filename = "lib" + package_name + ".a"
>> + liba = target_dir / args.target_triple / args.profile / liba_filename
>> +
>> + env, cargo_cmd = get_cargo_rustc(args)
>> + out = run_cargo(env, cargo_cmd)
>> + logging.debug("cp %s %s", liba, args.outdir)
>> + shutil.copy2(liba, args.outdir)
>> +
>> +
>> +def main() -> None:
>> + parser = argparse.ArgumentParser()
>> + parser.add_argument("-v", "--verbose", action="store_true")
>> + parser.add_argument(
>> + "--color",
>> + metavar="WHEN",
>> + choices=["auto", "always", "never"],
>> + default="auto",
>> + help="Coloring: auto, always, never",
>> + )
>> + parser.add_argument(
>> + "--config-headers",
>> + metavar="CONFIG_HEADER",
>> + action="append",
>> + dest="config_headers",
>> + required=False,
>> + default=[],
>> + )
>> + parser.add_argument(
>> + "--meson-build-dir",
>> + metavar="BUILD_DIR",
>> + help="meson.current_build_dir()",
>> + type=pathlib.Path,
>> + dest="meson_build_dir",
>> + required=True,
>> + )
>> + parser.add_argument(
>> + "--meson-source-dir",
>> + metavar="SOURCE_DIR",
>> + help="meson.current_source_dir()",
>> + type=pathlib.Path,
>> + dest="meson_source_dir",
>> + required=True,
>> + )
>> + parser.add_argument(
>> + "--crate-dir",
>> + metavar="CRATE_DIR",
>> + type=pathlib.Path,
>> + dest="crate_dir",
>> + help="Absolute path that contains the manifest file of the crate to compile",
>> + required=True,
>> + )
>> + parser.add_argument(
>> + "--outdir",
>> + metavar="OUTDIR",
>> + type=pathlib.Path,
>> + dest="outdir",
>> + help="Path to copy compiled artifacts to for Meson to use.",
>> + required=True,
>> + )
>> + parser.add_argument(
>> + "--profile", type=str, choices=["release", "debug"], required=True
>> + )
>> + parser.add_argument(
>> + "--target-triple", type=str, choices=RUST_TARGET_TRIPLES, required=True
>> + )
>> +
>> + subparsers = parser.add_subparsers()
>> +
>> + buildlib = subparsers.add_parser("build-lib")
>> + buildlib.set_defaults(func=build_lib)
>> +
>> + args = parser.parse_args()
>> + if args.verbose:
>> + logging.basicConfig(level=logging.DEBUG)
>> + logging.debug("args: %s", args)
>> +
>> + args.func(args)
>> +
>> +
>> +if __name__ == "__main__":
>> + main()
>> --
>> γαῖα πυρί μιχθήτω
>>
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2024-06-11 14:21 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-10 18:22 [RFC PATCH v1 0/6] Implement ARM PL011 in Rust Manos Pitsidianakis
2024-06-10 18:22 ` [RFC PATCH v1 1/6] build-sys: Add rust feature option Manos Pitsidianakis
2024-06-10 19:25 ` Stefan Hajnoczi
2024-06-11 14:19 ` Alex Bennée [this message]
2024-06-11 17:53 ` Manos Pitsidianakis
2024-06-11 18:25 ` Stefan Hajnoczi
2024-06-12 8:04 ` Daniel P. Berrangé
2024-06-12 8:25 ` Marc-André Lureau
2024-06-10 18:22 ` [RFC PATCH v1 3/6] DO NOT MERGE: add rustdoc build for gitlab pages Manos Pitsidianakis
2024-06-10 18:22 ` [RFC PATCH v1 4/6] DO NOT MERGE: replace TYPE_PL011 with x-pl011-rust in arm virt machine Manos Pitsidianakis
2024-06-10 18:22 ` [RFC PATCH v1 6/6] DO NOT MERGE: update rustdoc gitlab pages gen Manos Pitsidianakis
2024-06-10 19:37 ` [RFC PATCH v1 0/6] Implement ARM PL011 in Rust Pierrick Bouvier
2024-06-10 20:29 ` Manos Pitsidianakis
2024-06-10 21:38 ` Pierrick Bouvier
2024-06-11 5:47 ` Manos Pitsidianakis
2024-06-11 9:21 ` Alex Bennée
2024-06-11 15:32 ` Pierrick Bouvier
2024-06-11 8:02 ` Daniel P. Berrangé
2024-06-11 9:18 ` Alex Bennée
2024-06-11 10:57 ` Daniel P. Berrangé
2024-06-11 10:58 ` Manos Pitsidianakis
2024-06-11 11:09 ` Daniel P. Berrangé
2024-06-11 11:32 ` Manos Pitsidianakis
2024-06-11 12:51 ` Alex Bennée
2024-06-11 12:54 ` Daniel P. Berrangé
2024-06-11 12:45 ` Antonio Caggiano
2024-06-11 12:49 ` Manos Pitsidianakis
2024-06-10 19:59 ` Stefan Hajnoczi
2024-06-10 20:15 ` Manos Pitsidianakis
2024-06-10 20:47 ` Stefan Hajnoczi
2024-06-11 8:42 ` Daniel P. Berrangé
2024-06-11 9:30 ` Alex Bennée
2024-06-11 13:13 ` Paolo Bonzini
2024-06-11 8:11 ` Philippe Mathieu-Daudé
2024-06-11 8:18 ` Daniel P. Berrangé
2024-06-11 9:53 ` Zhao Liu
2024-06-11 10:50 ` Manos Pitsidianakis
2024-06-11 8:22 ` Daniel P. Berrangé
2024-06-11 9:45 ` Zhao Liu
2024-06-11 10:41 ` Manos Pitsidianakis
2024-06-11 14:32 ` Zhao Liu
2024-06-11 10:40 ` Manos Pitsidianakis
2024-06-11 13:16 ` Paolo Bonzini
2024-06-11 14:11 ` Daniel P. Berrangé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wmmvy31s.fsf@draig.linaro.org \
--to=alex.bennee@linaro.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=crosa@redhat.com \
--cc=gustavo.romero@linaro.org \
--cc=jsnow@redhat.com \
--cc=mads@ynddal.dk \
--cc=manos.pitsidianakis@linaro.org \
--cc=marcandre.lureau@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=pierrick.bouvier@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=thuth@redhat.com \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.