The PR #22 added a workaround for issue #14.
However, this solution is not ideal as:
- it does not detect/respect
rust-toolchain in a project itself (it will use whatever toolchain is the default one, which is good enough for most cases)
- it is implemented as a workaround in a bash script: we simply pass an environment variable.
I tried to track this issue more deeply, but I could not find the proper solution. Anyway here is some info that can be useful for further investigation into it:
- Siderophile runs
cargo clean and cargo check through Cargo API:
|
/// Trigger a `cargo clean` + `cargo check` and listen to the cargo/rustc |
|
/// communication to figure out which source files were used by the build. |
|
pub(crate) fn resolve_rs_file_deps( |
|
copt: &CompileOptions, |
|
ws: &Workspace, |
|
) -> Result<HashMap<PathBuf, u32>, RsResolveError> { |
|
let config = ws.config(); |
|
// Need to run a cargo clean to identify all new .d deps files. |
|
// TODO: Figure out how this can be avoided to improve performance, clean |
|
// Rust builds are __slow__. |
|
let clean_opt = CleanOptions { |
|
config: &config, |
|
spec: vec![], |
|
target: None, |
|
release: false, |
|
doc: false, |
|
}; |
|
cargo::ops::clean(ws, &clean_opt).map_err(|e| RsResolveError::Cargo(e.to_string()))?; |
|
let inner_arc = Arc::new(Mutex::new(CustomExecutorInnerContext::default())); |
|
{ |
|
let cust_exec = CustomExecutor { |
|
cwd: config.cwd().to_path_buf(), |
|
inner_ctx: inner_arc.clone(), |
|
}; |
|
let exec: Arc<Executor> = Arc::new(cust_exec); |
|
cargo::ops::compile_with_exec(ws, &copt, &exec) |
|
.map_err(|e| RsResolveError::Cargo(e.to_string()))?; |
- It uses a custom Cargo executor for that where it calls the underlying rustc compilation by itself - this is the point where it fails to compile a dependency (on the
.exec(..) call) as it tries to do it with the toolchain specified in the dependency's rust-toolchain file:
|
fn exec( |
|
&self, |
|
cmd: ProcessBuilder, |
|
_id: PackageId, |
|
_target: &Target, |
|
_mode: CompileMode, |
|
) -> CargoResult<()> { |
|
let args = cmd.get_args(); |
|
let out_dir_key = OsString::from("--out-dir"); |
|
let out_dir_key_idx = args |
|
.iter() |
|
.position(|s| *s == out_dir_key) |
|
.ok_or_else(|| CustomExecutorError::OutDirKeyMissing(cmd.to_string()))?; |
|
let out_dir = args |
|
.get(out_dir_key_idx + 1) |
|
.ok_or_else(|| CustomExecutorError::OutDirValueMissing(cmd.to_string())) |
|
.map(PathBuf::from)?; |
|
|
|
// This can be different from the cwd used to launch the wrapping cargo |
|
// plugin. Discovered while fixing |
|
// https://github.com/anderejd/cargo-geiger/issues/19 |
|
let cwd = cmd |
|
.get_cwd() |
|
.map(PathBuf::from) |
|
.unwrap_or_else(|| self.cwd.to_owned()); |
|
|
|
{ |
|
// Scope to drop and release the mutex before calling rustc. |
|
let mut ctx = self |
|
.inner_ctx |
|
.lock() |
|
.map_err(|e| CustomExecutorError::InnerContextMutex(e.to_string()))?; |
|
for tuple in args |
|
.iter() |
|
.map(|s| (s, s.to_string_lossy().to_lowercase())) |
|
.filter(|t| t.1.ends_with(".rs")) |
|
{ |
|
let raw_path = cwd.join(tuple.0); |
|
let p = raw_path |
|
.canonicalize() |
|
.map_err(|e| CustomExecutorError::Io(e, raw_path))?; |
|
ctx.rs_file_args.insert(p); |
|
} |
|
ctx.out_dir_args.insert(out_dir); |
|
} |
|
cmd.exec()?; |
The PR #22 added a workaround for issue #14.
However, this solution is not ideal as:
rust-toolchainin a project itself (it will use whatever toolchain is the default one, which is good enough for most cases)I tried to track this issue more deeply, but I could not find the proper solution. Anyway here is some info that can be useful for further investigation into it:
cargo cleanandcargo checkthrough Cargo API:siderophile/src/deps.rs
Lines 244 to 270 in c3e6c76
.exec(..)call) as it tries to do it with the toolchain specified in the dependency'srust-toolchainfile:siderophile/src/deps.rs
Lines 389 to 434 in c3e6c76