japaric / xargo

The sysroot manager that lets you build and customize `std`
Apache License 2.0
1.1k stars 93 forks source link

xargo on windows fails to find linker.exe, cargo works #171

Open Trolldemorted opened 7 years ago

Trolldemorted commented 7 years ago

When running xargo with this target:

{
  "_": "Inspired by https://github.com/ryanbreen/breenix/blob/master/x86_64-unknown-none-gnu.json",
  "_note": "`is_like_mcvc` works since #32823, nightly 2016-04-12",
  "_note": "`data-layout` became mandatory since rust-lang/rust#32939, nightly 2016-04-20",

  "llvm-target": "x86_64-pc-windows-msvc",
  "target-endian": "little",
  "target-pointer-width": "64",
  "target-c-int-width": "32",
  "linker-flavor": "msvc",
  "data-layout": "e-m:w-i64:64-f80:128-n8:16:32:64-S128",

  "cpu": "x86-64",
  "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",

  "arch": "x86_64",
  "vendor": "pc",
  "os": "windows",
  "env": "msvc",

  "executables": true,
  "dynamic-linking": true,

  "is-like-windows": true,
  "is-like-msvc": true,

  "dll-prefix": "",
  "dll-suffix": ".sys",
  "exe-prefix": "",
  "exe-suffix": ".exe",
  "staticlib-prefix": "lib",
  "staticlib-suffix": ".lib",

  "no-default-libraries":     true,
  "no-compiler-rt":           true,
  "has-rpath":                false,

  "function-sections": true,
  "has-elf-tls":              false,
  "disable-redzone":          true,
  "custom-unwind-resume":     false,
  "eliminate-frame-pointer":  false,
  "position-independent-executables": false,

  "code-model":              "kernel",
  "relocation-model":        "dynamic-no-pic",

  "pre-link-args": ["/NOLOGO", "/NODEFAULTLIB", "/SUBSYSTEM:NATIVE", "/DRIVER", "/RELEASE", "/NXCOMPAT", "/DYNAMICBASE",
    "/INCREMENTAL:NO", "/MANIFEST:NO"],

  "post-link-args": ["/OPT:REF,ICF", "ntoskrnl.lib", "hal.lib",
    "/noimplib", "/ENTRY:DriverEntry", "/DEF:exports.def", "/MERGE:.edata=.rdata", "/MERGE:.rustc=.data"],

  "_end" : false
}

xargo fails because it cannot find link.exe:

note: the msvc targets depend on the msvc linker but `link.exe` was not found

note: please ensure that VS 2013 or VS 2015 was installed with the Visual C++ option

I don't have vs2015, but when running xargo from a VS 2017 dev prompt (which adds the appropriate directories to %PATH%) xargo build works like a charm. Cargo however does find link.exe without the dev prompt.

japaric commented 6 years ago

Xargo is simply a shim around the cargo binary that's in $PATH if Xargo "can't find the linker" that means that cargo can't find the linker and that means that rustc can't find the linker.

note: please ensure that VS 2013 or VS 2015 was installed with the Visual C++ option

This is a requirement of using a Rust toolchain to compile for a MSVC target and if you are using a custom MSVC target specification (i.e. linker-flavor: msvc) then the requirement also holds. My understanding is that rustc knows how to find link.exe (it doesn't need to be in $PATH and you don't need to load vcvarsall.bat (or whatever it was called)) if you are using VS2013+ or VS2015 build tools but it can't handle VS 2017 yet.

TL;DR you'll have to install VS 2013+ or VS 2015 build tools. rustc doesn't properly support VS 2017 AFAIK (that's why it only works from the VS 2017 dev prompt, I guess).

Trolldemorted commented 6 years ago

I assure you, cargo does find the linker.

I just built an unrelated project with cargo rustc -- -Z print-link-args, this is the output:

[...]
   Compiling sniff_machinery v0.1.0 (file:///C:/Users/Benni/repositories/sniff_machinery)
warning: unused variable: `packet`
   --> src\handlers.rs:113:33
    |
113 |     fn handle_packet(&mut self, packet: Arc<PcapPacket>) {
    |                                 ^^^^^^
    |
    = note: #[warn(unused_variables)] on by default
    = note: to avoid this warning, consider using `_packet` instead

"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\VC\\Tools\\MSVC\\14.11.25503\\bin\\HostX64\\x64\\link.exe" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery0.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery1.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery10.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery11.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery12.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery13.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery14.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery15.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery2.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery3.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery4.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery5.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery6.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery7.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery8.rust-cgu.o" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.sniff_machinery9.rust-cgu.o" "/OUT:C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.exe" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\sniff_machinery-873eaf0b904b8b4c.crate.allocator.rust-cgu.o" "/OPT:REF,NOICF" "/DEBUG" "/NATVIS:C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" "/LIBPATH:C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps" "/LIBPATH:C:\\Users\\Benni\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\pnet-0.19.0/lib" "/LIBPATH:C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libpnet-866419b8e237edf8.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libws2_32-b27395fb36cb3442.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libgetopts-b975797e9467e0f3.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libipnetwork-bebfa38001aa4d85.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libtime-84fb243e9f4e8dc4.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libpcap-297205b3a0fb172e.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\liblibc-1fbcaebbf5970ec5.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libwidestring-9935fd386a7fa5d9.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libpnet_macros_support-771cb066ced1566f.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libkernel32-38d26048d99ae2b7.rlib" "C:\\Users\\Benni\\repositories\\sniff_machinery\\target\\debug\\deps\\libwinapi-25fa6c5195d2ccbc.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-3ae694904c3465fd.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-3025ad11132f6ea9.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-ca52afc0ac849bf0.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-b3e23bd1911f85c1.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc_system-e966bb3912613b22.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-e0fe46556146b6b6.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_unicode-9632e3a95e3e4ff5.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librand-450d5ca745c8118b.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-f4d318b6df44aff0.rlib" "C:\\Users\\Benni\\.rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-a0b04ac09ab7eb57.rlib" "iphlpapi.lib" "Packet.lib" "ws2_32.lib" "wpcap.lib" "kernel32.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "shell32.lib" "msvcrt.lib"
    Finished dev [unoptimized + debuginfo] target(s) in 76.40 secs

As you can see, cargo has successfully located the msvc installation (there is neither VS 2013 nor VS 2015 installed, but it found the VS 2017 installation without hassle) and is invoking it with the full path instead of relying on link.exe being in %PATH%.

I don't know why or how cargo found it, but unfortunately xargo does not behave like cargo in this regard.

japaric commented 6 years ago

Well, barring errors in the custom target specification. The next thing to check would be whether cargo can find link.exe when invoked as a subprocess (Command.spawn) since that's how Xargo invokes Cargo (i.e. check for problems in inheritance of env variables). You can see the arguments that Xargo invokes Cargo with by passing -v to the xargo command. Xargo will invoke Cargo twice: once to build the sysroot (if not already built) and the second one is to execute the subcommand that was requested. In the latter case Xargo invokes Cargo with the RUSTFLAGS env variable set, since that's how it selects the custom sysroot. But, unless the linker detection depends on the RUSTFLAGS variable (which seems rather unlikely), that shouldn't affect the linker detection.

Trolldemorted commented 6 years ago

xargo build --target x86_64_windows_kernel -v yields this output:

+ "rustc" "--print" "sysroot"
+ "rustc" "--print" "target-list"
+ RUSTFLAGS="-C link-arg=/noimplib -C link-arg=/ENTRY:DriverEntry --sysroot C:\\Users\\Benni\\.xargo"
+ "cargo" "build" "--target" "x86_64_windows_kernel" "-v"
   Compiling hello_world_driver v0.1.0 (file:///C:/Users/Benni/repositories/hello_world_driver)
   Compiling windows_kernel_api v0.1.0 (file:///C:/Users/Benni/repositories/windows_kernel_api)
     Running `rustc --crate-name build_script_build build.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=28e8f8c7faabbd85 -C extra-filename=-28e8f8c7faabbd85 --out-dir C:\Users\Benni\repositories\hello_world_driver\target\debug\build\hello_world_driver-28e8f8c7faabbd85 -L dependency=C:\Users\Benni\repositories\hello_world_driver\target\debug\deps`
     Running `rustc --crate-name build_script_build C:\Users\Benni\repositories\windows_kernel_api\build.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=4a6c51fc8f9e404a -C extra-filename=-4a6c51fc8f9e404a --out-dir C:\Users\Benni\repositories\hello_world_driver\target\debug\build\windows_kernel_api-4a6c51fc8f9e404a -L dependency=C:\Users\Benni\repositories\hello_world_driver\target\debug\deps`
     Running `C:\Users\Benni\repositories\hello_world_driver\target\debug\build\windows_kernel_api-4a6c51fc8f9e404a\build-script-build`
     Running `C:\Users\Benni\repositories\hello_world_driver\target\debug\build\hello_world_driver-28e8f8c7faabbd85\build-script-build`
     Running `rustc --crate-name windows_kernel_api C:\Users\Benni\repositories\windows_kernel_api\src\lib.rs --crate-type lib --emit=dep-info,link -C panic=abort -C debuginfo=2 -C metadata=9a1baae4f7ef7524 -C extra-filename=-9a1baae4f7ef7524 --out-dir C:\Users\Benni\repositories\hello_world_driver\target\x86_64_windows_kernel\debug\deps --target x86_64_windows_kernel -L dependency=C:\Users\Benni\repositories\hello_world_driver\target\x86_64_windows_kernel\debug\deps -L dependency=C:\Users\Benni\repositories\hello_world_driver\target\debug\deps -C link-arg=/noimplib -C link-arg=/ENTRY:DriverEntry --sysroot C:\Users\Benni\.xargo -l NtosKrnl -l hal`
     Running `rustc --crate-name hello_world_driver src\lib.rs --crate-type cdylib --emit=dep-info,link -C panic=abort -C debuginfo=2 -C metadata=1228fda4cc5dec96 --out-dir C:\Users\Benni\repositories\hello_world_driver\target\x86_64_windows_kernel\debug\deps --target x86_64_windows_kernel -L dependency=C:\Users\Benni\repositories\hello_world_driver\target\x86_64_windows_kernel\debug\deps -L dependency=C:\Users\Benni\repositories\hello_world_driver\target\debug\deps --extern windows_kernel_api=C:\Users\Benni\repositories\hello_world_driver\target\x86_64_windows_kernel\debug\deps\libwindows_kernel_api-9a1baae4f7ef7524.rlib -C link-arg=/noimplib -C link-arg=/ENTRY:DriverEntry --sysroot C:\Users\Benni\.xargo`
error: could not exec the linker `link.exe`: Das System kann die angegebene Datei nicht finden. (os error 2)