qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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


  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).