Linking Libraries on Windows

I have been working on making a cross-platform engine, and wanted to dynamically link against all libraries. I encountered the following warning:

warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library

That sent me down a rabbit hole to learn about linking under Windows. There is definitely a missing gap for me, since I have been focused on Unix-like platforms. But here are a few notes that I want to remember.

Is a DLL 32- or 64-bit?

On Mac or Linux, this is easily done with file or objdump commands. On Windows, however, if I want to learn about luat51.dll:

dumpbin /HEADERS lua51.dll | findstr 14C

Linking Using Import Library

On Windows, .dll is the dynamically linked library, one that you need to ship with executable. .lib can be a static library, but also an import library that is used to link against a .dll. From time to time there are also .exp files that defines exported functions so that you can work with circular dependencies. More information here and here.

To summarize, if you want to build a toolchain for Windows, you need at the minimum the header files, .dll, and .lib.

LNK4098 Warning

This is a result of linking against libraries that were built using different multi-threading libraries. There are four variants: static release (/MT), static debug (/MTd), dynamic release (/MD), and dynamic debug (/MDd). All of the libraries you are linking against must have been built using the same switch or else you get LNK4098 warning. The library quoted in the warning changes depending on which switch current build target is using.

To change current build target to match libraries you are linking against, try linking using either /MD or /MT. In Visual Studio, this option is listed under the project's Configuration Properties (ALT+F7) → C/C++ → Code Generation → Runtime Library.

LNK2019 Error

There appears to be a lot of reasons why you get LNK2019 error. In my case, this worked when building for release but fails for debug.

As it turns out, not all libraries can be linked both as debug and release libraries. There may not be anything wrong, it just means you need another set of libraries that were build for debug or release instead.