Skip to content

Commit c184795

Browse files
pks-tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2462961 commit c184795

File tree

6 files changed

+92
-1
lines changed

6 files changed

+92
-1
lines changed

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "gitcore"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[lib]
7+
crate-type = ["staticlib"]
8+
9+
[dependencies]

meson.build

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ project('git', 'c',
220220
# learned to define __STDC_VERSION__ with C11 and later. We thus require
221221
# GNU C99 and fall back to C11. Meson only learned to handle the fallback
222222
# 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'],
224224
)
225225

226226
fs = import('fs')
@@ -1702,6 +1702,13 @@ version_def_h = custom_target(
17021702
)
17031703
libgit_sources += version_def_h
17041704

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+
17051712
libgit = declare_dependency(
17061713
link_with: static_library('git',
17071714
sources: libgit_sources,
@@ -2239,6 +2246,7 @@ summary({
22392246
'pcre2': pcre2,
22402247
'perl': perl_features_enabled,
22412248
'python': target_python.found(),
2249+
'rust': rust_option.allowed(),
22422250
}, section: 'Auto-detected features', bool_yn: true)
22432251

22442252
summary({

meson_options.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ option('zlib_backend', type: 'combo', choices: ['auto', 'zlib', 'zlib-ng'], valu
7171
# Build tweaks.
7272
option('breaking_changes', type: 'boolean', value: false,
7373
description: 'Enable upcoming breaking changes.')
74+
option('rust', type: 'feature', value: 'auto',
75+
description: 'Enable building with Rust.')
7476
option('macos_use_homebrew_gettext', type: 'boolean', value: true,
7577
description: 'Use gettext from Homebrew instead of the slightly-broken system-provided one.')
7678

src/cargo-meson.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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

Whitespace-only changes.

src/meson.build

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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

0 commit comments

Comments
 (0)