Reputation: 1788
This question is about the difference between using /p:Platform=x64
on the MSBuild command line versus using <Platform>x64</Platform>
in the csproj file.
I made two simple c# NET 5 solutions/projects with one executable (HsConsole) and one class library (HsLogger) to investigate when MSB3270 architecture mismatches occurred. Here is an example error message.
warning MSB3270: There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "HsLogger", "AMD64".
** Note the error message talks about MSIL (hsconsole) and AMD64 (hslogger), even though both the command line and project file specify x64 and NOT AMD64.
The HsLogger logger uses a post-build event to copy the class library to a folder that stores libraries for sharing among projects. The HsConsole project references the class library HsLogger from that folder.
The problem is that I get the MSB3270 error message (when compiling HsConsole) whenever I use /p:"Platform=x64"
on the MSbuild command line, but not when I use no arguments on the command line. <Platform>x64</Platform>
is already declared in the HsLogger project file in both cases.
Here are the two project files:
HsLogger
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Platform>x64</Platform>
<TargetFramework>net5.0-windows7.0</TargetFramework>
</PropertyGroup>
</Project>
HsConsole
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Platform>AnyCPU</Platform>
<TargetFramework>net5.0-windows7.0</TargetFramework>
</PropertyGroup>
</Project>
Here is a summary of experimental results:
MSBuild hslogger.csproj /t:clean;restore;build -> compiles okay
MsBuild hsconsole.csproy /t:clean;restore;build -> no MSB3270 error
MSBuild hslogger.csproj /t:clean;restore;build /p:Platform=x64 -> compiles okay
MsBuild hsconsole.csproj /t:clean;restore;build -> gives MSB3270 error as shown above
** Note the error message talks about MSIL (hsconsole) versus AMD64 (hslogger).
Q1. Why is AMD64 in the error message when only x64 is used?
Q2. Why is an error message being produced at all when the command line and internal property both specify x64?
Upvotes: 3
Views: 1577
Reputation: 1788
I carefully inspected the batch file output of the MSBuild command used to execute the commands shown above. In particular, the huge csc compiler command issued by MSBuild contains the argument /p:Platform=x64
only when the argument /p:Platform=x64
is provided on the command line.
The csc compiler command does NOT contain the x64 argument specified in the csproj file if no argument is given on the command line. In other words, the <Platform>x64</Platform>
property in the project file does not cause MSBuild to pass x64 to the compiler command. That was unintuitive to me. My expectation was that <Platform>x64</Platform>
in the project file would pass x64 to the compiler was not correct.
Then in the project file, I changed <Platform>x64</Platform>
to <PlatformTarget>x64</PlatformTarget>
and the x64 argument was passed to the compiler as /p:Platform=x64
(note: the argument passed to the compiler was Platform and not PlatformTarget).
Finally, when /p:PlatformTarget=x64
was given on the Msbuild command line, it produced the same results as <PlatformTarget>x64</PlatformTarget>
in the project file alone. In both these cases, the MSB3270 occurred because the class library was compiled as x64 whereas the hsconsole program (that consumed the library) was compiled as AnyCPU.
Takeaways
<Platform>
and <PlatformTarget>
in the project file are two different things. The <Platform>
value is used by the Clean target to delete folders but is NOT passed to the compiler. In contrast, the value of <PlatformTarget>
is translated to /p:Platform=value
, is passed to the compiler, and controls the type of output binary created by the compiler.
PlatformTarget
is not even listed in the Common MSBuild project properties page, even though it is the definitive XML element that is passed to the csc compiler.
https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties
/p:Platform=value
on the command line, /p:PlatformTarget=value
on the command line, and <PlatformTarget>value</PlatformTarget>
in the project file are all the same thing for compilation purposes. They all cause the value to be passed to the compiler.
My guess for the AMD64 part of the error message is that it comes from my dev computer, which contains an AMD CPU processor on the motherboard.
Upvotes: 7