Ninja generator adds "/DEF" linker flag for static libraries
Some of my Windows code statically links against FreeRDP. Previously I was using the "NMake Makefiles JOM" generator with jom to build my code. The code built fine. In the past, I also used regular nmake without problems.
Recently I switched to using the "Ninja" generator with ninja. The code still compiled fine, but I ran into problems running my executable. Every time I ran the executable, Windows would complain that "freerdp-client.dll" was missing. That was odd because I explicitly told FreeRDP to be built as a static library by putting this in my CMakeLists.txt:
set(BUILD_SHARED_LIBS OFF)
I eventually tracked the problem down to this code from client/common/CMakeLists.txt around line 42:
if(MSVC)
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def)
endif()
That line of code was causing the Ninja generator to add this linker flag to LINK_FLAGS
:
/DEF:C:\path\to\FreeRDP\client\common\module.def
I think the /DEF
linker flag was causing the linker to link freerdp-client.lib dynamically instead of statically to my code. The NMake and JOM generators did not add /DEF
to LINK_FLAGS
even though I was using the same CMakeLists.txt
. This difference in behavior was introduced recently in 43ce4414, which added this code to cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement
around line 660:
this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
Inside AddModuleDefinitionFlag
, the /DEF
linker flag is added if a module definition file is in the list of sources. I don't see the Nmake or JOM generators calling AddModuleDefinitionFlag
at all. Given that my code compiles and links correctly with JOM and NMake, I suspect this is a bug in the Ninja generator but I am not sure.
I confirmed that removing module.def
from the list of sources removes /DEF
from LINK_FLAGS
when using the Ninja generator and that my executable now runs correctly without looking for freerdp-client.dll
.
Coincidentally, the FreeRDP project recently modified their CMakeLists.txt files in PR 3168 to completely remove module.def from the list of sources. Thus, this problem should fix itself when I eventually upgrade to the latest version of FreeRDP but it still doesn't explain the difference between the Nmake/JOM and Ninja generators.