Skip to content

Commit 0fd237d

Browse files
kuznetsssCopilot
andauthored
chore: Add nix development environment (#6314)
--------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 3542daa commit 0fd237d

File tree

10 files changed

+318
-1
lines changed

10 files changed

+318
-1
lines changed

.github/workflows/pre-commit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ jobs:
1414
uses: XRPLF/actions/.github/workflows/pre-commit.yml@320be44621ca2a080f05aeb15817c44b84518108
1515
with:
1616
runs_on: ubuntu-latest
17-
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-ab4d1f0" }'
17+
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }'

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ gmon.out
4242
# Locally patched Conan recipes
4343
external/conan-center-index/
4444

45+
# Local conan directory
46+
.conan
47+
4548
# XCode IDE.
4649
*.pbxuser
4750
!default.pbxuser
@@ -72,5 +75,8 @@ DerivedData
7275
/.claude
7376
/CLAUDE.md
7477

78+
# Direnv's directory
79+
/.direnv
80+
7581
# clangd cache
7682
/.cache

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ repos:
5757
- .git/COMMIT_EDITMSG
5858
stages: [commit-msg]
5959

60+
- repo: local
61+
hooks:
62+
- id: nix-fmt
63+
name: Format Nix files
64+
entry: nix --extra-experimental-features 'nix-command flakes' fmt
65+
language: system
66+
types:
67+
- nix
68+
pass_filenames: true
69+
6070
exclude: |
6171
(?x)^(
6272
external/.*|

cspell.config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ words:
173173
- nftokens
174174
- nftpage
175175
- nikb
176+
- nixfmt
177+
- nixos
178+
- nixpkgs
176179
- nonxrp
177180
- noripple
178181
- nudb

docs/build/environment.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ environment complete with Git, Python, Conan, CMake, and a C++ compiler.
33
This document exists to help readers set one up on any of the Big Three
44
platforms: Linux, macOS, or Windows.
55

6+
As an alternative to system packages, the Nix development shell can be used to provide a development environment. See [using nix development shell](./nix.md) for more details.
7+
68
[BUILD.md]: ../../BUILD.md
79

810
## Linux

docs/build/nix.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Using Nix Development Shell for xrpld Development
2+
3+
This guide explains how to use Nix to set up a reproducible development environment for xrpld. Using Nix eliminates the need to manually install utilities and ensures consistent tooling across different machines.
4+
5+
## Benefits of Using Nix
6+
7+
- **Reproducible environment**: Everyone gets the same versions of tools and compilers
8+
- **No system pollution**: Dependencies are isolated and don't affect your system packages
9+
- **Multiple compiler versions**: Easily switch between different GCC and Clang versions
10+
- **Quick setup**: Get started with a single command
11+
- **Works on Linux and macOS**: Consistent experience across platforms
12+
13+
## Install Nix
14+
15+
Please follow [the official installation instructions of nix package manager](https://nixos.org/download/) for your system.
16+
17+
## Entering the Development Shell
18+
19+
### Basic Usage
20+
21+
From the root of the xrpld repository, enter the default development shell:
22+
23+
```bash
24+
nix --experimental-features 'nix-command flakes' develop
25+
```
26+
27+
This will:
28+
29+
- Download and set up all required development tools (CMake, Ninja, Conan, etc.)
30+
- Configure the appropriate compiler for your platform:
31+
- **macOS**: Apple Clang (default system compiler)
32+
- **Linux**: GCC 15
33+
34+
The first time you run this command, it will take a few minutes to download and build the environment. Subsequent runs will be much faster.
35+
36+
> [!TIP]
37+
> To avoid typing `--experimental-features 'nix-command flakes'` every time, you can permanently enable flakes by creating `~/.config/nix/nix.conf`:
38+
>
39+
> ```bash
40+
> mkdir -p ~/.config/nix
41+
> echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
42+
> ```
43+
>
44+
> After this, you can simply use `nix develop` instead.
45+
46+
> [!NOTE]
47+
> The examples below assume you've enabled flakes in your config. If you haven't, add `--experimental-features 'nix-command flakes'` after each `nix` command.
48+
49+
### Choosing a different compiler
50+
51+
A compiler can be chosen by providing its name with the `.#` prefix, e.g. `nix develop .#gcc15`.
52+
Use `nix flake show` to see all the available development shells.
53+
54+
Use `nix develop .#no_compiler` to use the compiler from your system.
55+
56+
### Example Usage
57+
58+
```bash
59+
# Use GCC 14
60+
nix develop .#gcc14
61+
62+
# Use Clang 19
63+
nix develop .#clang19
64+
65+
# Use default for your platform
66+
nix develop
67+
```
68+
69+
### Using a different shell
70+
71+
`nix develop` opens bash by default. If you want to use another shell this could be done by adding `-c` flag. For example:
72+
73+
```bash
74+
nix develop -c zsh
75+
```
76+
77+
## Building xrpld with Nix
78+
79+
Once inside the Nix development shell, follow the standard [build instructions](../../BUILD.md#steps). The Nix shell provides all necessary tools (CMake, Ninja, Conan, etc.).
80+
81+
## Automatic Activation with direnv
82+
83+
[direnv](https://direnv.net/) or [nix-direnv](https://github.com/nix-community/nix-direnv) can automatically activate the Nix development shell when you enter the repository directory.
84+
85+
## Conan and Prebuilt Packages
86+
87+
Please note that there is no guarantee that binaries from conan cache will work when using nix. If you encounter any errors, please use `--build '*'` to force conan to compile everything from source:
88+
89+
```bash
90+
conan install .. --output-folder . --build '*' --settings build_type=Release
91+
```
92+
93+
## Updating `flake.lock` file
94+
95+
To update `flake.lock` to the latest revision use `nix flake update` command.

flake.lock

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
description = "Nix related things for xrpld";
3+
inputs = {
4+
nixpkgs.url = "nixpkgs/nixos-unstable";
5+
};
6+
7+
outputs =
8+
{ nixpkgs, ... }:
9+
let
10+
forEachSystem = (import ./nix/utils.nix { inherit nixpkgs; }).forEachSystem;
11+
in
12+
{
13+
devShells = forEachSystem (import ./nix/devshell.nix);
14+
formatter = forEachSystem ({ pkgs, ... }: pkgs.nixfmt);
15+
};
16+
}

nix/devshell.nix

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
{ pkgs, ... }:
2+
let
3+
commonPackages = with pkgs; [
4+
ccache
5+
cmake
6+
conan
7+
gcovr
8+
git
9+
gnumake
10+
llvmPackages_21.clang-tools
11+
ninja
12+
perl # needed for openssl
13+
pkg-config
14+
pre-commit
15+
python314
16+
];
17+
18+
# Supported compiler versions
19+
gccVersion = pkgs.lib.range 13 15;
20+
clangVersions = pkgs.lib.range 18 21;
21+
22+
defaultCompiler = if pkgs.stdenv.isDarwin then "apple-clang" else "gcc";
23+
defaultGccVersion = pkgs.lib.last gccVersion;
24+
defaultClangVersion = pkgs.lib.last clangVersions;
25+
26+
strToCompilerEnv =
27+
compiler: version:
28+
(
29+
if compiler == "gcc" then
30+
let
31+
gccPkg = pkgs."gcc${toString version}Stdenv" or null;
32+
in
33+
if gccPkg != null && builtins.elem version gccVersion then
34+
gccPkg
35+
else
36+
throw "Invalid GCC version: ${toString version}. Must be one of: ${toString gccVersion}"
37+
else if compiler == "clang" then
38+
let
39+
clangPkg = pkgs."llvmPackages_${toString version}".stdenv or null;
40+
in
41+
if clangPkg != null && builtins.elem version clangVersions then
42+
clangPkg
43+
else
44+
throw "Invalid Clang version: ${toString version}. Must be one of: ${toString clangVersions}"
45+
else if compiler == "apple-clang" || compiler == "none" then
46+
pkgs.stdenvNoCC
47+
else
48+
throw "Invalid compiler: ${compiler}. Must be one of: gcc, clang, apple-clang, none"
49+
);
50+
51+
# Helper function to create a shell with a specific compiler
52+
makeShell =
53+
{
54+
compiler ? defaultCompiler,
55+
version ? (
56+
if compiler == "gcc" then
57+
defaultGccVersion
58+
else if compiler == "clang" then
59+
defaultClangVersion
60+
else
61+
null
62+
),
63+
}:
64+
let
65+
compilerStdEnv = strToCompilerEnv compiler version;
66+
67+
compilerName =
68+
if compiler == "apple-clang" then
69+
"clang"
70+
else if compiler == "none" then
71+
null
72+
else
73+
compiler;
74+
75+
gccOnMacWarning =
76+
if pkgs.stdenv.isDarwin && compiler == "gcc" then
77+
''
78+
echo "WARNING: Using GCC on macOS with Conan may not work."
79+
echo " Consider using 'nix develop .#clang' or the default shell instead."
80+
echo ""
81+
''
82+
else
83+
"";
84+
85+
compilerVersion =
86+
if compilerName != null then
87+
''
88+
echo "Compiler: "
89+
${compilerName} --version
90+
''
91+
else
92+
''
93+
echo "No compiler specified - using system compiler"
94+
'';
95+
96+
shellAttrs = {
97+
packages = commonPackages;
98+
99+
shellHook = ''
100+
echo "Welcome to xrpld development shell";
101+
${gccOnMacWarning}${compilerVersion}
102+
'';
103+
};
104+
in
105+
pkgs.mkShell.override { stdenv = compilerStdEnv; } shellAttrs;
106+
107+
# Generate shells for each compiler version
108+
gccShells = builtins.listToAttrs (
109+
map (version: {
110+
name = "gcc${toString version}";
111+
value = makeShell {
112+
compiler = "gcc";
113+
version = version;
114+
};
115+
}) gccVersion
116+
);
117+
118+
clangShells = builtins.listToAttrs (
119+
map (version: {
120+
name = "clang${toString version}";
121+
value = makeShell {
122+
compiler = "clang";
123+
version = version;
124+
};
125+
}) clangVersions
126+
);
127+
128+
in
129+
gccShells
130+
// clangShells
131+
// {
132+
# Default shells
133+
default = makeShell { };
134+
gcc = makeShell { compiler = "gcc"; };
135+
clang = makeShell { compiler = "clang"; };
136+
137+
# No compiler
138+
no-compiler = makeShell { compiler = "none"; };
139+
apple-clang = makeShell { compiler = "apple-clang"; };
140+
}

nix/utils.nix

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{ nixpkgs }:
2+
{
3+
forEachSystem =
4+
function:
5+
nixpkgs.lib.genAttrs
6+
[
7+
"x86_64-linux"
8+
"aarch64-linux"
9+
"x86_64-darwin"
10+
"aarch64-darwin"
11+
]
12+
(
13+
system:
14+
function {
15+
inherit system;
16+
pkgs = import nixpkgs { inherit system; };
17+
}
18+
);
19+
}

0 commit comments

Comments
 (0)