aspnet / RoslynCodeDomProvider

Roslyn CodeDOM provider
MIT License
84 stars 43 forks source link

When using MSBuild command line from buildserver without VS, the Roslyn files are not copied to the bin folder #120

Closed precisioninfinity closed 2 years ago

precisioninfinity commented 3 years ago

I have included a workaround for this below but first the problem (which might be related to others reporting something similar but this ticket has been opened with more details specific to this actual problem).

The project builds and works fine in VS but on the buildserver, even though it pulls in the nuget package fine, it never runs the required target to copy the compiler files.

I have a buildserver with MSBuild Tools installed from this source: https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019 (not the full VS install).

By comparing the build output on a VS machine, I see that VS is calling SetRoslynCompilerFiles target. There must be some special target on the VS installs that's calling this that doesn't exist on the msbuild tools install by itself.

WORKAROUND

In your .proj file (this example was done in a webapp.csproj file), make sure that the following import was already added by the install-package command (in my case it was):

<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" />

That import defines the targets needed to copy the files.

Find or add an AfterBuild target (which gets called during the build process) and set the condition to something that's specific to fire on your buildserver. Ours looks like this where we also run the aspnet compiler to compile all aspx pages (not required). The key new piece you need is the DependsOnTargets="SetRoslynCompilerFiles" which will ensure that target is run.

<Target Name="AfterBuild" DependsOnTargets="SetRoslynCompilerFiles" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
  </Target>
StephenMolloy commented 2 years ago

Wow, so this is an old one. I'm struggling to see how you might be going wrong here though. SetRoslynCompilerFiles doesn't actually cause anything to be copied. It just gets a list of files to copy, but doesn't even know where to copy them. The CopyRoslynCompilerFilesToOutputDirectory target does the copying, and it is set up to run after CopyFilesToOutputDirectory which surely must be running on your buildserver. I'd be curious to know what your chain of targets being executed is if you can still reproduce the issue.

The other possibility I see is that the Roslyn files actually are getting copied... but to the wrong place? A result of some confusion between $(OutDir) and $(OutputPath) and $(WebProjectOutputDir). I have seen reports of CI machines using msbuild where the use of "/p:OutDir=" causes confusion. For the web-application scenario in this case, the roslyn files do get copied I think, but into a subdirectory of $(OutDir) named something like '_PublishedWebsites\\\bin\roslyn'.

StephenMolloy commented 2 years ago

I think this was an OutDir issue. Possibly fixed by #130? Please reopen if this is still an issue with the latest preview.

precisioninfinity commented 1 year ago

Sorry, a little late on the response but yes I think this was fixed by the one you mentioned. We've updated our pipeline with the latest release and so far so good, thanks for keep this up to date.