Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi pre-build event not executing BEFORE compile

I'm busy automating our builds to include the svn revision number. We're using Delphi 2010. I added a pre-build event calling a batch file that injects the the svn revision number (read from the entries file in the .svn directory) and a specified version number into aVersionInfo.rc that is compiled with my project. The pre-build event looks like this:

call SetVersionInfo.bat 6 5 4

...and the batch file (hope someone finds this useful)...

@ECHO OFF
SETLOCAL
setLocal EnableDelayedExpansion

SET _myVar=0
FOR /F %%G in (.svn\entries.) DO (
IF !_myVar! LSS 3 SET /A _myVar+=1 & SET _svn_dir_rev=%%G
)

ECHO 1 VERSIONINFO > aVersionInfo.rc
ECHO. FILEVERSION %1,%2,%3,%_svn_dir_rev%   >> aVersionInfo.rc
ECHO. PRODUCTVERSION 1   >> aVersionInfo.rc
ECHO. FILEOS VOS__WINDOWS32   >> aVersionInfo.rc
ECHO. FILETYPE VFT_APP   >> aVersionInfo.rc
ECHO. BEGIN   >> aVersionInfo.rc
ECHO.   BLOCK "StringFileInfo"   >> aVersionInfo.rc
ECHO.   BEGIN   >> aVersionInfo.rc
ECHO.     BLOCK "080904b0"   >> aVersionInfo.rc
ECHO.     BEGIN   >> aVersionInfo.rc
ECHO.       VALUE "CompanyName","COMPANY\000"   >> aVersionInfo.rc
ECHO.       VALUE "FileDescription","APP\000"   >> aVersionInfo.rc
ECHO.       VALUE "FileVersion","%1.%2.%3.%_svn_dir_rev%\000"   >> aVersionInfo.rc
ECHO.       VALUE "InternalName","APP\000"   >> aVersionInfo.rc
ECHO.       VALUE "LegalCopyright","Copyright APP\000"   >> aVersionInfo.rc
ECHO.       VALUE "LegalTrademarks","APP\000"   >> aVersionInfo.rc
ECHO.       VALUE "OriginalFilename","APP.exe\000"   >> aVersionInfo.rc
ECHO.       VALUE "ProductName","APP\000"   >> aVersionInfo.rc
ECHO.       VALUE "ProductVersion,"1\000"   >> aVersionInfo.rc
ECHO.       VALUE "Comments","Compiled on %date% by %username%\000"   >> aVersionInfo.rc
ECHO.     END   >> aVersionInfo.rc
ECHO.   END   >> aVersionInfo.rc
ECHO.   BLOCK "VarFileInfo"   >> aVersionInfo.rc
ECHO.   BEGIN   >> aVersionInfo.rc
ECHO.     VALUE "Translation", 0x0809 1200   >> aVersionInfo.rc
ECHO.   END   >> aVersionInfo.rc
ECHO. END   >> aVersionInfo.rc
ENDLOCAL

The batch file does execute as part of a compile, aVersionInfo.rc is updated, aVersionInfo.res is recompiled, but for some reason the new res file is not used to compile the exe. It is, however, updated during a clean build or if I compile a second time. It seems the check for changes to the rc files takes place before the "pre"-build events are called. Which actually makes it a mid-build event. Or am I missing something?

I did try deleting the aVersionInfo.res file as another pre-build event, but then the compiler complains that this file is missing. Could it be that the

{$R 'aVersionInfo.res' 'aVersionInfo.rc'}

line is in the wrong place?

like image 443
Jaco Briers Avatar asked Jan 18 '10 16:01

Jaco Briers


3 Answers

Try using

{$R aVersionInfo.res}

and calling brcc32 aVersionInfo.rc manually from your batch file (after you're done with creating the .rc file). That way your .res file should be excluded from the normal IDE build.

like image 93
Ondrej Kelle Avatar answered Nov 18 '22 02:11

Ondrej Kelle


May be is missing a ["]
ECHO. VALUE "ProductName","APP\000" >> aVersionInfo.rc
ECHO. VALUE "ProductVersion,"1\000" >> aVersionInfo.rc
------- HERE -----------------------^
ECHO. VALUE "Comments","Compiled on %date% by %username%\000" >> aVersionInfo.rc Bye

like image 26
Luca Guzzon Avatar answered Nov 18 '22 03:11

Luca Guzzon


TL;DR:

Place the line {$R 'aVersionInfo.res' 'aVersionInfo.rc'} directly below the Program statement once, then build. Or use BRCC32 to force the first time build of the .RES file

Long version:

Your guess that the line:

{$R 'aVersionInfo.res' 'aVersionInfo.rc'}

is in the wrong place is partially correct.

When I initially set up using an .RC file under Delphi XE2, I had the same trouble with slightly different code, sometimes compiling and sometimes not. I tried variations like:

{$R 'aVersionInfo.res' 'aVersionInfo.rc'}
{$R '.\aVersionInfo.res' '.\aVersionInfo.rc'}

but the XE2 compiler kept complaining about the RES file not being found, if indeed it was not there (note that this was my initial build).

It turns out you first have to place that line directly below the Program statement:

program TTClient;
{$R 'VersionInfo.res' 'VersionInfo.rc'}

... and not in the vicinity of your already present

{$R *.res}

Then you build your program once.

After that you can move the line back to a more logical place:

{$R *.res}
{$R 'VersionInfo.res' 'VersionInfo.rc'}

For some weird reason, once Delphi 'knows' that the .rc file is part of the project, it no longer matters if you either:

  • place the line anywhere else
  • have a .res file present or not

No need for a precompile step. If the .RC file is modified, the compiler will rebuild the .RES file, whether an earlier version existed or not.

This weird behavior does not really help when you set up this system initially ;-(

There are other strange things going on with the parsing of the project source and the construction of the .dproj file which brought me to this solution, notably:

If you rename the .rc file, this may get you into trouble again: There are remnants in the .dproj file still pointing to the old .rc file and the compiler will complain about not finding it. You have to edit this old name out of the .dproj file to fix this.

Note this was all under XE2, under other version YMMV.


Edited to add: You may still have to battle with XE2 Version Info Not Working issue.

like image 1
Jan Doggen Avatar answered Nov 18 '22 02:11

Jan Doggen