Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crate specific overrides (eg. building OpenSSL without errors out of the box) #326

Merged
merged 7 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ Note that you shouldn't call `overrideAttrs` on a derivation built by Naersk
| `postInstall` | Optional hook to run after the compilation is done; inside this script, `$out/bin` contains compiled Rust binaries. Useful if your application needs e.g. custom environment variables, in which case you can simply run `wrapProgram $out/bin/your-app-name` in here. Default: `false` |
| `usePureFromTOML` | Whether to use the `fromTOML` built-in or not. When set to `false` the python package `remarshal` is used instead (in a derivation) and the JSON output is read with `builtins.fromJSON`. This is a workaround for old versions of Nix. May be used safely from Nix 2.3 onwards where all bugs in `builtins.fromTOML` seem to have been fixed. Default: `true` |
| `mode` | What to do when building the derivation. Either `build`, `check`, `test`, `fmt` or `clippy`. <br/> When set to something other than `build`, no binaries are generated. Default: `"build"` |
| `autoCrateSpecificOverrides` | Whether to automatically apply crate-specific overrides, mainly additional `buildInputs` for dependencies. <br /> For example, if you use the `openssl` crate, `pkgs.pkg-config` and `pkgs.openssl` are automatically added as buildInputs. Default: `true` |
Copy link
Collaborator

@nmattia nmattia May 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having it enabled by default might create issues for users that already build with openssl and already add dependencies manually. WDYT?

EDIT: to be clear I think it's a good idea to have it enabled by default, just wondering how we can avoid breaking existing setups, esp. for people with custom openssl packages

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One idea I have is to emit a warning if there is already a derivation in buildInputs with the same name. It would not work in 100% of the cases, but it should work most of the time. Or we can just disable it by default.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having it enabled by default is much nicer!



### Note on `overrideAttrs`
Expand Down Expand Up @@ -397,16 +398,3 @@ naersk.buildPackage {
```

([context](https://github.com/nix-community/naersk/pull/288))

### Using OpenSSL

If your application uses OpenSSL (making the build process fail), try:

```nix
naersk.buildPackage {
# ...

nativeBuildInputs = with pkgs; [ pkg-config ];
buildInputs = with pkgs; [ openssl ];
}
```
13 changes: 0 additions & 13 deletions README.tpl.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,16 +359,3 @@ naersk.buildPackage {
```

([context](https://github.com/nix-community/naersk/pull/288))

### Using OpenSSL

If your application uses OpenSSL (making the build process fail), try:

```nix
naersk.buildPackage {
# ...

nativeBuildInputs = with pkgs; [ pkg-config ];
buildInputs = with pkgs; [ openssl ];
}
```
37 changes: 35 additions & 2 deletions build.nix
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
, fetchurl
, lndir
, userAttrs
#| Some additional buildInputs/overrides individual crates require
, crateSpecificOverrides
, autoCrateSpecificOverrides
, pkgs
}:

let
Expand Down Expand Up @@ -130,14 +134,16 @@ let
jq
rsync
] ++ nativeBuildInputs
++ lib.optionals (mode == "clippy") [clippy];
++ lib.optionals (mode == "clippy") [clippy]
++ neededCrateSpecificOverrides.nativeBuildInputs;

buildInputs = lib.optionals stdenv.isDarwin [
darwin.Security
darwin.apple_sdk.frameworks.CoreServices
darwin.cf-private
darwin.libiconv
] ++ buildInputs;
] ++ buildInputs
++ neededCrateSpecificOverrides.buildInputs;

inherit builtDependencies;

Expand Down Expand Up @@ -374,6 +380,33 @@ let
};
};

# Crate-specific overrides needed for this build.
# They are merged from all the overrides of `cratesIoDependencies` defined in the `crate_specific.nix` file
#
# This can contain fields: `buildInputs`, `nativeBuildInputs`
# When changing them (eg. adding support for new ones/removing some), also update the comment in the `crate_specific.nix` file
neededCrateSpecificOverrides =
let
overridesList = builtins.map
( crateInfo:
if builtins.hasAttr crateInfo.name crateSpecificOverrides then
crateSpecificOverrides.${crateInfo.name} { inherit crateInfo; }
else {}
)
cratesIoDependencies;
emptyOverrides = { buildInputs = []; nativeBuildInputs = []; };
in if autoCrateSpecificOverrides then
builtins.foldl'
(acc: elem:
{
buildInputs = acc.buildInputs ++ elem.buildInputs or [];
nativeBuildInputs = acc.nativeBuildInputs ++ elem.nativeBuildInputs or [];
}
)
emptyOverrides
overridesList
else emptyOverrides;

# Crates.io dependencies required to compile user's crate.
#
# As an output, for each dependency, this derivation produces a subdirectory
Expand Down
11 changes: 10 additions & 1 deletion config.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ lib, libb, builtinz, arg }:
{ lib, libb, builtinz, arg, pkgs }:
let
allowFun = attrs0: attrName: default:
if builtins.hasAttr attrName attrs0 then
Expand Down Expand Up @@ -200,6 +200,12 @@ let
# What to do when building the derivation. Either `build`, `check`, `test`, `fmt` or `clippy`. <br/>
# When set to something other than `build`, no binaries are generated.
mode = attrs0.mode or "build";

# Whether to automatically apply crate-specific overrides, mainly additional
# `buildInputs` for dependencies. <br />
# For example, if you use the `openssl` crate, `pkgs.pkg-config` and
# `pkgs.openssl` are automatically added as buildInputs.
autoCrateSpecificOverrides = attrs0.autoCrateSpecificOverrides or true;
};

argIsAttrs =
Expand Down Expand Up @@ -302,6 +308,7 @@ let
cargoDocOptions
copyDocsToSeparateOutput
removeReferencesToSrcFromDocs
autoCrateSpecificOverrides

postInstall
;
Expand All @@ -311,6 +318,8 @@ let
# Example:
# [ { name = "wabt", version = "2.0.6", sha256 = "..." } ]
cratesIoDependencies = libb.mkVersions buildPlanConfig.cargolock;

crateSpecificOverrides = import ./crate_specific.nix { inherit pkgs; };
};

# config used when planning the builds
Expand Down
16 changes: 16 additions & 0 deletions crate_specific.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This file contains crate-specific build inputs.
#
# Each of them is an attribute with name of the crate and value being a function.
# This function gets as arguments:
# - `crateInfo` with information about the crate, such as sha256 or version
#
# Currently supported fields to return are: `buildInputs`, `nativeBuildInputs`
FireFragment marked this conversation as resolved.
Show resolved Hide resolved

{ pkgs }:

{
openssl-sys = { ... }: {
nativeBuildInputs = with pkgs; [ pkg-config ];
buildInputs = with pkgs; [ openssl ];
};
}
3 changes: 2 additions & 1 deletion default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
, writeText
, zstd
, clippy
, pkgs
}@defaultBuildAttrs:

let
Expand All @@ -22,7 +23,7 @@ let
{ inherit lib writeText remarshal runCommandLocal formats; };

mkConfig = arg:
import ./config.nix { inherit lib arg libb builtinz; };
import ./config.nix { inherit lib arg libb builtinz pkgs; };

buildPackage = arg:
let
Expand Down
1 change: 1 addition & 0 deletions test/fast/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ args: {
git-dep-dup = import ./git-dep-dup args;
git-single-repository-with-multiple-crates = import ./git-single-repository-with-multiple-crates args;
git-symlink = import ./git-symlink args;
openssl = import ./openssl args;
post-install-hook = import ./post-install-hook args;
readme = import ./readme args;
simple-dep = import ./simple-dep args;
Expand Down
33 changes: 33 additions & 0 deletions test/fast/openssl/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# OpenSSL needs `pkg-config` and `openssl` buildInputs. This tests whether we correctly supply them automatically.

{ naersk, pkgs, ... }:

let
# Whether the nixpkgs is version 23 or newer, because in older nixpkgs, rustc is too old to build openssl.
buildIt = with pkgs.lib;
(strings.toInt ((builtins.elemAt (splitString "." trivial.version) 0)) >= 23);
in

if buildIt then
naersk.buildPackage {
src = ./fixtures;
doCheck = true;
}
else
builtins.trace ''
Not building OpenSSL test, because Rust from nixpkgs under major version 23 cannot build OpenSSL
Current nixpkgs version: ${pkgs.lib.trivial.version}
''

pkgs.stdenv.mkDerivation {
name = "not-building-openssl-test";

dontUnpack = true;

buildPhase = ''
echo Not building OpenSSL test, because Rust from nixpkgs under major version 23 cannot build OpenSSL
echo Current nixpkgs version: ${pkgs.lib.trivial.version}
'';

installPhase = "mkdir $out";
}
140 changes: 140 additions & 0 deletions test/fast/openssl/fixtures/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions test/fast/openssl/fixtures/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Tests that default-run doesn't break the dependency build, see
# https://github.com/nmattia/naersk/issues/123

[package]
name = "openssl-test"
version = "0.1.0"
authors = ["FireFragment <[email protected]>"]
edition = "2018"

[dependencies]
openssl = "0.10.64"
3 changes: 3 additions & 0 deletions test/fast/openssl/fixtures/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
Loading