I’m trying to setup a development environment for out team. The requirements are as follows:
- Host OS is Ubuntu 24.04, nix is installed in
single-user-mode
(due to some IT restrictions). - flake-based with
nix-direnv
for ease of use. - C++ application, i.e. compiler, build system etc. need to be setup, as well as conan to compile dependencies.
A basic version of this looks currently like this (very much based on this):
{
description = "A Nix-flake-based C/C++ development environment";
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz";
outputs = { self, nixpkgs }:
let
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f system);
in
{
devShells = forEachSupportedSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in {
default = pkgs.mkShell.override
{
# Override stdenv in order to change compiler:
# stdenv = pkgs.clangStdenv;
}
{
packages = let
pkgs_clang_tools = import (builtins.fetchGit {
name = "clang_tools";
url = "https://github.com/NixOS/nixpkgs/";
ref = "refs/heads/nixos-unstable";
rev = "47c1824c261a343a6acca36d168a0a86f0e66292";
}) {inherit system;};
in [
pkgs_clang_tools.llvmPackages_15.clang-tools
pkgs_clang_tools.llvmPackages_15.clang
pkgs.cmake
pkgs.conan
pkgs.doxygen
pkgs.ninja
];
};
});
};
}
This works quite nicely, i.e. I can use all the tools I need and a small test application seems to compile just fine.
My problem is currently that some of the dependencies that we build have “system dependencies”, i.e. things that package expects the host to provide which are not really managed by a C++ dependency manager. To make a specific example: we use Qt6, which in turn has a list of dependencies, which you on Ubuntu normally install over
apt install \
libfontconfig1-dev \
libfreetype-dev \
libx11-dev \
libx11-xcb-dev \
libxcb-cursor-dev \
libxcb-glx0-dev \
libxcb-icccm4-dev \
libxcb-image0-dev \
libxcb-keysyms1-dev \
libxcb-randr0-dev \
libxcb-render-util0-dev \
libxcb-shape0-dev \
libxcb-shm0-dev \
libxcb-sync-dev \
libxcb-util-dev \
libxcb-xfixes0-dev \
libxcb-xinerama0-dev \
libxcb-xkb-dev \
libxcb1-dev \
libxext-dev \
libxfixes-dev \
libxi-dev \
libxkbcommon-dev \
libxkbcommon-x11-dev \
libxrender-dev
Now, if I understand nix
s role as package manager correctly then it should be able to replace this part of apt
as well. What I dont want to use is the qt6
version that nixpkgs
provides, we need to compile it ourselves, i.e. I need to find all these dependencies.
This is ofc. fine by me (especially since there is already a qt6
package (see here)), but before I start on this quest I wanted to check if this is the “correct” way to create such a development environment. I’m aware that there are probably more than one way to do this, and using a independent package manager like conan
defeats the purpose of nix to some degree, but what we are looking for is a way to quickly setup a reproducible development environment. Should nix be used for something like this? Is this too little commitment?
I’ve played around with nix for a few months and used it to configure development environments, but this Qt
thingy is certainly a bit more complicated than Im used to.