在解决方案文件上调用自定义MSBuild目标

时间:2014-05-28 11:27:32

标签: msbuild project target solution

我有一个解决方案文件( MySolution.sln ),其中包含一个项目( MyProject.vcxproj )。我想通过解决方案在我的项目上执行自定义目标( MyCustomTarget )。它看起来像这样:

msbuild MySolution.sln /t:MyCustomTarget

当我执行命令时,我会收到一条错误消息:

MySolution.sln.metaproj:错误MSB4057:目标" MyCustomTarget"在项目中不存在。 [MySolution.sln]

您可以使用Microsoft.Cpp.Win32.targets中的任何标准目标替换 MyCustomTarget (例如:ClCompile,Link)或您在MyProject.vcxproj中包含的.targets文件中选择的任何其他目标。他们都不会起作用。

当环境变量 msbuildemitsolution 设置为1时,我可以检查生成的 MySolution.sln.metaproj 文件。在底部指定了4个目标:构建,重建,清理和发布。使用这些目标而不是 MyCustomTarget ,项目构建正常。此外,如果我指定项目文件而不是解决方案文件,它也会构建:

msbuild MyProject.vcxproj /t:MyCustomTarget

但是使用这种格式,我将丢失 OutDir 属性,手动必须设置配置平台,所以我只是失去了拥有解决方案文件的好处。

有什么方法可以将我的自定义目标用于我原定的解决方案文件吗?

据我所知,问题是msbuild生成了这个中间项目文件( mysolution.sln.metproj ),但是它将从 MyProject.vcxproj 中导入,包括.targets文件。难怪 MyCustomTarget 无法识别。

我目前的解决方法是使用msbuild的项目文件,并尽量不要错过解决方案文件中的任何内容:

msbuild MyProject.vcxproj /t:MyCustomTarget /p:Configuration=MyConfig;Platform=MyPlatform;OutDir=MySolution\Platform_MyConfig\

但这不是一个正确的解决方案,不灵活,容易出错并且不会自动适应解决方案文件中的更改。

3 个答案:

答案 0 :(得分:2)

我想你已经回答了你的问题。答案是不。 .sln.metaproj文件中没有名为“MyCustomTarget”的目标,因此MSBuild会为您提供该错误消息。

现在,通过在命令行上传递额外参数来解决您的问题。如果在.vcxproj文件中设置默认值,则不需要传递平台和配置。在导入任何标准目标文件之前,在项目文件中的某处添加它:

<Platform Condition="'$(Platform)'==''">MyPlatform</Platform>
<Configuration Condition="'$(Configuration)'==''">MyConfiguration</Configuration>

配置OutDir,可以像这样在解决方案中的所有项目之间共享。我将假设您的解决方案是结构化的,以便.sln文件位于根文件夹中,并且所有项目都位于根目录下的子文件夹(任意深度)中,或者与解决方案位于同一文件夹中。如果不是这种情况,您必须稍微调整一下代码以适应您的情况。

在项目中定义平台和配置后,立即添加此属性组:

<PropertyGroup>
    <RootFolder>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),MySolutionName.sln))</RootFolder>
    <OutDir Condition="'$(OutDir)'==''">$(RootFolder)\$(Platform)_$(Configuration)</OutDir>
</PropertyGroup>

上面的代码遵循您将OutDir设置为MySolution\MyPlatform_MyConfiguration的惯例。

所有这些方法的缺点是您必须手动修改解决方案中的所有项目。但是它将来会给你很大的灵活性。例如,可以将所有项目共享的任何公共设置提取到单个.props文件中,您可以<Import>进入每个项目,因此可以在一个位置更改配置。

答案 1 :(得分:1)

要在使用解决方案文件构建时使用项目文件中存在的自定义目标,请使用以下格式:

msbuild MySolution.sln /t:MyProject:MyCustomTarget

请注意,如果项目位于子文件夹(解决方案文件夹)中,则需要添加文件夹名称:

msbuild MySolution.sln /t:src\MyProject:MyCustomTarget

如果项目名称包含空格或圆点,则用下划线替换它们。

答案 2 :(得分:1)

MSBuild 15现在自动将自定义目标提升到解决方案metaproj中,因此您现在应该可以直接在解决方案上运行目标。