我们目前正在从德尔福XE转换到德尔福XE3,我们有严重的问题,我们的前构建事件。
我们的预构建事件如下:
SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc
brcc32 -foProject.res VersionInfo.rc(请注意,这两个命令出现在单独的行中;并包含我们的“真实”命令中的绝对路径),即我们首先从工作副本中提取当前的SVN版本,将此信息写入VersionInfo.rc,然后使用Borland资源编译器生成一个资源文件。
这在以前的Delphi版本中非常有效,但是每当我们在XE3中打开项目选项时,XE3就会将其转换为:
SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc &brcc32 -foProject.res VersionInfo.rc(请注意,这是一行,这两个命令都由一个符号分隔)。这将导致构建失败。
我们当前的解决方法是手动将其更改为
SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc && brcc32 -foProject.res VersionInfo.rc也就是说,如果第一个命令成功,我们使用两个符号来执行第二个命令。
这是可行的,但只有在我们再次编辑项目选项之前,德尔菲XE3总是会扰乱构建前的事件:-(
有人知道解决这个问题的办法吗?我想我们可以编写一个调用SubWCRev和brcc32的简单命令行工具,但是我更喜欢一个更简单的解决方案。
UPDATE:轻松复制此bug的步骤
IDE
RAD Studio命令提示符
IDE
- click ok
RAD Studio命令提示符
发布于 2013-03-18 12:08:52
最后,我们使用了一个类似于David提出的解决方案:
如果有人感兴趣,下面是我们的PreBuild活动:
PreBuild "<path_to_SVN_working_copy>" "VersionInfo.rc.in" $(OUTPUTNAME).res下面是脚本PreBuild.rb:
#!/usr/bin/env ruby
require 'tempfile'
if ARGV.length < 3
puts "usage: #{$0} <path> <infile> <outfile>"
exit 1
end
# svnversion.exe is part of the SVN command line client
svnversion = "svnversion.exe"
path, infile, outfile = ARGV[0], ARGV[1], ARGV[2]
# call svnversion executable, storing its output in rev
rev_str = `#{svnversion} "#{path}"`.chop
# extract the first number (get rid of M flag for modified source)
rev = /^[0-9]+/.match(rev_str)[0]
# get current date
date = Time.new
# remove old output file (ignore errors, e.g. if file didn't exist)
begin
File.delete(outfile)
rescue
end
input = File.new(infile, "r")
tmpname = "VersionInfo.rc"
tmp = File.new(tmpname, "w+")
input.each do |line|
# replace $WCREV$ with revision from svnversion call
outline = line.gsub(/\$WCREV\$/, rev)
# replace $WCDATE$ with current date + time
outline = outline.gsub(/\$WCDATE\$/, date.to_s)
# write modified line to output file
tmp.puts(outline)
end
input.close
tmp.close
puts "SubWCRev: Revision: #{rev}, date: #{date}, written to #{tmpname}"
call = "brcc32 -fo#{outfile} #{tmpname}"
puts call
system(call)发布于 2013-12-06 19:41:19
我使用的是德尔菲XE4,几乎相同的命令也有同样的问题。我们的PreBuildEvent有4行,我尝试了这里描述的内容,将所有的内容放在一行中,并使用&&分隔命令,它起了作用。然后我尝试修改,看看XE4是否会破坏我的预构建,但是在将我的预构建放回4行之后,它仍然在工作。
我终于找到了能够重现这个错误的其他项目,通过删除每行末尾的CRLF,并将其从XE4环境中恢复,只需编辑脚本,就可以修复PreBuildEvent。
发布于 2019-05-05 04:35:49
最近几周我遇到了这个问题,我自己用Delphi解决了这个问题。
造成这个问题的是dproj的格式。由于dproj是XML格式,构建前/构建后事件使用"&“作为新行的标记,因此dproj将将其保存为"&”。
在某种程度上,Delphi将在保存项目时将其保存为“\n&”。这导致MSBuild误解了符号并显示了“语法错误”。
因此,为了解决这个问题,我们要做的是检测dproj中是否存在sLineBreak +‘&’,并将其发送给MSBuild。
通过修改,MSBuild将完美地处理dproj。我在下面的代码块中共享我的代码,该程序可以帮助我们更改版本号,更正编译前后的事件:
program changeProjVer;
////////////////////////////////////////////////////////////////////////////////
/// Created by Dennies Chang dennies@ms4.hinet, dennies226@gmail.com
///
/// If you need to use this utility, please refer the original URL:
/// https://firemonkeylessons.blogspot.com/2019/04/delphiBuildCommandAndTools.html
///
/// And do not remve these lines.
/// The code is opened for all Delphi programmers, you can use it as
/// commercial/non-commercial usage, what you have to do, is to have a notice
/// for the original author.
///
/// And send an Email to dennies@ms4.hinet.net to me, thanks.
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, IdGlobal, Classes;
var
currentFile, tmpStr, completeStr, tmpMajor, tmpMinor, tmpRelease,
tmpBuild, configName: String;
lineIdx: Integer;
src: TStringList;
bDebug : boolean;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
if ParamCount < 2 then begin
writeln('Usage: changeProjVer.exe dprojFileFullPath versionNo [Debug|Release]');
writeln('versionNo should be contain 3 dots, e.g.,: 107.1.108.321');
writeln;
Readln;
end
else begin
currentFile := ParamStr(1);
tmpBuild := ParamStr(2);
bDebug := False;
if ParamCount >= 3 then begin
configName := ParamStr(3);
bDebug := configName.ToLower = 'debug';
end;
tmpMajor := Trim(Fetch(tmpBuild, '.'));
tmpMinor := Trim(Fetch(tmpBuild, '.'));
tmpRelease := Trim(Fetch(tmpBuild, '.'));
tmpBuild := Trim(Fetch(tmpBuild, '.'));
if FileExists(currentFile) then begin
src := TStringList.Create;
try
src.LoadFromFile(currentFile, TEncoding.UTF8);
for lineIdx := 0 to src.Count - 1 do begin
completeStr := src.Strings[lineIdx];
tmpStr := '';
if Pos('<VerInfo_MajorVer>', completeStr) > 0 then begin
tmpStr := Fetch(completeStr, '<VerInfo_MajorVer>');
tmpStr := #9 + #9 + '<VerInfo_MajorVer>' + tmpMajor +
'</VerInfo_MajorVer>';
// completeStr := tmpStr;
end
else if Pos('<VerInfo_MinorVer>', completeStr) > 0 then begin
tmpStr := Fetch(completeStr, '<VerInfo_MinorVer>');
tmpStr := #9 + #9 + '<VerInfo_MinorVer>' + tmpMinor +
'</VerInfo_MinorVer>';
// completeStr := tmpStr;
end
else if Pos('<VerInfo_Release>', completeStr) > 0 then begin
tmpStr := Fetch(completeStr, '<VerInfo_Release>');
tmpStr := #9 + #9 + '<VerInfo_Release>' + tmpRelease +
'</VerInfo_Release>';
// completeStr := tmpStr;
end
else if Pos('<VerInfo_Build>', completeStr) > 0 then begin
tmpStr := Fetch(completeStr, '<VerInfo_Build>');
tmpStr := #9 + #9 + '<VerInfo_Build>' + tmpBuild +
'</VerInfo_Build>';
// completeStr := tmpStr;
end
else if Pos('FileVersion=', completeStr) > 0 then begin
// FileVersion
completeStr := src.Strings[lineIdx];
tmpStr := '';
while Pos('FileVersion=', completeStr) > 0 do begin
tmpStr := Fetch(completeStr, 'FileVersion=');
tmpStr := tmpStr + 'FileVersion=' +
StringReplace(ParamStr(2), ' ', '',
[rfReplaceAll]) + ';';
Fetch(completeStr, ';');
end;
if Length(completeStr) > 0 then begin
tmpStr := tmpStr + completeStr;
end;
end;
// 這兩個會出現在同一行, 不要加 else
if Pos('ProductVersion=', completeStr) > 0 then begin
completeStr := tmpStr;
tmpStr := '';
// ProductVersion
while Pos('ProductVersion=', completeStr) > 0 do begin
tmpStr := Fetch(completeStr, 'ProductVersion=');
tmpStr := tmpStr + 'ProductVersion=' +
StringReplace(ParamStr(2), ' ', '',
[rfReplaceAll]) + ';';
Fetch(completeStr, ';');
end;
if Length(completeStr) > 0 then begin
tmpStr := tmpStr + completeStr;
end;
end;
if (tmpStr = '') and (tmpStr <> completeStr) then
tmpStr := completeStr;
src.Strings[lineIdx] := tmpStr;
end;
src.Text := StringReplace(src.Text, sLineBreak + '&&', '&', [rfReplaceAll]);
src.SaveToFile(currentFile, TEncoding.UTF8);
finally
src.Free;
end;
end;
end;
except
on E: Exception do
writeln(E.ClassName, ': ', E.Message);
end;
end. https://stackoverflow.com/questions/14875499
复制相似问题