I'm struggling with this for a long time now.
The setup:
c# project has a reference for the c++ project with the following lines:
<ProjectReference Include="projectB.vcxproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</ProjectReference>
This works from withing visual-studio. This works when using devenv from command line. When using msbuild from command line - the output file of the c++ project is not copied over into the output directory of the c# project.
I wasn't able to fix that using msbuild. Read a lot about it, nothing worked. Tried to debug in using diag verbosity - but logs of msbuild and visual-studio are very different... I can't turn to using devenv as the build machine doesn't have valid visual-studio.
In msbuild log with diagnostic verbosity I see:
Target "GetCopyToOutputDirectoryItems" skipped. Previously built successfully.
This is where in the visual-studio log - it looks different - and actually works on copying the referenced native files to the c# output directory.
Perhaps something related with build order?..
In msbuild log - I also see:
Target "_CopyOutOfDateSourceItemsToOutputDirectoryAlways" skipped, due to false condition; ( '@(_SourceItemsToCopyToOutputDirectoryAlways)' != '' ) was evaluated as ( '' != '' ).
While in the visual-studio build log I see this target executed (it comes right after GetCopyToOutputDirectoryItems target)
Update 3: It seems that previous solutions cause unwanted side-effects such as breaking the build when running multi-threaded builds.
Current solution, that does seem to work is to add:
<Targets>Build;BuiltProjectOutputGroup</Targets>
to the ProjectReference
section.
Update 2:
Changing:
Targets="%(_MSBuildProjectReferenceExistent.Targets)"
to
Targets="%(_MSBuildProjectReferenceExistent.Targets);GetTargetPath"
in C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets
, in the MSBuild task preceded by the comment Build referenced projects when building from the command line.
- did the trick.
However, I have no confidence in this solution, as I don't understand the entire build process. This is just a guess.
Update 1:
using /p:DesignTimeBuild=true
affects dependency build order. Can't work. Continue investigation...
Possible solution 1:
After putting a lot of messaged into C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets
I finally got to the following:
QUIRKING FOR DEV10
I'm still not exactly sure what that is all about, and I saw that the developers plan to remove this quirk (see https://github.com/Microsoft/msbuild/issues/1890).
Suddenly DesignTimeBuild
caught my eye in the following line:
<Output TaskParameter="TargetOutputs" ItemName="_ResolvedProjectReferencePaths" Condition="'%(_MSBuildProjectReferenceExistent.ReferenceOutputAssembly)'=='true' or '$(DesignTimeBuild)' == 'true'"/>
I know that inside visual-studio this work. Googling got me to https://github.com/Microsoft/msbuild/wiki/MSBuild-Tips-&-Tricks.
From there the path was short to adding /p:DesignTimeBuild=true
to the msbuild command line.
That made it work. The referenced assembly was copied over.
I don't think this should be the solution, but it works, and don't seem to break anything else (yet).
Any other suggestions would be welcome.