Clang debug linking options on Windows

I’m trying to compile some code via IR and link it with the debug libraries on Windows, but getting errors. A minimal test case:

C:\t>type a.cpp
#define _HAS_EXCEPTIONS 0
#include <llvm/Support/Signals.h>

int main() {
llvm::sys::PrintStackTraceOnErrorSignal();
return 0;
}

C:\t>clang -I/llvm/build/include -I/llvm/include -S -emit-llvm -fms-compatibility-version=19 a.cpp

C:\t>clang a.ll \llvm\build\Debug\lib*.lib
warning: overriding the module target triple with x86_64-pc-windows-msvc18.0.0 [-Woverride-module]
1 warning generated.
LLVMSupport.lib(Signals.obj) : error LNK2038: mismatch detected for ‘_ITERATOR_DEBUG_LEVEL’: value ‘2’ doesn’t match value ‘0’ in a-db717b.o
LLVMSupport.lib(Signals.obj) : error LNK2038: mismatch detected for ‘RuntimeLibrary’: value ‘MTd_StaticDebug’ doesn’t match value ‘MT_StaticRelease’ in a-db717b.o
LLVMSupport.lib(Path.obj) : error LNK2038: mismatch detected for ‘_ITERATOR_DEBUG_LEVEL’: value ‘2’ doesn’t match value ‘0’ in a-db717b.o
LLVMSupport.lib(Path.obj) : error LNK2038: mismatch detected for ‘RuntimeLibrary’: value ‘MTd_StaticDebug’ doesn’t match value ‘MT_StaticRelease’ in a-db717b.o
LLVMSupport.lib(raw_ostream.obj) : error LNK2038: mismatch detected for ‘_ITERATOR_DEBUG_LEVEL’: value ‘2’ doesn’t match value ‘0’ in a-db717b.o

…etc…

There’s probably an option that I’m missing?

Try adding -g as a parameter to clang

You’re crossing the relase/debug MSVC CRT streams. Make sure all objects in a given image are using the same CRT.

In your specific example, you should add -D_DEBUG to the command line. You want to simulate the effect of passing /MTd to cl.exe or clang-cl.exe.

That almost works. What am I still missing? I tried -g but no effect.

C:\t>clang -D_DEBUG -I/llvm/build/include -I/llvm/include -S -emit-llvm -fms-compatibility-version=19 a.cpp

C:\t>clang a.ll \llvm\build\Debug\lib*.lib
warning: overriding the module target triple with x86_64-pc-windows-msvc18.0.0 [-Woverride-module]
1 warning generated.
LINK : warning LNK4098: defaultlib ‘LIBCMTD’ conflicts with use of other libs; use /NODEFAULTLIB:library
LLVMSupport.lib(TargetParser.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW
libcpmtd.lib(stdthrow.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW
libcpmtd.lib(syserror.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW
LLVMSupport.lib(ConvertUTFWrapper.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW
LLVMSupport.lib(Host.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW
LLVMSupport.lib(MemoryBuffer.obj) : error LNK2001: unresolved external symbol _CrtDbgReportW
etc…

Also try defining _MT

_MT has no effect; same errors.

Took a look at llvm/tools/clang/lib/Driver/Tools.cpp, and it looks like all you need to do is pass “/MTd” and clang will add the following:

-D_DEBUG
-D_MT
–dependent-lib=libcmtd

You’ll probably need it for both the compile and link steps.

I don’t have windows, so I can’t verify, so I hope this helps…
don

That works, thanks! It turns out to be only needed for the compile step, and it requires clang-cl - the option to output intermediate code is then ‘-c -Xclang -emit-llvm’ which will output files with .obj extension, but these are actually intermediate code files that just have to be renamed to .ll before machine code generation and linking.