-
Notifications
You must be signed in to change notification settings - Fork 227
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #537 from filmor/nif-version-features
Use features for minimal NIF version
- Loading branch information
Showing
12 changed files
with
140 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
mod common { | ||
use std::env; | ||
|
||
pub const MIN_SUPPORTED_VERSION: (u32, u32) = (2, 14); | ||
pub const MAX_SUPPORTED_VERSION: (u32, u32) = (2, 17); | ||
|
||
fn get_nif_version_from_env(version: &str) -> (u32, u32) { | ||
let parts: Vec<Result<_, _>> = version | ||
.split('.') | ||
.take(2) | ||
.map(|n| n.parse::<u32>()) | ||
.collect(); | ||
|
||
let mut nif_version = match &parts[..] { | ||
[Ok(major), Ok(minor)] => (*major, *minor), | ||
_other => panic!("The RUSTLER_NIF_VERSION is not a valid version"), | ||
}; | ||
|
||
if nif_version < MIN_SUPPORTED_VERSION { | ||
panic!( | ||
"The NIF version given from RUSTLER_NIF_VERSION is not supported: {}.{}", | ||
nif_version.0, nif_version.1 | ||
); | ||
} | ||
|
||
// TODO: This code will need adjustment if the Erlang developers ever decide to introduce | ||
// a new major NIF version. | ||
if nif_version > MAX_SUPPORTED_VERSION { | ||
eprintln!( | ||
"NIF version {}.{} is not yet supported, falling back to {}.{}", | ||
nif_version.0, nif_version.1, MAX_SUPPORTED_VERSION.0, MAX_SUPPORTED_VERSION.1 | ||
); | ||
nif_version = MAX_SUPPORTED_VERSION; | ||
} | ||
|
||
nif_version | ||
} | ||
|
||
pub fn handle_nif_version_from_env() -> Option<(u32, u32)> { | ||
println!("cargo:rerun-if-env-changed=RUSTLER_NIF_VERSION"); | ||
env::var("RUSTLER_NIF_VERSION").ok().map(|val| { | ||
let nif_version = get_nif_version_from_env(&val); | ||
|
||
// Activate all config flags for the supported NIF versions | ||
for minor in 0..=nif_version.1 { | ||
println!( | ||
"cargo:rustc-cfg=feature=\"nif_version_{}_{}\"", | ||
nif_version.0, minor | ||
); | ||
} | ||
|
||
nif_version | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,8 @@ | ||
/// Detect NIF version to build against | ||
/// It reads from the RUSTLER_NIF_VERSION env var. | ||
/// | ||
/// If this env var is not present we try to read from the installed Erlang. | ||
/// If the environment doesn't have Erlang installed, then we use the latest | ||
/// NIF version and write a warning to stderr. | ||
use std::env; | ||
use std::process::Command; | ||
|
||
// keep this sorted by version number | ||
const NIF_VERSION: &[&str] = &["2.14", "2.15", "2.16", "2.17"]; | ||
include!("build_common.rs"); | ||
|
||
fn main() { | ||
let latest_version = NIF_VERSION.last().unwrap().to_string(); | ||
let version = env::var("RUSTLER_NIF_VERSION").unwrap_or_else(|_| { | ||
match get_version_from_erl() { | ||
Some(nif_version) if NIF_VERSION.contains(&nif_version.as_str()) => { | ||
eprintln!("RUSTLER_NIF_VERSION env var is not set. Using version from Erlang: {}", nif_version); | ||
nif_version | ||
}, | ||
Some(ref nif_version) => panic!("The NIF version from Erlang is not supported by Rustler: {}", nif_version), | ||
None => { | ||
eprintln!("RUSTLER_NIF_VERSION env var is not set and `erl` command is not found. Using version {}", latest_version); | ||
latest_version | ||
}, | ||
} | ||
}); | ||
|
||
activate_versions(&version); | ||
common::handle_nif_version_from_env(); | ||
|
||
// The following lines are important to tell Cargo to recompile if something changes. | ||
println!("cargo:rerun-if-changed=build.rs"); | ||
println!("cargo:rerun-if-env-changed=RUSTLER_NIF_VERSION"); | ||
} | ||
|
||
fn get_version_from_erl() -> Option<String> { | ||
let args = vec![ | ||
"-noshell", | ||
"-eval", | ||
r#"io:format("~s~n", [erlang:system_info(nif_version)]), init:stop()."#, | ||
]; | ||
|
||
let version = Command::new("erl").args(args).output().ok()?.stdout; | ||
|
||
let version = String::from_utf8(version).ok()?; | ||
|
||
Some(version.trim().into()) | ||
} | ||
|
||
fn activate_versions(version: &str) { | ||
let index = NIF_VERSION | ||
.iter() | ||
.position(|&v| v == version) | ||
.unwrap_or_else(|| { | ||
panic!( | ||
"Erlang version {} not handled, please file a a bug report.", | ||
version | ||
) | ||
}); | ||
|
||
#[allow(clippy::needless_range_loop)] | ||
for i in 0..=index { | ||
println!( | ||
"cargo:rustc-cfg=nif_version_{}", | ||
version_feature(NIF_VERSION[i]) | ||
); | ||
} | ||
} | ||
|
||
fn version_feature(version: &str) -> String { | ||
version.replace('.', "_") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../build_common.rs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.