0

So I am making a desktop application using C and the Win32 API. I am also using CMake/Make in conjunction with MinGW. Everything went smoothly until I wanted to add an .rc file to the executable. From my understanding you write an .rc file which is then compiled to a .res file, then presumably you are supposed to embed it in the executable. Here's the problem however, when I attempt to compile the .rc file with the GNU utility windres it fails to compile. I always get the following error messages:

C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin\windres.exe: can't open file `page:': Invalid argument
C:\Code\C\test\resources.rc:4: fatal error: when writing output to : No such file or directory
4 | IDI_TEST_ICON    ICON    "test.ico"
  |
compilation terminated.
C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin\windres.exe: preprocessing failed.

This occurs with every .rc file I've tried, for completeness however, here is the current test file I am trying to compile:

#include <windows.h>
#include "resource.h"
IDI_TEST_ICON   ICON    "test.ico"

And the resource.h file:

#define IDI_TEST_ICON 101

So the final question is the following: Why doesn't windres compile the .rc file successfully? And what can I do about in the context of using MinGW?

Edit 1: Worth noting is that I also converted the .rc file to ANSI format since windres is notorious for yielding peculiar errors when formatted in UTF-8. Yet, the same errors occur.

  • 2
    How are you invoking `windres` exactly? The error message is complaining that `windres` can't *write* to the file named `page:`, which makes sense as that is not a valid filename. – Remy Lebeau Jun 20 '22 at 18:47
  • @RemyLebeau I am invoking it through the use of `windres -i resource.rc -o resource.res`. – Jack Henrikson Jun 20 '22 at 22:03
  • Don't put an answer into your question. If you want to provide an answer, you are [invited](https://stackoverflow.com/help/self-answer) to answer your own question – IInspectable Jun 22 '22 at 12:51

2 Answers2

1

windres actually generates an object file (in COFF format)

So you should run the command like this:

windres resource.rc -o resource.o

When I check the format of the generated file like this:

file resource.o

I get the following result:

resource.o: Intel amd64 COFF object file, no line number info, not stripped, 1 section, symbol offset=0x3c4c, 1 symbols

So you just need to include the generated .o file in the link step to include the resource.

For example when you run the following command you will get an .exe that won't run, but it will show the icon in Explorer:

gcc -shared -o resource.exe resource.o
Brecht Sanders
  • 6,215
  • 1
  • 16
  • 40
  • Idiomatic (in Windows-world) would be `windres resource.rc -o resource.res` I think, but otherwise +1 from me. – Paul Sanders Jun 21 '22 at 08:03
  • Alright, but the problem seems to be a faulty windres version or something because when I run the first command in your post I am greeted by the same "can't open file `page:': Invalid argument" error message. Could it perhaps be a faulty windres install? Is my .rc file properly formatted? – Jack Henrikson Jun 21 '22 at 12:15
  • Try a recent version of MinGW-w64 like the standalone build for Windows from https://winlibs.com/ – Brecht Sanders Jun 21 '22 at 19:40
0

After a lot of digging in old forum threads I managed to find a "solution" that works. However I still find it peculiar that this solves the problem. I followed Brecht Sanders advise and downloaded a standalone build from winlibs.com. Even this didn't solve the problem which led me to investigate possible RC_COMPILER_FLAGS which ultimately led me to the --use-temp-file flag.

This flag acts as an alternate approach to compile .rc files since it excludes the use of popen (or the equivalent of it in Windows). According to the documentation this flag should be used if the implemenation of popen is buggy on the host. What is interesting here is that the documentation states that this is known to happen on certain non-english versions of Windows. In my case I am using the Swedish language version of Windows which might explain why this is occuring.

Thus the final solution turns out to be:

windres -i resource.rc -o resource.o --use-temp-file

Which ultimately yields an object file which can then be included in the add_executable call in CMake.