如何使用cmake和MinGW构建带有资源文件的Win32应用程序?

15

理论上,使用CMake很容易构建一个带资源文件的Win32应用程序。在add_executable命令中,可以像列出C或C++源文件一样轻松地列出资源文件。然而,当使用MinGW工具进行构建时,存在已知的错误。

我发现了一个解决方法,将以下内容包含在CMakeFiles.txt中即可...

if(MINGW)
  set(CMAKE_RC_COMPILER_INIT windres)
  ENABLE_LANGUAGE(RC)
  SET(CMAKE_RC_COMPILE_OBJECT
      "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -o <OBJECT> <SOURCE>")
endif(MINGW)
很遗憾,这似乎行不通。情况似乎是这样的,windres 生成了一个 <whatever>.rc.res 文件,但 ld 不理解。
在我的搜索中,我强烈怀疑 Win32 支持被视为非常低的优先级,特别是在 Visual Studio 之外。这是可以理解的,因为 Win32 显然不像它曾经那么重要。当然,免费的 Visual Studio Express 版本很容易获得。
即使如此,如果我能够使用 MinGW GCC 来运行一些我仍在使用的旧 Win32 应用程序,那将非常方便。如果没有其他办法,我至少可以获取 GCOV 测试覆盖率统计数据。
显然,如果所有其他方法都失败了,我总可以使用自定义构建命令来处理资源文件。问题之一是我不熟悉 windres 或 ld,也不知道 MinGW 如何处理 Win32 资源文件。另一个问题是,如果有人已经拥有一个更好的轮子,并愿意与我共享,我真的不想重新发明轮子。
所以基本上就是这样了 - 我如何支持使用 cmake 构建 Win32 应用程序并使用 MinGW(但不破坏对 Visual Studio 的支持)?

看起来cmake bug(https://cmake.org/Bug/view.php?id=4068)已经在cmale 2.8.5中得到修复。2.8.12是目前仍在普遍使用的最旧版本,因此现在不需要任何解决方法。 - wheredidthatnamecomefrom
1个回答

7
我认为,你的问题出在这里:
<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -o <OBJECT> <SOURCE>

也许你应该像这样写一些内容:
<CMAKE_RC_COMPILER> <SOURCE> <OBJECT>

或更正式:

<CMAKE_RC_COMPILER> -i <SOURCE> -o <OBJECT>

可能的另一个问题是 - cmake会用哪个扩展名来替换?因为windress将从中猜测所需的输出文件格式。
参考资料在这里: www.mingw.org/wiki/MS_resource_compiler “res”文件不适用于ld,正如您已经知道的那样,windres示例 sourceware.org/binutils/docs/binutils/windres.html windres手册 编辑 问题作者...
修复后的cmake代码片段如下...
if(MINGW)
  set(CMAKE_RC_COMPILER_INIT windres)
  ENABLE_LANGUAGE(RC)
  SET(CMAKE_RC_COMPILE_OBJECT
    "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
endif(MINGW)

它可能应该设置一个标志变量而不是在命令模板中插入-O选项,但这样也可以。


谢谢你的回答。我现在很忙,可能需要几天时间才能再次研究这个问题。有一件事我想指出 - 我试图告诉cmake使用另一个扩展名。有一个变量指定使用哪个扩展名,我尝试在enable_language之后更改它以及更改编译器。但是,cmake仍然使用.res - 不知道为什么。无论如何,在这一点上任何帮助都是+1,但在我尝试之前可能需要一段时间。 - user180247
我有时间再次尝试,结果发现主要问题是虽然我将其描述为文件格式问题,但我首先考虑的是文件扩展名问题。解决方案是重新查看windres手册,并有意识地尝试使用“-O coff”指定coff输出格式,而不考虑文件扩展名是否有效。我应该找出cmake用于RC标志的变量,但在文件扩展名变量无效后,我只是将选项插入到模板命令中。 - user180247
希望您不介意在接受答案之前我添加一点内容。 - user180247
-O coff 我没有提到这个,因为它写在windres手册中,我认为指向那里就足够了,但问题已经解决 :) - PF4Public
这个解决方案对我来说不起作用,直到我删除了CMAKE_RC_COMPILE_OBJECT命令中的<FLAGS>部分;windres一直在抱怨一个未知的标志--L。希望这可以帮助到你。 - congusbongus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接