| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1bb42ad commit d1eec5d
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,6 +99,7 @@ widestring = { workspace = true } | |||
| 99 | 99 | wasm-bindgen = { workspace = true, optional = true } | |
| 100 | 100 | ||
| 101 | 101 | [build-dependencies] | |
| 102 | + chrono = { workspace = true } | ||
| 102 | 103 | glob = { workspace = true } | |
| 103 | 104 | itertools = { workspace = true } | |
| 104 | 105 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,8 @@ | |||
| 3 | 3 | reason = "build scripts cannot use rustpython-host_env" | |
| 4 | 4 | )] | |
| 5 | 5 | ||
| 6 | + use chrono::{Local, prelude::DateTime}; | ||
| 7 | + use core::time::Duration; | ||
| 6 | 8 | use itertools::Itertools; | |
| 7 | 9 | use std::{ | |
| 8 | 10 | env, | |
@@ -24,17 +26,27 @@ fn main() { | |||
| 24 | 26 | } | |
| 25 | 27 | println!("cargo:rerun-if-changed=../../Lib/importlib/_bootstrap.py"); | |
| 26 | 28 | ||
| 29 | + // = 3.14.0alpha | ||
| 30 | + python_version(3, 14, 0, "alpha", 0); | ||
| 31 | + | ||
| 27 | 32 | println!("cargo:rustc-env=RUSTPYTHON_GIT_HASH={}", git_hash()); | |
| 28 | 33 | println!( | |
| 29 | 34 | "cargo:rustc-env=RUSTPYTHON_GIT_TIMESTAMP={}", | |
| 30 | 35 | git_timestamp() | |
| 31 | 36 | ); | |
| 32 | 37 | println!("cargo:rustc-env=RUSTPYTHON_GIT_TAG={}", git_tag()); | |
| 33 | 38 | println!("cargo:rustc-env=RUSTPYTHON_GIT_BRANCH={}", git_branch()); | |
| 39 | + println!( | ||
| 40 | + "cargo:rustc-env=RUSTPYTHON_GIT_IDENTIFIER={}", | ||
| 41 | + git_identifier() | ||
| 42 | + ); | ||
| 43 | + println!("cargo:rustc-env=RUSTPYTHON_BUILD_INFO={}", get_build_info()); | ||
| 34 | 44 | println!("cargo:rustc-env=RUSTC_VERSION={}", rustc_version()); | |
| 35 | 45 | ||
| 36 | 46 | let release_level = option_env!("RUSTPYTHON_RELEASE_LEVEL").unwrap_or("alpha"); | |
| 37 | 47 | println!("cargo:rustc-env=RUSTPYTHON_RELEASE_LEVEL={release_level}"); | |
| 48 | + let release_level_n = release_to_n(release_level); | ||
| 49 | + println!("cargo:rustc-env=RUSTPYTHON_RELEASE_LEVEL_N={release_level_n}"); | ||
| 38 | 50 | let release_serial = option_env!("RUSTPYTHON_RELEASE_SERIAL").unwrap_or("0"); | |
| 39 | 51 | println!("cargo:rustc-env=RUSTPYTHON_RELEASE_SERIAL={release_serial}"); | |
| 40 | 52 | ||
@@ -81,11 +93,119 @@ fn git(args: &[&str]) -> io::Result<String> { | |||
| 81 | 93 | command("git", args) | |
| 82 | 94 | } | |
| 83 | 95 | ||
| 96 | + #[must_use] | ||
| 97 | + fn get_build_info() -> String { | ||
| 98 | + // See: https://reproducible-builds.org/docs/timestamps/ | ||
| 99 | + let revision = git_hash(); | ||
| 100 | + let separator = if revision.is_empty() { "" } else { ":" }; | ||
| 101 | + let identifier = git_identifier(); | ||
| 102 | + | ||
| 103 | + format!( | ||
| 104 | + "{id}{sep}{revision}, {date:.20}, {time:.9}", | ||
| 105 | + id = if identifier.is_empty() { | ||
| 106 | + "default" | ||
| 107 | + } else { | ||
| 108 | + &identifier | ||
| 109 | + }, | ||
| 110 | + sep = separator, | ||
| 111 | + revision = revision, | ||
| 112 | + date = get_git_date(), | ||
| 113 | + time = get_git_time(), | ||
| 114 | + ) | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + fn git_identifier() -> String { | ||
| 118 | + let tag = git_tag(); | ||
| 119 | + if tag.is_empty() || tag.eq_ignore_ascii_case("undefined") { | ||
| 120 | + git_branch() | ||
| 121 | + } else { | ||
| 122 | + tag | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + fn get_git_timestamp_datetime() -> DateTime<Local> { | ||
| 127 | + let timestamp = git_timestamp().parse::<u64>().unwrap_or_default(); | ||
| 128 | + let datetime = UNIX_EPOCH + Duration::from_secs(timestamp); | ||
| 129 | + datetime.into() | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + #[must_use] | ||
| 133 | + fn get_git_date() -> String { | ||
| 134 | + let datetime = get_git_timestamp_datetime(); | ||
| 135 | + | ||
| 136 | + datetime.format("%b %e %Y").to_string() | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + #[must_use] | ||
| 140 | + fn get_git_time() -> String { | ||
| 141 | + let datetime = get_git_timestamp_datetime(); | ||
| 142 | + | ||
| 143 | + datetime.format("%H:%M:%S").to_string() | ||
| 144 | + } | ||
| 145 | + | ||
| 84 | 146 | fn rustc_version() -> String { | |
| 85 | 147 | let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); | |
| 86 | 148 | command(rustc, &["-V"]).unwrap_or_else(|_| "rustc [unknown]".into()) | |
| 87 | 149 | } | |
| 88 | 150 | ||
| 151 | + fn python_version(major: usize, minor: usize, micro: usize, release: &str, serial: usize) { | ||
| 152 | + println!("cargo:rustc-env=MAJOR_CPY={major}"); | ||
| 153 | + println!("cargo:rustc-env=MINOR_CPY={minor}"); | ||
| 154 | + println!("cargo:rustc-env=MICRO_CPY={micro}"); | ||
| 155 | + println!("cargo:rustc-env=RELEASE_LEVEL_CPY={release}"); | ||
| 156 | + println!( | ||
| 157 | + "cargo:rustc-env=RELEASE_LEVEL_N_CPY={}", | ||
| 158 | + release_to_n(release) | ||
| 159 | + ); | ||
| 160 | + println!("cargo:rustc-env=SERIAL_CPY={serial}"); | ||
| 161 | + | ||
| 162 | + println!("cargo:rustc-env=WINVER_CPY={major}.{minor}",); | ||
| 163 | + | ||
| 164 | + let cpy_version = format!("{major}.{minor}.{micro}.{release}"); | ||
| 165 | + | ||
| 166 | + let (left, right) = get_version(&cpy_version); | ||
| 167 | + println!("cargo:rustc-env=RUSTPYTHON_VERSION_LEFT={left}"); | ||
| 168 | + println!("cargo:rustc-env=RUSTPYTHON_VERSION_RIGHT={right}"); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + #[must_use] | ||
| 172 | + fn get_version(cpy_version: &str) -> (String, String) { | ||
| 173 | + // Windows: include MSC v. for compatibility with ctypes.util.find_library | ||
| 174 | + // MSC v.1929 = VS 2019, version 14+ makes find_msvcrt() return None | ||
| 175 | + let msc_info = cfg_select! { | ||
| 176 | + windows => {{ | ||
| 177 | + // Include both RustPython identifier and MSC v. for compatibility | ||
| 178 | + if cfg!(target_pointer_width = "64") { | ||
| 179 | + " MSC v.1929 64 bit (AMD64)" | ||
| 180 | + } else { | ||
| 181 | + " MSC v.1929 32 bit (Intel)" | ||
| 182 | + } | ||
| 183 | + }}, | ||
| 184 | + _ => "", | ||
| 185 | + }; | ||
| 186 | + | ||
| 187 | + // `left` and `right` are split by \n like PyPy. Passing a string with a newline to rustc | ||
| 188 | + // truncates everything from the newline onward, so we have to manually combine them later. | ||
| 189 | + let left = format!("{:.80} ({:.80})", cpy_version, get_build_info()); | ||
| 190 | + let right = format!( | ||
| 191 | + "[RustPython {} with {:.80}{}]", | ||
| 192 | + env!("CARGO_PKG_VERSION"), | ||
| 193 | + rustc_version(), | ||
| 194 | + msc_info, | ||
| 195 | + ); | ||
| 196 | + (left, right) | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + fn release_to_n(release: &str) -> usize { | ||
| 200 | + match release { | ||
| 201 | + "alpha" => 0xA, | ||
| 202 | + "beta" => 0xB, | ||
| 203 | + "candidate" => 0xC, | ||
| 204 | + "final" => 0xD, | ||
| 205 | + _ => panic!("`release` must be one of: 'alpha', 'beta', 'candidate', 'final'"), | ||
| 206 | + } | ||
| 207 | + } | ||
| 208 | + | ||
| 89 | 209 | fn command(cmd: impl AsRef<std::ffi::OsStr>, args: &[&str]) -> io::Result<String> { | |
| 90 | 210 | Command::new(&cmd).args(args).output().and_then(|output| { | |
| 91 | 211 | // TODO: Switch to exit_ok()? when stable. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -649,7 +649,7 @@ pub mod sys { | |||
| 649 | 649 | fn _git(vm: &VirtualMachine) -> PyTupleRef { | |
| 650 | 650 | vm.new_tuple(( | |
| 651 | 651 | ascii!("RustPython"), | |
| 652 | - version::get_git_identifier(), | ||
| 652 | + version::GIT_IDENTIFIER, | ||
| 653 | 653 | version::GIT_REVISION, | |
| 654 | 654 | )) | |
| 655 | 655 | } | |
@@ -706,17 +706,13 @@ pub mod sys { | |||
| 706 | 706 | vm.ctx.none() | |
| 707 | 707 | } | |
| 708 | 708 | ||
| 709 | - #[pyattr] | ||
| 710 | - fn version(_vm: &VirtualMachine) -> String { | ||
| 711 | - version::get_version() | ||
| 712 | - } | ||
| 709 | + #[pyattr(name = "version")] | ||
| 710 | + const VERSION: &str = version::RUSTPYTHON_VERSION; | ||
| 713 | 711 | ||
| 712 | + // Note: This is Python DLL version in CPython, but we arbitrary fill it for compatibility | ||
| 714 | 713 | #[cfg(windows)] | |
| 715 | - #[pyattr] | ||
| 716 | - fn winver(_vm: &VirtualMachine) -> String { | ||
| 717 | - // Note: This is Python DLL version in CPython, but we arbitrary fill it for compatibility | ||
| 718 | - version::get_winver_number() | ||
| 719 | - } | ||
| 714 | + #[pyattr(name = "winver")] | ||
| 715 | + const WINVER: &str = version::WINVER; | ||
| 720 | 716 | ||
| 721 | 717 | #[pyattr] | |
| 722 | 718 | fn _xoptions(vm: &VirtualMachine) -> PyDictRef { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,145 +1,72 @@ | |||
| 1 | - //! Several function to retrieve version information. | ||
| 2 | - | ||
| 3 | - use chrono::{Local, prelude::DateTime}; | ||
| 4 | - use core::time::Duration; | ||
| 5 | - use std::time::UNIX_EPOCH; | ||
| 1 | + //! Version info constants. | ||
| 2 | + //! | ||
| 3 | + //! Most of the constants are auto calculated at compile time. The main exception is the | ||
| 4 | + //! target CPython version. This is defined and updated in `build.rs`. | ||
| 5 | + | ||
| 6 | + macro_rules! parse_consts { | ||
| 7 | + ($name: ident, $var: literal) => { | ||
| 8 | + pub const $name: usize = match usize::from_str_radix(env!($var), 10) { | ||
| 9 | + Ok(v) => v, | ||
| 10 | + Err(_) => panic!(concat!("Compile with Cargo to get '", $var, "'")), | ||
| 11 | + }; | ||
| 12 | + }; | ||
| 13 | + } | ||
| 6 | 14 | ||
| 7 | - // = 3.14.0alpha | ||
| 8 | - pub const MAJOR: usize = 3; | ||
| 9 | - pub const MINOR: usize = 14; | ||
| 10 | - pub const MICRO: usize = 0; | ||
| 11 | - pub const RELEASELEVEL: &str = "alpha"; | ||
| 12 | - pub const RELEASELEVEL_N: usize = 0xA; | ||
| 13 | - pub const SERIAL: usize = 0; | ||
| 15 | + // CPython target version info | ||
| 16 | + parse_consts!(MAJOR, "MAJOR_CPY"); | ||
| 17 | + parse_consts!(MINOR, "MINOR_CPY"); | ||
| 18 | + parse_consts!(MICRO, "MICRO_CPY"); | ||
| 19 | + pub const RELEASELEVEL: &str = env!("RELEASE_LEVEL_CPY"); | ||
| 20 | + parse_consts!(RELEASELEVEL_N, "RELEASE_LEVEL_N_CPY"); | ||
| 21 | + parse_consts!(SERIAL, "SERIAL_CPY"); | ||
| 14 | 22 | pub const VERSION_HEX: usize = | |
| 15 | 23 | (MAJOR << 24) | (MINOR << 16) | (MICRO << 8) | (RELEASELEVEL_N << 4) | SERIAL; | |
| 16 | 24 | ||
| 25 | + #[cfg(windows)] | ||
| 26 | + pub const WINVER: &str = env!("WINVER_CPY"); | ||
| 27 | + | ||
| 17 | 28 | pub const GIT_REVISION: &str = env!("RUSTPYTHON_GIT_HASH"); | |
| 18 | - const GIT_TAG: &str = env!("RUSTPYTHON_GIT_TAG"); | ||
| 19 | - const GIT_BRANCH: &str = env!("RUSTPYTHON_GIT_BRANCH"); | ||
| 29 | + pub const GIT_IDENTIFIER: &str = env!("RUSTPYTHON_GIT_IDENTIFIER"); | ||
| 30 | + // const GIT_TAG: &str = env!("RUSTPYTHON_GIT_TAG"); | ||
| 31 | + // const GIT_BRANCH: &str = env!("RUSTPYTHON_GIT_BRANCH"); | ||
| 20 | 32 | ||
| 21 | 33 | // RustPython version | |
| 22 | - pub const MAJOR_IMPL: usize = match usize::from_str_radix(env!("CARGO_PKG_VERSION_MAJOR"), 10) { | ||
| 23 | - Ok(v) => v, | ||
| 24 | - Err(_) => panic!("Compile with Cargo to get 'CARGO_PKG_VERSION_MAJOR'"), | ||
| 25 | - }; | ||
| 26 | - pub const MINOR_IMPL: usize = match usize::from_str_radix(env!("CARGO_PKG_VERSION_MINOR"), 10) { | ||
| 27 | - Ok(v) => v, | ||
| 28 | - Err(_) => panic!("Compile with Cargo to get 'CARGO_PKG_VERSION_MINOR'"), | ||
| 29 | - }; | ||
| 30 | - pub const MICRO_IMPL: usize = match usize::from_str_radix(env!("CARGO_PKG_VERSION_PATCH"), 10) { | ||
| 31 | - Ok(v) => v, | ||
| 32 | - Err(_) => panic!("Compile with Cargo to get 'CARGO_PKG_VERSION_PATCH'"), | ||
| 33 | - }; | ||
| 34 | + parse_consts!(MAJOR_IMPL, "CARGO_PKG_VERSION_MAJOR"); | ||
| 35 | + parse_consts!(MINOR_IMPL, "CARGO_PKG_VERSION_MINOR"); | ||
| 36 | + parse_consts!(MICRO_IMPL, "CARGO_PKG_VERSION_PATCH"); | ||
| 34 | 37 | pub const RELEASELEVEL_IMPL: &str = env!("RUSTPYTHON_RELEASE_LEVEL"); | |
| 35 | - pub const SERIAL_IMPL: usize = match usize::from_str_radix(env!("RUSTPYTHON_RELEASE_SERIAL"), 10) { | ||
| 36 | - Ok(v) => v, | ||
| 37 | - Err(_) => panic!("Compile with Cargo to get 'RUSTPYTHON_RELEASE_SERIAL'"), | ||
| 38 | - }; | ||
| 38 | + parse_consts!(RELEASELEVEL_N_IMPL, "RUSTPYTHON_RELEASE_LEVEL_N"); | ||
| 39 | + parse_consts!(SERIAL_IMPL, "RUSTPYTHON_RELEASE_SERIAL"); | ||
| 39 | 40 | pub const VERSION_HEX_IMPL: usize = (MAJOR_IMPL << 24) | |
| 40 | 41 | | (MINOR_IMPL << 16) | |
| 41 | 42 | | (MICRO_IMPL << 8) | |
| 42 | - | (RELEASELEVEL_N << 4) | ||
| 43 | + | (RELEASELEVEL_N_IMPL << 4) | ||
| 43 | 44 | | SERIAL_IMPL; | |
| 44 | 45 | ||
| 45 | - #[must_use] | ||
| 46 | - pub fn get_version() -> String { | ||
| 47 | - // Windows: include MSC v. for compatibility with ctypes.util.find_library | ||
| 48 | - // MSC v.1929 = VS 2019, version 14+ makes find_msvcrt() return None | ||
| 49 | - let msc_info = cfg_select! { | ||
| 50 | - windows => {{ | ||
| 51 | - let arch = if cfg!(target_pointer_width = "64") { | ||
| 52 | - "64 bit (AMD64)" | ||
| 53 | - } else { | ||
| 54 | - "32 bit (Intel)" | ||
| 55 | - }; | ||
| 56 | - // Include both RustPython identifier and MSC v. for compatibility | ||
| 57 | - format!(" MSC v.1929 {arch}",) | ||
| 58 | - }}, | ||
| 59 | - _ => String::new(), | ||
| 60 | - }; | ||
| 61 | - | ||
| 62 | - format!( | ||
| 63 | - "{:.80} ({:.80}) \n[RustPython {} with {:.80}{}]", // \n is PyPy convention | ||
| 64 | - get_version_number(), | ||
| 65 | - get_build_info(), | ||
| 66 | - env!("CARGO_PKG_VERSION"), | ||
| 67 | - COMPILER, | ||
| 68 | - msc_info, | ||
| 69 | - ) | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - #[must_use] | ||
| 73 | - pub fn get_version_number() -> String { | ||
| 74 | - format!("{MAJOR}.{MINOR}.{MICRO}{RELEASELEVEL}") | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - #[must_use] | ||
| 78 | - pub fn get_winver_number() -> String { | ||
| 79 | - format!("{MAJOR}.{MINOR}") | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - const COMPILER: &str = env!("RUSTC_VERSION"); | ||
| 46 | + pub const RUSTPYTHON_BUILD_INFO: &str = env!("RUSTPYTHON_BUILD_INFO"); | ||
| 47 | + pub const RUSTPYTHON_VERSION: &str = const { | ||
| 48 | + const LEFT: &str = env!("RUSTPYTHON_VERSION_LEFT"); | ||
| 49 | + const RIGHT: &str = env!("RUSTPYTHON_VERSION_RIGHT"); | ||
| 50 | + const LEN: usize = LEFT.len() + RIGHT.len() + 1; | ||
| 83 | 51 | ||
| 84 | - #[must_use] | ||
| 85 | - pub fn get_build_info() -> String { | ||
| 86 | - // See: https://reproducible-builds.org/docs/timestamps/ | ||
| 87 | - let separator = if GIT_REVISION.is_empty() { "" } else { ":" }; | ||
| 88 | - let git_identifier = get_git_identifier(); | ||
| 52 | + const fn concat() -> [u8; LEN] { | ||
| 53 | + let mut bytes_temp = [0u8; LEN]; | ||
| 89 | 54 | ||
| 90 | - format!( | ||
| 91 | - "{id}{sep}{revision}, {date:.20}, {time:.9}", | ||
| 92 | - id = if git_identifier.is_empty() { | ||
| 93 | - "default" | ||
| 94 | - } else { | ||
| 95 | - git_identifier | ||
| 96 | - }, | ||
| 97 | - sep = separator, | ||
| 98 | - revision = GIT_REVISION, | ||
| 99 | - date = get_git_date(), | ||
| 100 | - time = get_git_time(), | ||
| 101 | - ) | ||
| 102 | - } | ||
| 55 | + let (left, _) = bytes_temp.split_at_mut(LEFT.len()); | ||
| 56 | + left.copy_from_slice(LEFT.as_bytes()); | ||
| 57 | + let (_, right) = bytes_temp.split_at_mut(LEFT.len() + 1); | ||
| 58 | + right.copy_from_slice(RIGHT.as_bytes()); | ||
| 59 | + bytes_temp[LEFT.len()] = b'\n'; | ||
| 103 | 60 | ||
| 104 | - #[must_use] | ||
| 105 | - pub const fn get_git_identifier() -> &'static str { | ||
| 106 | - if GIT_TAG.is_empty() || GIT_TAG.eq_ignore_ascii_case("undefined") { | ||
| 107 | - GIT_BRANCH | ||
| 108 | - } else { | ||
| 109 | - GIT_TAG | ||
| 61 | + bytes_temp | ||
| 110 | 62 | } | |
| 111 | - } | ||
| 112 | - | ||
| 113 | - fn get_git_timestamp_datetime() -> DateTime<Local> { | ||
| 114 | - let timestamp = option_env!("RUSTPYTHON_GIT_TIMESTAMP").unwrap_or_default(); | ||
| 115 | - let timestamp = timestamp.parse::<u64>().unwrap_or_default(); | ||
| 116 | - | ||
| 117 | - let datetime = UNIX_EPOCH + Duration::from_secs(timestamp); | ||
| 118 | - | ||
| 119 | - datetime.into() | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - #[must_use] | ||
| 123 | - pub fn get_git_date() -> String { | ||
| 124 | - let datetime = get_git_timestamp_datetime(); | ||
| 125 | - | ||
| 126 | - datetime.format("%b %e %Y").to_string() | ||
| 127 | - } | ||
| 128 | - | ||
| 129 | - #[must_use] | ||
| 130 | - pub fn get_git_time() -> String { | ||
| 131 | - let datetime = get_git_timestamp_datetime(); | ||
| 132 | - | ||
| 133 | - datetime.format("%H:%M:%S").to_string() | ||
| 134 | - } | ||
| 135 | 63 | ||
| 136 | - #[must_use] | ||
| 137 | - pub fn get_git_datetime() -> String { | ||
| 138 | - let date = get_git_date(); | ||
| 139 | - let time = get_git_time(); | ||
| 140 | - | ||
| 141 | - format!("{date} {time}") | ||
| 142 | - } | ||
| 64 | + const BUF: [u8; LEN] = concat(); | ||
| 65 | + match str::from_utf8(&BUF) { | ||
| 66 | + Ok(v) => v, | ||
| 67 | + Err(_) => unreachable!(), | ||
| 68 | + } | ||
| 69 | + }; | ||
| 143 | 70 | ||
| 144 | 71 | // Must be aligned to Lib/importlib/_bootstrap_external.py | |
| 145 | 72 | // Bumped to 2994 for new CommonConstant discriminants (BuiltinList, BuiltinSet) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments