如何将所有 SYSLIB 警告标记为错误

时间:2021-04-06 12:13:49

标签: compiler-errors msbuild warnings compiler-warnings .net-5

我正在将大型项目从 net framework 移植到 net5,这带来了大量警告。我想让所有以 SYSLIB 开头的警告都是错误的。 一种可能的解决方案是在 WarnAsError 中列出所有警告,但对于这样一个简单的任务来说,写太多了,而且如果出现另一个警告(例如 syslib00013),新版本将是警告,而不是错误。

<WarnAsError>($WarnAsError);SYSLIB0001;SYSLIB0002;etc</WarnAsError>

<WarnAsError>true</WarnAsError>不是一种选择

尝试编写 <WarningsAsErrors>$(WarnAsError);SYSLIB</WarningsAsErrors> 没有帮助

1 个答案:

答案 0 :(得分:0)

一段时间后,我找到了一种很好且干净的方法。

我不得不写UsingTask

  <UsingTask TaskName="ExpandRanges"
             TaskFactory="RoslynCodeTaskFactory"
             AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"
             >
    <ParameterGroup>
      <Ranges ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
      <Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System.Linq" />
      <Using Namespace="System.Collections.Generic" />
      <Code Type="Fragment" Language="cs">
     <![CDATA[
        const string prefixName = "Prefix";

        var list = new List<ITaskItem>(Ranges.Length);

        foreach (var range in Ranges)
        {
          string include = range.ToString();
          string prefix = range.GetMetadata(prefixName);
          if (string.IsNullOrEmpty(prefix))
          {
              Log.LogWarning($"Metadata {prefixName} was not found in {include} and will be ignored");
              continue;
          }

          if (include.All(char.IsDigit))
          {
              list.Add(new TaskItem(prefix + include));
          }
          else if (include.Split('-') is { Length: 2 } splitted)
          {
              int start = int.Parse(splitted[0]);
              int stop = int.Parse(splitted[1]);

              for (int i = start; i < stop + 1; i++)
              {
                  list.Add(new TaskItem($"{prefix}{i:0000}"));
              }
          }
          else
          {
              Log.LogWarning($"{include} have incorrect format and will be ignored");
          }
        }

        Result = list.ToArray();
]]>
      </Code>
    </Task>
  </UsingTask>

还有Target

  <Target Name="ExpandWarningsAsErrorsRange"
          BeforeTargets="CoreCompile"
          Inputs="@(WarningsAsErrorsRange)"
          Outputs="$(WarningsAsErrors)"
          >
    <ExpandRanges Ranges="@(WarningsAsErrorsRange)">
      <Output ItemName="_WarnRange" TaskParameter="Result" />
    </ExpandRanges>

    <PropertyGroup>
      <WarningsAsErrors>$(WarningsAsErrors);@(_WarnRange)</WarningsAsErrors>
    </PropertyGroup>
  </Target>

这两个东西都应该位于 Directory.Build.targets 中,项目只需要包含特定的警告

  <ItemGroup>
    <WarningsAsErrorsRange Include="0000-0002" Prefix="SYSLIB" />
    <WarningsAsErrorsRange Include="0006" Prefix="SYSLIB" />
  </ItemGroup>

这个解决方案有一些缺陷,比如它不支持 ItemGroup 中的 Exclude 但对我来说已经足够了。

相关问题