about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2022-10-12T09·26-0700
committertazjin <tazjin@tvl.su>2022-10-24T12·20+0000
commitf7ba502005d6376328e1e2591d70973d4f1d6b15 (patch)
treec1a78d6a960cc4766b69d77de00e5b4f599c4f83
parente2f0967d3fd44cac78ac50425bc2dbe65fd4a8c4 (diff)
feat(tvix/eval): implement builtins.currentSystem r/5190
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 <adam@westernsemico.com>
Change-Id: I947f504b2af5a7fee8cf0cb301421d2fc9174ce1
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6986
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
-rw-r--r--tvix/eval/build.rs9
-rw-r--r--tvix/eval/src/builtins/mod.rs7
-rw-r--r--tvix/eval/src/lib.rs1
-rw-r--r--tvix/eval/src/systems.rs343
-rw-r--r--tvix/eval/src/tests/nix_tests/eval-okay-builtins.exp (renamed from tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.exp)0
-rw-r--r--tvix/eval/src/tests/nix_tests/eval-okay-builtins.nix (renamed from tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.nix)0
6 files changed, 360 insertions, 0 deletions
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<Builtin> {
         },
     )]
 }
+// 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<NixString, Value> = 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<Builtin>| {
         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/notyetpassing/eval-okay-builtins.exp b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.exp
index 0661686d61..0661686d61 100644
--- a/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.exp
+++ b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.exp
diff --git a/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.nix b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.nix
index e9d65e88a8..e9d65e88a8 100644
--- a/tvix/eval/src/tests/nix_tests/notyetpassing/eval-okay-builtins.nix
+++ b/tvix/eval/src/tests/nix_tests/eval-okay-builtins.nix