views:

125

answers:

1

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)?

+2  A: 

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.

PF4Public
Thanks for the answer. I'm busy ATM, so it may be a few days before I can look into this again. One thing I will point out - I tried to tell cmake to use another extension. There's a variable that specifies which extension is used, and I tried changing that after the `enable_language` above along with the which-compiler change. cmake went ahead and used `.res` anyway - don't know why. Anyway, +1 because anythings helpful at this point, but it may be a little while before I try it out.
Steve314
@PF4Public: I got the time to play with this again, and it turns out that the main problem is that although I described this as a file format problem I was thinking of it first/foremost as a file extension problem. The solution was to revisit the windres manual, and have the sense to try specifying the coff output format using `-O coff` irrespective of the file extension worked. I should probably have figured out the variable cmake uses for RC flags, but after the file extension variable didn't work, I just inserted the option into the template command.
Steve314
@PF4Public - hope you don't mind me adding a little to your answer before accepting.
Steve314
-O coffI didn't tell about that, because it's written in a windres manual, which I pointed, thinking that's enough, but nevertheless problem solved :)
PF4Public