You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
cargo run --release --target x86_64-pc-windows-msvc --example shader_custom_material
Linker error: LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'
Details
This linker error no longer occurs if I modify glslang to build x86_64-pc-windows-msvc from source like i686-pc-windows-msvc.
The RUSTFLAGS environment variable is not available at build time. I do not believe cargo has a standard way of telling build.rs whether or not the user is requesting a static or dynamic build, which means we cannot automatically switch to building from source whenever a static build is requested.
This places us in an awkward situation for 64-bit MSVC (and potentially all platforms where it uses the prebuilt libraries), because building from source adds to the compilation time, and not everyone should have to pay for optional static linking support (especially since bevy docs recommends a setup with dynamic linking!).
Issues with Attempted Solution
I can make minimal code changes to conditionally compile glsl-to-spirv when the build-from-source feature flag is enabled:
let bin_dir = match target {// conditionally build from source"x86_64-pc-windows-msvc" => {ifcfg!(feature = "build-from-source"){
build::build_libraries(&target)}else{
cargo_dir.join("build").join(&target)}}// other targets};
Unfortunately, cargo stable will always attempt to enable the feature. This means instead of build-from-source being an opt-in feature, cargo stable will instead prevent opting out.
Nightly allows us to opt out, as mentioned in #7, by using a flag which is stabilized as resolver version 2, and to be made default in rust edition 2021 (see rust-lang/cargo#9048):
# don't eagerly enable features
cargo +nightly run -Z features=itarget --release --target x86_64-pc-windows-msvc --example shader_custom_material
In which case the user can properly opt-in by requesting the feature directly in their Cargo.toml:
[dependencies]
bevy-glsl-to-spirv-builder = { version = "0.1.0", features = ["build-from-source"] }
Potential Impact on Dynamic Builds (until cargo resolver 2 is stable)
Since building from source occurs in parallel with compilation of other bevy dependencies, measurements must not be isolated to building glsl-to-spirv alone. I use the shader_custom_material as a baseline, and cargo clean before every run. The following was run on a Ryzen 7 3700X CPU.
This is a 28s addition to what was a 105s build process (up by 26.7%) for first time builds and all subsequent builds post-cargo clean.
Temporary Conclusions
Although this cost is only incurred once for the user as it will reuse the libraries on subsequent runs, the additional compile time may be a significant turn-off for new users who just want to get started, and does not give a good impression. Further more, any uses of cargo clean immediately wipes the slate and requires building from source again, as published crates are not allowed to place libraries outside of OUT_DIR.
Once cargo defaults to using resolver version 2, we can make this an opt-in feature without any drawbacks to dynamic builds by default.
Current Workarounds
You could target i686-pc-windows-msvc when static linking, since that target always has to build anyway, but that comes with all the limitations of a 32-bit application vs a 64-bit application.
GNU toolchains currently require dynamically linking stdc++ (unless someone can figure out how to statically link that), so they are not an alternative to MSVC if you are looking for static builds.
The text was updated successfully, but these errors were encountered:
Considered Alternatives
We can gate this behind the debug/release flag instead:
let bin_dir = match target {// conditionally build from source"x86_64-pc-windows-msvc" => {ifcfg!(debug_assertions){
cargo_dir.join("build").join(&target)}else{
build::build_libraries(&target)}}// other targets};
This means dynamic builds only need to start paying for compilation cost when --release is requested.
Unfortunately, this has its own problems:
Many people use release mode when working on their games because debug mode is too slow, so they'd be hit with the one-time compilation cost anyway.
You would be unable to build statically linked games in debug mode, only in release mode.
I also tested replacing the pre-compiled dynamic library with a pre-compiled statically linked one. The dynamic build of bevy does not like the statically generated libraries, so that would not be a viable solution.
Motivation
A statically built binary allows us to run bevy games without the additional installation of runtimes on the user end.
Reproduction steps
bevy
master.cargo/config
:bevy
example:LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'
Details
This linker error no longer occurs if I modify
glslang
to buildx86_64-pc-windows-msvc
from source likei686-pc-windows-msvc
.The
RUSTFLAGS
environment variable is not available at build time. I do not believe cargo has a standard way of tellingbuild.rs
whether or not the user is requesting a static or dynamic build, which means we cannot automatically switch to building from source whenever a static build is requested.This places us in an awkward situation for 64-bit MSVC (and potentially all platforms where it uses the prebuilt libraries), because building from source adds to the compilation time, and not everyone should have to pay for optional static linking support (especially since bevy docs recommends a setup with dynamic linking!).
Issues with Attempted Solution
I can make minimal code changes to conditionally compile
glsl-to-spirv
when thebuild-from-source
feature flag is enabled:Unfortunately, cargo stable will always attempt to enable the feature. This means instead of
build-from-source
being an opt-in feature, cargo stable will instead prevent opting out.Nightly allows us to opt out, as mentioned in #7, by using a flag which is stabilized as resolver version 2, and to be made default in rust edition 2021 (see rust-lang/cargo#9048):
# don't eagerly enable features cargo +nightly run -Z features=itarget --release --target x86_64-pc-windows-msvc --example shader_custom_material
In which case the user can properly opt-in by requesting the feature directly in their
Cargo.toml
:Potential Impact on Dynamic Builds (until cargo resolver 2 is stable)
Since building from source occurs in parallel with compilation of other
bevy
dependencies, measurements must not be isolated to buildingglsl-to-spirv
alone. I use theshader_custom_material
as a baseline, andcargo clean
before every run. The following was run on a Ryzen 7 3700X CPU.This is a 28s addition to what was a 105s build process (up by 26.7%) for first time builds and all subsequent builds post-
cargo clean
.Temporary Conclusions
Although this cost is only incurred once for the user as it will reuse the libraries on subsequent runs, the additional compile time may be a significant turn-off for new users who just want to get started, and does not give a good impression. Further more, any uses of
cargo clean
immediately wipes the slate and requires building from source again, as published crates are not allowed to place libraries outside ofOUT_DIR
.Once cargo defaults to using resolver version 2, we can make this an opt-in feature without any drawbacks to dynamic builds by default.
Current Workarounds
You could target
i686-pc-windows-msvc
when static linking, since that target always has to build anyway, but that comes with all the limitations of a 32-bit application vs a 64-bit application.GNU toolchains currently require dynamically linking
stdc++
(unless someone can figure out how to statically link that), so they are not an alternative to MSVC if you are looking for static builds.The text was updated successfully, but these errors were encountered: