Description
(by a 'rustc shim' I'm referring to things like rustup - it puts a shim rustc on the path which invokes the true rustc)
As part of invoking rustc for compilations, cargo will put a number of paths in the 'library environment', performed here (called from Compilation::rustc_process
, which is called from prepare_rustc
): https://github.com/rust-lang/cargo/blob/d4ee795/src/cargo/core/compiler/compilation.rs#L188-L204
However, a few things conspire against us:
- the paths are added to the beginning of the variable, i.e. with the highest priority
- on Windows the environment variable these new paths get added to (
util::dylib_path_envvar()
) is the same as the binary search path (i.e.PATH
) - on Windows, the sysroot dylibs for the compiler are in the same directory as the actual binaries (i.e.
rustc.exe
lives alongside dylibs likerustc_typeck-4d5d5a72bda8f430.dll
)
This means that when actually performing the compilation, an attempted invocation of rustc
will jump straight to the sysroot binaries rather than using the shim - anything that the shim does (like telemetry, in the case of the rustup) gets completely skipped for any compilations. You can observe this with a build plan on Windows:
{
"invocations": [
{
"package_name": "cde",
"package_version": "0.1.0",
"target_kind": [
"bin"
],
"kind": "Host",
"deps": [],
"outputs": [
"C:\\X\\cde\\target\\release\\deps\\cde-63a3117d8b95571a.exe",
"C:\\X\\cde\\target\\release\\deps\\cde-63a3117d8b95571a.pdb"
],
"links": {
"C:\\X\\cde\\target\\release\\cde.exe": "C:\\X\\cde\\target\\release\\deps\\cde-63a3117d8b95571a.exe",
"C:\\X\\cde\\target\\release\\cde.pdb": "C:\\X\\cde\\target\\release\\deps\\cde-63a3117d8b95571a.pdb"
},
"program": "rustc",
"args": [
"--crate-name",
"cde",
"src\\main.rs",
"--crate-type",
"bin",
"--emit=dep-info,link",
"-C",
"opt-level=3",
"-C",
"metadata=63a3117d8b95571a",
"-C",
"extra-filename=-63a3117d8b95571a",
"--out-dir",
"C:\\X\\cde\\target\\release\\deps",
"-L",
"dependency=C:\\X\\cde\\target\\release\\deps"
],
"env": {
"CARGO": "\\\\?\\C:\\Users\\aidanhs\\.rustup\\toolchains\\nightly-2018-08-19-x86_64-pc-windows-msvc\\bin\\cargo.exe",
"CARGO_MANIFEST_DIR": "C:\\X\\cde",
[...]
"CARGO_PRIMARY_PACKAGE": "1",
"PATH": "C:\\X\\cde\\target\\release\\deps;C:\\Users\\aidanhs\\.rustup\\toolchains\\nightly-2018-08-19-x86_64-pc-windows-msvc\\bin;C:\\Users\\aidanhs\\.cargo\\bin;C:\\Users\\aidanhs\\.rustup\\toolchains\\nightly-2018-08-19-x86_64-pc-windows-msvc\\bin;[...]"
},
"cwd": "C:\\X\\cde"
}
],
"inputs": [
"C:\\X\\cde\\Cargo.toml"
]
}
Note the C:\\Users\\aidanhs\\.rustup\\toolchains\\nightly-2018-08-19-x86_64-pc-windows-msvc\\bin
with a higher priority than C:\\Users\\aidanhs\\.cargo\\bin
in the PATH
.
There is an additional oddity though - when performing configuration tests at cargo startup (
cargo/src/cargo/core/compiler/build_context/target_info.rs
Lines 68 to 75 in d4ee795
Quick thoughts:
- I'm not clear why we need to add the sysroot dylib path to the environment - on Linux the rustc binary has an rpath, and Windows will apparently attempt to use the directory of the executable first (https://msdn.microsoft.com/en-us/library/7d83bc18.aspx)
- Adding paths at the end of the variable could cause oddities with unusual setups, but I would imagine the risks are fairly low given the hashes added to the end of rustc-generated dylibs.
- Move dylibs into a different directory in the rust distribution - likely to make standalone rustc calls fail.