mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-03-17 20:28:03 +02:00
This adds info about whether PCRE2 is available or not to the output of --version. Essentially, --version now subsumes --pcre2-version, although we do retain the former because it (usefully) emits an exit code based on whether PCRE2 is available or not. Closes #2645
181 lines
5.5 KiB
Rust
181 lines
5.5 KiB
Rust
/*!
|
|
Provides routines for generating version strings.
|
|
|
|
Version strings can be just the digits, an overall short one-line description
|
|
or something more verbose that includes things like CPU target feature support.
|
|
*/
|
|
|
|
use std::fmt::Write;
|
|
|
|
/// Generates just the numerical part of the version of ripgrep.
|
|
///
|
|
/// This includes the git revision hash.
|
|
pub(crate) fn generate_digits() -> String {
|
|
let semver = option_env!("CARGO_PKG_VERSION").unwrap_or("N/A");
|
|
match option_env!("RIPGREP_BUILD_GIT_HASH") {
|
|
None => semver.to_string(),
|
|
Some(hash) => format!("{semver} (rev {hash})"),
|
|
}
|
|
}
|
|
|
|
/// Generates a short version string of the form `ripgrep x.y.z`.
|
|
pub(crate) fn generate_short() -> String {
|
|
let digits = generate_digits();
|
|
format!("ripgrep {digits}")
|
|
}
|
|
|
|
/// Generates a longer multi-line version string.
|
|
///
|
|
/// This includes not only the version of ripgrep but some other information
|
|
/// about its build. For example, SIMD support and PCRE2 support.
|
|
pub(crate) fn generate_long() -> String {
|
|
let (compile, runtime) = (compile_cpu_features(), runtime_cpu_features());
|
|
|
|
let mut out = String::new();
|
|
writeln!(out, "{}", generate_short()).unwrap();
|
|
writeln!(out).unwrap();
|
|
writeln!(out, "features:{}", features().join(",")).unwrap();
|
|
if !compile.is_empty() {
|
|
writeln!(out, "simd(compile):{}", compile.join(",")).unwrap();
|
|
}
|
|
if !runtime.is_empty() {
|
|
writeln!(out, "simd(runtime):{}", runtime.join(",")).unwrap();
|
|
}
|
|
let (pcre2_version, _) = generate_pcre2();
|
|
writeln!(out, "\n{pcre2_version}").unwrap();
|
|
out
|
|
}
|
|
|
|
/// Generates multi-line version string with PCRE2 information.
|
|
///
|
|
/// This also returns whether PCRE2 is actually available in this build of
|
|
/// ripgrep.
|
|
pub(crate) fn generate_pcre2() -> (String, bool) {
|
|
let mut out = String::new();
|
|
|
|
#[cfg(feature = "pcre2")]
|
|
{
|
|
use grep::pcre2;
|
|
|
|
let (major, minor) = pcre2::version();
|
|
write!(out, "PCRE2 {}.{} is available", major, minor).unwrap();
|
|
if cfg!(target_pointer_width = "64") && pcre2::is_jit_available() {
|
|
writeln!(out, " (JIT is available)").unwrap();
|
|
} else {
|
|
writeln!(out, " (JIT is unavailable)").unwrap();
|
|
}
|
|
(out, true)
|
|
}
|
|
|
|
#[cfg(not(feature = "pcre2"))]
|
|
{
|
|
writeln!(out, "PCRE2 is not available in this build of ripgrep.")
|
|
.unwrap();
|
|
(out, false)
|
|
}
|
|
}
|
|
|
|
/// Returns the relevant SIMD features supported by the CPU at runtime.
|
|
///
|
|
/// This is kind of a dirty violation of abstraction, since it assumes
|
|
/// knowledge about what specific SIMD features are being used by various
|
|
/// components.
|
|
fn runtime_cpu_features() -> Vec<String> {
|
|
#[cfg(target_arch = "x86_64")]
|
|
{
|
|
let mut features = vec![];
|
|
|
|
let sse2 = is_x86_feature_detected!("sse2");
|
|
features.push(format!("{sign}SSE2", sign = sign(sse2)));
|
|
|
|
let ssse3 = is_x86_feature_detected!("ssse3");
|
|
features.push(format!("{sign}SSSE3", sign = sign(ssse3)));
|
|
|
|
let avx2 = is_x86_feature_detected!("avx2");
|
|
features.push(format!("{sign}AVX2", sign = sign(avx2)));
|
|
|
|
features
|
|
}
|
|
#[cfg(target_arch = "aarch64")]
|
|
{
|
|
let mut features = vec![];
|
|
|
|
// memchr and aho-corasick only use NEON when it is available at
|
|
// compile time. This isn't strictly necessary, but NEON is supposed
|
|
// to be available for all aarch64 targets. If this isn't true, please
|
|
// file an issue at https://github.com/BurntSushi/memchr.
|
|
let neon = cfg!(target_feature = "neon");
|
|
features.push(format!("{sign}NEON", sign = sign(neon)));
|
|
|
|
features
|
|
}
|
|
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
|
|
{
|
|
vec![]
|
|
}
|
|
}
|
|
|
|
/// Returns the SIMD features supported while compiling ripgrep.
|
|
///
|
|
/// In essence, any features listed here are required to run ripgrep correctly.
|
|
///
|
|
/// This is kind of a dirty violation of abstraction, since it assumes
|
|
/// knowledge about what specific SIMD features are being used by various
|
|
/// components.
|
|
///
|
|
/// An easy way to enable everything available on your current CPU is to
|
|
/// compile ripgrep with `RUSTFLAGS="-C target-cpu=native"`. But note that
|
|
/// the binary produced by this will not be portable.
|
|
fn compile_cpu_features() -> Vec<String> {
|
|
#[cfg(target_arch = "x86_64")]
|
|
{
|
|
let mut features = vec![];
|
|
|
|
let sse2 = cfg!(target_feature = "sse2");
|
|
features.push(format!("{sign}SSE2", sign = sign(sse2)));
|
|
|
|
let ssse3 = cfg!(target_feature = "ssse3");
|
|
features.push(format!("{sign}SSSE3", sign = sign(ssse3)));
|
|
|
|
let avx2 = cfg!(target_feature = "avx2");
|
|
features.push(format!("{sign}AVX2", sign = sign(avx2)));
|
|
|
|
features
|
|
}
|
|
#[cfg(target_arch = "aarch64")]
|
|
{
|
|
let mut features = vec![];
|
|
|
|
let neon = cfg!(target_feature = "neon");
|
|
features.push(format!("{sign}NEON", sign = sign(neon)));
|
|
|
|
features
|
|
}
|
|
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
|
|
{
|
|
vec![]
|
|
}
|
|
}
|
|
|
|
/// Returns a list of "features" supported (or not) by this build of ripgrpe.
|
|
fn features() -> Vec<String> {
|
|
let mut features = vec![];
|
|
|
|
let simd_accel = cfg!(feature = "simd-accel");
|
|
features.push(format!("{sign}simd-accel", sign = sign(simd_accel)));
|
|
|
|
let pcre2 = cfg!(feature = "pcre2");
|
|
features.push(format!("{sign}pcre2", sign = sign(pcre2)));
|
|
|
|
features
|
|
}
|
|
|
|
/// Returns `+` when `enabled` is `true` and `-` otherwise.
|
|
fn sign(enabled: bool) -> &'static str {
|
|
if enabled {
|
|
"+"
|
|
} else {
|
|
"-"
|
|
}
|
|
}
|