Linker problem with mixed debug/release libs

Hello,

I'm trying to link a static lib built in rust to a C++ executable, and I'm running into issues with my dependencies. If I pull in wgpu into the rust portion, it seems to be pulling in spirv-cross. The issue is, it looks like the objects from spirv-cross are complied for Release, while the rest of my project is compiled for Debug. I only seem to have this problem on Windows. This causes me to see the following errors:

rust_lib.lib(wrapper.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(wrapper.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_cross.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_cross.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_cross_util.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_cross_util.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_glsl.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_glsl.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_hlsl.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_hlsl.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_msl.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_msl.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_cfg.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_cfg.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_cross_parsed_ir.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_cross_parsed_ir.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
rust_lib.lib(spirv_parser.o) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.cpp.obj
rust_lib.lib(spirv_parser.o) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in main.cpp.obj
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
rust_lib.lib(gfx_backend_dx12-c67ba4afb37d0d59.gfx_backend_dx12.24fc9stw-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol DXGIGetDebugInterface1 referenced in function _ZN16gfx_backend_dx128Instance6create17hf47424177c38609eE
cpp-exe\cpp-exe.exe : fatal error LNK1120: 1 unresolved externals
ninja: build stopped: subcommand failed.

I've put together a repro here: https://github.com/robmikh/linkerhell
Just run .\scripts\windows\winBuild.cmd. It requires MSVC and ninja to build. It does not repro on Linux or macOS (you can try it yourself with their respective scripts).

I have a couple questions:

  • Is it normal for Debug and Release to be mixed like this?
  • Is there a way to force my dependencies to build as Debug?
  • Am I totally off-base and missing something simple?

Any pointers would be appreciated :slight_smile:

EDIT: I'm also aware that I don't have all the required libs specified in the repro (d3d12.lib, dxgi.lib, etc), I just haven't bothered hunting down all the other requirements since I haven't been able to fix this specific issue yet.

EDIT2: I updated the script with the ability to build in release mode (as well as fill in the missing wgpu dependencies). As expected, this doesn't repro when building release. Just pass "release" when you call the script.

EDIT3: I added scripts for Linux (tested on popOS) and macOS. Neither platform reproduces the problem.

It's an imperfect solution, but compiling with /MD resolved the issue on Windows.

I was informed that Rust always uses the release CRT. The solution that was found is the only solution when static linking.