diff --git a/.bazelrc b/.bazelrc index bde5ec6be..6b8968e35 100644 --- a/.bazelrc +++ b/.bazelrc @@ -83,6 +83,9 @@ try-import %workspace%/lre.bazelrc # Generated by the darwin flake module. try-import %workspace%/darwin.bazelrc +# Generated by the NixOS flake module. +try-import %workspace%/nixos.bazelrc + # Generated by the nativelink flake module. try-import %workspace%/nativelink.bazelrc diff --git a/.envrc b/.envrc index 2f8e1d3f7..cffc922b0 100644 --- a/.envrc +++ b/.envrc @@ -1 +1 @@ -use flake --impure +use flake . --impure diff --git a/.gitignore b/.gitignore index 66d402011..a3a6384fe 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ MODULE.bazel.lock trivy-results.sarif Pulumi.dev.yaml lre.bazelrc +nixos.bazelrc rust-project.json darwin.bazelrc nativelink.bazelrc diff --git a/flake.nix b/flake.nix index 97bafac3a..693842b6a 100644 --- a/flake.nix +++ b/flake.nix @@ -43,6 +43,7 @@ inputs.git-hooks.flakeModule ./local-remote-execution/flake-module.nix ./tools/darwin/flake-module.nix + ./tools/nixos/flake-module.nix ./flake-module.nix ]; perSystem = { @@ -463,6 +464,16 @@ else lre-cc.meta.Env; prefix = "linux"; }; + nixos.settings = { + path = with pkgs; [ + "/run/current-system/sw/bin" + "${binutils.bintools}/bin" + "${uutils-coreutils-noprefix}/bin" + "${customClang}/bin" + "${git}/bin" + "${python3}/bin" + ]; + }; devShells.default = pkgs.mkShell { nativeBuildInputs = let bazel = pkgs.writeShellScriptBin "bazel" '' @@ -531,6 +542,13 @@ # to NativeLink's read-only cache. ${config.nativelink.installationScript} + # If on NixOS, generate nixos.bazelrc which adds the required + # NixOS binary paths to the bazel environment. + if [ -e /etc/nixos ]; then + ${config.nixos.installationScript} + export CC=customClang + fi + # The Bazel and Cargo builds in nix require a Clang toolchain. # TODO(aaronmondal): The Bazel build currently uses the # irreproducible host C++ toolchain. Provide @@ -556,6 +574,7 @@ default = ./flake-module.nix; darwin = ./tools/darwin/flake-module.nix; local-remote-execution = ./local-remote-execution/flake-module.nix; + nixos = ./tools/nixos/flake-module.nix; }; }; } diff --git a/tools/nixos/flake-module.nix b/tools/nixos/flake-module.nix new file mode 100644 index 000000000..4f643dc25 --- /dev/null +++ b/tools/nixos/flake-module.nix @@ -0,0 +1,44 @@ +{ + lib, + flake-parts-lib, + ... +}: { + options = { + perSystem = flake-parts-lib.mkPerSystemOption ( + { + config, + options, + pkgs, + ... + }: let + cfg = config.nixos; + in { + options = { + nixos = { + pkgs = lib.mkOption { + type = lib.types.uniq (lib.types.lazyAttrsOf (lib.types.raw or lib.types.unspecified)); + description = "Nixpkgs to use."; + default = pkgs; + defaultText = lib.literalMD "`pkgs` (module argument)"; + }; + settings = lib.mkOption { + type = lib.types.submoduleWith { + modules = [./modules/nixos.nix]; + specialArgs = {inherit (cfg) pkgs;}; + }; + default = {}; + description = "Configuration for Bazel on NixOS."; + }; + installationScript = lib.mkOption { + type = lib.types.str; + description = "Create nixos.bazelrc."; + default = cfg.settings.installationScript; + defaultText = lib.literalMD "bazelrc content"; + readOnly = true; + }; + }; + }; + } + ); + }; +} diff --git a/tools/nixos/modules/nixos.nix b/tools/nixos/modules/nixos.nix new file mode 100644 index 000000000..2a246a588 --- /dev/null +++ b/tools/nixos/modules/nixos.nix @@ -0,0 +1,54 @@ +{ + config, + lib, + pkgs, + ... +}: let + pathString = builtins.concatStringsSep ":" config.path; + bazelrc = pkgs.writeText "nixos.bazelrc" '' + build --action_env=PATH=${pathString} + build --host_action_env=PATH=${pathString} + ''; +in { + options = { + installationScript = lib.mkOption { + type = lib.types.str; + description = "A bash snippet which creates a nixos.bazelrc file in the + repository."; + }; + path = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "List of paths to include in the Bazel environment."; + }; + }; + config = { + installationScript = '' + if ! type -t git >/dev/null; then + # In pure shells + echo 1>&2 "WARNING: nixos: git command not found; skipping installation." + elif ! ${pkgs.git}/bin/git rev-parse --git-dir &> /dev/null; then + echo 1>&2 "WARNING: nixos: .git not found; skipping installation." + else + GIT_WC=`${pkgs.git}/bin/git rev-parse --show-toplevel` + + # These update procedures compare before they write, to avoid + # filesystem churn. This improves performance with watch tools like + # lorri and prevents installation loops by lorri. + + if ! readlink "''${GIT_WC}/nixos.bazelrc" >/dev/null \ + || [[ $(readlink "''${GIT_WC}/nixos.bazelrc") != ${bazelrc} ]]; then + echo 1>&2 "nixos: updating $PWD repository" + [ -L nixos.bazelrc ] && unlink nixos.bazelrc + + if [ -e "''${GIT_WC}/nixos.bazelrc" ]; then + echo 1>&2 "nixos: WARNING: Refusing to install because of pre-existing nixos.bazelrc" + echo 1>&2 " Remove the nixos.bazelrc file and add nixos.bazelrc to .gitignore." + else + ln -fs ${bazelrc} "''${GIT_WC}/nixos.bazelrc" + fi + fi + fi + ''; + }; +} diff --git a/web/platform/src/content/docs/docs/contribute/nix.mdx b/web/platform/src/content/docs/docs/contribute/nix.mdx index 704dd23cb..cd5c6e14b 100644 --- a/web/platform/src/content/docs/docs/contribute/nix.mdx +++ b/web/platform/src/content/docs/docs/contribute/nix.mdx @@ -49,3 +49,12 @@ To view the tag of an image ```sh nix eval github:TraceMachina/nativelink#image.imageTag --raw ``` + +## On NixOS + +If you're on NixOS, add the following to your system configuration: + +```nix +programs.nix-ld.enable = true; +services.envfs.enable = true; +```