起因
之前使用QT5.15写了一个图形应用,当时用的是qmake构建,但由于最近想导入一些别的库,qmake搞起来比较麻烦,使用cmake可以直接导入源代码,编译更加方便,所以尝试着将原本的qmake转换成cmake来构建应用,绝大部分工作可使用QT自家提供的qmake2cmake.py来实现,但exe图标和exe文件属性的问题涉及到使用windres编译rc文件并将其添加到exe,我搜了好久才自己探索了一个完整的方法。
使用方法
这里直接使用该项目中实际使用的代码作为示例,首先在CMakeLists.txt
中添加以下代码:
set(PROJECT_DESCRIPTION "QFileTrans - 传输小助手")
set(PROJECT_INTERNAL_NAME "QFileTrans")
set(PROJECT_COPYRIGHT "Copyright XT29 2022")
set(PROJECT_ORIGINAL_FILENAME "QFileTrans")
set(PROJECT_PRODUCT_NAME "QFileTrans - 传输小助手")
set(PROJECT_COMPANY "XT29 Group")
set(PROJECT_LANG_CHARSET "080404B0") # 简体中文
set(PROJECT_LANG_ID "0x0804") # 简体中文
set(PROJECT_CHARSET_ID "1200") # Unicode
set(PROJECT_ICON "QFileTransIcon.ico")
注意:根据StringFileInfo文档中的说明,PROJECT_LANG_CHARSET
的前四位0804表示简体中文,而后四位04B0为1200的十六进制表示,表示采用Unicode编码,建议后四位不要修改,前四位可以修改为想要的语言。
另外,只修改PROJECT_LANG_CHARSET
是不会修改最终文件中的语言属性的,必须根据VarFileInfo文档修改PROJECT_LANG_ID
为0x0804才可以在文档属性中显示简体中文。
然后在你想要保存的目录新建一个versionInfo.rc.in
文件,将下面的内容写入该文件:
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
PRODUCTVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},${PROJECT_VERSION_TWEAK}
FILEVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},${PROJECT_VERSION_TWEAK}
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "${PROJECT_LANG_CHARSET}"
BEGIN
VALUE "CompanyName", "${PROJECT_COMPANY}\0"
VALUE "FileDescription", "${PROJECT_DESCRIPTION}\0"
VALUE "FileVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.${PROJECT_VERSION_TWEAK}\0"
VALUE "InternalName", "${PROJECT_INTERNAL_NAME}\0"
VALUE "LegalCopyright", "${PROJECT_COPYRIGHT}\0"
VALUE "OriginalFilename", "${PROJECT_ORIGINAL_FILENAME}\0"
VALUE "ProductName", "${PROJECT_PRODUCT_NAME}\0"
VALUE "ProductVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.${PROJECT_VERSION_TWEAK}\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", ${PROJECT_LANG_ID}, ${PROJECT_CHARSET_ID}
END
END
IDI_ICON1 ICON DISCARDABLE "${PROJECT_ICON}"
最后在CMakeLists.txt
中添加以下代码以自动修改rc文件内容:
if(WIN32)
set(VersionInfoFile "${CMAKE_SOURCE_DIR}/versionInfo.rc.in")
set(VersionInfoFileOut "${CMAKE_CURRENT_BINARY_DIR}/versionInfo.rc")
configure_file(${VersionInfoFile} ${VersionInfoFileOut})
file(COPY "${CMAKE_SOURCE_DIR}/${PROJECT_ICON}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif()
到了这里还是不能成功的,必须要手工指定rc文件编译器,在CMakeLists.txt
中添加以下代码:
# Under Windows, we also include a resource file to the build
if(WIN32)
# Make sure that the resource file is seen as an RC file to be compiled with a resource compiler, not a C++ compiler
set_source_files_properties(${VersionInfoFileOut} LANGUAGE RC)
# Add the resource file to the list of sources
# For MinGW, we have to change the compile flags
if(MINGW)
# resource compilation for mingw
set(CMAKE_RC_COMPILER_INIT windres)
enable_language(RC)
SET(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -o <OBJECT> <SOURCE>")
set(RC_CFLAGS "-DMINGW -Ocoff")
# If any sort of debugging is being enabled, add a _DEBUG define to the flags for the resource compiler
set_source_files_properties(${VersionInfoFileOut} COMPILE_FLAGS "${RC_CFLAGS}")
# For anything else, assumingly Visual Studio at this point, use a different set of compile flags
endif(MINGW)
target_sources(${USING_PROJECT_NAME} PUBLIC ${VersionInfoFileOut})
endif(WIN32)
这里可将target_sources
一行省略,直接在add_executable
中添加rc文件也可达到一样的效果。
效果
参考链接
引用微软自家中文文档:
- VarFileInfo BLOCK 语句:https://docs.microsoft.com/zh-cn/windows/win32/menurc/varfileinfo-block
- StringFileInfo BLOCK 语句:https://docs.microsoft.com/zh-cn/windows/win32/menurc/stringfileinfo-block