From f7ba502005d6376328e1e2591d70973d4f1d6b15 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Wed, 12 Oct 2022 02:26:40 -0700 Subject: feat(tvix/eval): implement builtins.currentSystem This commit implements builtins.currentSystem, by capturing the cargo environment variable `TARGET` and exposing it to rustc as `TVIX_CURRENT_SYSTEM` so it can be inserted into the source code using `env!()`. The resulting value needs to be massaged a bit, since it is an "LLVM triple". The current code should work for all the platforms for which cppnix works (thanks qyliss for generating the list!). It does *not* reject all of the triples that cppnix's configure.ac rejects -- it is much more forgiving. We can tighten this up in a future commit. Signed-off-by: Adam Joseph Change-Id: I947f504b2af5a7fee8cf0cb301421d2fc9174ce1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6986 Tested-by: BuildkiteCI Reviewed-by: tazjin --- tvix/eval/build.rs | 9 + tvix/eval/src/builtins/mod.rs | 7 + tvix/eval/src/lib.rs | 1 + tvix/eval/src/systems.rs | 343 +++++++++++++++++++++ .../src/tests/nix_tests/eval-okay-builtins.exp | 1 + .../src/tests/nix_tests/eval-okay-builtins.nix | 12 + .../nix_tests/notyetpassing/eval-okay-builtins.exp | 1 - .../nix_tests/notyetpassing/eval-okay-builtins.nix | 12 - 8 files changed, 373 insertions(+), 13 deletions(-) create mode 100644 tvix/eval/build.rs create mode 100644 tvix/eval/src/systems.rs create mode 100644 tvix/eval/src/tests/nix_tests/eval-okay-builtins.exp create mode 100644 tvix/eval/src/tests/nix_tests/eval-okay-builtins.nix delete mode 100644 tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.exp delete mode 100644 tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.nix (limited to 'tvix/eval') diff --git a/tvix/eval/build.rs b/tvix/eval/build.rs new file mode 100644 index 0000000000..a9c9a78b06 --- /dev/null +++ b/tvix/eval/build.rs @@ -0,0 +1,9 @@ +use std::env; + +fn main() { + println!( + "cargo:rustc-env=TVIX_CURRENT_SYSTEM={}", + &env::var("TARGET").unwrap() + ); + println!("cargo:rerun-if-changed-env=TARGET") +} diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 2209edd962..25d00070e9 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -663,6 +663,8 @@ fn placeholders() -> Vec { }, )] } +// we set TVIX_CURRENT_SYSTEM in build.rs +pub const CURRENT_PLATFORM: &str = env!("TVIX_CURRENT_SYSTEM"); fn builtins_set() -> NixAttrs { let mut map: BTreeMap = BTreeMap::new(); @@ -673,6 +675,11 @@ fn builtins_set() -> NixAttrs { Value::String("2.3-compat-tvix-0.1".into()), ); + map.insert( + "currentSystem".into(), + crate::systems::llvm_triple_to_nix_double(CURRENT_PLATFORM).into(), + ); + let mut add_builtins = |builtins: Vec| { for builtin in builtins { map.insert(builtin.name().into(), Value::Builtin(builtin)); diff --git a/tvix/eval/src/lib.rs b/tvix/eval/src/lib.rs index 04b5a3290b..70d2dbbe38 100644 --- a/tvix/eval/src/lib.rs +++ b/tvix/eval/src/lib.rs @@ -8,6 +8,7 @@ mod opcode; mod pretty_ast; mod source; mod spans; +mod systems; mod upvalues; mod value; mod vm; diff --git a/tvix/eval/src/systems.rs b/tvix/eval/src/systems.rs new file mode 100644 index 0000000000..e06bf57e78 --- /dev/null +++ b/tvix/eval/src/systems.rs @@ -0,0 +1,343 @@ +/// true iff the argument is recognized by cppnix as the second +/// coordinate of a "nix double" +fn is_second_coordinate(x: &str) -> bool { + match x { + "linux" | "darwin" | "netbsd" | "openbsd" | "freebsd" => true, + _ => false, + } +} + +/// This function takes an llvm triple (which may have three or four +/// components, separated by dashes) and returns the "best" +/// approximation as a nix double, where "best" is currently defined +/// as "however cppnix handles it". +pub fn llvm_triple_to_nix_double(llvm_triple: &str) -> String { + let parts: Vec<&str> = llvm_triple.split('-').collect(); + let cpu = match parts[0] { + "armv6" => "armv6l", // cppnix appends an "l" to armv6 + "armv7" => "armv7l", // cppnix appends an "l" to armv7 + x => match x.as_bytes().as_ref() { + [b'i', _, b'8', b'6'] => "i686", // cppnix glob-matches against i*86 + _ => x, + }, + }; + let os = match parts[1..] { + [_vendor, kernel, _environment] if is_second_coordinate(kernel) => kernel, + [_vendor, kernel] if is_second_coordinate(kernel) => kernel, + [kernel, _environment] if is_second_coordinate(kernel) => kernel, + _ => panic!("unrecognized triple {llvm_triple}"), + }; + format!("{cpu}-{os}") +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_systems() { + assert_eq!( + llvm_triple_to_nix_double("aarch64-unknown-linux-gnu"), + "aarch64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("i686-unknown-linux-gnu"), + "i686-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("x86_64-apple-darwin"), + "x86_64-darwin" + ); + assert_eq!( + llvm_triple_to_nix_double("x86_64-unknown-linux-gnu"), + "x86_64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("aarch64-apple-darwin"), + "aarch64-darwin" + ); + assert_eq!( + llvm_triple_to_nix_double("aarch64-unknown-linux-musl"), + "aarch64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("arm-unknown-linux-gnueabi"), + "arm-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("arm-unknown-linux-gnueabihf"), + "arm-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-unknown-linux-gnueabihf"), + "armv7l-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips-unknown-linux-gnu"), + "mips-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips64-unknown-linux-gnuabi64"), + "mips64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips64-unknown-linux-gnuabin32"), + "mips64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips64el-unknown-linux-gnuabi64"), + "mips64el-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips64el-unknown-linux-gnuabin32"), + "mips64el-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mipsel-unknown-linux-gnu"), + "mipsel-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc-unknown-linux-gnu"), + "powerpc-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc64-unknown-linux-gnu"), + "powerpc64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc64le-unknown-linux-gnu"), + "powerpc64le-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("s390x-unknown-linux-gnu"), + "s390x-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("x86_64-unknown-linux-musl"), + "x86_64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("x86_64-unknown-netbsd"), + "x86_64-netbsd" + ); + assert_eq!( + llvm_triple_to_nix_double("aarch64-linux-android"), + "aarch64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("arm-linux-androideabi"), + "arm-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("arm-unknown-linux-musleabi"), + "arm-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("arm-unknown-linux-musleabihf"), + "arm-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv5te-unknown-linux-gnueabi"), + "armv5te-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv5te-unknown-linux-musleabi"), + "armv5te-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-linux-androideabi"), + "armv7l-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-unknown-linux-gnueabi"), + "armv7l-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-unknown-linux-musleabi"), + "armv7l-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-unknown-linux-musleabihf"), + "armv7l-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("i586-unknown-linux-gnu"), + "i686-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("i586-unknown-linux-musl"), + "i686-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("i686-linux-android"), + "i686-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("i686-unknown-linux-musl"), + "i686-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips-unknown-linux-musl"), + "mips-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips64-unknown-linux-muslabi64"), + "mips64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips64el-unknown-linux-muslabi64"), + "mips64el-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mipsel-unknown-linux-musl"), + "mipsel-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("sparc64-unknown-linux-gnu"), + "sparc64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("thumbv7neon-linux-androideabi"), + "thumbv7neon-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("thumbv7neon-unknown-linux-gnueabihf"), + "thumbv7neon-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("x86_64-linux-android"), + "x86_64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("x86_64-unknown-linux-gnux32"), + "x86_64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("aarch64-unknown-linux-gnu_ilp32"), + "aarch64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("aarch64-unknown-netbsd"), + "aarch64-netbsd" + ); + assert_eq!( + llvm_triple_to_nix_double("aarch64_be-unknown-linux-gnu_ilp32"), + "aarch64_be-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("aarch64_be-unknown-linux-gnu"), + "aarch64_be-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armeb-unknown-linux-gnueabi"), + "armeb-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv4t-unknown-linux-gnueabi"), + "armv4t-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv6-unknown-netbsd-eabihf"), + "armv6l-netbsd" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-unknown-linux-uclibceabi"), + "armv7l-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-unknown-linux-uclibceabihf"), + "armv7l-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("armv7-unknown-netbsd-eabihf"), + "armv7l-netbsd" + ); + assert_eq!( + llvm_triple_to_nix_double("hexagon-unknown-linux-musl"), + "hexagon-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("i686-unknown-netbsd"), + "i686-netbsd" + ); + assert_eq!( + llvm_triple_to_nix_double("m68k-unknown-linux-gnu"), + "m68k-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips-unknown-linux-uclibc"), + "mips-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mips64-openwrt-linux-musl"), + "mips64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mipsel-unknown-linux-uclibc"), + "mipsel-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mipsisa32r6-unknown-linux-gnu"), + "mipsisa32r6-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mipsisa32r6el-unknown-linux-gnu"), + "mipsisa32r6el-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mipsisa64r6-unknown-linux-gnuabi64"), + "mipsisa64r6-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("mipsisa64r6el-unknown-linux-gnuabi64"), + "mipsisa64r6el-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc-unknown-linux-gnuspe"), + "powerpc-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc-unknown-linux-musl"), + "powerpc-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc-unknown-netbsd"), + "powerpc-netbsd" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc64-unknown-linux-musl"), + "powerpc64-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("powerpc64le-unknown-linux-musl"), + "powerpc64le-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("riscv32gc-unknown-linux-gnu"), + "riscv32gc-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("riscv32gc-unknown-linux-musl"), + "riscv32gc-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("riscv64gc-unknown-linux-musl"), + "riscv64gc-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("s390x-unknown-linux-musl"), + "s390x-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("sparc-unknown-linux-gnu"), + "sparc-linux" + ); + assert_eq!( + llvm_triple_to_nix_double("sparc64-unknown-netbsd"), + "sparc64-netbsd" + ); + assert_eq!( + llvm_triple_to_nix_double("thumbv7neon-unknown-linux-musleabihf"), + "thumbv7neon-linux" + ); + } +} diff --git a/tvix/eval/src/tests/nix_tests/eval-okay-builtins.exp b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.exp new file mode 100644 index 0000000000..0661686d61 --- /dev/null +++ b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.exp @@ -0,0 +1 @@ +/foo diff --git a/tvix/eval/src/tests/nix_tests/eval-okay-builtins.nix b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.nix new file mode 100644 index 0000000000..e9d65e88a8 --- /dev/null +++ b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.nix @@ -0,0 +1,12 @@ +assert builtins ? currentSystem; +assert !builtins ? __currentSystem; + +let { + + x = if builtins ? dirOf then builtins.dirOf /foo/bar else ""; + + y = if builtins ? fnord then builtins.fnord "foo" else ""; + + body = x + y; + +} diff --git a/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.exp b/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.exp deleted file mode 100644 index 0661686d61..0000000000 --- a/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.exp +++ /dev/null @@ -1 +0,0 @@ -/foo diff --git a/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.nix b/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.nix deleted file mode 100644 index e9d65e88a8..0000000000 --- a/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.nix +++ /dev/null @@ -1,12 +0,0 @@ -assert builtins ? currentSystem; -assert !builtins ? __currentSystem; - -let { - - x = if builtins ? dirOf then builtins.dirOf /foo/bar else ""; - - y = if builtins ? fnord then builtins.fnord "foo" else ""; - - body = x + y; - -} -- cgit 1.4.1