Skip to content

Add Nix Flake devshell + direnv#432

Open
thebrandonlucas wants to merge 1 commit into
roc-lang:mainfrom
thebrandonlucas:nix-dev-shell
Open

Add Nix Flake devshell + direnv#432
thebrandonlucas wants to merge 1 commit into
roc-lang:mainfrom
thebrandonlucas:nix-dev-shell

Conversation

@thebrandonlucas

@thebrandonlucas thebrandonlucas commented Jul 16, 2026

Copy link
Copy Markdown

flake.nix was removed from #413 to avoid bundling another change into that large PR.

I've added back the flake.nix as mentioned here removing unnecessary tools and adding new ones (Zig 16, etc.). One problem I ran into was that while the old flake.nix was able to just use the standard Roc compiler from unstable nixpkgs, that doesn't work for the new compiler because it's unreleased on nixpkgs. To solve that here we'd have to pin a particular nightly release and just keep basic-cli up to date with it, modifying the flake with every incompatibility.

That seemed like too much overhead to be worth it, and I felt that this must be a general pain point for other projects, so I created roc-overlay to solve this problem for this and other projects that wish to use it. It's modeled after zig-overlay and is useful for any project which intends to keep up with the latest nightly compilers (or pin themselves to previous ones). More here.

Updated CONTRIBUTING.md to add the section about using Nix for the development environment. We could probably also take advantage of this to simplify CI (and have a single source of truth) once roc-overlay proves it's mettle a bit more.

I also added direnv which is a great convenience tool for automatically loading dev environments upon shell entry. It requires manual activation by the user once, then subsequently loads the shell with all appropriate dependencies thereafter.

Comment thread rust-toolchain.toml

channel = "1.83.0" # check ^^^ when changing this
components = ["rust-analyzer"]
components = ["rust-analyzer", "llvm-tools-preview"]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Support host stripping performed in scripts/build.py

Comment thread scripts/build.py
Comment on lines +120 to 145
def rust_target_is_installed(rust_target: str) -> bool:
result = subprocess.run(
["rustc", "--print", "target-libdir", "--target", rust_target],
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
text=True,
)
return result.returncode == 0 and Path(result.stdout.strip()).is_dir()


def install_rust_target(rust_target: str, *, required: bool = False) -> None:
if rust_target_is_installed(rust_target):
return

if shutil.which("rustup") is None:
message = (
f"Rust target {rust_target} is not installed and rustup is unavailable; "
"enter `nix develop` or install the target manually"
)
if required:
raise SystemExit(message)
print(f"warning: {message}")
return

run("rustup", "target", "add", rust_target, check=required)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously we assumed Rust targets were always managed bu rustup and unconditionally ran this every time, even if the target was already installed. Nix manages this via the nix store and does not use this rustup. So this would fail with rustup: command not found even if all the targets were available. By using rustc to ask where the target libraries should be, then verifying it exists there via result.returncode == 0 and Path(result.stdout.strip()).is_dir(), we maintain backward compat for non-nix users.

@thebrandonlucas
thebrandonlucas marked this pull request as ready for review July 16, 2026 14:33
Restores and updates the old flake.nix to add a post-Zig
migration devshell. Also adds direnv for automatic env
loading upon entering the directory.

Since Zig compiler has no stable release yet, this uses
roc-overlay to always use latest nightly roc compiler,
so the user doesn't have to continuously download
nightly.

Adds checks to scripts/build.py to not download the
rust toolchain on every build if it already exists,
and to allow interop with Nix users and backward
compatibility for non Nix users.

Also updates CONTRIBUTING.md with new Nix usage section.

docs: note required Nix features
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant