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

Use Nix for reproducible environments? #57

Closed
will-ca opened this issue Nov 30, 2022 · 7 comments
Closed

Use Nix for reproducible environments? #57

will-ca opened this issue Nov 30, 2022 · 7 comments
Labels
common Things common to all implementations enhancement New feature or request

Comments

@will-ca
Copy link
Contributor

will-ca commented Nov 30, 2022

I got the below error trying to run the Zig version:

./build.zig:22:8: error: no member named 'addLibraryPath' in struct 'std.build.LibExeObjStep'
    exe.addLibraryPath("/Users/shish2k/homebrew/lib/");
       ^
./lib/sdl/Sdk.zig:139:63: error: expected type 'std.mem.Allocator', found 'std.zig.CrossTarget'
    const target = (std.zig.system.NativeTargetInfo.detect(exe.target) catch @panic("failed to detect native target info!")).target;
                                                              ^
/usr/lib/zig/std/mem/Allocator.zig:1:1: note: std.mem.Allocator declared here
//! The standard memory allocation interface.
^
/usr/lib/zig/std/zig/CrossTarget.zig:1:1: note: std.zig.CrossTarget declared here
//! Contains all the same data as `Target`, additionally introducing the concept of "the native target".
^
./lib/sdl/Sdk.zig:86:9: error: no member named 'source' in struct 'std.build.Pkg'
        .source = .{ .path = sdkPath("/src/wrapper/sdl.zig") },
        ^

Rather than endlessly trying to keep track of libraries, version incompatibilities, etc., I think Nix can be used to declaratively define reproducible, self-contained development environments as needed.

For example, I have the below shell.nix file for the Python version:

{ pkgs ? import <nixpkgs> {} } : pkgs.mkShell {
	buildInputs = with pkgs; [
		(python310.withPackages (pypkgs: with pypkgs; [
			pysdl2
			setuptools
			
			mypy
			black
		])).out
	];
}

(To read this if you haven't looked into Nix before: The language is functional. Colons are function definitions, with signature to the left and the return expression to the right. Calls are names followed by a space and then argument. With makes names from a mapping available in the subsequent scope. Lists are whitespace-separated, and curly braces are mappings. — The root expression is a function that takes the argument pkgs (or actually uses the default value import <nixpkgs> {}) and returns an environment, and the argument passed to .withPackages is a function that takes the argument pypkgs and returns a list of Python packages.)

And then, anyone on any distro of Linux or MacOS can just run $ nix-shell in the terminal to get the exact right development environment. The packages are stored entirely self-contained in /nix, and symlinked in ~/.nix-profile or added to $PATH as requested.

For perfect reproducibility, the packages used can be pinned to a specific version by downloading from a specific commit in the nixpkgs respository. So this way, if you specify a version of a library or language that works on your machine, anyone else running it will get the exact same version.

{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/facfd565093c8f410be840dc427975a6d7368f91.tar.gz") {} } : pkgs.mkShell {
	buildInputs = [];
}

More info:

https://nixos.org/guides/declarative-and-reproducible-developer-environments.html

I'm not trying to evangelize. I bring this up as somebody who is reluctant to modify my global computing environment for a local requirement— I.E. I'm not going to change my system Zig, set up venvs everywhere, or install new pip packages just to run this, so I was just thinking it'd be useful if a declarative ad-hoc environment were provided.

I do see there's already something similar with Docker/Podman, which I guess fills the same purpose. But that seems heavier (pulling in a whole Debian, looks like?), and involves more permissions and system configuration to set up. — FWIW, Nix can also be used to generate Docker images, and it looks like there's a Nix image on Docker (though I haven't tried either).

Anyway, it's just an idea.

@shish
Copy link
Owner

shish commented Nov 30, 2022

Having nix as an alternative to docker for self-contained reproducible environments seems reasonable - I've no idea how that works, but pull requests would be welcome :)

(I expect we'd still want the Docker image for windows users to have a reproducible dev environment, as it seems nix doesn't work there?)

@rrbutani
Copy link
Contributor

I started putting together a flake for this repo last month; it's since fallen out of date (and I only got as far as doing C++/Rust/Zig/Go) but if there's interest and if it looks like something that upstream would accept I'm happy to update it and add Nim/PHP/Python support.

@shish shish added enhancement New feature or request common Things common to all implementations labels Dec 2, 2022
@shish
Copy link
Owner

shish commented Dec 2, 2022

I have interest \o/

Especially if utils/shell.sh was updated to use nix if that's installed, else use docker if that's installed, else error -- then the docs can be "use this script to get a self-contained dev environment in whatever way is appropriate for your system"

@shish
Copy link
Owner

shish commented Dec 2, 2022

(There should probably also be a shell.bat for windows users, but that's an issue for another time...)

@will-ca
Copy link
Contributor Author

will-ca commented Dec 3, 2022

Just FYI I've got a branch where I've set up a working shell.nix for all of the implementations except for Zig (which I think I did, but still need to test/finish), as well as a global shell.nix that imports and combines every language implementation together. Will finish off and then PR with details later.

Do all the languages work well on Windows?

@shish
Copy link
Owner

shish commented Dec 3, 2022

AFAIK all the languages should work on windows, but I've only personally used linux and macos

@shish
Copy link
Owner

shish commented Dec 31, 2022

closing this as nix is now my main development method for mac-based development

(though if somebody wants to put up a PR showing how flakes would work and why they're better, that would be interesting too)

@shish shish closed this as completed Dec 31, 2022
@rrbutani rrbutani mentioned this issue Jan 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
common Things common to all implementations enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants