当前位置: 首页 > article >正文

如何在CMake项目中实现类似MFC的版本信息配置:详解VS_VERSION_INFO的应用

1. 为什么需要版本信息配置在Windows平台上开发应用程序时版本信息是一个非常重要的元数据。它不仅能帮助用户识别软件版本还能在系统管理、错误报告和更新检查中发挥关键作用。如果你用过MFC开发一定对资源文件中的版本信息配置非常熟悉。右键点击一个exe文件选择属性在详细信息标签页看到的那些版本号、公司名称等信息就是通过VS_VERSION_INFO资源实现的。传统MFC项目直接在.rc资源文件中硬编码这些信息但对于现代CMake项目来说我们需要更灵活的配置方式。想象一下每次发布新版本都要手动修改资源文件既容易出错又不便于自动化构建。我在实际项目中就遇到过因为忘记更新版本号导致测试混乱的情况后来改用CMake动态生成才彻底解决了这个问题。2. 准备工作理解VS_VERSION_INFO结构2.1 VS_VERSION_INFO资源详解VS_VERSION_INFO是Windows定义的标准资源类型它采用了一种特殊的结构体格式。这个结构包含了两类信息固定信息包括文件版本、产品版本、文件类型等字符串信息包含可读的版本字符串、公司名称、版权信息等在资源脚本(.rc)中它通常长这样VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS VOS__WINDOWS32 FILETYPE VFT_APP { BLOCK StringFileInfo { BLOCK 040904E4 { VALUE FileVersion, 1.0.0 VALUE ProductName, 我的应用 } } BLOCK VarFileInfo { VALUE Translation, 0x409, 1252 } }2.2 版本号的组成规则Windows版本号通常由4个数字组成格式为主版本.次版本.修订号.构建号。在实际项目中我建议这样使用主版本重大功能更新次版本新增功能修订号bug修复构建号持续集成系统的自动递增编号3. CMake项目中的实现方案3.1 创建模板文件version.rc.in首先我们需要创建一个模板文件让CMake能够动态填充版本信息。在项目根目录下新建version.rc.in#include windows.h VS_VERSION_INFO VERSIONINFO FILEVERSION PROJECT_VERSION_MAJOR,PROJECT_VERSION_MINOR,PROJECT_VERSION_PATCH,0 PRODUCTVERSION PROJECT_VERSION_MAJOR,PROJECT_VERSION_MINOR,PROJECT_VERSION_PATCH,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS VOS__WINDOWS32 FILETYPE VFT_APP { BLOCK StringFileInfo { BLOCK 040904E4 { VALUE FileVersion, PROJECT_VERSION_MAJOR.PROJECT_VERSION_MINOR.PROJECT_VERSION_PATCH VALUE ProductVersion, PROJECT_VERSION_MAJOR.PROJECT_VERSION_MINOR.PROJECT_VERSION_PATCH VALUE CompanyName, PROJECT_COMPANY_NAME VALUE FileDescription, PROJECT_DESCRIPTION VALUE ProductName, PROJECT_NAME VALUE LegalCopyright, PROJECT_COPYRIGHT } } BLOCK VarFileInfo { VALUE Translation, 0x409, 1252 } }这个模板使用了CMake的变量替换语法VAR_NAME稍后我们会在CMakeLists.txt中定义这些变量。3.2 配置CMakeLists.txt接下来修改你的CMakeLists.txt添加版本信息配置# 设置版本号 set(PROJECT_VERSION_MAJOR 1) set(PROJECT_VERSION_MINOR 0) set(PROJECT_VERSION_PATCH 0) # 设置其他元数据 set(PROJECT_NAME 我的应用) set(PROJECT_COMPANY_NAME 我的公司) set(PROJECT_DESCRIPTION 这是一个使用CMake构建的应用程序) set(PROJECT_COPYRIGHT 版权所有 © 2023) # 生成版本资源文件 configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc ONLY ) # 添加资源文件到项目 add_executable(MyApp WIN32 src/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/version.rc )这里有几个关键点需要注意configure_file命令会将模板中的变量替换为实际值生成的文件放在CMAKE_CURRENT_BINARY_DIR保持源码目录干净资源文件必须添加到可执行文件的源文件列表中4. 高级配置技巧4.1 自动生成构建号手动维护构建号很麻烦我们可以利用CMake的脚本功能自动生成# 获取当前日期作为构建号 string(TIMESTAMP BUILD_DATE %Y%m%d) set(PROJECT_BUILD_NUMBER ${BUILD_DATE}) # 在模板中使用 FILEVERSION PROJECT_VERSION_MAJOR,PROJECT_VERSION_MINOR,PROJECT_VERSION_PATCH,${PROJECT_BUILD_NUMBER}4.2 支持多语言如果你的应用需要支持多语言可以修改StringFileInfo块BLOCK StringFileInfo { BLOCK 040904E4 # 英语(美国) { VALUE FileDescription, English description } BLOCK 040404E4 # 中文(简体) { VALUE FileDescription, 中文描述 } }4.3 从外部文件读取版本号对于大型项目建议将版本信息单独放在一个文件中比如version.cmake# version.cmake set(PROJECT_VERSION_MAJOR 1) set(PROJECT_VERSION_MINOR 2) set(PROJECT_VERSION_PATCH 3)然后在主CMakeLists.txt中包含它include(version.cmake)这样版本管理会更清晰也便于自动化脚本处理。5. 常见问题与解决方案5.1 版本信息不显示如果生成的exe文件没有显示版本信息检查以下几点确保资源文件被正确添加到add_executable检查生成的version.rc文件内容是否正确尝试清理并重新生成整个项目5.2 版本号格式问题Windows资源管理器显示的版本字符串有时会忽略最后的0这是正常现象。比如1.0.0.0可能显示为1.0.0。5.3 调试版与发布版的区分在模板中我们使用了预处理器判断_DEBUG宏#ifdef _DEBUG FILEFLAGS 0x1L # VS_FF_DEBUG #else FILEFLAGS 0x0L #endif这可以确保调试版和发布版有不同的版本标志。6. 实际应用案例在我最近的一个跨平台项目中我们使用这套方案管理Windows版本的版本信息同时通过Git标签自动生成版本号。具体实现如下# 从Git标签获取版本号 find_package(Git) if(GIT_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev0 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_TAG OUTPUT_STRIP_TRAILING_WHITESPACE ) if(GIT_TAG) string(REGEX MATCH v([0-9])\\.([0-9])\\.([0-9]) _ ${GIT_TAG}) set(PROJECT_VERSION_MAJOR ${CMAKE_MATCH_1}) set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_2}) set(PROJECT_VERSION_PATCH ${CMAKE_MATCH_3}) endif() endif()这样每次打tag发布时版本号会自动更新完全不需要手动维护。

相关文章:

如何在CMake项目中实现类似MFC的版本信息配置:详解VS_VERSION_INFO的应用

1. 为什么需要版本信息配置 在Windows平台上开发应用程序时,版本信息是一个非常重要的元数据。它不仅能帮助用户识别软件版本,还能在系统管理、错误报告和更新检查中发挥关键作用。如果你用过MFC开发,一定对资源文件中的版本信息配置非常熟悉…...

结合数学思维来深入内存理解哈希散列的实现原理和处理冲突的逻辑靶

Julia(julialang.org)由Stefan Karpinski、Jeff Bezanson等在2009年创建,目标是融合Python的易用性、C的高性能、R的统计能力、Matlab的科学计算生态。 其核心设计哲学是: 高性能:编译型语言(JIT&#xff0…...

WordPress插件存储型XSS漏洞CVE-2026-0800深度剖析:输入净化缺失导致未授权脚本注入

CVE-2026-0800: WordPress插件“User Submitted Posts”中的存储型跨站脚本漏洞 严重等级: 高危 类型: 漏洞 CVE ID: CVE-2026-0800 CVE-2026-0800 是存在于 WordPress 插件“User Submitted Posts – Enable Users to Submit Posts from the Front End”(由 specia…...

2026办公软件终极指南:AI正在重写你的工作台

效率革命已至,你的工具该升级了打开任何一个办公软件,你都会发现一个显著的变化——AI不再是藏在角落里的“实验性功能”,而是像回车键一样自然地融入了每一次敲击。AI已经在重写整个Office软件栈。 从文档创作到数据处理,从会议纪…...

CVE-2024-3094 漏洞自动化检测与修复工具

CVE-2024-3094 漏洞自动化检测与修复工具 本项目针对近期曝光的 CVE-2024-3094 漏洞(xz-utils 恶意代码后门),提供了完整的自动化检测与修复方案。包含适用于单机快速响应的 Shell 脚本,以及面向大规模服务器集群的 Ansible Playb…...

WordPress NextMove Lite 插件权限绕过漏洞利用工具 (CVE-2024-25092)

CVE-2024-25092 漏洞利用工具 项目描述 本项目是针对 CVE-2024-25092 漏洞的自动化利用脚本。该漏洞存在于 WordPress XLPlugins NextMove Lite 插件(版本号 ≤ 2.17.0)中,由于缺少授权检查,导致具有订阅者(Subscriber…...

免费获取全球900+语言支持的Noto字体库:设计师与开发者的终极解决方案

免费获取全球900语言支持的Noto字体库:设计师与开发者的终极解决方案 【免费下载链接】noto-fonts Noto fonts, except for CJK and emoji 项目地址: https://gitcode.com/gh_mirrors/no/noto-fonts Noto字体库是谷歌开发的开源字体项目,旨在为全…...

8大网盘直链解析神器:告别限速,享受极速下载体验

8大网盘直链解析神器:告别限速,享受极速下载体验 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 …...

Pixel Mind Decoder 性能调优教程:解决GPU显存不足与推理加速

Pixel Mind Decoder 性能调优教程:解决GPU显存不足与推理加速 1. 为什么需要性能调优 当你第一次把Pixel Mind Decoder模型跑起来时,可能会遇到两个让人头疼的问题:要么显存不够用导致程序崩溃,要么推理速度慢得像蜗牛爬。这种情…...

7天连续挑战:OpenClaw+Qwen3-32B完成100个自动化任务实录

7天连续挑战:OpenClawQwen3-32B完成100个自动化任务实录 1. 挑战背景与实验设计 去年冬天第一次接触OpenClaw时,我就被它"用自然语言操控电脑"的理念吸引了。但当时受限于本地显卡性能,只能跑动7B级别的小模型,复杂任…...

3分钟搞定Jellyfin中文元数据:MetaShark插件全攻略

3分钟搞定Jellyfin中文元数据:MetaShark插件全攻略 【免费下载链接】jellyfin-plugin-metashark jellyfin电影元数据插件 项目地址: https://gitcode.com/gh_mirrors/je/jellyfin-plugin-metashark 还在为Jellyfin媒体库中那些没有中文信息的电影和剧集发愁吗…...

ThinkPHP 8+CPU的生命周期的庖丁解牛

它的本质是:理解 PHP 代码(高级语言)如何被编译为 Opcode,进而被 Zend 引擎解释执行,最终转化为 CPU 能够理解的机器指令(Machine Code),并在 CPU 的流水线、缓存(L1/L2/…...

ThinkPHP 8+ES的生命周期的庖丁解牛

它的本质是:PHP 应用作为客户端,通过 HTTP 协议与 ES 集群进行交互。这个过程涉及 JSON 序列化/反序列化、HTTP 连接管理、倒排索引的异步构建以及最终一致性的等待。与 MySQL 的同步事务不同,ES 的操作通常是“近实时 (NRT)”的,…...

ThinkPHP 8+redis的生命周期的庖丁解牛

它的本质是:PHP 进程(客户端)通过 TCP 套接字与 Redis 守护进程(服务端)建立连接,发送基于 RESP 协议的指令,接收二进制响应,并将结果映射回 PHP 变量的全过程。在 TP8 中&#xff0…...

用了半年只留下这1个!2026年我亲测好用的视频文案提取网站真的太香了

做技术的要转需求评审会,做市场的要转客户访谈,做HR要转整箱的面试录音,做内容的要扒视频文案写稿。不同岗位需求天差地别,有的要准,有的要快,有的要掏得起钱。我测了半年换了八款工具,直接给结…...

2026最新!3款亲测搞定音频怎么转换成文字的免费神器,实用必备不踩坑!

很多朋友找音频转文字工具,第一个坑就是只盯着“免费”两个字,要么是限额度转不全,要么是错漏百出改到秃头,算下来时间成本贵到离谱。作为蹲了大半年工具的测评博主,我亲测了3款目前能用的高性价比工具,直接…...

3分钟实现Zotero文献PDF自动下载:科研效率的终极革命

3分钟实现Zotero文献PDF自动下载:科研效率的终极革命 【免费下载链接】zotero-scipdf Download PDF from Sci-Hub automatically For Zotero7 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-scipdf 还在为找不到论文PDF而烦恼吗?每天花费数…...

基于File-Based App开发MVP项目仿

Issue 概述 先来看看提交这个 Issue 的作者是为什么想到这个点子的,以及他初步的核心设计概念。?? 本 PR 实现了 Apache Gravitino 与 SeaTunnel 的集成,将其作为非关系型连接器的外部元数据服务。通过 Gravitino 的 REST API 自动获取表结构和元数据&…...

别再只用Curl了!用libhv的HttpClient类,5分钟搞定C++里的GET/POST请求

别再只用Curl了!用libhv的HttpClient类,5分钟搞定C里的GET/POST请求 如果你还在用Curl命令行工具或者复杂的libcurl API来处理C项目中的HTTP请求,那么是时候认识一下libhv了。这个轻量级、高性能的网络库,用起来简直像在写Python一…...

Beyond Compare 5密钥生成器:快速激活与完整使用指南

Beyond Compare 5密钥生成器:快速激活与完整使用指南 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen 你是否正在寻找Beyond Compare 5的激活解决方案?BCompare_Keygen是一…...

3分钟搞定游戏手柄兼容性:用ViGEmBus让所有手柄在Windows上畅玩

3分钟搞定游戏手柄兼容性:用ViGEmBus让所有手柄在Windows上畅玩 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 还在为心爱的手柄无法在Windows游…...

Realistic Vision V5.1效果展示:惊艳写实人像生成案例分享

Realistic Vision V5.1效果展示:惊艳写实人像生成案例分享 1. 开篇:重新定义AI人像摄影 当AI生成的人像照片已经能以假乱真,我们不禁要问:数字艺术与传统摄影的边界在哪里?Realistic Vision V5.1作为当前Stable Diff…...

Vivado IBERT实战:从眼图扫描到误码率分析的链路质量评估

1. 认识IBERT:高速串行链路的"体检医生" 第一次接触IBERT时,我正被一个诡异的高速数据传输问题困扰——在实验室测试时链路表现完美,但一到现场部署就频繁出现数据丢包。当时一位资深工程师递给我一根光纤线说:"用…...

食品商家狂喜:易元AI让你的产品视频“香”到流口水,下单率暴涨

食品电商剪辑,最头疼的难题就是:无法通过视频激发用户食欲,即便产品口感再好、性价比再高,也难以带动下单——很多食品商家的视频要么画面单调、色泽暗淡,要么缺乏食欲感,无法让用户产生“想立刻吃”的冲动…...

从软体机器人到鞋垫分析:Abaqus超弹性材料(Ogden模型)仿真配置全流程

从实验数据到高效求解:Abaqus超弹性材料Ogden模型实战指南 在柔性结构设计和生物力学仿真领域,超弹性材料的精确建模一直是工程师面临的挑战。当我们需要模拟橡胶密封件在压缩状态下的应力松弛、运动鞋垫在行走过程中的能量反馈,或是医疗植入…...

告别“字符串拼接”:在.NET中用LINQ重塑数据查询

告别“字符串拼接”:在.NET中用LINQ重塑数据查询在 .NET Framework 3.5 问世之前,C# 程序员在处理数据时往往面临着“精神分裂”般的痛苦:我们需要在 C# 代码中编写逻辑,而在处理数据库时又要切换到 SQL 字符串,处理 X…...

KMS_VL_ALL_AIO:如何用智能激活脚本彻底解决Windows和Office激活难题

KMS_VL_ALL_AIO:如何用智能激活脚本彻底解决Windows和Office激活难题 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 你是否曾经遇到过这样的尴尬时刻:在重要会议演示时&…...

KMS_VL_ALL_AIO:Windows与Office智能激活终极指南 - 3分钟解决授权问题

KMS_VL_ALL_AIO:Windows与Office智能激活终极指南 - 3分钟解决授权问题 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO KMS_VL_ALL_AIO 是一款功能强大的智能激活脚本工具&#xff0…...

Playwright MCP:重新定义浏览器自动化边界的智能会话桥接方案

Playwright MCP:重新定义浏览器自动化边界的智能会话桥接方案 【免费下载链接】playwright-mcp Playwright MCP server 项目地址: https://gitcode.com/gh_mirrors/pl/playwright-mcp 在当今Web自动化测试领域,开发者们面临着一个普遍困境&#x…...

告别CAJ格式束缚:caj2pdf开源工具深度解析与实战指南

告别CAJ格式束缚:caj2pdf开源工具深度解析与实战指南 【免费下载链接】caj2pdf Convert CAJ (China Academic Journals) files to PDF. 转换中国知网 CAJ 格式文献为 PDF。佛系转换,成功与否,皆是玄学。 项目地址: https://gitcode.com/gh_…...