Search code examples
msbuildappharborpost-build-eventlibgit2sharp

Binary files copied to a wrong folder on build


Recent libgit2sharp Nuget uses a new Nuget feature that allows you to include a piece of a build script in your NuGet. The purpose it to copy a native dll to a subfolder of the bin folder, like that:

    <ItemGroup>
    <None Include="$(MSBuildThisFileDirectory)\..\..\lib\net40\NativeBinaries\amd64\git2-e0902fb.dll">
        <Link>NativeBinaries\amd64\git2-e0902fb.dll</Link>
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>...

Now, it was all nice and beautiful locally, but when I deployed it to AppHarbor, the native dlls appeared in the /bin folder (in addition to the target subfolder), which caused my app to fail.

The problem lies in the _CopyWebApplicationLegacy target, which does not execute locally (it's run only if you have a non-default output dir), thus I don't have this problem on my dev machine. Namely, it executes the following piece of code:

<!-- Copy items that have been marked to be copied to the bin folder -->
<Copy SourceFiles="@(_SourceItemsToCopyToOutputDirectory)" 
      DestinationFolder="$(WebProjectOutputDir)\bin" 
      SkipUnchangedFiles="true" 
      Retries="$(CopyRetryCount)"
      RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"/>

You can see that the target folder is always /bin -- I believe it's a bug in the Microsoft.WebApplication.targets file (I can't control it on the target machine).

Is there a simple fix, or should I revert to a script in the PostBuild event (which I'll have to update with each new version)?


Solution

  • As mentioned here: https://github.com/libgit2/libgit2sharp/issues/1089#issuecomment-111000722

    the way AppHarbor is building your project, it's triggering the old _CopyWebApplicationLegacy target, and that is basically broken. It messes up all files that are using the Copy to Output Directory property by putting them directly into the output directory instead of respecting the relative folder structure. It also doesn't run any web.config transforms you may have.

    You can make your project use the newer _CopyWebApplication target instead by adding the following to your project file:

    <UseWPP_CopyWebApplication>True</UseWPP_CopyWebApplication>
    <PipelineDependsOnBuild>False</PipelineDependsOnBuild>
    

    The thing I'm not sure about is if AppHarbor has some reason why they wouldn't want you to use the newer copy target instead of the old broken one.