0
votes

Background:

I am currently using VS2010.

There is a known issue with MSBuild where project dependencies in a solution work when building from the IDE, but do not work when the solution is built through MSBuild.

(MSBuild is run via Cruise Control .NET like so:)

<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>

Thus, I solve this issue by using a non-linking project reference:

<!-- Inside ProjectB.csproj -->
<ProjectReference Include="..\ProjectA\ProjectA.vcxproj">
  <LinkLibraryDependencies>false</LinkLibraryDependencies>
  <Project>{GUID}</Project>
  <Name>ProjectA</Name>
</ProjectReference>

In this case, ProjectA is a SWIG project that generates CS source files to be compiled into ProjectB. I accomplish this like so:

<ItemGroup>
  <Compile Include="Properties\AssemblyInfo.cs" />
  <Compile Include="..\ProjectA\generated\cs\*.cs" />
</ItemGroup>

However, although this works fine when building through the IDE, it includes none of these files when building through MSBuild. I was able to get it to work by adding the following:

<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>

Actual Issue:

It seems like MSBuild is no longer respecting the project reference, so it will usually try to build ProjectB before ProjectA.

2
What is the MSBuild command line that you are using? In particular are you building a solution or a project?Justin
I've added the info about the MSBuild command. I am building a solution.Veggie

2 Answers

1
votes

It appears that the issue was not build order so much as when the wildcards are evaluated.

In my example, the CSFile tag is evaluated before the generated .cs files from ProjectA exist, so even though ProjectA happens first, they are not included in the build.

To circumvent this, I have to manually call ProjectA from ProjectB through MSBuild, read the file list at runtime, and manually append it to the Compile collection.

At the end of the ProjectB.csproj file, I've inserted:

<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>

This will add all generated .cs files to the project, as well as print all their names to the console.

0
votes

Looks like SWIG projects can't be compiled by MSBuild at all, but you might be able to compile your solution with SWIG using Visual Studio itself. Note that you'll have to have Visual Studio + SWIG on your Cruise Control build server, and somehow get Cruise Control to call devenv.exe with the correct Devenv Command Line Switches.

Background: In Visual Studio, most project files format function as both:

  1. Project files that Visual Studio understands, possibly with a Visual Studio plugin like SWIG
  2. MSBuild file that MSBuild understands.

This includes csproj, vcxproj, and many others. However, some project types like setup projects (vdproj) only support (1) above - and SWIG appear to be like that as well.