How do I build a Win32 app with a resource file using cmake and MinGW?

Steve314 picture Steve314 · Aug 20, 2010 · Viewed 11.5k times · Source

In theory, it's very easy to build a Win32 app with a resource file using cmake. In an add_executable command, a resource file can be listed as easily as a C or C++ source file. There is a known bug, however, when building using MinGW tools.

I found a workaround, which is to include the following in 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)

Unfortunately, this doesn't seem to work. What seems to happen is that windres generates a <whatever>.rc.res file which ld doesn't understand.

In my searches, I've developed a strong suspicion that Win32 support is seen as a very low priority, especially outside of Visual Studio. This is understandable, as Win32 obviously isn't as important as it once was. And of course Visual Studio Express Editions are easily available for free.

Even so, it would be convenient for me if I could use MinGW GCC for a few old Win32 apps I still use. If nothing else, I can get GCOV test coverage stats.

Obviously if all else fails, I could always handle resource files using a custom build command. One issue is that I'm not familiar with either windres or ld, or how MinGW is meant to handle Win32 resource files. Another is that I don't really want to reinvent the wheel if someone already has a superior wheel they'd like to share with me.

So that's basically it - how can I support building Win32 apps with resource files using cmake, and using MinGW (but not breaking support for Visual Studio)?

Answer

PF4Public picture PF4Public · Aug 23, 2010

I think, your problem is here:

<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> -o <OBJECT> <SOURCE>

Maybe you should write something like this:

<CMAKE_RC_COMPILER> <SOURCE> <OBJECT>

Or more formal:

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

The other possible problem could be with - which extension does cmake substitutes? As windress will guess the needed output file format from that.

References are here: www.mingw.org/wiki/MS_resource_compiler

"res" files are unappropriate for ld, as you already know, and the windres example sourceware.org/binutils/docs/binutils/windres.html

windres man

EDIT by question author...

The fixed cmake code snippet is as follows...

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)

It should probably be setting a flags variable rather than inserting the -O option in the command template, but this works.