MSBuild:从命令行指定目标

25

我有一个 MSBuild 任务,用于编译解决方案文件中的特定项目。它看起来像这样:

<Target Name="Baz">
  <MSBuild Projects="Foo.sln" Targets="bar:$(BuildCmd)" />
</Target>

在命令行中,我可以将BuildCmd设置为RebuildClean,它可以按预期工作:

msbuild /target:Baz /property:BuildCmd=Rebuild MyMsbuildFile.xml msbuild /target:Baz /property:BuildCmd=Clean MyMsbuildFile.xml

但是,要怎样设置BuildCmd才能只进行构建呢?我已经尝试过使用BuildCompile,以及留空或未定义,但总是出现错误。

msbuild /target:Baz /property:BuildCmd=Build MyMsbuildFile.xml Foo.sln : error MSB4057:项目中不存在目标“bar:Build”。

msbuild /target:Baz /property:BuildCmd=Compile MyMsbuildFile.xml Foo.sln : error MSB4057:项目中不存在目标“bar:Compile”。

msbuild /target:Baz MyMsbuildFile.xml Foo.sln : error MSB4057:项目中不存在目标“bar:”。

5个回答

24

我理解您想要使用特定命令(Build、Clean等)构建目标。

以下是我的建议:

创建一个属性来接收您的构建命令,如果未指定,则默认为Build。

<PropertyGroup>
  <BuildCmd Condition=" '$(BuildCmd)' == ''">Build</BuildCmd>
</PropertyGroup>

接着,创建一个目标,在参数中指定MSBuild将以该目标启动:

<Target Name="Stackoverflow">
  <MsBuild Projects="Foo.sln" Targets="$(BuildCmd)" />
</Target>

然后按以下方式使用目标和BuildCmd参数调用您的MSBuild文件:
msbuild msbuild.xml /t:Stackoverflow /p:BuildCmd=Clean

请确保目标在解决方案或项目文件中存在。


1
我正在尝试在Foo.sln中仅构建特定的项目。 - Derek
请确保目标在解决方案或项目文件中存在。如何将自定义目标添加到sln文件中? - Piotr Owsiak
原来不只我遇到了这个问题,在这里可以看到J.Elster的评论:http://msdn.microsoft.com/en-us/library/ms164311.aspx - Piotr Owsiak

7

来源: http://msdn.microsoft.com/en-us/library/ms164311.aspx

/target:targets

此命令将在该项目中构建这些目标。使用分号或逗号来分隔多个目标,或单独指定每个目标。 /t 也可接受。例如: /target:Resources;Compile

该命令用于指定在构建项目时要构建哪些目标,可以使用分号或逗号来分隔多个目标名,也可以单独指定每个目标名。例如:/target:Resources;Compile

7
问题在于如何针对每个目标进行具体操作:构建、重新构建、清除。问题的一部分在于,"target"这个术语用于命令行中指定msbuild文件中的一个目标,同时也用于指定解决方案文件中要构建的项目(名称空间冲突)。需要注意的是,在翻译过程中不要改变原意,只需使内容更通俗易懂即可。 - Derek

2
关键是将BuildCmd属性条件化。
 <Target Name="Baz">
   <PropertyGroup>
     <BuildCmd Condition="'$(BuildCmd)' != ''">:$(BuildCmd)</BuildCmd>
   </PropertyGroup>
   <MSBuild Projects="Foo.sln" Targets="bar$(BuildCmd)" />
 </Target>

如果设置了Clean或Rebuild,就会添加冒号。如果没有添加任何内容,则BuildCmd将为空,即默认为Build目标。

注意 - 属性组必须位于目标中,否则在命令行上指定时它将被覆盖。


0
使用CheGueVerra的模板,我想出了以下解决方案:
<PropertyGroup>
    <ProjBuildCmd Condition="'$(BuildCmd)' != 'Build'">:$(BuildCmd)</ProjBuildCmd>
    <SolnBuildCmd Condition="'$(BuildCmd)' != 'Build'">$(BuildCmd)</SolnBuildCmd>
</PropertyGroup>

然后我不直接使用$(BuildCmd),而是像这样使用$(ProjBuildCmd)$(SolnBuildCmd):

<!-- Build the 'bar' project only -->
<Target Name="Baz">
  <MSBuild Projects="Foo.sln" Targets="bar$(ProjBuildCmd)" />
</Target>

<!-- Build the whole solution -->
<Target Name="Baz2">
  <MSBuild Projects="Foo.sln" Targets="$(SolnBuildCmd)" />
</Target>

1
这个解决方案在VS10上不起作用。你有任何更新吗? - Mike

-10

只需自己编辑sln文件并找出 - MSBuild是一种真正简单的语法,只需查找目标即可。


3
.sln文件不符合MSBuild语法。 - Derek

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