Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency checking on RC files in Delphi

If an RC file is modified, Delphi will compile it again. If an RC file has RCDATA or BITMAP declarations that reference files that have changed, Delphi will not recompile the .RC file to .RES again until I force it to by deleting the .RES file or doing a "touch" (modify file timestamp) on the top level .RC file.

Here's a sample TEST.RC file:

SAMPLE   RCDATA "File.txt"

When TEST.RC is modified, that will cause a recompilation, when "File.txt" is modified, however Delphi does not recompile the resources, on a "Compile". I am not willing to just use "Build" because it increases my time from seconds to several minutes.

Has anyone ever gotten Delphi to work properly with .RC text files and dependencies? Granted some people add resources and never change them, but I have started using .RC files for things that I may often change such as binary or text data that is in RCDATA sections in an .RC file.

Note that trying to put a "delete .res" step in pre-build or post-build appears to break the Delphi IDE/compiler. I can sort this out externally when building outside the IDE (always delete certain .res files before I run msbuild), but inside the IDE, Delphi doesn't give me much of a choice.

Has anyone got a solution? (I'm having this problem in Delphi 2007, but any solution that works with any version of Delphi from 2007 up to XE3 would be welcome.)

like image 638
Warren P Avatar asked Dec 13 '12 21:12

Warren P


1 Answers

This is not exactly a perfect answer since no dependency checking is done by the below sample, however the basic problem of the resource not being rebuilt frequently enough is fixed by Always Rebuilding Every Time, which is Good Enough.

That in the end is more correct than Delphi's built in behaviour which varies from (a) not recompiling frequently enough while you build from an {$R foo.res foo.rc} declaration when you use it inside the IDE to the even worse state of (b) not building at all from the commandline if you include a {$R foo.res foo.rc} declaration in your .dpr file.

So, with all that, here's a working pre-build step, which does what David suggested I do:

  call $(PROJECTDIR)\SubDir\foo.cmd $(PROJECTDIR)

here's what my foo.cmd contains:

  cd %1\SubDir
  rc.exe foo.rc
  echo compiled foo RCDATA

For anyone wondering what foo.rc might contain it might look like this:

  SQL_QUERY_1  RCDATA  "SqlDir1\MYSQL.SQL"

ERRATA:

I have found that {$R foo.res foo.rc} only builds properly in Delphi 2007 from within the IDE. From the commandline MSBUILD, it won't build. You just get "DCC ERROR 1" and the build aborts without a real error message. You may be interested to know that one of the reasons delphi MSBUILD compiles mysteriously abort without any error output in the error log or to stdout, is when RC.exe returns an errorlevel. RC.exe outputs a real error message (Hey Delphi you sent me invalid command line parameters, I'm giving up), and either Delphi DCC32doesn't forward that along back to you, or it is somehow otherwise gobbled up and not given back to users so they can have enough information to know why their build mysteriously breaks. Nasty little msbuild-dcc32 integration mis-feature, that.

Instead of {$R subdir\foo.res subdir\foo.rc}, you should have this in your DPR:

  {$R SubDir\foo.res}

That means "link that binary resource and don't try to recompile, because we did it fer ya already". All of the above is just by way of making explicit what David suggested in a comment. Hat tip to David.

like image 106
Warren P Avatar answered Sep 23 '22 08:09

Warren P