Delphi pre-build event not executing BEFORE compile

試著忘記壹切 提交于 2019-11-26 20:26:48

问题


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?


回答1:


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.




回答2:


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




回答3:


Add a line to your batch file that modifies the Delphi source file that includes the resource:

touch VersionInfo.pas

Then the source file should get recompiled. If the source file isn't modified, then there's no reason for the compiler to re-link that portion of the program, and so the updated resource file won't be noticed.




回答4:


You could call brcc32 inside the batch file so it will always update the .res file. I do something similar and it works in a compile as well as a build.




回答5:


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.



来源:https://stackoverflow.com/questions/2087402/delphi-pre-build-event-not-executing-before-compile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!