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

Sha*_*ron 5 msbuild project solution target

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

msbuild MySolution.sln /t:MyCustomTarget
Run Code Online (Sandbox Code Playgroud)

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

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

您可以将MyCustomTarget替换为 Microsoft.Cpp.Win32.targets 中的任何标准目标(例如:ClCompile、Link)或您从 MyProject.vcxproj 中的 .targets 文件中选择的任何其他目标。他们都不会工作。

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

msbuild MyProject.vcxproj /t:MyCustomTarget
Run Code Online (Sandbox Code Playgroud)

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

有什么方法可以将我的自定义目标与我最初打算的解决方案文件一起使用吗?

据我了解,问题是 msbuild 生成了这个中间项目文件(mysolution.sln.metproj),但这将赢得来自MyProject.vcxproj的导入,包括 .targets 文件。难怪MyCustomTarget不被识别。

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

msbuild MyProject.vcxproj /t:MyCustomTarget /p:Configuration=MyConfig;Platform=MyPlatform;OutDir=MySolution\Platform_MyConfig\
Run Code Online (Sandbox Code Playgroud)

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

sev*_*tov 2

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

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

<Platform Condition="'$(Platform)'==''">MyPlatform</Platform>
<Configuration Condition="'$(Configuration)'==''">MyConfiguration</Configuration>
Run Code Online (Sandbox Code Playgroud)

配置 OutDir(在解决方案中的所有项目之间共享)可以这样完成。我假设您的解决方案的结构使得 .sln 文件位于根文件夹中,并且所有项目都位于根目录下的子文件夹(任意深)中,或者位于与解决方案相同的文件夹中。如果情况并非如此,您将需要稍微调整代码以适应您的情况。

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

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

上面的代码遵循将 OutDir 设置为 的约定MySolution\MyPlatform_MyConfiguration

所有这些方法的缺点是您必须手动修改解决方案中的所有项目。然而,它将在未来为您提供很大的灵活性。例如,所有项目共享的任何通用设置都可以提取到单个 .props 文件中,您可以将其<Import>添加到每个项目中,因此可以在一个地方完成配置更改。