Skip to content

auxoncorp/cargo-5730

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A workaround for cargo#5730

Overview

The problem

Cargo can’t deal with different kinds of dependencies having different features enabled. If you have both a regular dependency and a build dependency on a single library, and the build dependency has a different feature selection, that gets used for the regular one as well. This is a big problem for no_std projects, where you have the standard library available for the build script but not for the application itself.

The project’s namesake is, of course, rust-lang/cargo#5730.

The solution

A build script is just a program that looks at special environment variables and writes magical values to stdout. We can just write a regular program that does that. This library helps you manage such a program.

(If you’re using .cargo/config to set compiler flags for embedded development and you try to do this by hand, you’ll note Cargo’s recursive config resolution scheme gives you the same flags for the build script, preventing it from working. This library also works around that problem by building out of /tmp.)

Getting Started

Dependencies

cargo-5730 intentionally has no dependencies, to avoid adding fuel to dependency management fire it’s attempting to extinguish.

It currently runs only on Linux.

Building

cargo build

Usage

  1. Add this library as the only build dependency in your main crate’s Cargo.toml. Put the build dependencies you actually want inside [workaround-build-dependencies].
    [build-dependencies]
    cargo-5730 = "0.2"
    
    [workaround-build-dependencies]
    great-crate = "1.0"
        
  2. Modify your build.rs to run your real script behind the ‘workaround_build’ flag, or to invoke this crate otherwise.
    #[cfg(not(workaround_build))]
    fn main() {
        cargo_5730::run_build_script();
    }
    
    #[cfg(workaround_build)]
    fn main() {
        great_crate::succeed();
    }
        
  3. After building, you’ll have a build-script-target directory and Cargo.build.lock file. The former is the target dir for your build script, and should be ignored in the same way as target. The lock file is just like Cargo.lock, but for your build script; you should probably check it in.
    git add Cargo.build.lock
    echo build-script-target >> .gitignore
        

Example

See the example directory for a cargo project set up as described above. To see the library in action, compile it with cargo build -vv. Among the other output, you will see something like:

[bin-crate 0.1.0] cargo:rerun-if-changed=build-script
[bin-crate 0.1.0] Copying build crate source from build-script to /tmp/build-script-c2717537984a6f51b94ee464d0cf90
[bin-crate 0.1.0]    Compiling lib-crate v0.1.0 (/home/mullr/devel/cargo-5730/example/lib-crate)
[bin-crate 0.1.0]      Running `CARGO_PKG_VERSION_MAJOR=0 CARGO=/home/mullr/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo CARGO_`
[bin-crate 0.1.0]    Compiling build-script v0.1.0 (/tmp/build-script-c2717537984a6f51b94ee464d0cf90)
[bin-crate 0.1.0]      Running `CARGO_PKG_VERSION_MAJOR=0 CARGO=/home/mullr/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo CARGO_`
[bin-crate 0.1.0]     Finished dev [unoptimized + debuginfo] target(s) in 0.40s
[bin-crate 0.1.0] Adding the numbers 1 and 2
[bin-crate 0.1.0] Build script says: the sum is 3
[bin-crate 0.1.0] Removing build crate staging dir: /tmp/build-script-c2717537984a6f51b94ee464d0cf90

License

© 2019, Auxon Corporation Please see the LICENSE file for more details.