我能否在msbuild命令行中添加条件定义?

18

我有以下样本代码:

program boohoo;

{$APPTYPE CONSOLE}

{$IFDEF boo}
{$MESSAGE warn 'boo'}
{$ENDIF}

{$IFDEF hoo}
{$MESSAGE warn 'hoo'}
{$ENDIF}

begin
end.
在项目选项中定义了条件boo。我想能够将条件hoo作为我的msbuild命令行的一部分添加进去。
我已经尝试过以下方式:
msbuild boohoo.dproj /p:Config=Release;DCC_Define="$(DCC_Define);hoo"
输出显示hoo但不显示boo。当我使用详细输出查看dcc32命令时,我看到
-D$;hoo

显然,我可以这样做:

msbuild boohoo.dproj /p:Config=Release;DCC_Define="boo;hoo"

但我自然希望使用项目选项中声明的所有条件语句,以及我在命令行中指定的内容。

是否有办法让我参考底层配置的值来指定此属性?


我可以重现这个事实,即似乎你在这里有一个二选一的选择:使用dproj中的定义或命令行中的定义,但将一个附加到另一个似乎需要你编写某种实用程序来提取特定构建的定义,然后将它们追加到一起。 - Warren P
@Warren 你可以重现我描述的行为。但我希望可能会有一些魔法。例如,如果你能写DCC_Define+=hoo,会怎样呢? - David Heffernan
你可能会通过黑客Borland.Delphi.Targets msbuild配置文件来取得一些成功。但这对我来说似乎非常不可移植。我怀疑这行代码:<Defines>$(DCC_Define)</Defines>。 - Warren P
5个回答

23

免责声明:本人尚未使用过 MsBuild,以下内容来自文档和一些 IDE 实验。

根据 MsBuild 命令行参考资料(http://msdn.microsoft.com/en-us/library/ms164311.aspx):

/property:name=value

设置或覆盖这些项目级属性,其中 name 是属性名称,value 是属性值。使用分号或逗号分隔多个属性,或单独指定每个属性。也可以使用 /p。例如:/property:WarningLevel=2;OutputDir=bin\Debug

你只能对属性值进行设置或覆盖操作。从项目文件中添加属性值要么不可能,要么是一个隐藏功能。

但我想你可以在 dproj 文件中定义一个具有默认值为“ ”的自定义属性:

<PropertyGroup>
  <ExtraDefines> </ExtraDefines>
</PropertyGroup>

在您的定义语句中引用它

<DCC_Define>DUNIT;$(ExtraDefines);$(DCC_Define)</DCC_Define>

在IDE中应该是 DUNIT;$(ExtraDefines)

然后在命令行上指定:

msbuild boohoo.dproj /p:Config=Release;ExtraDefines="hoo"

我测试了在IDE中将$(ExtraDefines)添加到项目的包含选项中。至少这没有让我感到困扰,即使在dproj中没有定义该选项。IDE从此生成的命令行是:

...rad studio\7.0\bin\dcc32.exe --no-config -B -Q -DDEBUG;DUNIT; -E....
似乎表明 $(ExtraDefines) 被消除了,因为它没有值。需要使用 MSBuild 并在命令行上指定一个值来选择它。

谢谢。思路不错。一到机器旁边我就试试看。 - David Heffernan
4
太好了。这很完美地达到了预期效果。真是出色的想法,非常感谢你。 - David Heffernan

19

差不多过去了5年,但所有答案都不是太优雅))

最近,我也遇到了同样的问题

以下是解决方案:

通常,DCC_Define在.dproj文件中像这样定义:

<PropertyGroup Condition="'$(Cfg_1)'!=''">
    <DCC_Define>boo;$(DCC_Define)</DCC_Define>

我们都尝试过通过/property:DCC_Define=blah-blah来定义DCC_Define。

但是根据如何: 使用不同的选项构建相同的源文件

在命令行上指定的属性值优先于项目文件中设置的任何属性值,而项目文件中的该值优先于环境变量中的值。

所以,失败了(这里是问题!)

但是!如何:在构建中使用环境变量

要在 MSBuild 项目中使用环境变量

  • 引用环境变量的方式与引用项目文件中声明的变量的方式相同。例如,以下代码引用 BIN_PATH 环境变量:

    <FinalOutput>$(BIN_PATH)\MyAssembly.dll</FinalOutput>
    
    因此,我们必须定义名为 DCC_Define 的环境变量,并将其值设置为我们的ADDITIONAL条件。
> set DCC_Define=hoo;doo;moo;foo

然后只需运行

> msbuild boohoo.dproj /p:Config=Release

DCC32将获取-Dboo;hoo;doo;moo;foo


绝妙的技巧,绝对值得更多点赞! - Fr0sT

2
直接的解决方案是创建一个新的构建配置(比如说,boohooRelease),将boohoo条件定义都添加到其中,并编译为msbuild boohoo.dproj /p:Config=boohooRelease。这不完全符合你所尝试做的事情,但它能够起作用。

是的,这样做可以实现,但我正在寻找一些更轻量级的方法,以便在构建包含条件代码的实验性代码版本时,将dproj文件与构建分离。 - David Heffernan

2

我刚尝试了以下操作,它起作用了,所以不知道微软是否已经更改了它:

msbuild "myApp.dproj" /t:build /property:DCC_Define="boo"

请记得加上双引号"",否则它不会生效。


1
请注意,使用此功能将覆盖项目设置中列出的任何条件定义。 - havrlisan

1
另一种方法是创建一个类似这样的包装项目文件:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Full" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Full">
  <CreateProperty Value="$(DCC_Define);$(ExtraDefines)">
    <Output TaskParameter="Value" PropertyName="DCC_Define"/>
  </CreateProperty>
</Target>
<Import Project="example.dproj" />
</Project>

并像这样调用:
msbuild.exe "/t:Clean;Full;Build" "/p:config=Debug" /p:ExtraDefines=SOME_DEFINE wrapper.proj

虽然不太优雅,但您不必修改 .dproj 文件。


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