【OpenCV】CMake 源码生成 VS2017 win32 静态库工程时,如何指定 /MT 和 /MD

我在集成开源 OpenCV 的图像质量评估功能时碰到一个运行时库问题。

win32平台开发需要:

  1. 先用 CMake 源码生成 VS2017 win32 静态库工程 (优先使用开源项目的静态库lib)
  2. 然后将OpenCV静态库的接口封装成一个DLL
  3. 最后将封装后DLL集成到项目中

但在第2步生成DLL时链接报错:

bash 复制代码
1>------ 已启动生成: 项目: xxxcv, 配置: Release Win32 ------
1>opencv_world4130.lib(mean.dispatch.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(calibinit.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(calibration.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(out.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(loadsave.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(thresh.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(cornersubpix.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(matrix.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(convert.dispatch.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(color.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(matrix_wrap.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(system.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(deriv.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
1>opencv_world4130.lib(norm.dispatch.obj) : error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"(cloopbuffer.obj 中)
......

❌ 问题:运行时库(Runtime Library)不匹配

复制代码
error LNK2038: 检测到"RuntimeLibrary"的不匹配项: 值"MT_StaticRelease"不匹配值"MD_DynamicRelease"

🔍 原因:

  • OpenCV 静态库 opencv_world4130.lib 是用 /MT(静态链接运行时库)编译的。
  • 而你的项目 cloopbuffer.obj 是用 /MD(动态链接运行时库)编译的。
  • Visual Studio 不允许混合使用 /MT/MD,因为它们使用不同的 C 运行时(CRT)。

✅ 解决方案:

统一运行时库选项。

下面有两种改法:

方案 1:将你的项目改为使用 /MT
  1. 在 Visual Studio 中右键你的项目 → 属性(Properties)
  2. 进入 C/C++ → Code Generation
  3. Runtime Library 设置为:
    • Release 模式Multi-threaded (/MT)
    • Debug 模式Multi-threaded Debug (/MTd)

⚠️ 注意:如果你的项目依赖其他第三方库,也要确保它们也是用 /MT 编译的,否则会再次出现类似冲突。

方案 2:重新编译 OpenCV 使用 /MD

如果你不想改自己的项目设置(比如你必须用 /MD),那么你需要:

  • 从源码重新编译 OpenCV,并在 CMake 配置时指定 /MD

💡 OpenCV 官方预编译的 opencv_world4130.lib 默认是 /MT 的(尤其是 static 版本),所以大多数情况下建议你改自己的项目为 /MT。


🔧 补充:如何确认 lib 的编译方式?

你可以用 dumpbin 查看 .lib 文件的编译选项:

cmd 复制代码
dumpbin /directives xxx.lib | findstr "RuntimeLibrary"

或者用工具如 Dependency WalkerVisual Studio 的 lib 工具


项目其他组件库都是 /MD ,所以我只能选择 "方案2 重新编译 OpenCV 使用 /MD"

重新编译 OpenCV 使用 /MD

我再重编 OpenCV 时,使用了许多方法来指定 /MD ,但都失败了,结果都是 /MT

失败举例:

  1. 使用 CMake 配置选项 DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL"
bash 复制代码
cmake -G "Visual Studio 15 2017" -A Win32 \
      -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" \
      ......
  1. 使用 OpenCV 提供的专用选项 OPENCV_LINK_RUNTIMEDYNAMIC
bash 复制代码
cmake -G "Visual Studio 15 2017" -A Win32 \
      -D CMAKE_BUILD_TYPE=Release \
      -D OPENCV_LINK_RUNTIMEDYNAMIC=ON \
      -D BUILD_SHARED_LIBS=ON \
      ......
  1. CMake 同时使用两个变量(双重保险)
bash 复制代码
cmake -G "Visual Studio 15 2017" -A Win32 \
      -D CMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" \
      -D OPENCV_LINK_RUNTIMEDYNAMIC=ON \
      -D BUILD_SHARED_LIBS=ON \
      ......
  1. 在 CMake 命令行中显式清除 /MT 并注入 /MD
bash 复制代码
cmake -G "Visual Studio 15 2017" -A Win32 ^
      -D CMAKE_BUILD_TYPE=Release ^
      -D BUILD_SHARED_LIBS=OFF ^
      -D OPENCV_LINK_RUNTIMEDYNAMIC=ON ^
      -D CMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" ^
      -D CMAKE_CXX_FLAGS_RELEASE="/MD -Ob2 -Oi -O2" ^
      -D CMAKE_C_FLAGS_RELEASE="/MD -Ob2 -Oi -O2" ^
      -D CMAKE_CXX_FLAGS_DEBUG="/MDd -Zi -Ob0 -Od" ^
      -D CMAKE_C_FLAGS_DEBUG="/MDd -Zi -Ob0 -Od" ^
      ......
  1. 用 msbuild 覆盖项目属性(强制指定 /MD)
    即使OpenCV VS2017项目文件原本是 /MDd 或 /MT,你也可以在 msbuild 命令行中覆盖 RuntimeLibrary 属性
bash 复制代码
msbuild opencv.sln /p:Configuration=Release /p:Platform=Win32 ^
                   /p:RuntimeLibrary=MultiThreadedDLL

但是以上所有方案全都失败了!

🔍 推测失败原因:

OpenCV 在其他地方(如 OpenCVUtils.cmakeOpenCVMinDepVersions.cmake)或通过 CMake 的默认行为设置了 /MT

  • OpenCV 其他脚本注入 /MT | 显式覆盖 `CMAKE_CXX_FLAGS_*

🛠️ 建议:查找真正的 /MT 注入点

在 OpenCV 源码中全局搜索:

bash 复制代码
grep -r "/MT" cmake/
grep -r "MultiThreaded[^D]" cmake/

重点关注:

  • cmake/OpenCVUtils.cmake
  • cmake/OpenCVMinDepVersions.cmake
  • CMakeLists.txt

查找结果1:

OpenCVCRTLinkage.cmake 文件中:

bash 复制代码
if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
  if(MSVC_RUNTIME_SET_BY_ABSTRACTION STREQUAL "NEW")
    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
  else()
    foreach(flag_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(${flag_var} MATCHES "/MD")
        string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
      endif()
      if(${flag_var} MATCHES "/MDd")
        string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
      endif()
    endforeach(flag_var)
  endif()

  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:atlthunk.lib")
  set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:msvcrt.lib")
  set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:libcpmtd.lib /NODEFAULTLIB:msvcrtd.lib")
else()
  if(NOT MSVC_RUNTIME_SET_BY_ABSTRACTION STREQUAL "NEW")
    foreach(flag_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(${flag_var} MATCHES "/MT")
        string(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}")
      endif()
      if(${flag_var} MATCHES "/MTd")
        string(REGEX REPLACE "/MTd" "/MDd" ${flag_var} "${${flag_var}}")
      endif()
    endforeach(flag_var)
  endif()
endif()

上面提供完整的 OpenCVCRTLinkage.cmake 逻辑!现在我们可以100% 精准定位问题并给出终极解决方案


🔍 问题本质(结合你提供的完整逻辑)

该文件的核心逻辑如下:

cmake 复制代码
if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
    # → 强制使用 /MT(静态 CRT)
else()
    # → 强制使用 /MD(动态 CRT) ← 这才是你要的路径!
endif()

✅ 关键结论:

要让 OpenCV 静态库(BUILD_SHARED_LIBS=OFF)使用 /MD,必须确保 BUILD_WITH_STATIC_CRT=OFF

否则,程序会进入第一个 if 分支,无论你是否设置了 CMAKE_MSVC_RUNTIME_LIBRARYOPENCV_LINK_RUNTIMEDYNAMIC=ON,都会被强制覆盖为 /MT


在 OpenCV 中,OPENCV_LINK_RUNTIMEDYNAMIC 的作用通常是:

cmake 复制代码
# 在某处(如 CMakeLists.txt)有类似逻辑:
if(DEFINED OPENCV_LINK_RUNTIMEDYNAMIC)
    set(BUILD_WITH_STATIC_CRT ${OPENCV_LINK_RUNTIMEDYNAMIC} EQUAL 0)
endif()

如果这个映射发生在 OpenCVCRTLinkage.cmake 被包含之后 ,或者变量作用域有问题,BUILD_WITH_STATIC_CRT 仍可能保持默认值 ON

因此,最可靠的方式是直接设置 BUILD_WITH_STATIC_CRT=OFF,绕过中间层。


✅ 终极解决方案:正确 CMake 命令

bat 复制代码
cmake -G "Visual Studio 15 2017" -A Win32 ^
      -D CMAKE_BUILD_TYPE=Release ^
      -D BUILD_SHARED_LIBS=OFF ^
      -D BUILD_WITH_STATIC_CRT=OFF ^          ← ⭐ 必须显式关闭!
      -D CMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" ^
      -D CMAKE_POLICY_DEFAULT_CMP0091=NEW ^
      <opencv_source_path>

参数说明:

参数 作用
-D BUILD_SHARED_LIBS=OFF 构建静态库(.lib)
-D BUILD_WITH_STATIC_CRT=OFF 关键! 禁用 /MT,走 else() 分支 → 使用 /MD
-D CMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" CMake ≥3.15 标准方式,与新策略兼容
-D CMAKE_POLICY_DEFAULT_CMP0091=NEW 启用 CMake 新的运行时库抽象机制

🔎 验证是否成功

配置完成后,检查以下两点:

1. CMakeCache.txt 中:

txt 复制代码
BUILD_WITH_STATIC_CRT:BOOL=OFF

2. 生成的 .vcxproj 文件中(任一项目):

xml 复制代码
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>   <!-- Release -->
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <!-- Debug -->

💡 如果看到 MultiThreaded(无 DLL),说明仍走了 /MT 分支,BUILD_WITH_STATIC_CRT 未生效。


⚠️ 特别注意:else() 分支中的 /MT → /MD 替换

你提供的 else() 分支中有这段代码:

cmake 复制代码
if(NOT MSVC_RUNTIME_SET_BY_ABSTRACTION STREQUAL "NEW")
  foreach(flag_var ...)
    if(${flag_var} MATCHES "/MT")
      string(REGEX REPLACE "/MT" "/MD" ...)
    endif()
  endforeach()
endif()

这意味着:

  • 如果你使用 CMake < 3.15CMP0091 未启用),OpenCV 会主动把 flags 中的 /MT 改成 /MD
  • 但如果初始 flags 是空的,或已经是 /MD,则无需替换。
  • 但在你的场景中,我们希望走这个 else() 分支,并且最好配合 CMAKE_MSVC_RUNTIME_LIBRARY(CMake ≥3.15)以避免字符串替换的不确定性。

📌 最佳实践总结

场景 推荐配置
静态库 + /MD(你的需求) -D BUILD_SHARED_LIBS=OFF -D BUILD_WITH_STATIC_CRT=OFF
静态库 + /MT(默认) 不设置 BUILD_WITH_STATIC_CRT(默认 ON)
动态库(.dll) -D BUILD_SHARED_LIBS=ON(此时 BUILD_WITH_STATIC_CRT 默认 OFF,用 /MD

记住:BUILD_WITH_STATIC_CRT 是控制 /MT vs /MD 的总开关,优先级高于其他变量。


🔚 附加建议

如果你仍然遇到问题,请在 CMake 配置输出中搜索:

txt 复制代码
BUILD_WITH_STATIC_CRT

确认其值是否为 OFF。如果仍是 ON,说明命令行参数未传入成功(检查拼写、缓存等)。

也可以先清理构建目录:

bat 复制代码
rd /s /q build
mkdir build
cd build
cmake -G ...(完整命令)

这样可避免 CMake 缓存旧值。

查找结果2:

CMakeLists.txt 文件中:

bash 复制代码
# OpenCV build components
# ===================================================
OCV_OPTION(BUILD_SHARED_LIBS        "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" NOT (ANDROID OR APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_opencv_apps        "Build utility applications (used for example to train classifiers)" (NOT ANDROID AND NOT WINRT) IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_opencv_js          "Build JavaScript bindings by Emscripten" OFF )
OCV_OPTION(BUILD_ANDROID_PROJECTS   "Build Android projects providing .apk files" ON  IF ANDROID )
OCV_OPTION(BUILD_ANDROID_EXAMPLES   "Build examples for Android platform"         ON  IF ANDROID )
OCV_OPTION(BUILD_DOCS               "Create build rules for OpenCV Documentation" OFF  IF (NOT WINRT AND NOT APPLE_FRAMEWORK))
OCV_OPTION(BUILD_EXAMPLES           "Build all examples"                          OFF )
OCV_OPTION(BUILD_PACKAGE            "Enables 'make package_source' command"       ON  IF NOT WINRT)
OCV_OPTION(BUILD_PERF_TESTS         "Build performance tests"                     NOT INSTALL_CREATE_DISTRIB  IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_TESTS              "Build accuracy & regression tests"           NOT INSTALL_CREATE_DISTRIB  IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_WITH_DEBUG_INFO    "Include debug info into release binaries ('OFF' means default settings)" OFF )
OCV_OPTION(BUILD_WITH_STATIC_CRT    "Enables use of statically linked CRT for statically linked OpenCV" ON IF MSVC )
OCV_OPTION(BUILD_WITH_DYNAMIC_IPP   "Enables dynamic linking of IPP (only for standalone IPP)" OFF )
OCV_OPTION(BUILD_FAT_JAVA_LIB       "Create Java wrapper exporting all functions of OpenCV library (requires static build of OpenCV modules)" ANDROID IF NOT BUILD_SHARED_LIBS)
OCV_OPTION(BUILD_ANDROID_SERVICE    "Build OpenCV Manager for Google Play" OFF IF ANDROID )
OCV_OPTION(BUILD_CUDA_STUBS         "Build CUDA modules stubs when no CUDA SDK" OFF  IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_JAVA               "Enable Java support"                         (ANDROID OR NOT CMAKE_CROSSCOMPILING)  IF (ANDROID OR (NOT APPLE_FRAMEWORK AND NOT WINRT)) )
OCV_OPTION(BUILD_OBJC               "Enable Objective-C support"                  ON  IF APPLE_FRAMEWORK )
OCV_OPTION(BUILD_KOTLIN_EXTENSIONS  "Build Kotlin extensions (Android)"           ON  IF ANDROID )

上面提供 CMakeLists.txt 中关于构建选项的关键片段!现在我们可以彻底、精准地解释为什么你的 OpenCV 静态库工程仍然使用 /MT,以及如何 100% 可靠地切换到 /MD


🔥 核心问题定位(基于你提供的代码)

CMakeLists.txt 中,有这一行:

cmake 复制代码
OCV_OPTION(BUILD_WITH_STATIC_CRT "Enables use of statically linked CRT for statically linked OpenCV" ON IF MSVC )

✅ 关键解读:

  • 默认值:ON
  • 生效条件:IF MSVC → 在 Windows + Visual Studio 下总是生效
  • 作用对象:即使你构建的是静态库(BUILD_SHARED_LIBS=OFF),它也会启用静态 CRT(即 /MT

📌 这就是你所有问题的根源!

OpenCV 在 MSVC 平台下默认为静态库启用 /MT,这是设计行为,不是 bug。


✅ 正确解决方案(终极版)

要让 OpenCV 静态库使用 动态 CRT(/MD ,你必须显式覆盖这个默认值

bat 复制代码
cmake -G "Visual Studio 15 2017" -A Win32 ^
      -D BUILD_SHARED_LIBS=OFF ^
      -D BUILD_WITH_STATIC_CRT=OFF ^     ← ⭐ 这是唯一关键参数!
      <other options...>
      path\to\opencv-source

为什么其他参数不够?

参数 是否足够? 原因
-D OPENCV_LINK_RUNTIMEDYNAMIC=ON ❌ 不一定 它可能只是 BUILD_WITH_STATIC_CRT=OFF 的别名,但在某些版本中映射不及时
-D CMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" ❌ 不够 OpenCV 的 OpenCVCRTLinkage.cmake先于 CMake 抽象机制强制覆盖 flags
-D BUILD_WITH_STATIC_CRT=OFF 足够且必要 直接关闭 OpenCV 的 /MT 强制逻辑,走 else() 分支 → 使用 /MD

🔍 内部机制详解(结合你之前提供的文件)

  1. CMakeLists.txt 设置默认值

    cmake 复制代码
    OCV_OPTION(BUILD_WITH_STATIC_CRT ... ON IF MSVC)

    → 在 MSVC 下,BUILD_WITH_STATIC_CRT=ON(除非你覆盖)

  2. OpenCVCRTLinkage.cmake 执行逻辑

    cmake 复制代码
    if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
        # 强制 /MT
    else()
        # 强制 /MD ← 你要进这里!
    endif()
  3. 只有当你设置 -D BUILD_WITH_STATIC_CRT=OFF ,才会进入 else() 分支,从而:

    • 如果 CMake ≥ 3.15 + CMP0091=NEW → 使用 CMAKE_MSVC_RUNTIME_LIBRARY
    • 否则 → 主动将 flags 中的 /MT 替换为 /MD

✅ 推荐完整命令(VS2017 Win32 静态库 + /MD)

bat 复制代码
cmake -G "Visual Studio 15 2017" -A Win32 ^
      -D CMAKE_BUILD_TYPE=Release ^
      -D BUILD_SHARED_LIBS=OFF ^
      -D BUILD_WITH_STATIC_CRT=OFF ^
      -D CMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDLL" ^
      -D CMAKE_POLICY_DEFAULT_CMP0091=NEW ^
      -D BUILD_EXAMPLES=OFF ^
      -D BUILD_TESTS=OFF ^
      opencv-source

💡 即使不加 CMAKE_MSVC_RUNTIME_LIBRARYCMP0091,只要 BUILD_WITH_STATIC_CRT=OFF,OpenCV 也会通过字符串替换确保使用 /MD。但加上更规范(尤其 CMake ≥3.15)。


🔎 验证步骤

  1. 检查 CMake 输出

    txt 复制代码
    --   Static CRT:                 NO

    (如果显示 YES,说明 BUILD_WITH_STATIC_CRT=ON 仍生效)

  2. 检查 CMakeCache.txt

    txt 复制代码
    BUILD_WITH_STATIC_CRT:BOOL=OFF
  3. 检查生成的 .vcxproj

    xml 复制代码
    <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>

📌 总结

问题 答案
为什么设置了 /MD 还是 /MT 因为 BUILD_WITH_STATIC_CRT 默认为 ON(MSVC 下)
最关键的 CMake 参数是什么? -D BUILD_WITH_STATIC_CRT=OFF
是否需要 OPENCV_LINK_RUNTIMEDYNAMIC=ON 不需要,它是冗余的(除非你用非常老的 OpenCV 版本)
是否必须升级 CMake? 不必须,但 ≥3.15 更规范

记住:在 OpenCV + MSVC + 静态库场景下,BUILD_WITH_STATIC_CRT 是控制 /MT vs /MD 的"总闸"

只要设置 -D BUILD_WITH_STATIC_CRT=OFF,问题立即解决。

相关推荐
柳鲲鹏2 小时前
OpenCV: DNN超采样,性能差,只能整数
人工智能·opencv·dnn
格林威2 小时前
Baumer相机铁轨表面裂纹巡检:提升铁路安全监测能力的 7 个关键技术,附 OpenCV+Halcon 实战代码!
人工智能·数码相机·opencv·算法·安全·计算机视觉·分类
子夜江寒2 小时前
OpenCV 学习:文档扫描与视频运动检测与跟踪
opencv·学习·计算机视觉·音视频
暗之星瞳3 小时前
opencv进阶——掩膜的应用等
人工智能·opencv·计算机视觉
子夜江寒16 小时前
OpenCV 学习:图像拼接与答题卡识别的实现
python·opencv·学习·计算机视觉
测试人社区-浩辰18 小时前
AI与区块链结合的测试验证方法
大数据·人工智能·分布式·后端·opencv·自动化·区块链
一招定胜负19 小时前
OpenCV实战:DNN风格迁移与CSRT物体追踪
人工智能·opencv·dnn
Pyeako20 小时前
opencv计算机视觉--图形透视(投影)变换&图形拼接
人工智能·python·opencv·计算机视觉·图片拼接·投影变换·图形透视变换
saoys20 小时前
Opencv 学习笔记:轮廓筛选 + 拟合(边界框 / 最小矩形 / 包围圆)
笔记·opencv·学习