Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nix devshell #1231

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

162 changes: 162 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# TODO
# * [x] deal with hardcoded path
# * [x] the dependency z3
# * [ ] remove duplicates
# * [ ] verus as an app (which checks whether verus was build beforehand, otherwise instructs user to call the vargo app)
# * [ ] think about command names
# * [x] vargo as a package (technically doable with a cargo)

# MAYBE LATER
# * [ ] pick right z3 dependency automagically (not super simple when all we have the url in the script...)
# * [ ] verus as a package (not doable yet, since verus calls rustup and that means internet access during the build phase, which is not possible in nix)

# How to use (if you have the nix package manager installed. These days, I recommend [Lix](https://lix.systems).)
# ===============================
#
# How to use the devshell (meant for developping on vargo or verus itself)
# `nix develop` This will drop you in a shell environment where all dependencies are (should be) available
#
# How to call vargo:
# `cd src && nix run .#vargo-br`
#
# How to call verus;
# TODO

{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};

outputs = {
nixpkgs,
self,
...
}: let
supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });

overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml));
in {
packages = forAllSystems (system: let
pkgs = nixpkgsFor.${system};
in {
vargo = import ./vargo.nix { inherit pkgs; };
});

# enter a dev shell with `nix develop
devShells = forAllSystems (system: let
pkgs = nixpkgsFor.${system};
libPath = with pkgs; lib.makeLibraryPath [
# load external libraries that you need in your rust project here
];
in {
default = pkgs.mkShell {
RUSTC_VERSION = overrides.toolchain.channel;
# https://github.com/rust-lang/rust-bindgen#environment-variables
LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ];

# Add precompiled library to rustc search path
RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [
# add libraries here (e.g. pkgs.libvmi)
]);
LD_LIBRARY_PATH = libPath;
# Add glibc, clang, glib, and other headers to bindgen search path
BINDGEN_EXTRA_CLANG_ARGS =
# Includes normal include path
(builtins.map (a: ''-I"${a}/include"'') [
# add dev libraries here (e.g. pkgs.libvmi.dev)
pkgs.glibc.dev
])
# Includes with special directory paths
++ [
''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"''
''-I"${pkgs.glib.dev}/include/glib-2.0"''
''-I${pkgs.glib.out}/lib/glib-2.0/include/''
];

packages = [
pkgs.z3_4_12
pkgs.cvc5
pkgs.singular

pkgs.clang
pkgs.llvmPackages.bintools
pkgs.rustup
(import ./vargo.nix { inherit pkgs; })
];
shellHook = ''
export PATH=$PATH:''${CARGO_HOME}/bin
export PATH=$PATH:''${RUSTUP_HOME}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/
export PATH=$(realpath .)/source/target-verus/release:$PATH
export VERUS_Z3_PATH=$(which z3)
export VERUS_CVC5_PATH=$(which cvc5)
export VERUS_SINGULAR_PATH=$(which Singular) # what exactly does it need on the path?
'';
};
});

# this only works if you have rustup installed system wide
# invoke as `nix run .#vargo`
apps = forAllSystems (system: let
pkgs = nixpkgsFor.${system};
libPath = with pkgs; lib.makeLibraryPath [
# load external libraries that you need in your rust project here
];
# todo put these vars inside
RUSTC_VERSION = overrides.toolchain.channel; # TODO das hier wird noch gar nicht genutzt so
# https://github.com/rust-lang/rust-bindgen#environment-variables
LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ];

# Add precompiled library to rustc search path
RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [
# add libraries here (e.g. pkgs.libvmi)
]);
LD_LIBRARY_PATH = libPath;
# Add glibc, clang, glib, and other headers to bindgen search path
BINDGEN_EXTRA_CLANG_ARGS =
# Includes normal include path
(builtins.map (a: ''-I"${a}/include"'') [
# add dev libraries here (e.g. pkgs.libvmi.dev)
pkgs.glibc.dev
])
# Includes with special directory paths
++ [
''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"''
''-I"${pkgs.glib.dev}/include/glib-2.0"''
''-I${pkgs.glib.out}/lib/glib-2.0/include/''
];
vargoWithRustup = pkgs.writeShellApplication {
name = "vargo";
runtimeInputs = [
pkgs.z3_4_12
pkgs.cvc5
pkgs.singular

pkgs.clang
pkgs.llvmPackages.bintools
pkgs.rustup
(import ./vargo.nix { inherit pkgs; })
];


text = ''
VERUS_Z3_PATH=$(which z3)
export VERUS_Z3_PATH


export PATH=$PATH:~/.cargo/bin
export PATH=$PATH:~/.rutup/toolchains/${RUSTC_VERSION}-x86_64-unknown-linux-gnu/bin/


vargo build --release
'';
};
in {
vargo-br = {
type = "app";
program = "${vargoWithRustup}/bin/vargo";
};
});
};
}
28 changes: 28 additions & 0 deletions vargo.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--- vargo/src/main.rs 2024-07-05 20:51:28.181535045 +0200
+++ vargo/src/main.rs 2024-07-05 20:52:04.385986052 +0200
@@ -5,8 +5,11 @@
// `target/debug` or `target/release` when they are the main build target, and
// not when they're a dependency of another target.

-#[path = "../../common/consts.rs"]
-mod consts;
+
+mod consts {
+ pub const EXPECTED_Z3_VERSION: &str = "4.12.5";
+ pub const EXPECTED_CVC5_VERSION: &str = "1.1.2";
+}

const MINIMUM_VERUSFMT_VERSION: [u64; 3] = [0, 3, 0];

@@ -289,11 +291,6 @@
let cur_hash = &crate::util::hash_file_contents(
files.iter().map(|(f, n)| (f.as_str(), &n[..])).collect(),
);
- if build_hash != cur_hash {
- return Err(format!(
- "vargo sources have changed since it was last built, please re-build vargo"
- ));
- }
}

let rust_toolchain_toml_channel = rust_toolchain_toml.get("toolchain").and_then(|t| t.get("channel"))
22 changes: 22 additions & 0 deletions vargo.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
pkgs
}: pkgs.rustPlatform.buildRustPackage {
pname = "vargo";
version = "0.1.0";

src = pkgs.lib.cleanSource ./tools/vargo;
cargoLock.lockFile = ./tools/vargo/Cargo.lock; # yes, this does not use the rust toolchain

patches = [ ./vargo.diff ];
# it references a file outside the vargo dir which is just a headache... don't forget to update it if needed
# oh and maybe just remove the entire "toolchain-check"! (although I'd prefer if that worked with the specified Cargo.lock)

meta = {
description = "Verus is a tool for verifying the correctness of code written in Rust.";
homepage = "https://github.com/verus-lang/verus";
license = pkgs.lib.licenses.mit;
};
}

# docs for packaging this:
# https://m7.rs/blog/2022-11-01-package-a-rust-app-with-nix/index.html