Delphi 预构建事件在编译之前不执行
我正忙于自动化我们的构建以包含 svn 修订号。我们使用的是 Delphi 2010。我添加了一个预构建事件,调用一个批处理文件,该批处理文件将 svn 修订号(从 .svn 目录中的条目文件读取)和指定的版本号注入到 aVersionInfo.rc 中,该版本号是用我的项目。预构建事件如下所示:
call SetVersionInfo.bat 6 5 4
...以及批处理文件(希望有人发现这有用)...
@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
批处理文件确实作为编译的一部分执行,更新了 aVersionInfo.rc,重新编译了 aVersionInfo.res,但是由于某种原因,新的 res 文件不用于编译 exe。但是,它会在干净构建期间或我第二次编译时更新。看来对 rc 文件更改的检查是在调用“预”构建事件之前进行的。这实际上使它成为一个中期构建事件。或者我错过了什么?
我确实尝试删除 aVersionInfo.res 文件作为另一个预构建事件,但编译器抱怨该文件丢失。难道是
{$R 'aVersionInfo.res' 'aVersionInfo.rc'}
线放错地方了?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
尝试
从批处理文件中手动使用和调用
brcc32 aVersionInfo.rc
(在创建 .rc 文件后)。这样您的 .res 文件就应该从正常的 IDE 构建中排除。Try using
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.可能缺少 ["]
回声。值“产品名称”,“APP\000”>> aVersionInfo.rc
ECHO。 VALUE "ProductVersion,"1\000" >> aVersionInfo.rc
----- 这里 -----------------------^
回声。 VALUE "评论","由 %username%\000 于 %date% 编译" >>>版本信息.rc
再见
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
TL;DR:
将行
{$R 'aVersionInfo.res' 'aVersionInfo.rc'}
直接放在 Program 语句的下面一次,然后构建。或者使用 BRCC32 强制第一次构建 .RES 文件长版本:
您对行:
位于错误位置的猜测部分正确。
当我最初在 Delphi XE2 下使用 .RC 文件进行设置时,我遇到了同样的问题,代码略有不同,有时可以编译,有时不能。我尝试了如下变体:
但 XE2 编译器一直抱怨找不到 RES 文件,如果确实不存在的话(请注意,这是我的初始构建)。
事实证明,您首先必须将该行直接放在 Program 语句下面:
... 而不是放在已经存在的附近
然后您构建一次程序。
之后,您可以将该行移回到更合乎逻辑的位置:
出于某种奇怪的原因,一旦 Delphi“知道”.rc 文件是项目的一部分,则不再重要:
预编译步骤。如果.RC 文件被修改,编译器将重建.RES 文件,无论早期版本是否存在。
当您最初设置这个系统时,这种奇怪的行为并没有真正的帮助;-(
在解析项目源代码和构建 .dproj 文件时还发生了其他奇怪的事情,这让我这个解决方案,值得注意的是:
如果您重命名 .rc 文件,这可能会让您再次陷入麻烦:.dproj 文件中的残留部分仍然指向旧的 .rc 文件,编译器会抱怨找不到它。您必须从 .dproj 文件中编辑此旧名称才能解决此问题。
请注意,这一切都在 XE2 下,在其他版本 YMMV。
编辑添加:您可能仍然需要与 XE2 版本信息不工作问题。
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 fileLong version:
Your guess that the line:
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:
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:
... and not in the vicinity of your already present
Then you build your program once.
After that you can move the line back to a more logical place:
For some weird reason, once Delphi 'knows' that the .rc file is part of the project, it no longer matters if you either:
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.
在批处理文件中添加一行,修改包含该资源的 Delphi 源文件:
然后应重新编译源文件。如果源文件未修改,则编译器没有理由重新链接程序的该部分,因此不会注意到更新的资源文件。
Add a line to your batch file that modifies the Delphi source file that includes the resource:
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.
您可以在批处理文件中调用 brcc32,以便它始终更新 .res 文件。我做了类似的事情,它在编译和构建中都有效。
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.