Search code examples
c++cmakemfclinker-errorsintel-oneapi

Linker error: duplicate symbols from libucrt and libmmt, but need both


I'm trying to build a project with the Intel OneAPI 2024.2.1 compiler. My 32-bit release build has the issue of multiply defined symbols. There's a few math functions that are causing problems:

lld-link: error: duplicate symbol: __CIcos
>>> defined at libmmt.lib(cos_iface_c99.obj)
>>> defined at libucrt.lib(cos_impl.obj)

lld-link: error: duplicate symbol: __CIexp
>>> defined at libmmt.lib(exp_iface_c99.obj)
>>> defined at libucrt.lib(87ctran.obj)

lld-link: error: duplicate symbol: __CIlog
>>> defined at libmmt.lib(log_iface_c99.obj)
>>> defined at libucrt.lib(log_impl.obj)

lld-link: error: duplicate symbol: __CIpow
>>> defined at libmmt.lib(pow_iface_c99.obj)
>>> defined at libucrt.lib(pow_impl.obj)

lld-link: error: duplicate symbol: __CIsin
>>> defined at libmmt.lib(sin_iface_c99.obj)
>>> defined at libucrt.lib(sin_impl.obj)

lld-link: error: duplicate symbol: __CItan
>>> defined at libmmt.lib(tan_iface_c99.obj)
>>> defined at libucrt.lib(tan_impl.obj)

The big problem is, when I exclude either of these libraries (using /nodefaultlib) I get a bunch of missing implementations.

I read something somewhere about stripping some objects out of libucrt, but that's the very last thing I want to be doing. And I can't imagine that's really necessary: there's no way I'm the very first person to try and build a 32 bit release build.

What am I missing here?

Bit more context: I'm trying to use CMakeLists to stitch together multiple libraries. I'm setting /MT (and replacing /MD) on everything I've made myself, but there's a lot I'm pulling from git repos. However, I'm not getting any warnings about static/dynamic linking mismatch. So I'm assuming the linker errors I'm getting now aren't due to "mixing runtimes" (correct me if I'm wrong, my knowledge on this is very basic).


Solution

  • In the end, the solution turned out to be very counterintuitive:

    I had to use /nodefaultlib on libucrt.lib, and then link libucrt.lib

    The specific line in my CMakeLists (for the Intel compiler, which uses /Qoption,link, as a prefix for the linker option) was as follows:

    target_link_options(MyTarget PUBLIC /Qoption,link,/NODEFAULTLIB:libucrt.lib libucrt.lib)