Delphi XE自定义构建目标始终被禁用

178

我创建了一个自定义的MSBuild .targets文件,并通过IDE将其包含在Delphi XE项目中,并从项目管理器的上下文菜单中启用它。尽管该文件经过验证,但每次重新保存项目文件后都会被禁用。

这是一个简化版的目标文件,名为Custom.targets

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Hello">
    <Message Text="Hello from custom target"/>
  </Target>
</Project>

作为一个独立文件,这个程序的运行符合预期:输入...
MSBuild Custom.target /t:Hello

在命令行中输入指定命令会得到预期的消息。
通过IDE将Custom.targets添加到Delphi项目中,可以如预期地在项目管理器中显示该文件,并且.dproj文件现在包含以下行...
<TargetsFile Include="Custom.targets"/>

我在IDE的项目管理器中右键单击文件并选择启用。但是,当项目构建时,构建消息窗口显示如下:

[MSBuild Warning] Custom.targets(1): 忽略已禁用的导入:PathToProjectSource\\Custom.targets

在项目管理器中再次右键单击仍然显示启用选项,而不是预期的禁用选项。

在命令行中运行MSBuild ProjectName.dproj /t:Hello也会失败。

我尝试修改.dproj文件添加以下行...

<Import Project="Custom.targets"/>

现在键入MSBuild ProjectName.dproj /t:Hello是有效的。但是下一次我从IDE保存项目文件时,<Import>语句将被删除。请问有人知道出了什么问题吗?

10
在您使用命令行调用msbuild的示例中,您展示了_Custom.target_,而其他地方都使用_Custom.targets_。到底是哪个? - Kenneth Cochran
4
好眼力 - 尽管我一直盯着代码看,但我没有注意到这一点。我未来几天无法使用安装了 Delphi 的机器(在医院里!),但我会尽快尝试在能够使用“目标”或“目标对象”时保持一致的代码。 - delphidabbler
6
我不是 Delphi 用户,但根据这个,“所有的 .targets 文件必须包含没有错误的有效的 MSBuild 脚本。如果文件有任何错误,您将收到通知,并且如果项目引用无效的 .targets 文件,则该文件将被禁用,直到错误被纠正为止。”或许值得仔细检查一下所有的内容是否正确,因为这可以解释你所遇到的症状。 - Daniel Morritt
很遗憾,在XE7中我无法重现您的问题,一切似乎都按预期工作:使用/t:Hello从命令行提示符构建以及在IDE中通过右键单击项目管理器 - 目标 - Hello进行构建。我通过右键单击项目管理器 - 添加 - (浏览文件)将Custom.targets添加到了该项目中。路径与.dproj文件相同目录。 - Ondrej Kelle
2个回答

2
我建议手动包含targets文件并使用MSBuild进行外部构建,而不是从IDE中进行编译,因为从IDE编译时,很难知道您应用了哪些配置和目标(是在项目上单击的那个还是已启用目标的那个?你没有任何视觉提示表明已启用自定义目标)。
我通常会在Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"之前完成这些操作,这样它们就不会显示在IDE上(它们存在,但对开发人员隐藏)。
例如,我的Delphi XE4项目以以下内容结尾:
    <Import Project="..\BuildServer.Targets"/>
    <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
    <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

我的.targets文件定义了一个自定义的“PropertyGroup”和“Target”,并带有一个条件,因此只有在从MSBuild调用时才会应用它们:

  <PropertyGroup  Condition="'$(Config)'=='CustomConfig'">
    <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
    ...
  </PropertyGroup>
  <Target Name="DisplayProjectInfo">
    <Message Text="Project File Name = $(MSBuildProjectFile)"/>
    <Message Text="Version = $(VerInfo_Keys)"/>
    <Message Text="OutputDir = $(DCC_ExeOutput)"/>
  </Target>
  <Target Name="CustomTarget" Condition="'$(Config)'=='CustomConfig'">
  <MSBuild Projects="$(MSBuildProjectFile)" Targets="Clean" />
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" />
    <CallTarget Targets="DisplayProjectInfo"/>
  </Target>

然后使用以下命令进行编译:

msbuild /t:CustomTarget /p:config=CustomConfig poject.dproj

使用此方法可以自定义构建目标,确保每个应用程序都能获得正确的设置,而不受任何人所做更改的影响。


2

Delphi自动生成整个dproj内容,这个自定义导入将始终被删除。

你可以编写自己的msbuild xml文件,但dproj属于Delphi。

除非你有源代码或愿意猴子补丁ide,否则你不能这样做。

如果你真的想要一个灵活的xml方式来构建delphi项目并创建各种目标,请尝试使用want或want vnext(我在bitbucket上的分支)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接