在解决方案文件上调用自定义MSBuild目标 [英] Invoke Custom MSBuild Target on Solution File

查看:112
本文介绍了在解决方案文件上调用自定义MSBuild目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a solution file (MySolution.sln) with a single project in it (MyProject.vcxproj). I would like to execute a custom target (MyCustomTarget) on my project through the solution. It would look something like this:

msbuild MySolution.sln /t:MyCustomTarget

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

When I execute the command, I'll get an error message:

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

您可以用Microsoft.Cpp.Win32.targets中的任何标准目标(例如,ClCompile,Link)或您从MyProject.vcxproj中的.targets文件中选择的任何其他目标替换 MyCustomTarget .他们都不行.

You can replace MyCustomTarget with any standard targets from Microsoft.Cpp.Win32.targets (e.g.: ClCompile, Link) or any other target of your choice you include from .targets files in MyProject.vcxproj. None of them would work.

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

When the environment variable msbuildemitsolution is set to 1, I can inspect the generated MySolution.sln.metaproj file. At the bottom 4 targets are specified: Build, Rebuild, Clean, and Publish. Using these targets instead of MyCustomTarget, the project builds ok. Also, if I specify the project file instead of the solution file, it builds too:

msbuild MyProject.vcxproj /t:MyCustomTarget

但是使用这种格式,我会丢失 OutDir 属性,必须手动设置 Configuration Platform ,所以我只会丢失拥有解决方案文件的好处.

But using this format, I will lose the OutDir property, manually have to set the Configuration and Platform, so I just lose the benefits of having a solution file.

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

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

As far as I understand the problem is that msbuild generates this intermediate project file (mysolution.sln.metproj) but that will won have the imports from MyProject.vcxproj, including the .targets files. No wonder MyCustomTarget is not recognized.

我当前的解决方法是将项目文件与msbuild一起使用,并尝试不丢失解决方案文件中的任何内容:

My current workaround is using the project file with msbuild and trying not to miss anything from the solution file:

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

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

But this is not a proper solution, inflexible, prone to error and does not automatically adapt changes in the solution file.

推荐答案

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

I think you already answered your question. The answer is NO. There is no target called "MyCustomTarget" inside the .sln.metaproj file, so MSBuild gives you that error message.

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

Now, to resolve your problem with passing extra parameters on command line. Passing platform and configuration won't be required, if you set defaults in your .vcxproj file. Add this somewhere in your project file, before any of the standard target files are imported:

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

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

Configuring OutDir, which is shared across all projects in solution can be done like this. I will assume your solution is structured so that .sln file is in root folder, and all projects are in sub-folders (arbitrarily deep) under the root, or in the same folder as the solution. If this is not the case, you will have to tweak the code a little to adjust to your situation.

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

Right after you defined Platform and Configuration in your project, add this property group:

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

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

The code above follows your convention of setting OutDir to MySolution\MyPlatform_MyConfiguration.

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

The downside of all this approach is that you have to manually modify all projects in your solution. However it will give you lots of flexibility in the future. For example, any common settings shared across all projects, could be extracted into single .props file that you can <Import> into every project, so changes to configuration could be done in one place.

这篇关于在解决方案文件上调用自定义MSBuild目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆