aboutsummaryrefslogtreecommitdiff
path: root/nix/compile.nix
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2023-04-25 12:34:26 +0200
committerAlex Auvolat <alex@adnab.me>2023-04-25 12:34:26 +0200
commitfa78d806e3ae40031e80eebb86e4eb1756d7baea (patch)
tree144662fb430c484093f6f9a585a2441c2ff26494 /nix/compile.nix
parent654999e254e6c1f46bb5d668bc1230f226575716 (diff)
parenta16eb7e4b8344d2f58c09a249b7b1bd17d339a35 (diff)
downloadgarage-fa78d806e3ae40031e80eebb86e4eb1756d7baea.tar.gz
garage-fa78d806e3ae40031e80eebb86e4eb1756d7baea.zip
Merge branch 'main' into next
Diffstat (limited to 'nix/compile.nix')
-rw-r--r--nix/compile.nix417
1 files changed, 215 insertions, 202 deletions
diff --git a/nix/compile.nix b/nix/compile.nix
index 3ea5035e..54e920db 100644
--- a/nix/compile.nix
+++ b/nix/compile.nix
@@ -1,227 +1,240 @@
-{
- system,
- target ? null,
- pkgsSrc,
- cargo2nixOverlay,
- compiler ? "rustc",
- release ? false,
- git_version ? null,
- features ? null,
-}:
+{ system, target ? null, pkgsSrc, cargo2nixOverlay, compiler ? "rustc"
+, release ? false, git_version ? null, features ? null, }:
let
log = v: builtins.trace v v;
- pkgs =
- if target != null then
- import pkgsSrc {
- inherit system;
- crossSystem = {
- config = target;
- isStatic = true;
- };
- overlays = [ cargo2nixOverlay ];
- }
- else
- import pkgsSrc {
- inherit system;
- overlays = [ cargo2nixOverlay ];
+ pkgs = if target != null then
+ import pkgsSrc {
+ inherit system;
+ crossSystem = {
+ config = target;
+ isStatic = true;
};
+ overlays = [ cargo2nixOverlay ];
+ }
+ else
+ import pkgsSrc {
+ inherit system;
+ overlays = [ cargo2nixOverlay ];
+ };
- /*
- Cargo2nix is built for rustOverlay which installs Rust from Mozilla releases.
- This is fine for 64-bit platforms, but for 32-bit platforms, we need our own Rust
- to avoid incompatibilities with time_t between different versions of musl
- (>= 1.2.0 shipped by NixOS, < 1.2.0 with which rustc was built), which lead to compilation breakage.
- So we want a Rust release that is bound to our Nix repository to avoid these problems.
- See here for more info: https://musl.libc.org/time64.html
- Because Cargo2nix does not support the Rust environment shipped by NixOS,
- we emulate the structure of the Rust object created by rustOverlay.
- In practise, rustOverlay ships rustc+cargo in a single derivation while
- NixOS ships them in separate ones. We reunite them with symlinkJoin.
+ /* Cargo2nix is built for rustOverlay which installs Rust from Mozilla releases.
+ This is fine for 64-bit platforms, but for 32-bit platforms, we need our own Rust
+ to avoid incompatibilities with time_t between different versions of musl
+ (>= 1.2.0 shipped by NixOS, < 1.2.0 with which rustc was built), which lead to compilation breakage.
+ So we want a Rust release that is bound to our Nix repository to avoid these problems.
+ See here for more info: https://musl.libc.org/time64.html
+ Because Cargo2nix does not support the Rust environment shipped by NixOS,
+ we emulate the structure of the Rust object created by rustOverlay.
+ In practise, rustOverlay ships rustc+cargo in a single derivation while
+ NixOS ships them in separate ones. We reunite them with symlinkJoin.
*/
- toolchainOptions =
- if target == null || target == "x86_64-unknown-linux-musl" || target == "aarch64-unknown-linux-musl" then {
- rustVersion = "1.63.0";
- extraRustComponents = [ "clippy" ];
- } else {
- rustToolchain = pkgs.symlinkJoin {
- name = "rust-static-toolchain-${target}";
- paths = [
- pkgs.rustPlatform.rust.cargo
- pkgs.rustPlatform.rust.rustc
- # clippy not needed, it only runs on amd64
- ];
- };
+ toolchainOptions = if target == null || target == "x86_64-unknown-linux-musl"
+ || target == "aarch64-unknown-linux-musl" then {
+ rustVersion = "1.63.0";
+ extraRustComponents = [ "clippy" ];
+ } else {
+ rustToolchain = pkgs.symlinkJoin {
+ name = "rust-static-toolchain-${target}";
+ paths = [
+ pkgs.rustPlatform.rust.cargo
+ pkgs.rustPlatform.rust.rustc
+ # clippy not needed, it only runs on amd64
+ ];
};
+ };
+ buildEnv = (drv:
+ {
+ rustc = drv.setBuildEnv;
+ clippy = ''
+ ${drv.setBuildEnv or ""}
+ echo
+ echo --- BUILDING WITH CLIPPY ---
+ echo
+
+ export NIX_RUST_BUILD_FLAGS="''${NIX_RUST_BUILD_FLAGS} --deny warnings"
+ export RUSTC="''${CLIPPY_DRIVER}"
+ '';
+ }.${compiler});
+
+ /* Cargo2nix provides many overrides by default, you can take inspiration from them:
+ https://github.com/cargo2nix/cargo2nix/blob/master/overlay/overrides.nix
+
+ You can have a complete list of the available options by looking at the overriden object, mkcrate:
+ https://github.com/cargo2nix/cargo2nix/blob/master/overlay/mkcrate.nix
+ */
+ packageOverrides = pkgs:
+ pkgs.rustBuilder.overrides.all ++ [
+ /* [1] We add some logic to compile our crates with clippy, it provides us many additional lints
+
+ [2] We need to alter Nix hardening to make static binaries: PIE,
+ Position Independent Executables seems to be supported only on amd64. Having
+ this flag set either 1. make our executables crash or 2. compile as dynamic on some platforms.
+ Here, we deactivate it. Later (find `codegenOpts`), we reactivate it for supported targets
+ (only amd64 curently) through the `-static-pie` flag.
+ PIE is a feature used by ASLR, which helps mitigate security issues.
+ Learn more about Nix Hardening at: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/cc-wrapper/add-hardening.sh
+
+ [3] We want to inject the git version while keeping the build deterministic.
+ As we do not want to consider the .git folder as part of the input source,
+ we ask the user (the CI often) to pass the value to Nix.
+
+ [4] We don't want libsodium-sys and zstd-sys to try to use pkgconfig to build against a system library.
+ However the features to do so get activated for some reason (due to a bug in cargo2nix?),
+ so disable them manually here.
+ */
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage";
+ overrideAttrs = drv:
+ (if git_version != null then {
+ # [3]
+ preConfigure = ''
+ ${drv.preConfigure or ""}
+ export GIT_VERSION="${git_version}"
+ '';
+ } else
+ { }) // {
+ # [1]
+ setBuildEnv = (buildEnv drv);
+ # [2]
+ hardeningDisable = [ "pie" ];
+ };
+ })
+
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_rpc";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
- buildEnv = (drv: {
- rustc = drv.setBuildEnv;
- clippy = ''
- ${drv.setBuildEnv or "" }
- echo
- echo --- BUILDING WITH CLIPPY ---
- echo
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_db";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
- export NIX_RUST_BUILD_FLAGS="''${NIX_RUST_BUILD_FLAGS} --deny warnings"
- export RUSTC="''${CLIPPY_DRIVER}"
- '';
- }.${compiler});
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_util";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
- /*
- Cargo2nix provides many overrides by default, you can take inspiration from them:
- https://github.com/cargo2nix/cargo2nix/blob/master/overlay/overrides.nix
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_table";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
- You can have a complete list of the available options by looking at the overriden object, mkcrate:
- https://github.com/cargo2nix/cargo2nix/blob/master/overlay/mkcrate.nix
- */
- packageOverrides = pkgs: pkgs.rustBuilder.overrides.all ++ [
- /*
- [1] We add some logic to compile our crates with clippy, it provides us many additional lints
-
- [2] We need to alter Nix hardening to make static binaries: PIE,
- Position Independent Executables seems to be supported only on amd64. Having
- this flag set either 1. make our executables crash or 2. compile as dynamic on some platforms.
- Here, we deactivate it. Later (find `codegenOpts`), we reactivate it for supported targets
- (only amd64 curently) through the `-static-pie` flag.
- PIE is a feature used by ASLR, which helps mitigate security issues.
- Learn more about Nix Hardening at: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/cc-wrapper/add-hardening.sh
-
- [3] We want to inject the git version while keeping the build deterministic.
- As we do not want to consider the .git folder as part of the input source,
- we ask the user (the CI often) to pass the value to Nix.
-
- [4] We don't want libsodium-sys and zstd-sys to try to use pkgconfig to build against a system library.
- However the features to do so get activated for some reason (due to a bug in cargo2nix?),
- so disable them manually here.
- */
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage";
- overrideAttrs = drv:
- (if git_version != null then {
- /* [3] */ preConfigure = ''
- ${drv.preConfigure or ""}
- export GIT_VERSION="${git_version}"
- '';
- } else {})
- //
- {
- /* [1] */ setBuildEnv = (buildEnv drv);
- /* [2] */ hardeningDisable = [ "pie" ];
- };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_rpc";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_db";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_util";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_table";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_block";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_model";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_api";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_web";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "k2v-client";
- overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "libsodium-sys";
- overrideArgs = old: {
- features = [ ]; /* [4] */
- };
- })
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_block";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "zstd-sys";
- overrideArgs = old: {
- features = [ ]; /* [4] */
- };
- })
- ];
-
- /*
- We ship some parts of the code disabled by default by putting them behind a flag.
- It speeds up the compilation (when the feature is not required) and released crates have less dependency by default (less attack surface, disk space, etc.).
- But we want to ship these additional features when we release Garage.
- In the end, we chose to exclude all features from debug builds while putting (all of) them in the release builds.
- */
- rootFeatures = if features != null then features else
- ([
- "garage/bundled-libs"
- "garage/sled"
- "garage/k2v"
- ] ++ (if release then [
- "garage/consul-discovery"
- "garage/kubernetes-discovery"
- "garage/metrics"
- "garage/telemetry-otlp"
- "garage/lmdb"
- "garage/sqlite"
- ] else []));
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_model";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
+
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_api";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
+
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_web";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
+
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "k2v-client";
+ overrideAttrs = drv: { # [1]
+ setBuildEnv = (buildEnv drv);
+ };
+ })
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "libsodium-sys";
+ overrideArgs = old: {
+ features = [ ]; # [4]
+ };
+ })
+
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "zstd-sys";
+ overrideArgs = old: {
+ features = [ ]; # [4]
+ };
+ })
+ ];
+
+ /* We ship some parts of the code disabled by default by putting them behind a flag.
+ It speeds up the compilation (when the feature is not required) and released crates have less dependency by default (less attack surface, disk space, etc.).
+ But we want to ship these additional features when we release Garage.
+ In the end, we chose to exclude all features from debug builds while putting (all of) them in the release builds.
+ */
+ rootFeatures = if features != null then
+ features
+ else
+ ([ "garage/bundled-libs" "garage/sled" "garage/k2v" ] ++ (if release then [
+ "garage/consul-discovery"
+ "garage/kubernetes-discovery"
+ "garage/metrics"
+ "garage/telemetry-otlp"
+ "garage/lmdb"
+ "garage/sqlite"
+ ] else
+ [ ]));
packageFun = import ../Cargo.nix;
- /*
- We compile fully static binaries with musl to simplify deployment on most systems.
- When possible, we reactivate PIE hardening (see above).
+ /* We compile fully static binaries with musl to simplify deployment on most systems.
+ When possible, we reactivate PIE hardening (see above).
- Also, if you set the RUSTFLAGS environment variable, the following parameters will
- be ignored.
+ Also, if you set the RUSTFLAGS environment variable, the following parameters will
+ be ignored.
- For more information on static builds, please refer to Rust's RFC 1721.
- https://rust-lang.github.io/rfcs/1721-crt-static.html#specifying-dynamicstatic-c-runtime-linkage
+ For more information on static builds, please refer to Rust's RFC 1721.
+ https://rust-lang.github.io/rfcs/1721-crt-static.html#specifying-dynamicstatic-c-runtime-linkage
*/
codegenOpts = {
- "armv6l-unknown-linux-musleabihf" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* compile as dynamic with static-pie */
- "aarch64-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* segfault with static-pie */
- "i686-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* segfault with static-pie */
- "x86_64-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static-pie" ];
+ "armv6l-unknown-linux-musleabihf" = [
+ "target-feature=+crt-static"
+ "link-arg=-static"
+ ]; # compile as dynamic with static-pie
+ "aarch64-unknown-linux-musl" = [
+ "target-feature=+crt-static"
+ "link-arg=-static"
+ ]; # segfault with static-pie
+ "i686-unknown-linux-musl" = [
+ "target-feature=+crt-static"
+ "link-arg=-static"
+ ]; # segfault with static-pie
+ "x86_64-unknown-linux-musl" =
+ [ "target-feature=+crt-static" "link-arg=-static-pie" ];
};
- /*
- NixOS and Rust/Cargo triples do not match for ARM, fix it here.
- */
- rustTarget = if target == "armv6l-unknown-linux-musleabihf"
- then "arm-unknown-linux-musleabihf"
- else target;
-
-in
- pkgs.rustBuilder.makePackageSet ({
- inherit release packageFun packageOverrides codegenOpts rootFeatures;
- target = rustTarget;
- } // toolchainOptions)
+ # NixOS and Rust/Cargo triples do not match for ARM, fix it here.
+ rustTarget = if target == "armv6l-unknown-linux-musleabihf" then
+ "arm-unknown-linux-musleabihf"
+ else
+ target;
+
+in pkgs.rustBuilder.makePackageSet ({
+ inherit release packageFun packageOverrides codegenOpts rootFeatures;
+ target = rustTarget;
+} // toolchainOptions)