Hi Nix community, I am fairly new to Nix and even newer to nix flakes (have been using shell.nix for awhile) and I like how the devShell in the flake is structured hence venturing into flakes. I’ve manage to create a simple devShell with CMake, gcc-12 and Boost but I was wondering how do I go about creating a default.nix that inherits the system and buildInputs from the devShell of the flake and has a buildPhase that runs a simple command to compile and link to boost for the boost::format() in my executable. This is how my flake is currently set up:
{
description = "A simple development environment with g++ for x86-64 Linux and ARM-based MacBooks";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/master";
utils.url = "github:numtide/flake-utils";
utils.inputs.nixpkgs.follows = "nixpkgs";
};
# This is for running on X86-64 Linux (the norm), Intel and M1 Macs.
outputs = { self, nixpkgs, ... }@inputs: inputs.utils.lib.eachSystem [
"x86_64-linux" "x86_64-darwin" "aarch64-darwin"
] (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShell = pkgs.mkShell {
buildInputs = [
pkgs.gcc12
pkgs.cmake
pkgs.boost180
];
shellHook = ''
echo "Welcome to the Nix g++ development environment!"
'';
};
}
);
}
The executable just includes boost/format.hpp and does a std::cout with that formatted string.
I was hoping to create a default.nix that could inherit the system and devShell buildInputs so that I don’t have to redefine them again and also keep track of them in place.
You would typically do the opposite. Create a package derivation first, and then make a shell from it, e.g. using inputsFrom attribute.
And since you are already using Flakes, I would create a packages output rather than use default.nix. If you really want to have a fallback for the legacy nix-build command, you can use flake-compat shim.
Ok I followed the recommendation and tried to add a packages.${system}.default below the devShell and get this error: error: flake does not provide attribute ‘packages.x86_64-linux.default’ or ‘defaultPackage.x86_64-linux’ when I try to run nix build
{
description = "A simple development environment with g++ for x86-64 Linux and ARM-based MacBooks";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/master";
utils.url = "github:numtide/flake-utils";
utils.inputs.nixpkgs.follows = "nixpkgs";
};
# This is for running on X86-64 Linux (the norm), Intel and M1 Macs.
outputs = { self, nixpkgs, ... }@inputs: inputs.utils.lib.eachSystem [
"x86_64-linux" "x86_64-darwin" "aarch64-darwin"
] (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShell = pkgs.mkShell {
buildInputs = [
pkgs.gcc12
pkgs.cmake
pkgs.boost180
];
shellHook = ''
echo "Welcome to the Nix g++ development environment!"
'';
};
packages.${system}.default =
with import nixpkgs { inherit system; };
stdenv.mkDerivation {
name = "nix_testing";
src = self;
inputsFrom = [ devShell.buildInputs ];
buildPhase = "g++ ./nix_testing.cpp -o nix_testing";
installPhase = "echo Installing";
};
}
);
}
You are passing that definition to inputs.utils.lib.eachSystem function so you do not need to specify the system again – just use packages.default like you use devShells.default.