msbuild doesn't copy c++ referenced content file into c# output dir

Created on 25 Dec 2017  路  5Comments  路  Source: dotnet/msbuild

Steps to reproduce

one solution including:
one c# project
one c++ project
x64 solution configuration, including c++ as x64, and c# as Any Cpu (or x64 - doesn't matter)
in the csproj file add:

<ProjectReference Include="..\cpplinux\cpplinux.vcxproj">
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
      <OutputItemType>Content</OutputItemType>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</ProjectReference>

Command line

msbuild solution.sln /m /t:rebuild /p:configuration=debug /p:platform=x64

Expected behavior

the native dll should be copied over to the output of the c# project

Actual behavior

the native dll is not copied over to the output of the c# project

Environment data

msbuild /version output:
Microsoft (R) Build Engine version 15.3.409.57025 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

15.3.409.57025

OS info:

Windows 10, Visual Studio 2017

More info:
In visual studio - this works fine.
I have reduced my debugging to Microsoft.Common.CurrentVersion.targets, to where QUIRKING FOR DEV10 exists. Seems like adding GetTargetPath to the msbuild task that has the following comment -
Build referenced projects when building from the command line. - makes it work.
Also, setting DesignTimeBuild to true - solves this, but dependencies are not built in the correct order - so in the end this is not a solution.

Most helpful comment

You can try this one, it worked for me both from command line and VS
(msbuild 15.7.177.53362):
ProjectReference in csproj:

    <ProjectReference Include="..\MyVcx\My.vcxproj">
      <Project>{ProjectGuid}</Project>
      <Name>projectname</Name>
    </ProjectReference>

In My.vcxproj: add

  <ItemGroup>
....
    <Content Include="$(TargetPath)" >
      <Link>%(Filename)%(Extension)</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
...
  <!-- You can also add this for PDB -->
    <Content Include="$(TargetPath.Replace('.dll', '.pdb'))" >
      <Link>%(Filename)%(Extension)</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

All 5 comments

I changed:
Targets="%(_MSBuildProjectReferenceExistent.Targets)"
to
Targets="%(_MSBuildProjectReferenceExistent.Targets);GetTargetPath"

It seems that it solved it, without doing any other harm (at least nothing I noticed). Could that be the root cause?

adding GetTargetPath breaks other things, such as multithreaded build execution.
Current solution, that do seem to work is to add: <Targets>Build;BuiltProjectOutputGroup</Targets> to the ProjectReference section.

Is that correct?

You can try this one, it worked for me both from command line and VS
(msbuild 15.7.177.53362):
ProjectReference in csproj:

    <ProjectReference Include="..\MyVcx\My.vcxproj">
      <Project>{ProjectGuid}</Project>
      <Name>projectname</Name>
    </ProjectReference>

In My.vcxproj: add

  <ItemGroup>
....
    <Content Include="$(TargetPath)" >
      <Link>%(Filename)%(Extension)</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
...
  <!-- You can also add this for PDB -->
    <Content Include="$(TargetPath.Replace('.dll', '.pdb'))" >
      <Link>%(Filename)%(Extension)</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

@Alexander-Bartosh's solution of adding a <Content> element worked a treat for me.

Was this page helpful?
0 / 5 - 0 ratings