CMake скомпилировать с /MT вместо /MD

Я использую cmake на Windows с Windows SDK и NMake Makefiles

По умолчанию он компилируется с ключом компилятора /MD.

Как я могу изменить его для компиляции с ключом /MT вместо этого?

6 ответов

Решение

Вы можете изменить CMAKE_CXX_FLAGS_<Build Type> и / или CMAKE_C_FLAGS_<Build Type> переменные:

set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")

Если ваши флаги CMake уже содержат /MD, вы можете убедиться, что вышеуказанные команды выполняются после того момента, когда /MD вставляется (позднее добавление /MT переопределяет конфликтующий существующий параметр), или вы можете установить флаги с нуля:

set(CMAKE_CXX_FLAGS_RELEASE "/MT")
set(CMAKE_CXX_FLAGS_DEBUG "/MTd")

Или, в качестве альтернативы, вы можете заменить существующий /MD а также /MDd значения с /MT а также /MTd соответственно делая что-то вроде:

set(CompilerFlags
        CMAKE_CXX_FLAGS
        CMAKE_CXX_FLAGS_DEBUG
        CMAKE_CXX_FLAGS_RELEASE
        CMAKE_C_FLAGS
        CMAKE_C_FLAGS_DEBUG
        CMAKE_C_FLAGS_RELEASE
        )
foreach(CompilerFlag ${CompilerFlags})
  string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()

CMake наконец добавил правильную поддержку для этого в версии 3.15 с MSVC_RUNTIME_LIBRARY целевое свойство:

cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW)
project(my_project)

add_executable(foo foo.c)
set_property(TARGET foo PROPERTY
             MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

Вы также можете указать глобальное значение по умолчанию, установив CMAKE_MSVC_RUNTIME_LIBRARY переменная вместо

Похоже, для Visual Studio 15 2017 и CMake 3.12 способ заменить/MD по /MT заключается в добавлении этого фрагмента в файл CMakeLists.txt:

if(MSVC)
    add_compile_options(
        $<$<CONFIG:>:/MT> #---------|
        $<$<CONFIG:Debug>:/MTd> #---|-- Statically link the runtime libraries
        $<$<CONFIG:Release>:/MT> #--|
    )
endif()

Я нашел это решение в официальном репозитории CMake: https://gitlab.kitware.com/cmake/cmake/issues/18390

Я должен использовать set( ... CACHE ... FORCE) переписать кеш MSVC по умолчанию.

Если я не использую этот метод, MSVC все еще выводит /MD параметры.

set(CompilerFlags
        CMAKE_CXX_FLAGS
        CMAKE_CXX_FLAGS_DEBUG
        CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_MINSIZEREL
        CMAKE_CXX_FLAGS_RELWITHDEBINFO
        CMAKE_C_FLAGS
        CMAKE_C_FLAGS_DEBUG
        CMAKE_C_FLAGS_RELEASE
        CMAKE_C_FLAGS_MINSIZEREL
        CMAKE_C_FLAGS_RELWITHDEBINFO
        )
foreach(CompilerFlag ${CompilerFlags})
    string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
    set(${CompilerFlag} "${${CompilerFlag}}" CACHE STRING "msvc compiler flags" FORCE)
    message("MSVC flags: ${CompilerFlag}:${${CompilerFlag}}")
endforeach()

Начиная с cmacke 3.15, вы можете использовать MSVC_RUNTIME_LIBRARY. См. https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html .

checkout ucm_set_runtime - этот макрос заменит флаги для статической или динамической среды выполнения - чтобы увидеть эффекты, используйте ucm_print_flags (также извлекаем этот поток stackru)

Другие вопросы по тегам