首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Delphi XE3:复杂预构建事件的问题

Delphi XE3:复杂预构建事件的问题
EN

Stack Overflow用户
提问于 2013-02-14 13:04:01
回答 3查看 2.8K关注 0票数 16

我们目前正在从德尔福XE转换到德尔福XE3,我们有严重的问题,我们的前构建事件。

我们的预构建事件如下:

代码语言:javascript
运行
复制
  SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc
  brcc32 -foProject.res VersionInfo.rc

(请注意,这两个命令出现在单独的行中;并包含我们的“真实”命令中的绝对路径),即我们首先从工作副本中提取当前的SVN版本,将此信息写入VersionInfo.rc,然后使用Borland资源编译器生成一个资源文件。

这在以前的Delphi版本中非常有效,但是每当我们在XE3中打开项目选项时,XE3就会将其转换为:

代码语言:javascript
运行
复制
  SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc &brcc32 -foProject.res VersionInfo.rc

(请注意,这是一行,这两个命令都由一个符号分隔)。这将导致构建失败。

我们当前的解决方法是手动将其更改为

代码语言:javascript
运行
复制
  SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc && brcc32 -foProject.res VersionInfo.rc

也就是说,如果第一个命令成功,我们使用两个符号来执行第二个命令。

这是可行的,但只有在我们再次编辑项目选项之前,德尔菲XE3总是会扰乱构建前的事件:-(

有人知道解决这个问题的办法吗?我想我们可以编写一个调用SubWCRev和brcc32的简单命令行工具,但是我更喜欢一个更简单的解决方案。

UPDATE:轻松复制此bug的步骤

IDE

  • ->新-> VCL窗体应用程序(Delphi)
  • 构建Project1
  • 文件->保存所有,保留建议名称Unit1.pa/ Project1.dpr
  • 项目->选项
  • 选择目标“所有配置-所有平台”
  • Build ->预生成事件,输入以下内容(两行,不好意思设置格式): 回声一号> out.txt echo 2 >> out.txt
  • 从IDE构建项目
  • 保存和关闭项目

RAD Studio命令提示符

  • 导航到项目目录
  • MSBuildProject1.dproj => OK

IDE

  • 项目-> Options
    • 点击“搜索路径”
      • 输入"a“
      • 删除"a“

代码语言:javascript
运行
复制
- click ok  

  • 项目->构建项目
  • 保存和关闭项目

RAD Studio命令提示符

  • MSBuildProject1.dproj =>错误
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-18 12:08:52

最后,我们使用了一个类似于David提出的解决方案:

  • 将所有调用合并到一个(Ruby)脚本PreBuild.rb中
  • 将这个Ruby脚本编译成一个独立的可执行文件(因为不是所有的开发人员都安装了Ruby )
  • 在Delphi中使用单个预构建事件。

如果有人感兴趣,下面是我们的PreBuild活动:

代码语言:javascript
运行
复制
PreBuild "<path_to_SVN_working_copy>" "VersionInfo.rc.in" $(OUTPUTNAME).res

下面是脚本PreBuild.rb:

代码语言:javascript
运行
复制
  #!/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)
票数 2
EN

Stack Overflow用户

发布于 2013-12-06 19:41:19

我使用的是德尔菲XE4,几乎相同的命令也有同样的问题。我们的PreBuildEvent有4行,我尝试了这里描述的内容,将所有的内容放在一行中,并使用&&分隔命令,它起了作用。然后我尝试修改,看看XE4是否会破坏我的预构建,但是在将我的预构建放回4行之后,它仍然在工作。

我终于找到了能够重现这个错误的其他项目,通过删除每行末尾的CRLF,并将其从XE4环境中恢复,只需编辑脚本,就可以修复PreBuildEvent。

票数 2
EN

Stack Overflow用户

发布于 2019-05-05 04:35:49

最近几周我遇到了这个问题,我自己用Delphi解决了这个问题。

造成这个问题的是dproj的格式。由于dproj是XML格式,构建前/构建后事件使用"&“作为新行的标记,因此dproj将将其保存为"&”。

在某种程度上,Delphi将在保存项目时将其保存为“\n&”。这导致MSBuild误解了符号并显示了“语法错误”。

因此,为了解决这个问题,我们要做的是检测dproj中是否存在sLineBreak +‘&’,并将其发送给MSBuild。

通过修改,MSBuild将完美地处理dproj。我在下面的代码块中共享我的代码,该程序可以帮助我们更改版本号,更正编译前后的事件:

代码语言:javascript
运行
复制
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 + '&amp;&amp;', '&amp;', [rfReplaceAll]);
               src.SaveToFile(currentFile, TEncoding.UTF8);
            finally
               src.Free;
            end;
         end;
      end;
   except
      on E: Exception do
         writeln(E.ClassName, ': ', E.Message);
   end;

end. 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14875499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档