Git fork

meson: add infrastructure to build internal Rust library

Add the infrastructure into Meson to build an internal Rust library.
Building the Rust parts of Git are for now entirely optional, as they
are mostly intended as a test balloon for both Git developers, but also
for distributors of Git. So for now, they may contain:

- New features that are not mission critical to Git and that users can
easily live without.

- Alternative implementations of small subsystems.

If these test balloons are successful, we will eventually make Rust a
mandatory dependency for our build process in Git 3.0.

The availability of a Rust toolchain will be auto-detected by Meson at
setup time. This behaviour can be tweaked via the `-Drust=` feature
toggle.

Next to the linkable Rust library, also wire up tests that can be
executed via `meson test`. This allows us to use the native unit testing
capabilities of Rust.

Note that the Rust edition is currently set to 2018. This edition is
supported by Rust 1.49, which is the target for the upcoming gcc-rs
backend. For now we don't use any features of Rust that would require a
newer version, so settling on this old version makes sense so that
gcc-rs may become an alternative backend for compiling Git. If we _do_
want to introduce features that were added in more recent editions of
Rust though we should reevaluate that choice.

Inspired-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
c184795f 24629612

+92 -1
+9
Cargo.toml
··· 1 + [package] 2 + name = "gitcore" 3 + version = "0.1.0" 4 + edition = "2018" 5 + 6 + [lib] 7 + crate-type = ["staticlib"] 8 + 9 + [dependencies]
+9 -1
meson.build
··· 220 220 # learned to define __STDC_VERSION__ with C11 and later. We thus require 221 221 # GNU C99 and fall back to C11. Meson only learned to handle the fallback 222 222 # with version 1.3.0, so on older versions we use GNU C99 unconditionally. 223 - default_options: meson.version().version_compare('>=1.3.0') ? ['c_std=gnu99,c11'] : ['c_std=gnu99'], 223 + default_options: meson.version().version_compare('>=1.3.0') ? ['rust_std=2018', 'c_std=gnu99,c11'] : ['rust_std=2018', 'c_std=gnu99'], 224 224 ) 225 225 226 226 fs = import('fs') ··· 1702 1702 ) 1703 1703 libgit_sources += version_def_h 1704 1704 1705 + cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust')) 1706 + rust_option = get_option('rust').disable_auto_if(not cargo.found()) 1707 + if rust_option.allowed() 1708 + subdir('src') 1709 + libgit_c_args += '-DWITH_RUST' 1710 + endif 1711 + 1705 1712 libgit = declare_dependency( 1706 1713 link_with: static_library('git', 1707 1714 sources: libgit_sources, ··· 2239 2246 'pcre2': pcre2, 2240 2247 'perl': perl_features_enabled, 2241 2248 'python': target_python.found(), 2249 + 'rust': rust_option.allowed(), 2242 2250 }, section: 'Auto-detected features', bool_yn: true) 2243 2251 2244 2252 summary({
+2
meson_options.txt
··· 71 71 # Build tweaks. 72 72 option('breaking_changes', type: 'boolean', value: false, 73 73 description: 'Enable upcoming breaking changes.') 74 + option('rust', type: 'feature', value: 'auto', 75 + description: 'Enable building with Rust.') 74 76 option('macos_use_homebrew_gettext', type: 'boolean', value: true, 75 77 description: 'Use gettext from Homebrew instead of the slightly-broken system-provided one.') 76 78
+32
src/cargo-meson.sh
··· 1 + #!/bin/sh 2 + 3 + if test "$#" -lt 2 4 + then 5 + exit 1 6 + fi 7 + 8 + SOURCE_DIR="$1" 9 + BUILD_DIR="$2" 10 + BUILD_TYPE=debug 11 + 12 + shift 2 13 + 14 + for arg 15 + do 16 + case "$arg" in 17 + --release) 18 + BUILD_TYPE=release;; 19 + esac 20 + done 21 + 22 + cargo build --lib --quiet --manifest-path="$SOURCE_DIR/Cargo.toml" --target-dir="$BUILD_DIR" "$@" 23 + RET=$? 24 + if test $RET -ne 0 25 + then 26 + exit $RET 27 + fi 28 + 29 + if ! cmp "$BUILD_DIR/$BUILD_TYPE/libgitcore.a" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1 30 + then 31 + cp "$BUILD_DIR/$BUILD_TYPE/libgitcore.a" "$BUILD_DIR/libgitcore.a" 32 + fi
src/lib.rs

This is a binary file and will not be displayed.

+40
src/meson.build
··· 1 + libgit_rs_sources = [ 2 + 'lib.rs', 3 + ] 4 + 5 + # Unfortunately we must use a wrapper command to move the output file into the 6 + # current build directory. This can fixed once `cargo build --artifact-dir` 7 + # stabilizes. See https://github.com/rust-lang/cargo/issues/6790 for that 8 + # effort. 9 + cargo_command = [ 10 + shell, 11 + meson.current_source_dir() / 'cargo-meson.sh', 12 + meson.project_source_root(), 13 + meson.current_build_dir(), 14 + ] 15 + if get_option('buildtype') == 'release' 16 + cargo_command += '--release' 17 + endif 18 + 19 + libgit_rs = custom_target('git_rs', 20 + input: libgit_rs_sources + [ 21 + meson.project_source_root() / 'Cargo.toml', 22 + ], 23 + output: 'libgitcore.a', 24 + command: cargo_command, 25 + ) 26 + libgit_dependencies += declare_dependency(link_with: libgit_rs) 27 + 28 + if get_option('tests') 29 + test('rust', cargo, 30 + args: [ 31 + 'test', 32 + '--manifest-path', 33 + meson.project_source_root() / 'Cargo.toml', 34 + '--target-dir', 35 + meson.current_build_dir() / 'target', 36 + ], 37 + timeout: 0, 38 + protocol: 'rust', 39 + ) 40 + endif