我遇到的问题
mingw编译生成的exe,任务栏显示名称不符合预期
使用mingw编译代码时生成的eeschema.exe文件,eeschema.exe启动后在任务栏鼠标右键显示的名字并不是rc文件中的名字,为什么?
这个问题可能与 eeschema.rc 文件中的资源信息有关。在 Windows 平台下,应用程序的名称和版本信息等资源信息通常存储在 .rc 文件中,并在编译时使用 windres.exe 程序将其嵌入到可执行文件中。
您可以尝试修改 eeschema.rc 文件中的资源信息,以确保应用程序名称正确显示在任务栏中。具体来说,您可以修改 RC_VER_FILE_DESCRIPTION 和 RC_VER_PRODUCTNAME 宏的值,例如:
#define RC_VER_FILE_DESCRIPTION "Schematic Editor " KICAD_WIN32_RC_PRODVER_STR
#define RC_VER_PRODUCTNAME "Schematic Editor "
请注意,在修改这些宏的值之前,最好先备份原始文件,以免出现错误。另外,需要重新编译应用程序,才能使新的资源信息生效。
如果您已经修改了 eeschema.rc 文件中的资源信息,但应用程序名称仍然不正确显示在任务栏中,请检查一下您的操作系统设置,确保没有其他应用程序更改了任务栏显示名称。
操作系统设置?
如何操作系统的设置,主要查看什么内容的设置,设置什么内容回影响到应用程序在任务栏的显示名字
在 Windows 操作系统中,应用程序在任务栏上的显示名称通常由应用程序的窗口标题决定。如果您想要更改应用程序在任务栏上的显示名称,可以尝试以下方法:
- 修改应用程序窗口标题
您可以在应用程序代码中修改窗口标题,以更改应用程序在任务栏上的显示名称。具体来说,您可以使用 Windows API 中的 SetWindowText() 函数将窗口标题设置为所需的名称。例如:
SetWindowText(hwnd, "Schematic Editor");
这个示例中,hwnd 是应用程序窗口的句柄,“BTD-ABS Schematic Editor” 是所需的窗口标题。
- 修改操作系统注册表
您可以通过修改操作系统注册表中的相关键值来更改应用程序在任务栏上的显示名称。具体来说,您可以打开注册表编辑器,找到 HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics 键,并修改 CaptionHeight 和 CaptionWidth 键的值。这个方法需要谨慎操作,不当的修改可能会导致系统不稳定或不可用。
请注意,如果您更改了操作系统设置,可能会影响到其他应用程序的显示名称和外观。因此,在进行任何更改之前,请务必备份您的系统设置和数据,并谨慎评估风险和效益。
cmake基础
.cmake文件干什么用的
.cmake 文件是 CMake 中的一种文件格式,用于定义 CMake 模块。CMake 模块是一些预定义的脚本文件,用于提供常用的构建规则和功能,例如查找库文件、设置编译选项、定义变量等。
CMake 模块可以在 CMakeLists.txt 文件中通过 include() 命令来加载和使用。当 CMake 执行 include() 命令时,它会搜索指定的 .cmake 文件,并将其内容加载到当前的 CMakeLists.txt 文件中。
例如,假设我们有一个名为 FindFoo.cmake 的模块文件,用于查找名为 Foo 的库文件。我们可以在 CMakeLists.txt 文件中使用以下方式来加载这个模块:
# 加载 FindFoo.cmake 模块
include(FindFoo)
# 使用 Foo 库文件
find_package(Foo REQUIRED)
target_link_libraries(myapp Foo::Foo)
在这个示例中,我们使用 include() 命令来加载 FindFoo.cmake 模块。然后,我们使用 find_package() 命令来查找 Foo 库文件,并将其链接到 myapp 目标中。
请注意,CMake 自带了一些常用的模块,例如 FindBoost.cmake、FindOpenSSL.cmake 等。此外,您也可以编写自己的模块文件,并将其放置在合适的位置,以便在 CMakeLists.txt 文件中使用。
.rc文件
eeschema.rc
这是我的eeschema.rc文件,
icon_eeschema ICON "../resources/bitmaps_png/icons/icon_eeschema.ico"
#define RC_VER_FILE_DESCRIPTION "Schematic Editor " KICAD_WIN32_RC_PRODVER_STR
#define RC_VER_INTERNALNAME "eeschema"
#define RC_VER_ORIGINALFILENAME "eeschema.exe"
#define RC_VER_PRODUCTNAME "Schematic Editor "
#include "kiwin32.rc"
这是一个 Windows 平台下的资源文件,用于指定应用程序的图标和版本信息等。具体来说,该文件包含了以下内容:
icon_eeschema 条目,用于指定应用程序的图标文件路径。在这里,图标文件的路径为 “…/resources/bitmaps_png/icons/icon_eeschema.ico”。
RC_VER_FILE_DESCRIPTION 宏,用于指定应用程序的文件描述信息。在这里,文件描述信息为 "BTD-ABS Schematic Editor " 加上 KICAD_WIN32_RC_PRODVER_STR 宏所表示的版本号。
RC_VER_INTERNALNAME 宏,用于指定应用程序的内部名称。在这里,内部名称为 “eeschema”。
RC_VER_ORIGINALFILENAME 宏,用于指定应用程序的原始文件名。在这里,原始文件名为 “eeschema.exe”。
RC_VER_PRODUCTNAME 宏,用于指定应用程序的产品名称。在这里,产品名称为 "Schematic Editor "。
#include “kiwin32.rc” 命令,用于包含 KiCad 库中的 Windows 平台资源文件。这个文件包含了一些默认的资源定义,例如菜单、对话框等,可以在应用程序中使用。
需要注意的是,在这个资源文件中使用了 KICAD_WIN32_RC_PRODVER_STR 宏来指定应用程序的版本号。这个宏可能是在其他地方定义的,如果您想要修改版本号,可能需要到其他文件中查找并修改相应的定义。
kiwin32.rc
这是我的kiwin32.rc文件:
// Turn off wxWidgets attempting to use its own manifests
#define wxUSE_NO_MANIFEST 1
#include "wx/msw/wx.rc"
#include <winver.h> // defines VS_VERSION_INFO
#define INCLUDE_BTDCHIPLET_VERSION
#include <kicad_build_version.h>
#ifdef ISOLATION_AWARE_ENABLED
#define MANIFEST_ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID
#else
#define MANIFEST_ID CREATEPROCESS_MANIFEST_RESOURCE_ID
#endif
#if !defined( BTD_WIN32_DPI_AWARE ) || BTD_WIN32_DPI_AWARE == 0
#define MANIFEST_SUFFIX .manifest
#else
#define MANIFEST_SUFFIX _dpi_aware_pmv2.manifest
#endif
//MSYS2
#define RC_STR( text ) RC_STR2( text )
#define RC_STR2( text ) #text
//MSVC
#define RC_CONCAT( a, b, c ) RC_CONCAT2( a, b, c )
#define RC_CONCAT2( a, b, c ) a##b##c
#ifdef __GNUC__
#define MANIFEST_FILE "manifests/" RC_STR( BTD_BUILD_ARCH ) RC_STR( MANIFEST_SUFFIX )
#else
//Do not try and quote the first part, it won't work, also make sure the IDE doesn't reformat it with spaces between slashes
#define MANIFEST_FILE RC_CONCAT( manifests/, BTD_BUILD_ARCH, MANIFEST_SUFFIX )
#endif
MANIFEST_ID RT_MANIFEST MANIFEST_FILE
#ifndef DEBUG
#define VER_DEBUG 0
#else
#define VER_DEBUG VS_FF_DEBUG
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION BTDCHIPLET_WIN32_RC_FILEVER
PRODUCTVERSION BTDCHIPLET_WIN32_RC_PRODVER
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS (VER_DEBUG)
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
// this gets displayed in the windows 10 task manager
VALUE "FileDescription", RC_VER_FILE_DESCRIPTION
VALUE "FileVersion", BTDCHIPLET_WIN32_RC_FILEVER_STR
//original filename without extension
VALUE "InternalName", RC_VER_INTERNALNAME
VALUE "LegalCopyright", "Copyright (C) 2022 BTDChiplet Developers"
// the exe name
VALUE "OriginalFilename", RC_VER_ORIGINALFILENAME
// name of distributed package
VALUE "ProductName", "BTDChiplet EDA"
VALUE "ProductVersion", BTDCHIPLET_WIN32_RC_PRODVER_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
//RESOURCE FILES MUST CONTAIN A BLANK LINE AT THE END
这是一个 Windows 平台下的资源文件,用于定义 KiCad 应用程序的版本信息和其他一些资源。具体来说,该文件包含了以下内容:
-
#define wxUSE_NO_MANIFEST 1 命令,用于禁用 wxWidgets 库自动创建应用程序清单文件。这个命令是为了避免应用程序出现重复的清单文件,从而导致出错。
#include “wx/msw/wx.rc” 命令,用于包含 wxWidgets 库中的 Windows 平台资源文件。这个文件包含了一些默认的资源定义,例如菜单、对话框等,可以在应用程序中使用。
#define INCLUDE_BTDCHIPLET_VERSION 命令,用于指定应用程序版本信息的来源。在这里,版本信息来自于 kicad_build_version.h 文件中定义的 BTDCHIPLET_WIN32_RC_FILEVER 和
BTDCHIPLET_WIN32_RC_PRODVER 宏。#include <kicad_build_version.h> 命令,用于包含 KiCad 库中的版本信息文件。这个文件定义了一些与版本相关的宏,例如版本号、版权信息等。
#define MANIFEST_ID RT_MANIFEST MANIFEST_FILE 命令,用于指定应用程序清单文件的路径。在这里,清单文件的路径为 MANIFEST_FILE 宏所表示的路径。
#define MANIFEST_FILE RC_CONCAT( manifests/, BTD_BUILD_ARCH, MANIFEST_SUFFIX ) 命令,用于定义清单文件的完整路径。在这里,清单文件的路径由
manifests/、BTD_BUILD_ARCH 和 MANIFEST_SUFFIX 三个宏拼接而成。
MANIFEST_ID RT_MANIFEST MANIFEST_FILE 命令,用于将清单文件添加到应用程序资源中。这个命令会将清单文件编译成二进制格式,并将其添加到可执行文件中。
VS_VERSION_INFO VERSIONINFO 命令,用于定义应用程序的版本信息。在这里,版本信息包括文件版本、产品版本、文件描述等。其中,文件版本和产品版本来自于 BTDCHIPLET_WIN32_RC_FILEVER 和 BTDCHIPLET_WIN32_RC_PRODVER 宏所表示的版本号。
需要注意的是,在这个资源文件中使用了一些与 KiCad 库相关的宏和文件。如果您在其他应用程序中使用这个资源文件,可能需要修改其中的一些宏和路径等信息。
KICAD_WIN32_RC_PRODVER_STR
if( CMAKE_MATCH_COUNT EQUAL 3 )
# Match slot 0 is the full string, so we want slots 1 & 2
set( KICAD_MAJOR_MINOR_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" )
set( KICAD_MAJOR_MINOR_PATCH_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" )
set( KICAD_MAJOR_MINOR_PATCH_TUPLE "{ ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}, ${CMAKE_MATCH_3} }" )
set( KICAD_MAJOR_VERSION "${CMAKE_MATCH_1}" )
set( KICAD_MINOR_VERSION "${CMAKE_MATCH_2}" )
set( KICAD_PATCH_VERSION "${CMAKE_MATCH_3}" )
if( KICAD_MINOR_VERSION STREQUAL "99" )
set( KICAD_IS_NIGHTLY "1" )
else()
set( KICAD_IS_NIGHTLY "0" )
endif()
set( KICAD_WIN32_RC_FILEVER_STR "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}.${KICAD_GIT_REV}\\0" )
set( KICAD_WIN32_RC_FILEVER "${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}, ${CMAKE_MATCH_3}, ${KICAD_GIT_REV}" )
set( KICAD_WIN32_RC_PRODVER_STR "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}\\0" )
set( KICAD_WIN32_RC_PRODVER "${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}, ${CMAKE_MATCH_3}, ${KICAD_GIT_REV}" )
else()
message( FATAL_ERROR "Unable to extract major, minor and patch version string" )
endif()
这段代码什么意思?
这段代码是一个条件语句,用于提取主要、次要和修订版本号字符串,并将它们存储在不同的变量中。让我逐步解释每个部分的含义:
c
Copy
if( CMAKE_MATCH_COUNT EQUAL 3 )
这个条件语句判断 CMAKE_MATCH_COUNT 是否等于 3。CMAKE_MATCH_COUNT 是一个变量,表示正则表达式匹配的结果数量。如果结果数量等于 3,表示成功匹配到了主要、次要和修订版本号。
c
Copy
set( KICAD_MAJOR_MINOR_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" )
这行代码将 C M A K E M A T C H 1 . {CMAKE_MATCH_1}. CMAKEMATCH1.{CMAKE_MATCH_2} 的值赋给 KICAD_MAJOR_MINOR_VERSION 变量。${CMAKE_MATCH_1} 和 ${CMAKE_MATCH_2} 分别表示正则表达式中第一个和第二个捕获组的匹配结果。
类似地,接下来的几行代码将主要、次要和修订版本号的不同组合形式赋值给对应的变量,例如 KICAD_MAJOR_MINOR_PATCH_VERSION、KICAD_MAJOR_MINOR_PATCH_TUPLE、KICAD_MAJOR_VERSION、KICAD_MINOR_VERSION 和 KICAD_PATCH_VERSION。
c
Copy
if( KICAD_MINOR_VERSION STREQUAL "99" )
set( KICAD_IS_NIGHTLY "1" )
else()
set( KICAD_IS_NIGHTLY "0" )
endif()
这个条件语句根据 KICAD_MINOR_VERSION 的值是否等于 “99”,将 KICAD_IS_NIGHTLY 设置为 “1” 或 “0”。这个变量用于表示是否为每夜版(Nightly Build)。
最后,set() 命令将主要、次要和修订版本号以及 Git 修订号的不同组合形式赋值给 KICAD_WIN32_RC_FILEVER_STR、KICAD_WIN32_RC_FILEVER、KICAD_WIN32_RC_PRODVER_STR 和 KICAD_WIN32_RC_PRODVER 变量。
如果无法成功提取主要、次要和修订版本号字符串,将会显示错误信息并终止执行。
总之,这段代码的作用是从一个字符串中提取主要、次要和修订版本号,并将它们存储在不同的变量中,以及判断是否为每夜版。这些变量可以在后续的代码中使用,例如用于定义应用程序的版本信息。
cmake 怎么把rc文件与应用程序关联到一起的
在 CMake 中,将 .rc 文件与其他源文件关联在一起,以便在构建过程中进行编译和链接,可以使用 add_executable() 或 add_library() 命令来指定包含 .rc 文件的源文件列表。
具体步骤如下:
使用 add_executable() 或 add_library() 命令创建可执行文件或库的目标。例如:
add_executable(myapp main.cpp myresource.rc)
在命令中指定包含 .rc 文件的源文件列表。在上述示例中,myresource.rc 是要包含的 .rc 文件。
CMake 会自动将 .rc 文件与其他源文件一起编译,并将资源信息嵌入到生成的可执行文件或库中。
请注意,这只是一个简单的示例。实际情况可能因项目结构和需求而有所不同。如果您的项目需要更复杂的资源管理,可能需要使用特定的构建工具或自定义构建脚本来处理 .rc 文件。
我们代码中的add_executable
add_executable( eeschema WIN32 MACOSX_BUNDLE
${CMAKE_SOURCE_DIR}/common/single_top.cpp
${CMAKE_SOURCE_DIR}/common/pgm_base.cpp
${CMAKE_SOURCE_DIR}/common/btd_license/BitAnswer.cc
${CMAKE_SOURCE_DIR}/common/btd_license/BTDLicenseMrg.cc
${EESCHEMA_RESOURCES}
)
这段代码是使用 CMake 构建 KiCad Eeschema 组件可执行文件的一部分。
具体来说,这个代码使用了 CMake 的 add_executable 命令,用于创建一个可执行文件目标,并将多个源代码文件和资源文件添加到目标中。以下是这个命令的各个参数的含义:
eeschema:目标名称,即要创建的可执行文件的名称。
WIN32 和 MACOSX_BUNDLE:这两个参数是可选的,用于指定目标类型。WIN32 表示这是一个 Windows 应用程序,MACOSX_BUNDLE 表示这是一个 macOS 应用程序。如果不指定这些参数,则默认为普通的可执行文件。
${CMAKE_SOURCE_DIR}/common/single_top.cpp
等:这些是要添加到目标中的源代码文件和资源文件。${CMAKE_SOURCE_DIR} 表示 CMakeLists.txt 文件所在的源代码目录,因此 ${CMAKE_SOURCE_DIR}/common/single_top.cpp 表示源代码目录下的 common/single_top.cpp 文件。
在 KiCad Eeschema 组件中,这个命令将多个源代码文件和资源文件添加到可执行文件中,包括一些通用的源代码文件和许可证文件。这些文件将被编译成一个可执行文件,用于运行 Eeschema 组件。
请注意,这个命令只是 CMake 构建 KiCad Eeschema 组件可执行文件的一部分,还有其他命令和配置项需要设置才能成功构建整个项目。
关于EESCHEMA_RESOURCES 的定义
if( WIN32 )
if( MINGW )
# EESCHEMA_RESOURCES variable is set by the macro.
mingw_resource_compiler( eeschema )
else()
set( EESCHEMA_RESOURCES ${CMAKE_SOURCE_DIR}/resources/msw/eeschema.rc )
endif()
endif()
mingw_resource_compiler
macro(mingw_resource_compiler _NAME)
# Resource compiler name.
if(NOT DEFINED CMAKE_RC_COMPILER)
set(CMAKE_RC_COMPILER windres.exe)
endif(NOT DEFINED CMAKE_RC_COMPILER)
dbg_msg("CMAKE_RC_COMPILER: ${CMAKE_RC_COMPILER}")
# Input file.
set(_IN "${CMAKE_SOURCE_DIR}/resources/msw/${_NAME}.rc")
dbg_msg("_IN: ${_IN}")
# Output file.
set(_OUT "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_NAME}.dir/${_NAME}_rc.obj")
dbg_msg("_OUT: ${_OUT}")
# Include directories.
set(_WINDRES_INCLUDE_DIRS -I${CMAKE_CURRENT_SOURCE_DIR})
foreach(wx_include_dir ${wxWidgets_INCLUDE_DIRS})
set(_WINDRES_INCLUDE_DIRS ${_WINDRES_INCLUDE_DIRS} -I${wx_include_dir})
endforeach(wx_include_dir ${wxWidgets_INCLUDE_DIRS})
foreach(_mingw_rc_include_dir ${mingw_resource_compiler_INCLUDE_DIRS})
set(_WINDRES_INCLUDE_DIRS ${_WINDRES_INCLUDE_DIRS} -I${_mingw_rc_include_dir})
endforeach()
dbg_msg("_WINDRES_INCLUDE_DIRS: ${_WINDRES_INCLUDE_DIRS}")
foreach(_mingw_rc_define ${mingw_resource_compiler_DEFINES})
set(_WINDRES_DEFINES ${_WINDRES_DEFINES} -D${_mingw_rc_define})
endforeach()
dbg_msg("_WINDRES_DEFINES: ${_WINDRES_DEFINES}")
# windres arguments.
set(_ARGS ${_WINDRES_INCLUDE_DIRS} ${_WINDRES_DEFINES} -i${_IN} -o${_OUT})
dbg_msg("_ARGS: ${_ARGS}")
# Compile resource file.
add_custom_command(OUTPUT ${_OUT}
COMMAND ${CMAKE_RC_COMPILER}
ARGS ${_ARGS}
COMMENT "Compiling ${_NAME}'s resource file"
VERBATIM)
# Set a NAME_RESOURCES variable
string(TOUPPER ${_NAME} _NAME_UPPER)
set(${_NAME_UPPER}_RESOURCES ${_OUT})
dbg_msg("${_NAME_UPPER}_RESOURCES: ${${_NAME_UPPER}_RESOURCES}")
endmacro(mingw_resource_compiler)
这段代码什么意思
这段代码是一个 CMake 宏,用于编译 Windows 平台下的资源文件。具体来说,它使用 windres.exe 工具编译 .rc 文件,并将编译生成的 .o 文件作为输出。
该宏的参数 _NAME 指定了要编译的资源文件的名称。该宏首先设置了变量 CMAKE_RC_COMPILER,如果没有设置该变量,就将其设置为 windres.exe。然后指定了要编译的 .rc 文件的路径和输出文件的路径。
set(_WINDRES_INCLUDE_DIRS -I${CMAKE_CURRENT_SOURCE_DIR})
foreach(wx_include_dir ${wxWidgets_INCLUDE_DIRS})
set(_WINDRES_INCLUDE_DIRS ${_WINDRES_INCLUDE_DIRS} -I${wx_include_dir})
endforeach(wx_include_dir ${wxWidgets_INCLUDE_DIRS})
这段代码是用于设置编译 .rc 文件时所需的头文件搜索路径。
在 Windows 平台上,编译 .rc 文件需要使用 windres.exe 工具,这个工具需要知道头文件的搜索路径,才能正确地编译 .rc 文件。
具体来说,这个代码定义了一个变量 _WINDRES_INCLUDE_DIRS,用于保存所有需要添加到编译命令中的头文件搜索路径。这个变量的初始值为 -I${CMAKE_CURRENT_SOURCE_DIR},表示将当前源代码目录添加到头文件搜索路径中。
然后,这个代码使用 foreach 循环遍历变量 wxWidgets_INCLUDE_DIRS 中的所有元素(即 wxWidgets 库的头文件搜索路径),将每个路径都添加到 _WINDRES_INCLUDE_DIRS 变量中。
最终,这个代码将 _WINDRES_INCLUDE_DIRS 变量的值传递给 add_custom_command() 命令的 -D 参数,用于设置 windres.exe 工具的头文件搜索路径。这样,在使用 windres.exe 编译 .rc 文件时,就可以正确地搜索到所需的头文件了。
请注意,这段代码是在构建 wxWidgets 库时使用的,并且使用了 CMake 的变量和命令,因此需要在 CMakeLists.txt 文件中使用。如果您不是在构建 wxWidgets 库,或者使用其他构建工具和命令,请根据实际情况修改这段代码。
list(APPEND mingw_resource_compiler_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/resources/msw/ )
# include dir to allow getting the version header
list(APPEND mingw_resource_compiler_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/ )
这两句代码什么意思
这两句代码是用于设置编译 .rc 文件时所需的头文件搜索路径。
第一句代码使用 list(APPEND) 命令将 C M A K E S O U R C E D I R / r e s o u r c e s / m s w / 添加到变量 m i n g w r e s o u r c e c o m p i l e r I N C L U D E D I R S 的末尾。 {CMAKE_SOURCE_DIR}/resources/msw/ 添加到变量 mingw_resource_compiler_INCLUDE_DIRS 的末尾。 CMAKESOURCEDIR/resources/msw/添加到变量mingwresourcecompilerINCLUDEDIRS的末尾。{CMAKE_SOURCE_DIR}/resources/msw/ 表示项目源代码目录下的 resources/msw/ 目录,用于存放 Windows 平台下的资源文件。
第二句代码也使用 list(APPEND) 命令将 C M A K E B I N A R Y D I R / 添加到变量 m i n g w r e s o u r c e c o m p i l e r I N C L U D E D I R S 的末尾。 {CMAKE_BINARY_DIR}/ 添加到变量 mingw_resource_compiler_INCLUDE_DIRS 的末尾。 CMAKEBINARYDIR/添加到变量mingwresourcecompilerINCLUDEDIRS的末尾。{CMAKE_BINARY_DIR}/ 表示项目构建目录,用于存放编译生成的文件。
最终,这个变量的值将被传递给 add_custom_command() 命令的 -I 参数,用于设置 windres.exe 工具的头文件搜索路径。这样,在使用 windres.exe 编译 .rc 文件时,就可以正确地搜索到所需的头文件了。
请注意,这段代码是在使用 MinGW 工具链编译 Windows 应用程序时使用的,并且使用了 CMake 的变量和命令,因此需要在 CMakeLists.txt 文件中使用。如果您不是在使用 MinGW 工具链,或者使用其他构建工具和命令,请根据实际情况修改这段代码。
# Compile resource file.
add_custom_command(OUTPUT ${_OUT}
COMMAND ${CMAKE_RC_COMPILER}
ARGS ${_ARGS}
COMMENT "Compiling ${_NAME}'s resource file"
VERBATIM)
这段代码用于在构建过程中编译 .rc 文件,生成一个目标文件。
具体来说,这个代码使用 add_custom_command() 命令创建一个自定义的构建命令。这个命令的输出文件是 O U T ,表示生成的目标文件的路径和名称。 {_OUT},表示生成的目标文件的路径和名称。 OUT,表示生成的目标文件的路径和名称。{_ARGS} 是一个变量,表示传递给 CMAKE_RC_COMPILER 的参数列表,其中包括输入文件和输出文件等信息。
在执行这个自定义命令时,会调用 C M A K E R C C O M P I L E R 命令来编译 . r c 文件。 {CMAKE_RC_COMPILER} 命令来编译 .rc 文件。 CMAKERCCOMPILER命令来编译.rc文件。{CMAKE_RC_COMPILER} 是一个 CMake 变量,表示 Windows 平台下的资源编译器。在 Windows 平台上,通常使用 rc.exe 或 windres.exe 来编译 .rc 文件。
这个自定义命令还设置了一个注释信息,用于在构建过程中显示编译资源文件的进度。VERBATIM 参数表示将命令输出直接传递给构建系统,不做任何处理。
最终,这个自定义命令会在构建过程中被执行,生成一个目标文件,用于链接到可执行文件或者库文件中。
使用 windres.exe 工具编译 .rc 文件
在 Windows 平台上,可以使用 windres.exe 工具来编译 .rc 文件。windres.exe 工具是 MinGW 工具链中的一个工具,用于将 .rc 文件编译成 COFF 格式的目标文件。
以下是使用 windres.exe 工具编译 .rc 文件的步骤:
创建一个 .rc 文件,定义资源信息,例如图标、对话框、菜单等。.rc 文件是 Windows 平台下的资源文件格式,可以使用 Visual Studio 或者其他资源编辑器来编辑。
rc
Copy
// myresource.rc
#include "resource.h"
IDI_ICON1 ICON "myicon.ico"
IDD_DIALOG1 DIALOGEX 0, 0, 200, 200
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "My Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
LTEXT "Hello World!", IDC_STATIC, 10, 10, 100, 20
PUSHBUTTON "OK", IDOK, 10, 30, 50, 20
PUSHBUTTON "Cancel", IDCANCEL, 70, 30, 50, 20
END
使用 windres.exe 工具编译 .rc 文件,生成一个目标文件。以下是使用 windres.exe 工具编译 myresource.rc 文件的示例命令:
sh
Copy
windres.exe -i myresource.rc -o myresource.o
在这个命令中,-i 参数指定输入文件为 myresource.rc,-o 参数指定输出文件为 myresource.o。
将生成的目标文件链接到可执行文件或者库文件中。在使用 GCC 等编译器时,可以通过 -Wl,–subsystem,windows 参数来指定生成 Windows 应用程序。
sh
Copy
g++ main.cpp myresource.o -o myapp.exe -Wl,--subsystem,windows
在这个命令中,main.cpp 是源代码文件,myresource.o 是编译后的目标文件,myapp.exe 是生成的可执行文件。-Wl,–subsystem,windows 参数指定生成 Windows 应用程序。
总的来说,使用 windres.exe 工具编译 .rc 文件需要手动执行多个步骤,因此在 CMake 中通常会使用 configure_file() 命令和 add_custom_command() 命令来自动化这个过程。
cmake编译.rc文件的流程
在 CMake 中编译 .rc 文件的流程如下:
在 CMakeLists.txt 文件中,使用 add_executable() 或 add_library() 命令创建一个目标,并将 .rc 文件添加到目标中。
# 创建一个可执行文件目标
add_executable(myapp main.cpp myresource.rc)
在 .rc 文件中,定义资源信息,例如图标、对话框、菜单等。.rc 文件是 Windows 平台下的资源文件格式,可以使用 Visual Studio 或者其他资源编辑器来编辑。
rc
Copy
// myresource.rc
#include "resource.h"
IDI_ICON1 ICON "myicon.ico"
IDD_DIALOG1 DIALOGEX 0, 0, 200, 200
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "My Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
LTEXT "Hello World!", IDC_STATIC, 10, 10, 100, 20
PUSHBUTTON "OK", IDOK, 10, 30, 50, 20
PUSHBUTTON "Cancel", IDCANCEL, 70, 30, 50, 20
END
在 CMakeLists.txt 文件中,使用 configure_file() 命令将 .rc 文件复制到构建目录中,并生成一个头文件,用于在源代码中引用资源信息。
cmake
Copy
# 复制 myresource.rc 到构建目录中
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/myresource.rc ${CMAKE_CURRENT_BINARY_DIR}/myresource.rc COPYONLY)
# 使用 rc.exe 编译 myresource.rc,并生成 resource.h 头文件
execute_process(COMMAND rc.exe /fo ${CMAKE_CURRENT_BINARY_DIR}/myresource.res /i ${CMAKE_CURRENT_SOURCE_DIR} /r ${CMAKE_CURRENT_BINARY_DIR}/myresource.rc)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/resource.h COMMAND ${CMAKE_RC_COMPILER} -r -fo ${CMAKE_CURRENT_BINARY_DIR}/resource.h ${CMAKE_CURRENT_BINARY_DIR}/myresource.res)
在这个示例中,我们使用 configure_file() 命令将 myresource.rc 文件复制到构建目录中。然后,我们使用 execute_process() 命令调用 Windows 平台下的 rc.exe 工具编译 .rc 文件,并将编译结果保存为 myresource.res 文件。最后,我们使用 add_custom_command() 命令生成一个自定义命令,用于将 myresource.res 文件编译成 resource.h 头文件。
在源代码中包含生成的头文件,并使用其中定义的资源信息。
// main.cpp
#include "resource.h"
#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// 使用 IDI_ICON1 图标
HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
// 显示 IDD_DIALOG1 对话框
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, nullptr);
return 0;
}
在这个示例中,我们包含了生成的 resource.h 头文件,并使用其中定义的资源信息。例如,我们使用 IDI_ICON1 宏来加载图标,使用 IDD_DIALOG1 宏来显示对话框。
cmake project与add_executable区别
在 CMake 中,project 和 add_executable 命令都是用于定义和构建项目的命令,但它们的作用和用法略有不同。
project 命令用于定义整个项目的名称、版本、语言和编译选项等信息。具体来说,project 命令会自动设置一些变量,例如 PROJECT_NAME、PROJECT_VERSION、CMAKE_CXX_STANDARD 等,以便在后续的命令中使用。
示例:
project(MyProject VERSION 1.0.0 LANGUAGES CXX)
这个示例中,project 命令定义了一个名为 MyProject 的项目,版本为 1.0.0,使用的编程语言为 C++。
相比之下,add_executable 命令用于定义一个可执行文件的目标,并指定其源代码文件。具体来说,add_executable 命令会创建一个可执行文件的目标,并将指定的源代码文件与其关联起来。
示例:
add_executable(myapp main.cpp)
这个示例中,add_executable 命令定义了一个名为 myapp 的可执行文件目标,并将 main.cpp 源代码文件与其关联起来。
总的来说,project 命令是 CMake 项目的基础命令,用于定义项目的基本信息和选项。而 add_executable 命令是用于定义可执行文件目标的命令,用于将源代码文件与目标文件关联起来。在实际使用中,这两个命令通常会一起使用,以构建一个完整的 CMake 项目。