rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.85k stars 12.66k forks source link

When trying to use cross language LTO on windows for the MSVC target, proc macros give a linker error without an explicit target #92133

Open nico-abram opened 2 years ago

nico-abram commented 2 years ago

I'm building a hello world generated by cargo, using this .cargo/config:

[target.x86_64-pc-windows-msvc]
linker = "lld-link.exe"
rustflags = ["-Clinker=lld-link", "-Clinker-plugin-lto"]

I have LLVM/bin (From LLVM13 to match my current rust LLVM version) in my path. cargo build runs fine. But as soon as I add a dependency with a proc macro, it results in a linking error. For example:

[dependencies]
thiserror="1.0.30"

Results in:

    Updating crates.io index
   Compiling proc-macro2 v1.0.34
   Compiling unicode-xid v0.2.2
   Compiling syn v1.0.82
   Compiling quote v1.0.10
   Compiling thiserror-impl v1.0.30
error: Linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets

error: could not compile `thiserror-impl` due to previous error

This goes away if an explicit target is used: cargo build --target x86_64-pc-windows-msvc

After reading the cargo docs here

If the --target flag (or build.target) is used, then the flags will only be passed to the compiler for the target.
Things being built for the host, such as build scripts or proc macros, will not receive the args.
Without --target, the flags will be passed to all compiler invocations (including build scripts and proc macros) because dependencies are shared.
If you have args that you do not want to pass to build scripts or proc macros and are building for the host, pass --target with the host triple.

It makes sense but this is still super confusing, and the only reason I got it to work is someone suggested it to me. Could this restriction on prefer-dynamic + linker-plugin-lto be softened on proc-macros, or maybe the error message improved to suggest using an explicit target?

aminya commented 2 years ago

Here is the solution I have found for this issue:

rustflags = [
    # defers LTO optimizations to the linker
    "-C",
    "linker-plugin-lto",
    # static linking
    "-C",
    "prefer-dynamic=off",
]