Я следую инструкциям в разделе часто задаваемых вопросов CMake "Как я могу создать свое приложение MSVC со статической средой выполнения?" централизовать выбор среды выполнения MSVC для нескольких вложенных проектов CMake (они извлекаются как подмодули Git и добавляются в главный проект с помощью директивы CMake find_package()
).
Итак, я написал этот макрос CMake:
macro(configure_msvc_runtime)
if(MSVC)
# Default to statically-linked runtime.
if("${MSVC_RUNTIME}" STREQUAL "")
set(MSVC_RUNTIME "static")
endif()
# Set compiler options.
set(variables
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
if(${MSVC_RUNTIME} STREQUAL "static")
message(STATUS
"MSVC -> forcing use of statically-linked runtime."
)
foreach(variable ${variables})
if(${variable} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}")
endif()
endforeach()
else()
message(STATUS
"MSVC -> forcing use of dynamically-linked runtime."
)
foreach(variable ${variables})
if(${variable} MATCHES "/MT")
string(REGEX REPLACE "/MT" "/MD" ${variable} "${${variable}}")
endif()
endforeach()
endif()
endif()
endmacro()
Я вызываю этот макрос в начале моего корневого CMakeLists.txt
(до выполнения любого add_library()
или add_executable()
) и добавляю немного отладочных отпечатков:
configure_msvc_runtime()
set(variables
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
message(STATUS "Initial build flags:")
foreach(variable ${variables})
message(STATUS " '${variable}': ${${variable}}")
endforeach()
message(STATUS "")
Затем я запускаю CMake для генерации решения Visual Studio следующим образом:
cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=dynamic
и я получаю следующие выводы:
-- MSVC -> forcing use of dynamically-linked runtime.
-- Initial build flags:
-- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_C_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG
Дело в том, что когда я запускаю Visual Studio и проверяю свойства проекта в разделе "C/C++, Генерация кода", я вижу, что параметр "Библиотека времени выполнения" не согласуется с параметрами, напечатанными в оболочке. В конфигурациях "Release", "MinSizeRel" и "RelWithDebInfo" я получаю ожидаемые результаты ("Многопоточная DLL/MD", но в конфигурации "Debug" по-прежнему отображается "Многопоточная /MT").
Кроме того, когда я принудительно использую статически связанную среду выполнения, я получаю аналогичные результаты. Если я бегу
cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=static
Я получаю следующие выводы:
-- MSVC -> forcing use of statically-linked runtime.
-- Initial build flags:
-- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_C_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG
И все же все конфигурации выдают значение "Многопоточный /MT" для параметра "Библиотека времени выполнения".
Что я делаю не так, или это ошибка в CMake (2.8.7) или что-то в этом роде?
Для чего стоит, если я сгенерирую файлы проекта Visual Studio 2010, я получу другое значение для конфигурации "Отладка", но все равно не то, которое я выбрал.
Во всех случаях параметр отображается обычным шрифтом для конфигурации "Отладка", тогда как для других конфигураций он выделяется жирным шрифтом, указывая на то, что это переопределения. Более того, если я открою файлы проекта XML, то обнаружу, что в конфигурации "Отладка" нет настройки для атрибута "RuntimeLibrary" элемента "Инструмент" с атрибутом "Name = VCCLCompilerTool". Все остальные конфигурации имеют явную настройку.