crane icon indicating copy to clipboard operation
crane copied to clipboard

Support `cargoExtraArgs = "--bin bin-target-name"` (or similar) when `buildPackage` is used without explicitly setting `cargoArtifacts`

Open iliana opened this issue 1 year ago • 1 comments

Right now cargoExtraArgs = "--bin bin-target-name" (usually[^1]) doesn't work if you only specify lib.buildPackage (i.e., you don't split out the two lib.buildDepsOnly and lib.buildPackage steps yourself). I think this is due to buildDepsOnly clearing out your project's source code so it can build just the deps; whatever bin target you were looking for isn't there anymore.

A log from this situation:

$ nix log /nix/store/n9xik3k23ksncrhm0byhdq8xj1ibswxi-oxide-hello-deps-0.1.0.drv                                                                                                                                                                                                                                                
cargoArtifacts not set, will not reuse any cargo artifacts                                                                                                                                                                                                                                                                      
@nix { "action": "setPhase", "phase": "unpackPhase" }                                                                                                                                                                                                                                                                           
unpacking sources                                                                                                                                                                                                                                                                                                               
unpacking source archive /nix/store/czpn6g82n5qlxm1rqibqc6vz0kk94b4n-hello                                                                                                                                                                                                                                                      
source root is hello                                                                                                                                                                                                                                                                                                            
@nix { "action": "setPhase", "phase": "patchPhase" }                                                                                                                                                                                                                                                                            
patching sources                                                                                                                                                                                                                                                                                                                
Executing configureCargoCommonVars                                                                                                                                                                                                                                                                                              
@nix { "action": "setPhase", "phase": "configurePhase" }                                                                                                                                                                                                                                                                        
configuring                                                                                                                                                                                                                                                                                                                     
will append /build/hello/.cargo-home/config.toml with contents of /nix/store/1f6wsb6l4r1cqcggvv3dz12iz53sshl7-vendor-cargo-deps/config.toml                                                                                                                                                                                     
default configurePhase, nothing to do                                                                                                                                                                                                                                                                                           
@nix { "action": "setPhase", "phase": "buildPhase" }                                                                                                                                                                                                                                                                            
building                                                                                                                                                                                                                                                                                                                        
++ command cargo --version                                                                                                                                                                                                                                                                                                      
cargo 1.68.0 (115f34552 2023-02-26)                                                                                                                                                                                                                                                                                             
++ command cargo check --profile release --bin oxide-hello                                                                                                                                                                                                                                                                      
error: no bin target named `oxide-hello`.                                                                                                                                                                                                                                                                                       
Available bin targets:                                                                                                                                                                                                                                                                                                          
    crane-dummy

This is not a strong necessity for me but it seems like an issue someone else might trip over. Having some additional options for specifying targets (or even packages of a workspace?) to build would make the interface nicer.

[^1]: In a project I'm working on I got fooled into thinking it would work because the package I was building had a [[bin]] section manually declaring the bin target in Cargo.toml, which I think is why it worked in the buildDepsOnly stage?

iliana avatar Mar 15 '23 04:03 iliana

Thanks for reporting this @iliana! It was always the intention to maintain the same project structure (including any targets) between the deps-only and final builds (so that setting --bin whatever would just work out of the box), but it looks like some of that was lost in translation of reducing the chance of invalidating the build caches (i.e. if a new bin/whatever.rs file is added it would require rebuilding everything from scratch...)

  1. In a project I'm working on I got fooled into thinking it would work because the package I was building had a [[bin]] section manually declaring the bin target in Cargo.toml,

Great observation, this is exactly the root of the problem! Although we go to some lengths to preserve targets listed in Cargo.toml we don't consider auto-targets (e.g. files like src/bin/whatever.rs even if not declared as a [[bin]] in Cargo.toml).

The solution here is to expand the dummification logic to also peek at any autotargets (unless autoWHATEVER = false in Cargo.toml) and if present, replace them with the dummy source file

ipetkov avatar Mar 19 '23 21:03 ipetkov