Skip to main content

multivers_runner/
lib.rs

1#![doc = "README.md"]
2#![cfg_attr(not(test), no_main)]
3#![cfg_attr(test, allow(dead_code))]
4
5mod build;
6
7use std::ffi::c_char;
8
9use build::{Build, Executable};
10
11/// Function called at program startup.
12///
13/// When [main] is executed, it uncompresses and executes the version that matches the CPU features
14/// of the host.
15///
16/// # Example
17///
18/// ```no_run
19/// #![no_main]
20///
21/// pub use multivers_runner::main;
22/// ```
23///
24/// # Safety
25///
26/// - `argc` must never be negative.
27/// - `argv` and `envp` must be null-terminated arrays of valid pointers to null-terminated strings.
28/// - Each element of `argv` and `envp` must be valid for reads of bytes up to and including the null terminator.
29#[unsafe(no_mangle)]
30#[cfg(not(test))]
31pub unsafe extern "C" fn main(argc: i32, argv: *const *const c_char, envp: *const *const c_char) {
32    let result = unsafe { run(argc, argv, envp) };
33
34    proc_exit::exit(result);
35}
36
37unsafe fn run(
38    argc: i32,
39    argv: *const *const c_char,
40    envp: *const *const c_char,
41) -> proc_exit::ExitResult {
42    #[cfg(feature = "debug")]
43    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();
44
45    let build = Build::find().unwrap_or_default();
46
47    #[cfg(feature = "debug")]
48    log::debug!(
49        "Executing build with the following CPU features: {}",
50        build.features()
51    );
52
53    unsafe { build.exec(argc, argv, envp) }?;
54
55    Ok(())
56}