[CMake] MSVC /M[TD]<d> as a compatible interface property?

Walter Gray chrysalisx at gmail.com
Thu Jun 9 21:11:14 EDT 2016


Yeah, that issue with /MD and /MT is the reason every project I've seen
that deals with this problem uses something like this:

#
https://cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
foreach(flag_var
        CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
   if(${flag_var} MATCHES "/MD")
      string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
   endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)

Just appending also means that you cant just check if the compile flags
contain one or the other using string(FIND...)

/MD and /MT are by no means unique in being a compile flag that needs to be
the same between linked packages. I'd forgotten about
HAS_ITERATOR_DEBUGGING, but STL version also comes to mind (vs10 vs vs12,
libstdc++ vs libc++, ect)

On Thu, Jun 9, 2016 at 2:54 PM Daniel Schepler <
dschepler at scalable-networks.com> wrote:

> A while ago I did an experiment along the same lines, using something like
> this in CMake/MTflags.cmake.  (What we really needed was forcing /MT
> /D_HAS_ITERATOR_DEBUGGING=0 even on debug builds, because we were using an
> external library only available in /MT format.  So I might have
> accidentally broken it while adapting it here.)
>
> add_library(MTflags INTERFACE)
> target_compile_options(MTflags INTERFACE "/MT$<$<CONFIG:Debug>:d>")
> set_property(TARGET MTflags
>     PROPERTY INTERFACE_MSVC_MT ON)
> set_property(TARGET MTflags
>     APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL MSVC_MT)
>
> # Example usage:
> # include(MTflags)
> # add_library(A STATIC src1.cpp src2.cpp...)
> # target_link_libraries(A PUBLIC MTflags)
>
> That almost did what we wanted.  The biggest problem (and the one annoying
> enough to make me abandon the experiment for the time being) was: if you
> configured using the "NMake Makefiles" generator, then the compiler would
> give a warning on each source file because the build system was passing
> both the default /MD[d] and the additional /MT.
> --
> Daniel Schepler
> ------------------------------
> *From:* CMake [cmake-bounces at cmake.org] on behalf of Walter Gray [
> chrysalisx at gmail.com]
> *Sent:* Thursday, June 09, 2016 1:58 PM
> *To:* Cmake Mailing List
> *Subject:* [CMake] MSVC /M[TD]<d> as a compatible interface property?
>
> Setting /MT or /MD is pretty important, and is a transitive requirement.
> See: https://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.80).aspx
>
> The standard mechanism of using target_compile_options isn't quite
> appropriate because it will simply append the flags used by each library
> and use the last one with no complaint if there is a mismatch.
>
> Example:
> A uses /MT, B uses /MD, C Depends on both.
> This will result in errors when compiling, but will configure just fine. I
> would like to make it so that if there is a mismatch between linked
> targets, cmake will either fail or issue a warning.
>
>
> https://cmake.org/cmake/help/v3.5/manual/cmake-buildsystem.7.html#compatible-interface-properties
> This seems to be meant to be used for exactly this type of thing, but
> because there is no specific property for specifying MSVC_RUNTIME, that
> system cannot be used in this case.
>
> Any thoughts on how to address this?
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20160610/2eb00fe3/attachment-0001.html>


More information about the CMake mailing list