背景
我目前正在使用VS2010。
MSBuild存在一个已知问题,即从IDE构建时,解决方案中的项目依赖项可以正常工作,但在通过MSBuild构建解决方案时不起作用。
(MSBuild通过Cruise Control .NET运行,如下所示:)
<cb:define buildArgs="/noconsolelogger /p:Configuration=$(configuration);Platform=$(platform) /maxcpucount /v:minimal /nologo" />
<!-- ... -->
<cb:define name="buildSolution">
<msbuild>
<executable>$(msbuildExe)</executable>
<workingDirectory>$(localWorkingDirectory)</workingDirectory>
<projectFile>$(solutionfile)</projectFile>
<buildArgs>$(buildArgs)</buildArgs>
<targets>build</targets>
<timeout>7200</timeout>
<logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
</cb:define>
因此,我通过使用非链接项目引用解决了这个问题:
<!-- Inside ProjectB.csproj -->
<ProjectReference Include="..\ProjectA\ProjectA.vcxproj">
<LinkLibraryDependencies>false</LinkLibraryDependencies>
<Project>{GUID}</Project>
<Name>ProjectA</Name>
</ProjectReference>
在这种情况下,ProjectA是一个SWIG项目,它生成要编译到ProjectB的CS源文件。我完成了这样做:
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\ProjectA\generated\cs\*.cs" />
</ItemGroup>
但是,虽然这在通过IDE构建时工作正常,但在通过MSBuild构建时它不包含这些文件。我能够通过添加以下内容来实现它:
<ItemGroup>
<CSFile Include="..\ProjectA\generated\cs\*.cs" />
</ItemGroup>
<Target Name="Build" DependsOnTargets="BeforeBuild">
<Csc Sources="@(CSFile)" References="@(Reference)" OutputAssembly="$(OutputPath)$(AssemblyName).dll" TargetType="dll" />
</Target>
实际问题:
似乎MSBuild不再尊重项目引用,因此它通常会尝试在ProjectA之前构建ProjectB。
答案 0 :(得分:1)
看起来问题不是构建顺序,而是评估通配符时。
在我的示例中,在ProjectA生成的.cs文件存在之前评估CSFile
标记,因此即使ProjectA首先发生,它们也不包含在构建中。
为了避免这种情况,我必须通过MSBuild从ProjectB手动调用ProjectA,在运行时读取文件列表,然后手动将其附加到Compile
集合。
在ProjectB.csproj文件的末尾,我插入了:
<Target Name="BeforeBuild">
<!-- Force project references to build before this, because otherwise it doesn't... -->
<MSBuild Projects="@(ProjectReference)"
Targets="Build"
BuildInParallel="false"
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration);%(_MSBuildProjectReferenceExistent.SetPlatform)"
ContinueOnError="false" />
<CreateItem Include="..\ProjectA\generated\$(Platform)\$(Configuration)\cs\*.cs">
<Output ItemName="Compile" TaskParameter="Include" />
</CreateItem>
<CreateItem Include="..\ProjectA\generated\$(Platform)\$(Configuration)\cs\*.cs">
<Output ItemName="GeneratedCS" TaskParameter="Include" />
</CreateItem>
<Message Text="Generated .cs files...%0d @(GeneratedCS->'%(Filename)%(Extension)','%0d ')" Importance="high" />
</Target>
这会将所有生成的.cs文件添加到项目中,并将所有名称打印到控制台。
答案 1 :(得分:0)
看起来SWIG项目根本无法由MSBuild编译,但您可以使用Visual Studio本身使用SWIG编译解决方案。请注意,您必须在Cruise Control构建服务器上安装Visual Studio + SWIG,并以某种方式让Cruise Control使用正确的Devenv Command Line Switches来呼叫devenv.exe
。
后台:在Visual Studio中,大多数项目文件格式都兼具:
这包括csproj
,vcxproj
和其他许多内容。但是,某些项目类型(如安装项目(vdproj
)仅支持上述(1) - 而SWIG也似乎也是如此。