我们的解决方案(A.sln
)需要一个由另一个(遗留)解决方案(B.sln
)构建的二进制文件。我无法详细说明为什么这是必要的,这是一个漫长而毛茸茸的故事。
约束
A
生成的应用程序只需要运行时的B
工件,因此在构建过程中何时填充此依赖项并不重要。由于命名冲突,我们不想在同一目录中构建两个项目,而是将B
的一些工件复制到输出路径 A
的子目录中。
我试过了
1) 通过将以下内容添加到A.sln
,将依赖项B
添加为A
的构建目标
<Target Name="Build">
<MSBuild Projects="$(SolutionDir)..BB.sln" Properties=" Platform=Win32; Configuration=$(Configuration); " />
</Target>
出于某种原因,这会在 A
的输出目录中构建B
,这是不需要的。
2) 通过将以下内容添加到A.sln
,将构建后事件添加到A
调用 msbuild on B
<PropertyGroup>
<PostBuildEvent>
msbuild $(SolutionDir)..BB.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)MSBuildMicrosoftVisualStudiov14.0CodeAnalysisMicroso
ft.CodeAnalysis.targets(219,5): error MSB4175: The task factory "CodeTaskFactory
" could not be loaded from the assembly "C:WindowsMicrosoft.NETFramework64v4
.0.30319Microsoft.Build.Tasks.v12.0.dll". Could not load file or assembly 'file
:///C:WindowsMicrosoft.NETFramework64v4.0.30319Microsoft.Build.Tasks.v12.0.
dll' or one of its dependencies. The system cannot find the file specified. [C:
UsersChiel.tenBrinkeProjectsMyProjectBCppSourceB.vcxproj]
那么,最好的(即最简单、最易于维护、最干净的)方法是什么?
<PropertyGroup>
<PostBuildEvent>
msbuild $(SolutionDir)..BB.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('Win32Debugb.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>
我最终这样做的方式是在项目级别而不是解决方案级别。解决方案 A
项目中的 xml 采用以下形式:
<Target Name="AfterBuild">
<MSbuild
Projects="$(SolutionDir)..BCppSourceSomeProject.vcxproj"
Properties="
Configuration=$(ConfigurationName);
OutDir=$(SolutionDir)$(ConfigurationName)B;
"/>
</Target>