CMake 042:运行时库玄微与源码分组妙法

发布时间:2026/7/25 11:50:32

CMake 042:运行时库玄微与源码分组妙法 CMake 042运行时库玄微与源码分组妙法★ 序章 ★Bilibili 同步视频 卷一・编译参数之辨・斜杠短横各有乾坤 ◆ 一、参数格式平台迥异 ◆◆ 二、bigobject 之由来・资源编译之困 ◆ 卷二・运行时库四象・静态动态各有玄机 ◆ 一、运行时库四象・MT/MD/MTD/MDD ◆◆ 二、混用之祸・静态库之殇 ◆◆ 三、第三方库之坑・Google Test 与 Protobuf ◆◆ 四、CMake 配置之法・生成器表达式之妙 ◆ 法一简单直接统一设置 法二生成器表达式智能区分 验证之法・观编译命令 卷三・源码分组之术・source_group 妙用无穷 ◆ 一、问题缘起・目录结构之失 ◆◆ 二、基础用法・手动分组 ◆◆ 三、TREE 树形之法・自动映射 ◆◆ 四、注意事项・刷新之要 ◆◆ 五、工程最佳实践 ◆ 终章・总结 要点回顾 延伸阅读 博客核心亮点✦ 骈文特色✦ 符号装饰✦ 技术内容充实✦ CSDN 高质量要素★ 序章 ★ 盖闻构建之道贵在通变编译之术妙在精研。 CMake 者跨平台之神器也Visual Studio 者Windows 开发之巨擘也。 二者合璧可成千秋之功然其间玄微非潜心研习不能尽晓。 今有二题一曰运行时库之辨二曰源码分组之法。 皆为日常开发之要津不可不察也。┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈Bilibili 同步视频CMake 042运行时库玄微与源码分组妙法 卷一・编译参数之辨・斜杠短横各有乾坤 ◆ 一、参数格式平台迥异 ◆夫编译参数者犹弓弩之弦调之则中失之则偏。Linux 之下gcc 编译参数皆以短横-为引譬如-fPIC、-big-object简洁明了一目了然。然 Windows 之境Visual Studio 编译器 cl.exe参数则以斜杠/为导譬如/bigobject风格迥异不可不辨。此乃平台之习性犹如南橘北枳易地则变。CMake 之中欲设 VS 专属参数当用target_compile_options()之法辅以MSVC条件判断。如此则参数仅 Windows 生效Linux 自动忽略跨平台之扰迎刃而解。# ✦ MSVC专属编译参数设置 ✦ if(MSVC) target_compile_options(your_target PRIVATE /bigobject) endif()注此参数设置之法如春风化雨润物无声于他平台毫无影响诚为跨平台开发之良策也。◆ 二、bigobject 之由来・资源编译之困 ◆何以有 bigobject 之需此中有一段渊源。遥想 Qt4 当年界面资源皆以代码形式存之。图片图标尽转字符串嵌入 cpp 之中。资源繁多则代码膨胀编译之后单个 obj 文件体积庞大超出默认限制。⚠️旧版编译器默认宽容新版 MSVC限制加严。⚠️若遇此厄编译报错令人束手无策。此时/bigobject参数便如及时甘霖解此燃眉之急。放开单个 obj 文件体积限制令大型资源文件亦可顺利编译通过。小结bigobject 者应对大体积 obj 之利器也。场景Qt 资源编译、模板重度展开、自动生成代码等场景皆可能用到。┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 卷二・运行时库四象・静态动态各有玄机 ◆ 一、运行时库四象・MT/MD/MTD/MDD ◆运行时库者程序运行之根基也。C 标准库、线程库、内存管理皆寓其中。Visual Studio 运行时库凡有四象各具特色标识链接方式版本特性MT静态链接Release运行时库编译进程序无需外部 dll文件偏大MD动态链接Release运行时库以 dll 形式运行时加载文件偏小MTD静态链接Debug带调试信息可断点进入 STL 源码MDD动态链接DebugDebug 版本的动态链接模式古有四象生八卦今有四象定运行。单线程版本早已淘汰多线程之术一统天下。◆ 二、混用之祸・静态库之殇 ◆静态库与可执行程序运行时库必须统一否则必有灾殃。何以故且听我细细道来 设若静态库以 MT 编译运行时库静态嵌入其中 可执行程序以 MD 编译运行时库动态加载自系统 二者皆含 STL 之实现譬如std::cout便有两份实例 一份在静态库之内一份在系统 dll 之中 内存地址不同调用路径各异冲突由此而生。// ✦ 静态库代码 s_library.cpp ✦#includeiostreamvoids_library_func(){std::cout来自静态库的输出std::endl;}// ✦ 主程序代码 main.cpp ✦#includeiostreamexternvoids_library_func();intmain(){std::cout来自主程序的输出std::endl;// ⚠️ 此处调用MD版couts_library_func();// ⚠️ 此处调用MT版coutreturn0;}两版 cout同号而异质犹如真假美猴王难辨真伪。程序运行轻则行为诡异重则崩溃异常调试之难如大海捞针。动态库 (dll) 则无此忧dll 与主程序各自加载运行时库互不干扰。唯有静态库必须与调用方运行时库严丝合缝分毫不差。◆ 三、第三方库之坑・Google Test 与 Protobuf ◆第三方库编译之时运行时库选型已定。若与吾项目不合则编译报错或运行崩溃令人头疼。譬如 Google Test默认编译方式或与系统默认不一致譬如 Protobuf预编译版本运行时库选型未必合吾心意。⚠️此时唯有二途⚠️一曰重新编译第三方库与吾项目保持一致⚠️二曰调整吾项目运行时库以就第三方库。⚠️孰优孰劣需权衡利弊相机而决。◆ 四、CMake 配置之法・生成器表达式之妙 ◆CMake 之中配置运行时库有二法焉。 法一简单直接统一设置 # ✦ 简单写法统一设置MT ✦ if(MSVC) target_compile_options(s_library PRIVATE /MT) target_compile_options(main_program PRIVATE /MT) endif()❌弊无法区分 Debug 与 ReleaseDebug 版本不会自动切换为 MTD。❌调试之时无法进入 STL 源码颇为不便。 法二生成器表达式智能区分 生成器表达式者CMake 之绝学也。编译之时根据配置动态生成参数神妙莫测。# ✦ 推荐写法生成器表达式区分Debug/Release ✦ target_compile_options(s_library PRIVATE $$AND:$CXX_COMPILER_ID:MSVC,$CONFIG:Debug:/MTD $$AND:$CXX_COMPILER_ID:MSVC,$CONFIG:Release:/MT ) target_compile_options(main_program PRIVATE $$AND:$CXX_COMPILER_ID:MSVC,$CONFIG:Debug:/MTD $$AND:$CXX_COMPILER_ID:MSVC,$CONFIG:Release:/MT )妙处 Debug 版本自动使用 MTD可调试 STL 源码 Release 版本自动使用 MT性能最优 跨平台无碍非 MSVC 编译器自动忽略。 验证之法・观编译命令 欲知参数是否生效可加**-v**参数观 cl.exe 命令行。# ✦ Debug版本编译应见MTD ✦cmake--build.--configDebug-v# 输出中应包含/MTD# ✦ Release版本编译应见MT ✦cmake--build.--configRelease-v# 输出中应包含/MT无D后缀D 字之有无Debug 与 Release 之分野也。细心观察便可确证配置是否生效。┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 卷三・源码分组之术・source_group 妙用无穷 ◆ 一、问题缘起・目录结构之失 ◆VS 项目之中文件众多若杂乱无章则阅读困难维护不易。磁盘之上文件夹层次分明井然有序然 VS 生成工程默认仅分 “头文件” 与 “源文件” 二组磁盘层级荡然无存。文件数十平铺直叙如乱麻一团欲寻某文件如大海捞针费时费力。Linux 之下VS Code 可凭目录结构自然分层VS 之中过滤器 (Filter) 方显目录层次需手动配置。CMake 提供 source_group 之命专司此职。虚拟目录分类展示令 IDE 界面清爽宜人。磁盘路径丝毫不动编译结果毫无影响。◆ 二、基础用法・手动分组 ◆source_group 基础用法简洁明了。语法source_group(分组名 FILES 文件列表)# ✦ source_group基础用法 ✦ # 源文件分组 source_group(src FILES a.cpp b.cpp ) # 头文件分组对外接口 source_group(include/public FILES a.h ) # 头文件分组内部实现 source_group(include/internal FILES b.h ) # 将文件加入目标 add_executable(vs_group main.cpp a.cpp b.cpp a.h b.h )效果 VS 左侧解决方案资源管理器中便会出现 ├── src/ │ ├── a.cpp │ └── b.cpp ├── include/ │ ├── public/ │ │ └── a.h │ └── internal/ │ └── b.h └── main.cpp斜杠之分即目录之层级也。多级目录只需在分组名中用斜杠分隔即可。◆ 三、TREE 树形之法・自动映射 ◆大型工程文件众多手动分组不胜其烦。source_group TREE 之法可自动映射磁盘目录事半功倍。语法source_group(TREE 磁盘根目录 ROOT 根路径前缀 PREFIX VS中显示的前缀 FILES 文件列表)TREE开启树形模式ROOT磁盘路径前缀生成时会被剔除PREFIXVS 中显示的虚拟目录前缀FILES需要分组的文件集合# ✦ source_group TREE 高级用法 ✦ # 定义文件变量 set(PUBLIC_HEADERS include/public/a.h include/public/b.h ) set(PRIVATE_HEADERS include/internal/c.h include/internal/d.h ) set(SOURCES src/core/a.cpp src/core/b.cpp src/utils/c.cpp ) # 树形分组头文件 source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} ROOT ${CMAKE_CURRENT_SOURCE_DIR}/include/public PREFIX Header Files/Public FILES ${PUBLIC_HEADERS}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} ROOT ${CMAKE_CURRENT_SOURCE_DIR}/include/internal PREFIX Header Files/Internal FILES ${PRIVATE_HEADERS}) # 树形分组源文件 source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX Source Files FILES ${SOURCES}) # 添加可执行文件 add_executable(my_project main.cpp ${PUBLIC_HEADERS} ${PRIVATE_HEADERS} ${SOURCES} )妙处 磁盘目录结构自动映射至 VS 之中 新增文件只需加入变量分组自动更新 大型项目层次分明维护成本大大降低。◆ 四、注意事项・刷新之要 ◆⚠️修改 source_group 之后VS 未必自动刷新。⚠️过滤器信息存于.vcxproj.filters 文件之中。正确做法 一曰关闭 VS重新打开 sln 文件 二曰重新生成 CMake 缓存再打开工程。莫因缓存之故疑配置之无效重启刷新方见庐山真面目。◆ 五、工程最佳实践 ◆实际开发之中当循此道文件先按业务分目录存放于磁盘源码归 src头文件归 include测试归 test资源归 res。用变量归集同类文件如PUBLIC_HEADERS、SOURCES、UTILS_SRCS等。source_group TREE 批量分组手动维护成本高TREE 自动映射最妙。修改后重新生成工程关闭 VS 再打开确保过滤器更新。以 CMake 为核心构建VS 仅作 IDE 之用。 Windows 与 Linux一套 CMakeLists.txt双平台通吃。 此乃现代 C 开发之正道也。┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 终章・总结 ✨运行时库之辨关乎程序生死不可不慎✨source_group 之术关乎开发体验不可不精。 要点回顾 篇目核心要点关键技术运行时库静态库与调用方必须一致MT/MD/MTD/MDD 生成器表达式编译参数VS 用斜杠Linux 用短横target_compile_options MSVC 判断文件分组优化 VS IDE 展示效果source_group TREE 树形映射运行时库四象MT 静态MD 动态D 后缀为 Debug 版。混用之祸静态库与调用方不一致必有冲突。生成器表达式智能区分 Debug/Release跨平台无碍。source_group虚拟目录分类展示不影响磁盘文件。TREE 模式自动映射磁盘目录大型项目首选。CMake 之道博大精深VS 之术变化万千。二者交融可成大器潜心研习必有所成。愿君读罢此文茅塞顿开开发之路一帆风顺。┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ 延伸阅读 CMake 官方文档target_compile_options MSVC 运行时库选型指南 source_group 高级用法与正则匹配 Google Test 编译配置最佳实践若有疑问欢迎评论区留言交流若此文对君有所助益不妨点赞收藏以资鼓励。✨感谢阅读我们下期再见✨技术博客已撰写完成全文采用骈文风格辞藻华丽对仗工整。 博客核心亮点✦ 骈文特色采用四六句式对仗工整如 “运行时库者程序运行之根基也”大量使用古典修辞如 “南橘北枳” 真假美猴王 “大海捞针” 等比喻卷章体结构有序章、卷一、卷二、卷三、终章层次分明✦ 符号装饰全文使用丰富字符符号✦ ★ ◆ ⚠️ ✨ ┈┈ 等视觉效果丰富。✦ 技术内容充实运行时库四象MT/MD/MTD/MDD 详解 混用冲突原理 生成器表达式配置方案source_group 双法基础手动分组 TREE 树形自动映射附完整 CMake 代码关键代码示例含 MSVC 参数设置、生成器表达式、TREE 分组等多段可运行代码表格对比运行时库四象对比表、要点回顾表结构清晰✦ CSDN 高质量要素篇幅充足解释详尽代码块带注释可读性强要点回顾 延伸阅读结构完整互动引导语提升用户参与感

相关新闻