diff --git a/configure b/configure index aa7aae70fa..e832f211dc 100755 --- a/configure +++ b/configure @@ -207,6 +207,8 @@ for opt do ;; --objcc=*) objcc="$optarg" ;; + --rustc=*) RUSTC="$optarg" + ;; --cpu=*) cpu="$optarg" ;; --extra-cflags=*) @@ -252,6 +254,8 @@ python= download="enabled" skip_meson=no use_containers="yes" +rust="disabled" +rust_target_triple="" gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb") gdb_arches="" @@ -310,6 +314,7 @@ objcopy="${OBJCOPY-${cross_prefix}objcopy}" ld="${LD-${cross_prefix}ld}" ranlib="${RANLIB-${cross_prefix}ranlib}" nm="${NM-${cross_prefix}nm}" +readelf="${READELF-${cross_prefix}readelf}" strip="${STRIP-${cross_prefix}strip}" widl="${WIDL-${cross_prefix}widl}" windres="${WINDRES-${cross_prefix}windres}" @@ -317,6 +322,8 @@ windmc="${WINDMC-${cross_prefix}windmc}" pkg_config="${PKG_CONFIG-${cross_prefix}pkg-config}" sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}" +rustc="${RUSTC-rustc}" + check_define() { cat > $TMPC < "${TMPDIR1}/${TMPB}.out"; then + rust_host_triple=$(sed -n 's/^host: //p' "${TMPDIR1}/${TMPB}.out") +else + if test "$rust" = enabled; then + error_exit "could not execute rustc binary \"$rustc\"" + fi + rust=disabled +fi +if test "$rust" != disabled && test -z "$rust_target_triple"; then + # arch and os generally matches between meson and rust + rust_arch=$host_arch + rust_os=$host_os + rust_machine=unknown + rust_osvariant= + + # tweak rust_os if needed; also, machine and variant depend on the OS + android=no + case "$host_os" in + darwin) + # e.g. aarch64-apple-darwin + rust_machine=apple + ;; + + linux) + # detect android/glibc/musl + if check_define __ANDROID__; then + rust_osvariant=android + android=yes + else + cat > $TMPC << EOF +#define _GNU_SOURCE +#include +#ifndef __USE_GNU +error using musl +#endif +EOF + if compile_object; then + rust_osvariant=gnu + else + rust_osvariant=musl + fi + fi + + case "$host_arch" in + arm) + # e.g. arm-unknown-linux-gnueabi, arm-unknown-linux-gnueabihf + write_c_skeleton + compile_object + if $READELF -A $TMPO | grep Tag_API_VFP_args: > /dev/null; then + rust_osvariant=${rust_osvariant}eabihf + else + rust_osvariant=${rust_osvariant}eabi + fi + ;; + + mips64) + # e.g. mips64-unknown-linux-gnuabi64 + rust_osvariant=${rust_osvariant}abi64 + ;; + esac + ;; + + netbsd) + # e.g. arm-unknown-netbsd-eabihf + test "$host_arch" = arm && rust_osvariant=eabihf + ;; + + sunos) + rust_machine=pc + rust_os=solaris + ;; + + windows) + # e.g. aarch64-pc-windows-gnullvm, x86_64-pc-windows-gnu (MSVC not supported) + rust_machine=pc + if test "$host_arch" = aarch64; then + rust_osvariant=gnullvm + else + rust_osvariant=gnu + fi + ;; + esac + + # now tweak the architecture part, possibly based on pre-canonicalization --cpu + case "$host_arch" in + arm) + # preserve ISA version (armv7 etc.) from $raw_cpu if passed via --cpu + rust_arch=$raw_cpu + test "$rust_arch" = arm && test "$rust_os" != linux && rust_arch=armv7 + ;; + + mips|mips64) + # preserve ISA version (mipsisa64r6 etc.) and include endianness + rust_arch=${raw_cpu%el} + test "$bigendian" = no && rust_arch=${rust_arch}el + ;; + + riscv32|riscv64) + # e.g. riscv64gc-unknown-linux-gnu, but riscv64-linux-android + test "$android" = no && rust_arch=${rust_arch}gc + ;; + + sparc64) + if test "$rust_os" = solaris; then + rust_arch=sparcv9 + rust_machine=sun + fi + ;; + + x86_64) + # e.g. x86_64-unknown-linux-gnux32 + test "$raw_cpu" = x32 && rust_osvariant=${rust_osvariant}x32 + ;; + esac + + if test "$android" = yes; then + # e.g. aarch64-linux-android + rust_target_triple=$rust_arch-$rust_os-$rust_osvariant + else + rust_target_triple=$rust_arch-$rust_machine-$rust_os${rust_osvariant:+-$rust_osvariant} + fi +fi + ########################################## # functions to probe cross compilers @@ -1628,6 +1772,9 @@ if test "$container" != no; then echo "RUNC=$runc" >> $config_host_mak fi echo "SUBDIRS=$subdirs" >> $config_host_mak +if test "$rust" != disabled; then + echo "RUST_TARGET_TRIPLE=$rust_target_triple" >> $config_host_mak +fi echo "PYTHON=$python" >> $config_host_mak echo "MKVENV_ENSUREGROUP=$mkvenv ensuregroup $mkvenv_online_flag" >> $config_host_mak echo "GENISOIMAGE=$genisoimage" >> $config_host_mak @@ -1764,12 +1911,20 @@ if test "$skip_meson" = no; then echo "c = [$(meson_quote $cc $CPU_CFLAGS)]" >> $cross test -n "$cxx" && echo "cpp = [$(meson_quote $cxx $CPU_CFLAGS)]" >> $cross test -n "$objcc" && echo "objc = [$(meson_quote $objcc $CPU_CFLAGS)]" >> $cross + if test "$rust" != disabled; then + if test "$rust_host_triple" != "$rust_target_triple"; then + echo "rust = [$(meson_quote $rustc --target "$rust_target_triple")]" >> $cross + else + echo "rust = [$(meson_quote $rustc)]" >> $cross + fi + fi echo "ar = [$(meson_quote $ar)]" >> $cross echo "dlltool = [$(meson_quote $dlltool)]" >> $cross echo "nm = [$(meson_quote $nm)]" >> $cross echo "pkgconfig = [$(meson_quote $pkg_config)]" >> $cross echo "pkg-config = [$(meson_quote $pkg_config)]" >> $cross echo "ranlib = [$(meson_quote $ranlib)]" >> $cross + echo "readelf = [$(meson_quote $readelf)]" >> $cross if has $sdl2_config; then echo "sdl2-config = [$(meson_quote $sdl2_config)]" >> $cross fi @@ -1799,6 +1954,9 @@ if test "$skip_meson" = no; then echo "# Automatically generated by configure - do not modify" > $native echo "[binaries]" >> $native echo "c = [$(meson_quote $host_cc)]" >> $native + if test "$rust" != disabled; then + echo "rust = [$(meson_quote $rustc)]" >> $cross + fi mv $native config-meson.native meson_option_add --native-file meson_option_add config-meson.native @@ -1817,6 +1975,7 @@ if test "$skip_meson" = no; then test "$pie" = no && meson_option_add -Db_pie=false # QEMU options + test "$rust" != "auto" && meson_option_add "-Drust=$rust" test "$cfi" != false && meson_option_add "-Dcfi=$cfi" "-Db_lto=$cfi" test "$docs" != auto && meson_option_add "-Ddocs=$docs" test -n "${LIB_FUZZING_ENGINE+xxx}" && meson_option_add "-Dfuzzing_engine=$LIB_FUZZING_ENGINE" diff --git a/meson.build b/meson.build index 93ddaef500..f76f01f065 100644 --- a/meson.build +++ b/meson.build @@ -4325,8 +4325,9 @@ else endif summary_info += {'Rust support': have_rust} if have_rust - summary_info += {'rustc version': rustc.version()} - summary_info += {'rustc': ' '.join(rustc.cmd_array())} + summary_info += {'rustc version': rustc.version()} + summary_info += {'rustc': ' '.join(rustc.cmd_array())} + summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} endif option_cflags = (get_option('debug') ? ['-g'] : []) if get_option('optimization') != 'plain'