3

We have a visual studio solution with around 150 projects. 5 of these are executable, the other 95 are libraries which the executables reference, or test projects, etc.

Our automated CI builds the solution via MSBuild for both x86 and for x64. However, as the libraries are always built Any CPU, it should be possible to build the full solution Any CPU, and then build the executables again for each platform.

In visual studio, I have 3 solution platforms in the configuration manager, the x86/x64 platforms only build the 5 executables. Within VS, if I build Any CPU first, I can then build the other platforms.

However, I can't get this build to work from msbuild. After building Any CPU, I build x86, and it can't resolve the Project References. That is, /reference: arguments for the library binaries are not passed into csc.exe, and so csc fails because it cannot find any of the types that the binary depends on.

How do I get this to work with MSBuild? How does Visual Studio know to look in bin\Any CPU, but MSBuild does not?

Rob
  • 4,327
  • 6
  • 29
  • 55
  • Hi, what do you mean `it can't resolve Project References`.? I test in my machine, but the build can succeed though with warning like MSB3270 mismatch... – LoLance Aug 30 '19 at 08:53
  • @Lance Li-MSFT. When I look at the csc command emitted during msbuild, there are no `/reference:` arguments for the project binaries. And the executable csproj does not build because it cannot find the various types it depends on. – Rob Aug 30 '19 at 09:16

1 Answers1

0

After building Any CPU, I build x86, and it can't resolve the Project References. That is, /reference: arguments for the library binaries are not passed into csc.exe, and so csc fails because it cannot find any of the types that the binary depends on.

I can't reproduce this issue. Every time if the CoreCompile target executes, it will pass the referenced projectName.dll to csc.exe in my machine. For this, please make sure you're using references in this format to reference project dll:

   <ProjectReference Include="..\ClassLibraryOne\ClassLibraryOne.csproj">
      <Project>{xxx}</Project>
      <Name>ClassLibraryOne</Name>
    </ProjectReference>

And make sure you didn't add conditions like Condition="'$(Platform)' == 'AnyCPU'" to ProjectReference element.

How does Visual Studio know to look in bin\Any CPU, but MSBuild does not?

This is because Configuration Manager. Assuming I have a configuration setting like this:

enter image description here

I have an executable and two library projects in the solution. The executable depends on the two libraries.

1.In vs, when I build the solution with switch box set as Any CPU, it actually builds the three projects with platform Any CPU.

2.In vs, when I build the solution with switch box set as x86, it actually builds the two library projects with platform Any CPU, and builds the executable with x86 platform.

3.When I build the solution with Any CPU in msbuild command-line, it works the same as #1.

4.When I build the executable project with x86, it actually builds the three projects all in x86 platform. It's the big difference between VS and command-line.

For the difference, you should know the switch box in VS represents Solution Platform instead of Project Platform. So in VS when I set the switch box to x86, it knows for x86 solution platform, it should build libraries in Any CPU, and the executable in X86.

However when you build the project in command-line like: msbuild xx.csproj /p:xxx=x86. It only specify the project platform x86. And since msbuild can find this project depends on two library projects, it will build the library projects in x86 too. (The info about solution configurations and platforms are stored in xx.sln file instead of any xx,csproj file)

How do I get this to work with MSBuild?

Since it works in VS when you first build the solution Any CPU and then the five projects X86. I think you can modify the Configuration Manager. For your requirement,you should make sure the relationship between Solution platform and Project platform is:

1.
For solution: Debug Any CPU
For Library projects: Debug Any CPU
For executable projects: Debug Any CPU

2.
For solution: Debug x86
For Library projects: Debug Any CPU
For executable projects: Debug x86

3.
For solution: Debug x64
For Library projects: Debug Any CPU
For executable projects: Debug x64

Don't forget to check the settings in release mode. Then I think it will meet your needs:as the libraries are always built Any CPU, it should be possible to build the full solution Any CPU, and then build the executables again for each platform.. You should always build with solution file instead of project file:

msbuild xx.sln /p:Platform="Any CPU" ...
msbuild xx.sln /p:Platform=x86 ...
msbuild xx.sln /p:Platform=x64 ...

Since the libraries for Any CPU platform will be built when you first build it with Any CPU. In the second and third time, msbuild will only compile and build the executable projects for each platform. And it will skip building libraries again to save time.

enter image description here

Hope it makes some help and if I misunderstand anything, please feel free to correct me :)

LoLance
  • 25,666
  • 1
  • 39
  • 73