Recent

Author Topic: A trouble with Windres (Resource File Compiler)  (Read 10947 times)

ChrisF

  • Hero Member
  • *****
  • Posts: 542
A trouble with Windres (Resource File Compiler)
« on: March 12, 2013, 03:06:33 pm »
Hello,


I've encountered a trouble when trying to use an external resource file within a Lazarus/FPC project. Windres is unable to compile my resource file (a standard .rc text file) by default.


A basic sample:

-Add "{$R Test.rc}" to one of your unit, to include the concerned resource file to your current Lazarus/FPC project,
-Create this simple resource file (i.e. Test.rc):
Code: [Select]
MyDlg DIALOGEX 0, 0, 440, 178
   CAPTION  "My Title"
   STYLE    DS_MODALFRAME | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
   EXSTYLE  WS_EX_APPWINDOW
   FONT     8, "MS Sans Serif"
   CLASS    "MyDlgClass"
BEGIN
   DEFPUSHBUTTON  "&Quit", IDCANCEL, 368, 8, 64, 18, BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP
END
-Try to compile the Lazarus/FPC project.


Using the -vd option to compile my Lazarus/FPC project, I've got this error reported:
Code: [Select]
Calling resource compiler "C:\Lazarus\fpc\2.6.0\bin\i386-win32\windres.exe" with "--preprocessor=C:\Lazarus\fpc\2.6.0\bin\i386-win32\cpp.exe --include C:\Lazarus\fpc\2.6.0\bin\i386-win32\ -O res -o C:\WORK\INTER\ess\lib\i386-win32\Test.res C:/WORK/INTER/ess/Test.rc" as command line
windres: C:/WORK/INTER/ess/Test.rc:3: syntax error
Compiling resource C:\WORK\INTER\ess\Test.rc

According to my configuration, all the options given to the Windres utility are OK (especially the paths).


After a few investigations, it seems that, by default, Windres can't recognized the option keywords : "DIALOGEX", "CAPTION", "STYLE" ...  are OK, but "DS_MODALFRAME", "IDCANCEL", "WS_TABSTOP", ... are not.


If I'm replacing the concerned option keywords by their numerical values, it's now OK:
Code: [Select]
MyDlg DIALOGEX 0, 0, 440, 178
   CAPTION  "My Title"
   STYLE    0x80L | 0x20000L | 0xc00000L | 0x80000L
   EXSTYLE  0x40000L
   FONT     8, "MS Sans Serif"
   CLASS    "MyDlgClass"
BEGIN
   DEFPUSHBUTTON  "&Quit", 2, 368, 8, 64, 18, 0x1L | 0x10000L | 0x20000L
END


The other solution being also to manually include the "windres.h" to my resource file. This second solution is OK too ("windres.h" being present in my include directory, i.e. windres option "--include C:\Lazarus\fpc\2.6.0\bin\i386-win32\"):
Code: [Select]
#include "windres.h"

MyDlg DIALOGEX 0, 0, 440, 178
   CAPTION  "My Title"
   STYLE    DS_MODALFRAME | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
   EXSTYLE  WS_EX_APPWINDOW
   FONT     8, "MS Sans Serif"
   CLASS    "MyDlgClass"
BEGIN
   DEFPUSHBUTTON  "&Quit", IDCANCEL, 368, 8, 64, 18, BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP
END


Am I the only one concerned by this problem ?
BR. ChrisF


My configuration:
Windows XP SP3 32 bits
Lazarus 1.0.6
FPC 2.6.0
(No other CygWin, Mingw, ... package present)

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7216
Re: A trouble with Windres (Resource File Compiler)
« Reply #1 on: March 12, 2013, 03:44:34 pm »
Add

 #include <windres.h> 

as first line to your .rc

If constants are missing, add them to windres.h (should be in the same dir as windres.exe)

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: A trouble with Windres (Resource File Compiler)
« Reply #2 on: March 12, 2013, 06:58:35 pm »
Hello,

Thanks.

That's the solution I'm currently using, but it's a bit annoying to maintain 2 versions of my resource files (i.e. for Delphi and Lazarus/FPC), because there is no "windres.h" file within Delphi.

I know it's not a big deal to comment (i.e. Delphi) or un-comment  (i.e. FPC) the concerned include line. I could also add a "dummy" "windres.h" within the Delphi directory, but it's not quite satisfying (and not very portable).

Is there any way to make a conditional resource file compiling with the current Windres program and environment coming with Lazarus/FPC ?

Something like:
Code: [Select]
#ifdef Compiling_with_Windres_or_any_other_predefined_constant_for_it
  #include  <Windres.h>
#endif

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7216
Re: A trouble with Windres (Resource File Compiler)
« Reply #3 on: March 12, 2013, 07:25:40 pm »

That's the solution I'm currently using, but it's a bit annoying to maintain 2 versions of my resource files (i.e. for Delphi and Lazarus/FPC), because there is no "windres.h" file within Delphi.

I know it's not a big deal to comment (i.e. Delphi) or un-comment  (i.e. FPC) the concerned include line. I could also add a "dummy" "windres.h" within the Delphi directory, but it's not quite satisfying (and not very portable).

Windres is an external program, and not part of the FPC project.  But you can define symbols on the cmdline with -DFPC or something. (see windres.exe -h )

I don't know if Lazarus has options for windres somewhere, where you can add cmdline parameters.

 

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: A trouble with Windres (Resource File Compiler)
« Reply #4 on: March 12, 2013, 08:41:24 pm »
Hello,

Yes, I know that Windres is an external tool.

As you've suggested, I've already searched if there is an option within the Lazarus IDE to pass additional options to the resource compiler for the concerned project (to add my own -D option).

I didn't find any (only for the Pascal compiler). Though it's quite possible I've not searched enough: for instance, there are some "advanced" options within Lazarus for which I'm not completely sure about their aims.

In fact, I've not even found where the Windres program is called within Lazarus. I've looked at a few configuration files (fpc.cfg for instance), Make files, ... , but with no real success.

I've got in mind to make a test using GoRC instead of Windres (according to my tests, GoRC doesn't need the "#include <windres.h>" line), but couldn't figure where to make the appropriate change (if it's possible).

Or to add a specific -D option for all my resource file compilations with Windres; though it's probably not recommended (I guess a new Lazarus installation will cancel the modification).

Well, anyway thanks for your answers.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: A trouble with Windres (Resource File Compiler)
« Reply #5 on: March 13, 2013, 07:15:52 am »
AFAIU, the compiler calls the resource compiler when it hits resource compiler directives like {$R bla.rc} in the source code. I'd not be surprised Lazarus doesn't explicitly handle it....

BTW: if you have any updates for http://wiki.lazarus.freepascal.org/Lazarus_Resources#FPC_resources please feel free to make them ;)
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7216
Re: A trouble with Windres (Resource File Compiler)
« Reply #6 on: March 13, 2013, 10:55:28 am »
A workaround would be to create a small program that calls windres with all the parameters it gets, but adds -DFPC.

Then use -FR to make FPC call that program instead of windres.

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: A trouble with Windres (Resource File Compiler)
« Reply #7 on: March 13, 2013, 07:00:29 pm »
Hello,


Thanks for both your answers: they have really help me to better understand the process.


(@BigChimp) Yes, you are quite right. It seems that the call to Windres is definitively hard-coded within FPC (I formerly and wrongly supposed that Lazarus was the original caller).

If I understand it correctly:
-comprsrc.pas is responsible for doing the main job,
-the resource compiler program and parameters are defined within several units, depending of the OS and/or CPU: t_win.pas for Windows (i.e. res_gnu_windres_info or res_win64_gorc_info), rescmn.pas (common ?), i_bsd.pas (all unix ?), ...

So, no possibility to dynamically add a -D option in the parameters for the resource file compiler currently, not without modifying the source code of FPC and recompile it (which is of course a very bad idea, except for just test purposes).


(@marcov) I didn't know there was a possibility to change the resource compiler program within FPC, thanks (though I presume you probably mean the "-FC<x>" option instead, as the "-FR<x>" option is for linking the resources).

I thought first to call directly GoRC instead of Windres with this option, but the parameters are quite different between GoRC and Windres (and there is no possibility to change them).

So, I've just given your suggestion a try, using a sort of a "wrapper" to call Windres, and, as far as I've tested it's working (at least in most of the "standard" cases).

Here is my "quickly-programmed" test code, just for a proof of concept (it's definitively not a clean and correct one, i.e. paramstr(0), hard-coded strings, ...):
Code: [Select]
program MyRC;
{$APPTYPE CONSOLE}

{$mode objfpc}{$H+}

uses SysUtils;

var sPgmName, sParams: String;
var i1: Integer;

begin
   sPgmName:=ParamStr(0);
   sPgmName:=StringReplace(sPgmName,'MyRC.exe','windres.exe',[rfReplaceAll, rfIgnoreCase]);
   if not FileExists(sPgmName) then
      begin
         WriteLn(sPgmName+' : Error : rc compiler to call not found');
         Halt(1);
      end
   else
      begin
         sParams:=' -DFPC';
         for i1:=1 to ParamCount() do sParams:=sParams+' '+ParamStr(i1);
         //&&&& ToDo: Trap Error
         i1:=ExecuteProcess(sPgmName,sParams);
         if i1<>0 then
            begin
               WriteLn(sPgmName+' : Error : rc compiler return code='+IntToStr(i1));
               Halt(i1);
            end;
      end;
end.

After adding the "-FCMyRC" personalized option within my Lazarus/FPC project options, the / "#ifdef FPC" / #include <windres.h> / "#endif" / block is correctly detected and processed by Windres (and of course gives no error with the Delphi resource compilation).


(@BigChimp) Concerning the documentation for the resource files with FPC/Lazarus, I guess that adding marcov's first answer in this topic for instance (i.e. "Add #include <windres.h> as the first line to your .rc file, if you encounter windres errors compiling a <supposedly correct> .rc file") could help people in the future when having the same problem as I've got (especially when converting a Delphi project with FPC/Lazarus the first time).


BR  ChrisF

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7216
Re: A trouble with Windres (Resource File Compiler)
« Reply #8 on: March 13, 2013, 09:23:33 pm »
iirc gorc is used for 64-bit. But it can be this (the cmdline, and which resource compiler to use) is hardcoded per target

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: A trouble with Windres (Resource File Compiler)
« Reply #9 on: March 14, 2013, 04:27:29 pm »
Hello,

Yes, they are all hard-coded into the source code of FPC, depending of the OS.

For instance, for Windows the following data are defined in the "t_win.pas" unit :

Code: [Select]
{$ifndef x86_64}
...
   rcbin  : 'windres';
   rccmd  : '--include $INC -O res -o $RES $RC';
...
{$else x86_64}
...
   rcbin  : 'gorc';
   rccmd  : '/machine x64 /nw /ni /r /fo $RES $RC';
...