Search code examples
c#monoxbuild

xbuild fails to embed resources from shared project


I have a C# project A located in FolderA which references a shared project B. The files of the shared project are located in FolderB. The shared project B contains a file C.gz with the properties

Build Action Embedded Resource
Copy to Output Directory Do Not Copy

When I try to build project A using xbuild (specifically versions 4.8 and 4.8.1, x86 and x64 architectures):

xbuild A.csproj

I get the following build error:

C:\Program Files (x86)\Mono\lib\mono\xbuild\14.0\bin\Microsoft.Common.targets (CopyNonResxEmbeddedResources target) ->

C:\Program Files (x86)\Mono\lib\mono\xbuild\14.0\bin\Microsoft.Common.targets: error : Cannot copy FolderA\C.gz to FolderA\obj\Release\C.gz, as the source file doesn't exist.

i.e. xbuild searches for the embedded resource file in FolderA although it is apparently located in FolderB together with the other files of the shared project B.

It is not a feasible option for me to move the embedded resource file to project A, as the shared project is referenced from several other projects as well.

Is there something else I can do to make project A build successfully with xbuild?


Side note: is this an expected behavior in xbuild, or is it a bug? With msbuild I don't have this problem.


Solution

  • This issue appears to be a flaw in the current xbuild implementation, so I needed to apply a workaround specific for this problem.

    Since xbuild expects the embedded resource file to be available in the FolderA folder, I simply add a pre-build step in the project file:

    <ItemGroup>
      <FilesToCopy Include="..\FolderB\C.gz" />
    </ItemGroup>
    <Target Name="BeforeBuild">
      <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="."/>
    </Target>
    

    Optionally, one could also consider a cleanup after building by removing the copied file in the post-build.

    Note! To ensure that the pre-build step is properly accounted for, make sure to place it after this line:

    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />