dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.67k stars 1.06k forks source link

Linux: Compilation errors on lines with #line directives with Windows paths shows "csc.dll" exited with code 1 instead of the actual compilation error #43592

Open JonathanLydall opened 1 week ago

JonathanLydall commented 1 week ago

Describe the bug

On Linux, when a compilation issue occurs on a line with a #line directive above it with a Windows path, MSBuild output shows only "csc.dll" exited with code 1 instead of the actual compilation issue.

To Reproduce

On Linux (tested on WSL with Ubuntu 22.04):

Successful compilation:

Exceptions (if any)

Receive the following error only with the build:

/usr/share/dotnet/sdk/9.0.100-rc.1.24452.12/Roslyn/Microsoft.CSharp.Core.targets(89,5): error MSB6006: "csc.dll" exited with code 1.

Further technical details

dotnet --info

```text PS /home/jonathan/dev/dotnet_build_bug> dotnet --info .NET SDK: Version: 9.0.100-rc.1.24452.12 Commit: 81a714c6d3 Workload version: 9.0.100-manifests.a7bf2b8f MSBuild version: 17.12.0-preview-24422-09+d17ec720d Runtime Environment: OS Name: ubuntu OS Version: 22.04 OS Platform: Linux RID: linux-x64 Base Path: /usr/share/dotnet/sdk/9.0.100-rc.1.24452.12/ .NET workloads installed: Configured to use loose manifests when installing new manifests. There are no installed workloads to display. Host: Version: 9.0.0-rc.1.24431.7 Architecture: x64 Commit: static .NET SDKs installed: 8.0.200 [/usr/share/dotnet/sdk] 9.0.100-rc.1.24452.12 [/usr/share/dotnet/sdk] .NET runtimes installed: Microsoft.AspNetCore.App 8.0.5 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 9.0.0-rc.1.24452.1 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 8.0.5 [/usr/share/dotnet/shared/Microsoft.NETCore.App] Microsoft.NETCore.App 9.0.0-rc.1.24431.7 [/usr/share/dotnet/shared/Microsoft.NETCore.App] Other architectures found: None Environment variables: Not set global.json file: Not found Learn more: https://aka.ms/dotnet/info Download .NET: https://aka.ms/dotnet/download ```

Original bug report

The below is the original bug report before @KalleOlaviNiemitalo pointed out the root cause and I then simplified the reproduction steps above, it's probably irrelevant now but can still be reviewed if desired.

Original bug report

### Describe the bug When using `dotnet build` on Linux the output shows only `"csc.dll" exited with code 1` instead of the actual compilation issue. On Windows the actual compilation issue is shown. ### To Reproduce On Linux (tested on WSL with Ubuntu 22.04): - `git clone https://github.com/JonathanLydall/dotnet_build_bug.git` - `dotnet build` Successful compilation: - `git checkout fixed` - `dotnet build` ### Exceptions (if any) Receive the following error only with the build: ```text /usr/share/dotnet/sdk/9.0.100-rc.1.24452.12/Roslyn/Microsoft.CSharp.Core.targets(89,5): error MSB6006: "csc.dll" exited with code 1. ```

Full console output

```text PS /home/jonathan/dev/dotnet_build_bug> dotnet build Restore complete (0.4s) You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy Intent.Modules.ModuleBuilder failed with 1 error(s) and 7 warning(s) (0.5s) /home/jonathan/dev/dotnet_build_bug/Intent.Modules.ModuleBuilder/Templates/Api/ApiElementExtensionModel/ApiElementExtensionModelTemplatePartial.cs(86,36): warning CS0108: 'ApiElementExtensionModelTemplate.DeclareUsings()' hides inherited member 'CSharpTemplateBase.DeclareUsings()'. Use the new keyword if hiding was intended. /home/jonathan/dev/dotnet_build_bug/Intent.Modules.ModuleBuilder/Templates/Api/ApiElementModelExtensions/ApiElementModelExtensionsTemplatePartial.cs(52,36): warning CS0108: 'ApiElementModelExtensionsTemplate.DeclareUsings()' hides inherited member 'CSharpTemplateBase.DeclareUsings()'. Use the new keyword if hiding was intended. /home/jonathan/dev/dotnet_build_bug/Intent.Modules.ModuleBuilder/Api/AssociationEventHandlerModel.cs(26,33): warning CS0108: 'AssociationEventHandlerModel.ToPersistable()' hides inherited member 'ScriptModel.ToPersistable()'. Use the new keyword if hiding was intended. /home/jonathan/dev/dotnet_build_bug/Intent.Modules.ModuleBuilder/Api/ElementEventHandlerModel.cs(49,33): warning CS0108: 'ElementEventHandlerModel.ToPersistable()' hides inherited member 'ScriptModel.ToPersistable()'. Use the new keyword if hiding was intended. /home/jonathan/dev/dotnet_build_bug/Intent.Modules.ModuleBuilder/Templates/Registration/FilePerModel/FilePerModelTemplateRegistrationTemplatePartial.cs(66,36): warning CS0108: 'FilePerModelTemplateRegistrationTemplate.DeclareUsings()' hides inherited member 'CSharpTemplateBase.DeclareUsings()'. Use the new keyword if hiding was intended. /home/jonathan/dev/dotnet_build_bug/Intent.Modules.ModuleBuilder/Templates/Registration/SingleFileListModel/SingleFileListModelTemplateRegistrationTemplatePartial.cs(66,36): warning CS0108: 'SingleFileListModelTemplateRegistrationTemplate.DeclareUsings()' hides inherited member 'CSharpTemplateBase.DeclareUsings()'. Use the new keyword if hiding was intended. /home/jonathan/dev/dotnet_build_bug/Intent.Modules.ModuleBuilder/Api/RunScriptOptionModel.cs(50,32): warning CS0108: 'RunScriptOptionModel.ToPersistable()' hides inherited member 'ScriptModel.ToPersistable()'. Use the new keyword if hiding was intended. /usr/share/dotnet/sdk/9.0.100-rc.1.24452.12/Roslyn/Microsoft.CSharp.Core.targets(89,5): error MSB6006: "csc.dll" exited with code 1. Build failed with 1 error(s) and 7 warning(s) in 1.1s ```

However, when run on Windows you see the proper error details: ```text C:\Dev\Intent.Modules\Modules\Intent.Modules.ModuleBuilder\Templates\Api\ApiElementModel\ApiElementModelTemplate.tt(2,78): error CS0426: The type name 'ModuleBuilder' does not exist in the type 'Intent' [D:\De v\Spikes\VS\dotnet_build_bug\Intent.Modules.ModuleBuilder\Intent.Modules.ModuleBuilder.csproj] C:\Dev\Intent.Modules\Modules\Intent.Modules.ModuleBuilder\Templates\Api\ApiElementModel\ApiElementModelTemplate.tt(2,26): error CS0263: Partial declarations of 'ApiElementModelTemplate' must not specify diffe rent base classes [D:\Dev\Spikes\VS\dotnet_build_bug\Intent.Modules.ModuleBuilder\Intent.Modules.ModuleBuilder.csproj] ``` #### Additional context Initially I didn't get any compilation errors on Windows, `dotnet build` and compiling in VS 2022 would complete without error, I only noticed a problem when it was building on an Azure Pipelines hosted Linux agent. Testing on WSL Ubuntu 22.04 with .NET 8 reproduced the same error, rolling back just [this change](https://github.com/IntentArchitect/Intent.Modules/commit/dfc2289bb681bb145645c7e3684afb47ba01d695#diff-d0516a4def72405703d400d27ee897ff1605f2983bc40f884c42b3c07a861085R17) seemed to avoid the problem. When I was trying to make a simpler reproduction repository I eventually saw the `CS0426: The type name 'ModuleBuilder' does not exist in the type` on Windows and resolving it there resolved the issue on Linux.

KalleOlaviNiemitalo commented 1 week ago

ApiElementModelTemplate.cs includes #line directives with Windows-format file paths, which then get copied into compiler error messages. I wonder if those somehow confuse the logging on Linux, which expects a different path format.

If you build with --tl:off on Linux (or set MSBUILDTERMINALLOGGER=off in the environment), does it display the error message correctly then? I expect it doesn't; although TerminalLogger highlights the file name in error messages, it does that in a way that tolerates unexpected path formats.

JonathanLydall commented 1 week ago

Thank you @KalleOlaviNiemitalo, you're spot on the money, it's the #line directives with the Windows paths, I've updated this bug title and the reproduction accordingly.

These #line directives although sometimes useful are also particularly annoying with source control management where if any developer uses a different path, it causes noise in the diffs. I wish the T4 tooling would rather just do a relative path which MSBuild doesn't seem to mind at all.

MSBUILDTERMINALLOGGER=off didn't show any more details, it just showed the same output as if I was still running the .NET 8 SDK.

KalleOlaviNiemitalo commented 1 week ago

How about building with -p:GenerateFullPaths=false? The GenerateFullPaths property defaults to true and is passed to the Csc task, where it causes Roslyn to report full paths in diagnostic messages. Perhaps that applies to the paths in #line directives too and does not handle exceptions correctly. In which case this would be a dotnet/roslyn bug.

KalleOlaviNiemitalo commented 1 week ago

Another test for locating the bug would be to place a Windows file path in the File parameter of the Error task and run that on Linux. If that doesn't display the error either, then the bug is in MSBuild rather than in Roslyn.