Подтвердить что ты не робот

Компиляция с /MT вместо /MD с использованием CMake

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

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

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

4b9b3361

Ответ 1

Вы можете изменить переменные 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()

Ответ 2

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

Ответ 3

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.

Ответ 4

Я должен использовать 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()