在 CMake 中设置 MSVC 运行时

2024-02-09

我按照 CMake 常见问题解答条目中的说明进行操作“如何使用静态运行时构建我的 MSVC 应用程序?” https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#how-can-i-build-my-msvc-application-with-a-static-runtime集中选择一堆嵌套 CMake 项目的 MSVC 运行时(它们作为 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(前any add_library() or 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++,代码生成”下的项目属性时,我发现“运行时库”设置与 shell 中打印的选项不一致。在“Release”、“MinSizeRel”和“RelWithDebInfo”配置下,我得到了预期的结果(“多线程DLL /MD”,但“调试”配置仍然显示“多线程/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 项目文件,我发现“调试”配置没有对具有“Name=VCCLCompilerTool”属性的“Tool”元素的“RuntimeLibrary”属性进行设置。所有其他配置都有显式设置。


随着 cmake-3.15 的发布,此功能将得到改进。

  • CMAKE_MSVC_RUNTIME_LIBRARY https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html#variable:CMAKE_MSVC_RUNTIME_LIBRARY
  • CMP0091 https://cmake.org/cmake/help/latest/policy/CMP0091.html

应该是设置的问题CMAKE_MSVC_RUNTIME_LIBRARY,例如(来自文档)设置“多线程静态链接运行时库,根据配置带或不带调试信息”:

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 CMake 中设置 MSVC 运行时 的相关文章

  • 将 Doctest 与代码一起使用时将实现放在哪里

    我在用着doctest https github com onqtam doctest用于我的 C 项目中的测试 我想将测试代码与我的实现放在一起 正如库所说是可能的 但我似乎不知道如何处理 doctest 实现代码 我有一个doctest
  • 不使用 item.Document.FullName 获取 ProjectItem 路径

    我有一个 Visual Studio 插件项目 我必须利用这些文件的绝对 或相对 路径来迭代当前项目的项目 The item Document FullName有效 但仅适用于当前打开的文件 有没有其他方法可以访问此信息DTE object
  • 将 dll/lib 链接到 cmake 项目

    我试图将库链接到我的 cmake 项目 但遇到链接器错误 我花了 2 个小时尝试解决这个问题 并创建了一个简单的项目 在其中对所有路径进行了硬编码 CMAKE MINIMUM REQUIRED VERSION 3 0 PROJECT Tes
  • 如果在解决方案中使用项目依赖项,MSBuild 不会复制引用(DLL 文件)

    我的 Visual Studio 解决方案中有四个项目 每个项目都针对 NET 3 5 对于我的问题 只有这两个项目很重要 我的基地项目 我的网络项目1 我添加了 elmah dll 引用我的基地项目在 Visual Studio 2008
  • 如何防止 CMake 在构建时(而不是安装时)为共享库创建符号链接?

    我正在使用 CMake 在 Linux 上使用 Bullet3 构建一个项目 在构建整个解决方案时 它会构建附加了 SOVERSION 的 Bullet 输出库 并创建一个不带版本的符号链接 对于我的特定场景 我不喜欢这种行为 并且我不想编
  • 如何将最新的 Windows SDK 版本传递给 CMake?

    如何将最新的 Windows SDK 版本传递给 CMake 这样我就不需要进入 Visual Studio 并从配置属性 常规中手动放置它 我在互联网上搜索 找到了 CMAKE SYSTEM VERSION 变量 并且尝试使用 set C
  • 如何最大化 Visual Studio 面板?

    有没有办法快速最大化 然后恢复 Visual Studio 2010 面板 例如 我想暂时最大化输出窗口或单元测试结果窗口 在 Eclipse 中 我只需双击窗口选项卡 但在 VS 中 这会取消窗口的停靠 所需的行为是 双击以最大化窗口 然
  • 如何使用cmake查找库?

    要将可执行文件与驻留在标准位置的库链接 可以在 CmakeLists txt 文件中执行以下操作 create executable generate mesh generate mesh cpp target link libraries
  • 管理多个解决方案中存在的 C# 项目的 Nuget 包

    我现在正处于这样的阶段重构疯狂一个有很多的大项目遗留和不稳定的模块 我决定拆分解决方案目前 所有项目 大约有 20 个 而且由于下个月肯定会出现单元测试项目 还会有更多 链接在一起 使其更加独立和细化 通过这种方法 有一些模块 例如需要在多
  • Visual Studio 2008 中的外部编辑器

    有没有办法为 VS2008 设置外部编辑器集成 我的意思是 当我在解决方案资源管理器中双击 CPP 文件时 它应该在外部编辑器中打开 而不是在内部 VS 编辑器中打开 为了简单起见 假设我希望它在 Notepad 中打开文件 或者使用 No
  • 无法使用 Visual Studio 2013 中的 F5 进行调试,模块窗口为空

    我正在尝试使用调试程序启动外部程序在 Visual Studio 2013 中 所有项目文件都是 NET 3 5 顺便说一句 自从更新到VS2013 大约两周 以来我就这样调试过 但今天突然停止工作了 当我运行该程序时 它会启动 但是调试
  • 包含来自另一个目录的标头时出现 Visual Studio 链接错误

    简短的问题是 如何使用 Visual Studio 创建 编译 运行在不同目录中具有源代码的项目 以下是具体细节 我在一个目录中有一个类定义文件 hpp 和实现文件 cpp 在另一个目录中有一个 main cpp 文件 在 Visual S
  • ASP.NET Web API Swagger(Swashbuckle)重复OperationId

    I have a web api controller like below In swagger output I am having the below image And when I want to consume it in my
  • Visual Studio 2010 RTM 未通过 ClickOnce 发布

    有人在 VS2010 中使用 ClickOnce 吗 当解决方案构建良好时 我在发布时收到以下内容 Building WindowsFormsApplication1 Error Cannot publish because a proje
  • 无法找到请求的.Net Framework 数据提供程序。 (Sql客户端)

    我正在尝试使用来自 SQL Server 2005 的 DB First 迁移来设置一个简单的 ASP NET MVC 4 Web 应用程序 我已经在数据库中创建了表 并使用实体框架在代码中创建了对象 我可以使用这些对象访问数据 当我尝试使
  • 如何在 CMake Makefile 中包含 OpenCV 库

    我希望你可以帮助我 我有一个简单的 CMakeLists txt 以便在 Leopard 10 5 8 上构建我的项目 我正在使用 CMake 2 8 1 目前这是代码 cmake minimum required VERSION 2 8
  • C++ 中的字符串到 LPCWSTR

    我正在尝试从字符串转换为 LPCWSTR 我使用多位 1 例如 LPCWSTR ToLPCWSTR string text LPCWSTR sw LPCWSTR text c str return sw 2 返回中文字符 LPCWSTR T
  • Cmake选项默认值

    如果我有一个 CMakeLists txt 文件 cmake minimum required VERSION 2 8 OPTION FOO Foo Option OFF MESSAGE FOO FOO 然后我调用 cmake 得到以下输出
  • CMake(Ninja 后端)使用 /MT 编译

    我有一个类似的问题CMake 使用 MT 而不是 MD 进行编译 https stackoverflow com questions 14172856 cmake compile with mt instead of md但有一些差异 我正
  • 我是否需要 SQL Server 数据库项目中链接服务器的数据库引用?

    在我的数据库项目中 我添加了对链接服务器的引用 当我在视图中使用此链接服务器并尝试构建数据库项目时 SSDT 报告错误 因为它无法理解对链接服务器上引用的任何架构的引用 LinkedServer DB1 dbo Table1 上面的代码会返

随机推荐