Make it easier to build workspaces not at source root (#212)

This commit is contained in:
Ivan Petkov 2023-01-05 04:46:43 +00:00 committed by GitHub
parent dfe3afcdd9
commit 42e2fab6bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 97 additions and 18 deletions

View File

@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## Unreleased
### Changed
* Documented and made it easier to build a cargo workspace located in a
subdirectory of the source root
### Fixed
* Previously compiled build scripts now maintain their executable bit when
inherited

View File

@ -363,6 +363,14 @@ in
pname = "workspace-inheritance";
};
# https://github.com/ipetkov/crane/issues/209
workspaceRootNotAtSourceRoot = myLib.buildPackage {
src = myLib.cleanCargoSource ./workspace-not-at-root;
sourceRoot = "source/workspace";
cargoLock = ./workspace-not-at-root/workspace/Cargo.lock;
cargoToml = ./workspace-not-at-root/workspace/Cargo.toml;
};
workspaceRoot = myLib.buildPackage {
src = myLib.cleanCargoSource ./workspace-root;
pname = "workspace-root";

View File

@ -0,0 +1 @@
Example project where the cargo workspace root is not at the source root

View File

@ -0,0 +1,19 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "hello"
version = "0.1.0"
[[package]]
name = "print"
version = "0.1.0"
dependencies = [
"hello",
"world",
]
[[package]]
name = "world"
version = "0.1.0"

View File

@ -0,0 +1,4 @@
[workspace]
# NB: hello and world are intentionally left out cargo will
# promote them to members since they are listed as path deps
members = ["print"]

View File

@ -0,0 +1,4 @@
[package]
name = "hello"
version = "0.1.0"
edition = "2021"

View File

@ -0,0 +1,3 @@
pub fn hello() -> &'static str {
"hello"
}

View File

@ -0,0 +1,8 @@
[package]
name = "print"
version = "0.1.0"
edition = "2021"
[dependencies]
hello = { version = "*", path = "../hello" }
world = { version = "*", path = "../world" }

View File

@ -0,0 +1,3 @@
fn main() {
println!("{}, {}", hello::hello(), world::world());
}

View File

@ -0,0 +1,4 @@
[package]
name = "world"
version = "0.1.0"
edition = "2021"

View File

@ -0,0 +1,3 @@
pub fn world() -> &'static str {
"world!"
}

View File

@ -27,3 +27,4 @@
* [Building a subset of a workspace](./faq/build-workspace-subset.md)
* [Trouble building when using `include_str!` (or including other non-rust files)](./faq/building-with-non-rust-includes.md)
* [Dealing with sandbox-unfriendly build scripts](./faq/sandbox-unfriendly-build-scripts.md)
* [Cargo.toml is not at the source root](./faq/workspace-not-at-source-root.md)

View File

@ -0,0 +1,21 @@
## Cargo workspace root (Cargo.toml) is not at the root of the derivation's source
Most cargo projects have their `Cargo.toml` at the root of the source, but it's
still possible to build a project where the `Cargo.toml` file is nested in a
deeper directory:
```nix
# Assuming that we have the following directory structure:
# ./flake.nix
# ./flake.lock
# ./nested
# ./nested/Cargo.toml
# ./nested/Cargo.lock
# ./nested/src/*.rs
craneLib.buildPackage {
src = myLib.cleanCargoSource ./.;
sourceRoot = "source/nested"; # Needs to start with "source/" by default
cargoLock = ./nested/Cargo.lock;
cargoToml = ./nested/Cargo.toml;
}
```

View File

@ -23,24 +23,12 @@ let
"dummySrc"
];
throwMsg = throw ''
unable to find Cargo.toml and Cargo.lock at ${path}. please ensure one of the following:
- a Cargo.toml and Cargo.lock exists at the root of the source directory of the derivation
- set `cargoArtifacts = buildDepsOnly { src = ./some/path/to/cargo/root; }`
- set `cargoArtifacts = null` to skip reusing cargo artifacts altogether
'';
# Run tests by default to ensure we cache any dev-dependencies
doCheck = args.doCheck or true;
cargoCheckExtraArgs = args.cargoCheckExtraArgs or (if doCheck then "--all-targets" else "");
path = args.src or throwMsg;
cargoToml = path + "/Cargo.toml";
dummySrc = args.dummySrc or
(if builtins.pathExists cargoToml
then mkDummySrc args
else throwMsg);
dummySrc = args.dummySrc or (mkDummySrc args);
in
mkCargoDerivation (cleanedArgs // {
inherit doCheck;

View File

@ -3,13 +3,21 @@
args:
let
src = args.src or (throw ''
unable to infer crate name and version. Please make sure the src directory
contains a valid Cargo.toml file, or consider setting a derivation name explicitly
'');
throwMsg = throw ''
unable to infer crate name and version. please ensure one of the following:
- a Cargo.toml exists at the root of the source directory of the derivation
- `cargoToml` is set to a path to the package's Cargo.toml
- `cargoTomlContents` is set to the contents of the package's Cargo.toml
- `pname` and `version` are explicitly set
'';
src = args.src or throwMsg;
cargoToml = args.cargoToml or (args.src + "/Cargo.toml");
cargoTomlContents = args.cargoTomlContents or (builtins.readFile cargoToml);
cargoTomlContents = args.cargoTomlContents or (
if builtins.pathExists cargoToml
then builtins.readFile cargoToml
else throwMsg
);
toml = builtins.fromTOML cargoTomlContents;
in