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

Fra*_*itt 16 delphi delphi-xe3

我们目前正在从Delphi XE切换到Delphi XE3,我们的预构建事件存在严重问题.

我们的预构建事件如下所示:

  SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc
  brcc32 -foProject.res VersionInfo.rc
Run Code Online (Sandbox Code Playgroud)

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

这在以前的Delphi版本中完美运行,但每当我们在XE3中打开项目选项时,XE3会将其转换为:

  SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc &brcc32 -foProject.res VersionInfo.rc
Run Code Online (Sandbox Code Playgroud)

(请注意,这是一行,两个命令由单个&符号分隔).这会导致构建失败.

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

  SubWCRev "<SVN-Path>" "<InputFile>" VersionInfo.rc && brcc32 -foProject.res VersionInfo.rc
Run Code Online (Sandbox Code Playgroud)

即如果第一个命令成功,我们使用两个&符号来执行第二个命令.

这有效,但只有在我们再次编辑项目选项之前 - Delphi XE3总是弄乱预构建事件:-(

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

更新:轻松重现此错误的步骤

IDE

  • 文件 - >新建 - > VCL表单应用程序(Delphi)
  • 构建Project1
  • 文件 - >全部保存,保留建议名称Unit1.pas/Project1.dpr
  • 项目 - >选项
  • 选择目标"所有配置 - 所有平台"
  • 构建事件 - >预构建事件,输入此(两行,抱歉格式化):

    echo one> out.txt

    echo two >> out.txt

  • 从IDE构建项目

  • 保存并关闭项目

RAD Studio命令提示符

  • 导航到项目目录
  • msbuild Project1.dproj =>好的

IDE

  • 项目 - >选项
    • 点击"搜索路径"
      • 进入一个"
      • 删除"a"
    • 点击确定
  • 项目 - >建设项目
  • 保存并关闭项目

RAD Studio命令提示符

  • msbuild Project1.dproj =>错误

Fra*_*itt 2

我们最终使用了类似于 David Heffernan 提出的解决方法:

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

如果有人感兴趣,请观看我们的 PreBuild 活动:

PreBuild "<path_to_SVN_working_copy>" "VersionInfo.rc.in" $(OUTPUTNAME).res
Run Code Online (Sandbox Code Playgroud)

这是脚本 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)
Run Code Online (Sandbox Code Playgroud)