在MSBuild中通过命令行导入.targets文件

10

我目前有多个项目正在使用msbuild进行构建。 我有一个小定制需求需要通过.targets文件处理构建。 一种解决方法是添加以下代码片段

<Import Project="MyTargets.targets"/>

对于每个项目文件,我希望能够添加此信息。但是,理想情况下,我希望不要修改项目文件,并且能够将此信息作为参数传递给msbuild。这样,我就可以轻松地控制是否从命令行运行此自定义操作,而且不必触及现有的项目文件。

这种做法可行吗?

4个回答

9

您可以使用MSBuild 4.0轻松实现此操作(通过顶级属性 ToolsVersion="4.0" 检查您的版本):

在Common.targets和CSharp.targets加载之前或之后,您可以使用多个属性来导入您的目标。

最简单的方法是使用两组自解释的属性。第一组是: $(CustomBeforeMicrosoftCommonTargets) $(CustomAfterMicrosoftCommonTargets)

第二组是:

$(CustomBeforeMicrosoftCSharpTargets)
$(CustomAfterMicrosoftCSharpTargets)

属性名很容易理解。

只需通过 msbuild.exe 将完整文件名传递给任何此属性,例如:

msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets=c:\mytargets\custom.targets

如果你需要导入多个文件,可以使用其他"ImportByWildcard(Before|After)...."属性。但在这种情况下,你需要向命令行传递更多的参数。


你能在命令行中引用宏吗?例如:/p:CustomBeforeMicrosoftCSharpTargets="$(SolutionDir)\custom.targets"?但这对我似乎不起作用。 - Rabid
不太可能奏效,这个命令行无法被msbuild引擎处理,因为它会展开这些属性。您可以将路径专门设置为相对于构建脚本本身的路径。 - Alexey Shcherbak
设置上述四个属性中的任何一个,我都无法通过/target:<target>运行导入文件的任何目标(错误:项目中不存在目标“<target>”)。如果我在导入的文件中设置例如InitialTargets,则会执行该目标。难道不能外部引用导入的目标吗? - Jesper Matthiesen
嗯,你目前使用的MSBuild版本是什么?上面的答案已经有5年了,我记不清所有细节,而且自2013年以来可能会有一些变化;) 你能提供一些更具体的细节或开一个新问题并在这里引用它吗? - Alexey Shcherbak

3

0
假设您有一个名为“Project.msbuild”的项目文件。您可以添加以下条件导入:
<Import Project="$(TargetToImport)" Condition="'$(TargetToImport)' != ''" />

然后将您想要导入的目标文件的名称作为msbuild属性传递:

msbuild.exe Project.msbuild /p:TargetToImport="TargetFile.Target"

这并没有真正回答不想改变项目文件的问题(尽管这意味着一旦我进行了这个修改,所有其他修改都可以在项目文件之外完成)。问题实际上是在询问我是否可以通过命令行有效地插入一个<Import />元素。 - Lawrence

0

确保您使用目标文件的绝对路径并且它可以正常工作。
来源:Sayed Ibrahim Hashimi - MSBuild如何在CoreCompile部分之后执行目标2

msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets="c:\mytargets\custom.targets" /preprocess:out.xml

使用/preprocess[:filepath]命令来查看导入的结果。

您无需修改任何csprojvbproj文件。
当然,这只适用于可以设置MSBuild属性的情况下。


对我来说,这确实创建了一个 out.xml 文件,但它总是为空(零字节)。 - Jesper Matthiesen

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