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

在解决方案文件上调用自定义MSBuild目标,msbuild,project,target,solution,Msbuild,Project,Target,Solution,我有一个解决方案文件(MySolution.sln),其中只有一个项目(MyProject.vcxproj)。我想通过解决方案在我的项目上执行一个自定义目标(MyCustomTarget)。它看起来像这样: msbuild MySolution.sln /t:MyCustomTarget 当我执行命令时,我将得到一条错误消息: MySolution.sln.metaproj:错误MSB4057:项目中不存在目标“MyCustomTarget”。[MySolution.sln] 您可以将MyCu

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

msbuild MySolution.sln /t:MyCustomTarget
当我执行命令时,我将得到一条错误消息:

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

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

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

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\

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

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

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

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

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

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

$([MSBuild]::GetDirectoryNameOffileOver($(MSBuildThisFileDirectory),MySolutionName.sln))
$(根文件夹)\$(平台)\$(配置)
上面的代码遵循您将目录设置为
MySolution\MyPlatform\u MyConfiguration
的惯例


所有这种方法的缺点是,您必须手动修改解决方案中的所有项目。但是,它将在将来为您提供很多灵活性。例如,所有项目中共享的任何公共设置都可以提取到单个.props文件中,您可以
将该文件提取到每个项目中,因此可以在一个位置更改配置。

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

msbuild MySolution.sln /t:MyProject:MyCustomTarget
请注意,如果项目位于子文件夹(解决方案文件夹)中,则需要添加文件夹名称:

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

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

MSBuild 15现在会自动将自定义目标提升到解决方案元项目中,因此直接在解决方案上运行目标的初始方法现在应该可以工作。

您以前是否尝试过
。{solutionname}.sln.targets
?是否将目标文件作为解决方案的一部分导入?很高兴知道。:)不幸的是,我不再从事该项目,但这对其他人来说可能很有用。这是我将此放在此处的唯一原因:)