我们的解决方案(A.sln
)需要一个由另一个(遗留)解决方案(B.sln
)构建的二进制文件。我不能详细说明为什么这是必要的,这是一个冗长而多毛的故事。
A
生成的应用程序在运行时只需要B
的工件,因此在构建过程中何时满足此依赖关系并不重要。由于命名冲突,我们不希望在同一目录中构建两个项目,而是将B
的一些工件复制到输出路径A
的子目录中。
1)通过将以下内容添加到B
A
作为构建目标添加到A.sln
<Target Name="Build">
<MSBuild Projects="$(SolutionDir)..\B\B.sln" Properties=" Platform=Win32; Configuration=$(Configuration); " />
</Target>
出于某种原因,这会在B
的输出目录中构建A
,这是不需要的。
2)通过将以下内容添加到A
B
,在A.sln
上调用msbuild
<PropertyGroup>
<PostBuildEvent>
msbuild $(SolutionDir)..\B\B.sln /p:configuration=$(ConfigurationName)
xcopy /E /R /Y $(SolutionDir)..\B\$(ConfigurationName) $(SolutionDir)$(ConfigurationName)\B\
</PostBuildEvent>
</PropertyGroup>
出于某种原因,这适用于VS 2015命令提示符,但不适用于Visual Studio本身。 VS(2015)抱怨
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\CodeAnalysis\Microso
ft.CodeAnalysis.targets(219,5): error MSB4175: The task factory "CodeTaskFactory
" could not be loaded from the assembly "C:\Windows\Microsoft.NET\Framework64\v4
.0.30319\Microsoft.Build.Tasks.v12.0.dll". Could not load file or assembly 'file
:///C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Build.Tasks.v12.0.
dll' or one of its dependencies. The system cannot find the file specified. [C:\
Users\Chiel.tenBrinke\Projects\MyProject\B\CppSource\B.vcxproj]
那么,最好的(即最简单,最易维护,最干净)方法是什么?
答案 0 :(得分:1)
<PropertyGroup>
<PostBuildEvent>
msbuild $(SolutionDir)..\B\B.sln /p:configuration=$(ConfigurationName)
xcopy /E /R /Y $(SolutionDir)..\B\$(ConfigurationName) $(SolutionDir)$(ConfigurationName)\B\
</PostBuildEvent>
</PropertyGroup>
我认为这可能比ItemDefinitionGroup
更有意义,而不是PropertyGroup
。至少这就是Visual Studio如何放置它。
您也可以使用Condition
来加强它。也许是这样的:
<ItemDefinitionGroup Condition="!Exists('$(ConfigurationName)\b.exe')" Label="Copy b.exe">
<PostBuildEvent>
msbuild /t:Build /p:Configuration=$(ConfigurationName) B.vcxproj
xcopy /E /R /Y ...\B\$(ConfigurationName)\b.exe $(ConfigurationName)\B
</PostBuildEvent>
</ItemDefinitionGroup>
我们必须做类似的事情来破解无法用工具正确表达的项目外依赖性。和你一样,我感觉像Target
是可行的方式,但我也无法让它工作......
无论如何,这是我们的cryptdll.vcxproj实际上使用了项目外的依赖项黑客,所以我知道它有效。
<!-- The current project file is c.vcxproj. We have a hard requirement to always -->
<!-- use Win32/Debug EXE. Also, b.vcxproj depends on an artifact from a.vcxproj -->
<ItemDefinitionGroup Condition="!Exists('Win32\Debug\b.exe')" Label="MAC tool">
<PreBuildEvent>
<Message>Creating Win32/Release cryptest.exe for MAC computation</Message>
<Command>
msbuild /t:Build /p:Configuration=Debug;Platform=Win32 a.vcxproj
msbuild /t:Build /p:Configuration=Debug;Platform=Win32 b.vcxproj
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
答案 1 :(得分:1)
我最终做的方式是在项目级而不是解决方案级别。
解决方案A
项目中的xml具有以下形式:
<Target Name="AfterBuild">
<MSbuild
Projects="$(SolutionDir)..\B\CppSource\SomeProject.vcxproj"
Properties="
Configuration=$(ConfigurationName);
OutDir=$(SolutionDir)$(ConfigurationName)\B\;
"/>
</Target>