我可以在 msbuild 命令行中添加条件定义吗?

Posted

技术标签:

【中文标题】我可以在 msbuild 命令行中添加条件定义吗?【英文标题】:Can I add conditional defines in the msbuild command line? 【发布时间】:2012-01-20 09:33:25 【问题描述】:

我有以下示例代码:

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 你可以重现我描述的行为。但我希望可能有一些魔法。例如,如果你可以写DCC_Define+=hoo 您可以通过破解 Borland.Delphi.Targets msbuild 配置文件取得一些成功。但这对我来说似乎真的不便携。我怀疑这条线:<Defines>$(DCC_Define)</Defines> 【参考方案1】:

我刚刚尝试了以下,它工作,所以不知道微软是否改变它:

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

记得加双引号“”,否则不起作用

【讨论】:

【参考方案2】:

差不多 5 年后,但所有答案都不是很优雅))

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

这是解决方案:

通常,DCC_Define 在 .dproj 文件中定义如下:

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

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

但据How to: Build the Same Source Files with Different Options:

在命令行中指定的属性值优先于在项目文件中为同一属性设置的任何值,并且项目文件中的值优先于环境变量中的值。

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

但是! How to: Use Environment Variables in a Build

在 MSBuild 项目中使用环境变量

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

<FinalOutput>$(BIN_PATH)\MyAssembly.dll</FinalOutput>

因此,我们必须使用名称DCC_Define 和附加条件的值来定义环境变量

> set DCC_Define=hoo;doo;moo;foo

然后简单地运行

> msbuild boohoo.dproj /p:Config=Release

DCC32 会得到-Dboo;hoo;doo;moo;foo

【讨论】:

绝妙绝招,绝对值得更多赞!【参考方案3】:

另一种方法是像这样创建一个包装器项目文件:

<?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 文件。

【讨论】:

【参考方案4】:

直接的解决方案是创建一个新的构建配置(例如,boohooRelease),将boohoo 条件定义添加到它并编译为msbuild boohoo.dproj /p:Config=boohooRelease。不完全是您想要做的,但它确实有效。

【讨论】:

是的,这可行,但我正在寻找更轻的东西,以便在我想构建包含条件代码的代码的实验版本时将 dproj 文件与构建分离【参考方案5】:

免责声明:我自己还没有使用 MsBuild,全部来自文档和一些 IDE 实验

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

/property:name=value

设置或覆盖这些项目级属性,其中 name 是 属性名称和值是属性值。使用分号或 逗号分隔多个属性,或指定每个属性 分别地。 /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 获取它并在命令行上指定一个值。

【讨论】:

谢谢。好想法。我一拿到机器就试试这个。 太棒了。这很好用。非常好的想法,非常感谢。

以上是关于我可以在 msbuild 命令行中添加条件定义吗?的主要内容,如果未能解决你的问题,请参考以下文章

您可以从 msbuild.exe 命令行关闭条件编译符号吗?

命令行中的 Msbuild 不输出 Csc 警告和输出

为啥 CruiseControl.NET 无法构建,但使用命令行中的 msbuild.exe 有效?

我可以查看使用 MSBuild 实际执行的构建命令吗?

如何在命令行中编译和链接项目?

参数值中的 msbuild 任务条件运算符