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

generate an app per Rust workspace binary #212

Open
haraldh opened this issue Feb 13, 2024 · 4 comments
Open

generate an app per Rust workspace binary #212

haraldh opened this issue Feb 13, 2024 · 4 comments

Comments

@haraldh
Copy link

haraldh commented Feb 13, 2024

$ nix run 'github:rvolosatovs/nixify?dir=examples/rust-hello-multibin'
[...]

error: unable to execute '/nix/store/gm2sj4fii5pfyj0ghlfs5h2d5adg4bkx-rust-hello-multibin-0.1.0/bin/rust-hello-multibin': No such file or directory
@rvolosatovs
Copy link
Owner

Thanks for the report and sorry for a late response!
The fact that nix run does not work for this one is expected. cargo run also does not work with that crate:

error: `cargo run` could not determine which binary to run. Use the `--bin` option to specify a binary, or the `default-run` manifest key.
available binaries: bye, hello-other-path

The error message should certainly be improved though

@rvolosatovs rvolosatovs changed the title nix run fails for multibin example improve error message/disable nix run when executable package binary cannot be determined Mar 19, 2024
@haraldh
Copy link
Author

haraldh commented Mar 19, 2024

$ nix flake show --no-write-lock-file  'github:rvolosatovs/nixify?dir=examples/rust-hello-multibin'
[...]
github:rvolosatovs/nixify/e7295eaafb29bdb709fd449118c7cec30d4bbce3?dir=examples/rust-hello-multibin
├───apps
│   ├───aarch64-darwin
│   │   ├───default: app
│   │   ├───rust-hello-multibin: app
│   │   └───rust-hello-multibin-debug: app
│   ├───aarch64-linux
│   │   ├───default: app
│   │   ├───rust-hello-multibin: app
│   │   └───rust-hello-multibin-debug: app
│   ├───x86_64-darwin
│   │   ├───default: app
│   │   ├───rust-hello-multibin: app
│   │   └───rust-hello-multibin-debug: app
│   └───x86_64-linux
│       ├───default: app
│       ├───rust-hello-multibin: app
│       └───rust-hello-multibin-debug: app
[...]

Seems like there should be some app ... right?

@rvolosatovs
Copy link
Owner

rvolosatovs commented Mar 20, 2024

$ nix flake show --no-write-lock-file  'github:rvolosatovs/nixify?dir=examples/rust-hello-multibin'
[...]
github:rvolosatovs/nixify/e7295eaafb29bdb709fd449118c7cec30d4bbce3?dir=examples/rust-hello-multibin
├───apps
│   ├───aarch64-darwin
│   │   ├───default: app
│   │   ├───rust-hello-multibin: app
│   │   └───rust-hello-multibin-debug: app
│   ├───aarch64-linux
│   │   ├───default: app
│   │   ├───rust-hello-multibin: app
│   │   └───rust-hello-multibin-debug: app
│   ├───x86_64-darwin
│   │   ├───default: app
│   │   ├───rust-hello-multibin: app
│   │   └───rust-hello-multibin-debug: app
│   └───x86_64-linux
│       ├───default: app
│       ├───rust-hello-multibin: app
│       └───rust-hello-multibin-debug: app
[...]

Seems like there should be some app ... right?

Right, so cases where there are multiple binaries in a workspace are a bit tricky, right now, for example, we have this funky logic for OCI where, if there is a binary with the same name as the crate we're building or there's only one binary being built, then we assume that's the command we want to execute.

nixify/lib/rust/mkAttrs.nix

Lines 735 to 740 in c2134e5

// optionalAttrs (bins' ? ${pname'}) {
config.Cmd = [pname'];
}
// optionalAttrs (length bins == 1) {
config.Cmd = bins;
}

I think what really should happen here is that there should be a Nix app generated per binary in the workspace (with appropriate executable being run on nix run) and a Nix package per workspace to build all of it

We already know exactly which binaries cargo will build

trace' "crateBins" {
inherit
autobins
bin
cargoToml
includeCrate
isPackage
src
workspace
;
}
optionals
includeCrate (
# NOTE: `listToAttrs` seems to discard keys already present in the set
attrValues (
optionalAttrs (autobins && pathExists "${src}/src/main.rs") {
"src/main.rs" = cargoToml.package.name;
}
// listToAttrs (optionals (autobins && pathExists "${src}/src/bin") (map (name:
nameValuePair "src/bin/${name}" (removeSuffix ".rs" name))
(attrNames (filterAttrs (name: type: type == "regular" && hasSuffix ".rs" name || type == "directory") (readDir "${src}/src/bin")))))
// listToAttrs (map (
{
name,
path ? null,
...
}:
if path != null
then nameValuePair path name
else if autobins && pathExists "${src}/src/main.rs" && name == cargoToml.package.name
then nameValuePair "src/main.rs" name
else if autobins && pathExists "${src}/src/bin/${name}.rs"
then nameValuePair "src/bin/${name}.rs" name
else if autobins && pathExists "${src}/src/bin/${name}/main.rs"
then nameValuePair "src/bin/${name}/main.rs" name
else throw "failed to determine `${name}` binary path, please file a bug report and explicitly set `path` in `Cargo.toml` to temporarily work around this issue"
)
bin)
)
)
++ optionals (build'.workspace || !isPackage || packagesSelected) (flatten (map f workspace));
in
if build ? bins && length build.bins > 0
then build.bins
else unique (f src)
, it's just the matter of setting up the plumbing to extract those binaries from the workspace package. Those packages should be Nix "apps", the workspace package should be just that - a Nix package, not an "app" as it's marked now.

So, in result, rust-hello-multibin and rust-hello-multibin-debug would not show up in apps, those would keep only being available in packages.
We would, however have bye and hello-other-path apps available.
For rust-hello-multibin specifically, there would be no default app (but there would be a default package - the workspace build), but otherwise I think default app should be set if either:

  • there is only one binary in the workspace
  • there is a binary with the same name as the top-level crate being built

basically, the same logic that already exists for OCI

Does that make sense?

@rvolosatovs rvolosatovs changed the title improve error message/disable nix run when executable package binary cannot be determined generate an app per Rust workspace binary Mar 20, 2024
@haraldh
Copy link
Author

haraldh commented Mar 20, 2024

totally makes sense and would be exactly what I need :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants