cmake:msvc分别对不同的target使用不同的运行库选项(/MT或/MD)

很久以前写过一篇关于cmake下为msvc设置/MT的文章:

cmake:msvc编译第三方库时使用/MT静态库连接c/c++ runtime library

当时是为了解决用msvc编译时使用/MT连接static c library的问题。CMakeLists.txt中添加如下的代码,即可以将所有默认的C,CXX编译选项中的/MD替换成/MT.

if(MSVC)     
    # Use the static C library for all build types
    foreach(var 
        CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
        CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
        CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO
      )
      if(${var} MATCHES "/MD")
        # 正则表达式替换/MD为/MT
        string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
      endif()
    endforeach()    
endif(MSVC)

如果你希望CMakeLists.txt中所有的target都使用c/c++静态库,那么上面的做法就完全满足需要。
但如果希望针对CMakeLists.txt中的不同target使用不同的/MT/MD选项,这个办法就不行了。如果希望针对特定的target设置/MT选项,该怎么办呢?

这里就用到了target_compile_options命令还用到了Generator expressions,以下为封装成function的实现代码

# Use the static C library for all build types to a target
# MSVC编译时对指定的target设置'/MT'选项连接static c/c++ library
function (with_mt_if_msvc target )
if(MSVC) 
  # Generator expressions
  set(_mt "/MT$<$<CONFIG:Debug>:d")
  get_target_property(_options ${target} COMPILE_OPTIONS)
  if(_options)
    # message(STATUS "${target} COMPILE_OPTIONS=${_options}")
    if(${_options} MATCHES "/MD")
      string(REGEX REPLACE "/MD" "/MT" _options "${_options}")
    else()
      set(_options "${_options} ${_mt}")
    endif()    
  else()
    set(_options "${_mt}")
  endif() 
  get_target_property(_type ${target} TYPE)
  # 判断 ${target}是否为静态库
  if(_type STREQUAL "STATIC_LIBRARY")
    # 静态库将/MT选项加入INTERFACE_COMPILE_OPTIONS
    target_compile_options( ${target} PUBLIC "${_options}")
  else()
    target_compile_options( ${target} PRIVATE "${_options}")
  endif()
  # Cleanup temporary variables.
  unset(_mt)
  unset(_options)
  message(STATUS "target ${target} use static runtime /MT")
endif(MSVC)
endfunction()

有了这个with_mt_if_msvc函数,你可以针对target设置/MT选项,而那些没有指定的target仍使用默认的/MD选项

参考资料

Is it possible, in the same CMakeLists.txt, to setup projects with /MT and others with /MD?
target_compile_options
cmake-generator-expressions

猜你喜欢

转载自blog.csdn.net/10km/article/details/79973750