描述
我在我的.NET项目中无法可靠地生成C#代码。我可以在源文件事先存在或不存在的情况下构建它们。但是,我不能让相同的设置在这两种情况下都起作用。
为什么这很重要:如果我在开发机器上构建,则可能以前已经构建了代码,因此我需要它重新生成现有的源代码。但是,在构建机器上构建时,这些文件不存在,因此我需要在这种情况下从头开始生成代码。
设置
只需一个csproj和单个源文件即可复制此设置。
下面是引用示例GeneratedClass
的简单程序:
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine(GeneratedClass.MESSAGE);
}
}
这是我能想到的最简单的csproj文件。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<Target Name="GenerateCode" BeforeTargets="CoreCompile">
<!-- Removing the source code beforehand makes no difference
<Exec Command="rm $(ProjectDir)Generated/*.cs" IgnoreExitCode="true" />
-->
<Exec Command="echo 'class GeneratedClass { public static int MESSAGE = 1; }' > Generated/GeneratedClass.cs" />
<!-- Toggling this setting will cause failures in some scenarios and success in others
<ItemGroup>
<Compile Include="Generated/*$(DefaultLanguageSourceExtension)" />
</ItemGroup> -->
</Target>
</Project>
创建一个名为“Generated”的空目录。
在包含csproj和Program.cs文件的目录中运行
dotnet build
以进行构建。我在Linux上运行.NET Core 2.0.3。我的Docker构建容器使用
microsoft/dotnet:2.0-sdk
镜像;我可以在Docker内外复制该问题。症状
请注意,在上面的csproj文件中,有一个被注释掉的
<Compile Include
设置。同时请注意,多次运行构建将生成代码。(可以手动删除代码以复制代码一开始不存在的情况。)下表是我看到错误和未看到错误的矩阵:
+----------------------+----------------------+-----------------------------------+ | Compile Include=...? | Code Already Exists? | Result | +----------------------+----------------------+-----------------------------------+ | Present | YES | ERROR! "specified more than once" | | Present | NO | SUCCESS! | | Commented Out | YES | SUCCESS! | | Commented Out | NO | ERROR! "does not exist" | +----------------------+----------------------+-----------------------------------+
“指定了多次”错误的完整错误文本:
/usr/share/dotnet/sdk/2.0.3/Roslyn/Microsoft.CSharp.Core.targets(84,5): error MSB3105: The item "Generated/GeneratedClass.cs" was specified more than once in the "Sources" parameter. Duplicate items are not supported by the "Sources" parameter. [/home/user/tmp/CodeGenExample.csproj]
“不存在”错误的完整错误文本:Program.cs(5,34): error CS0103: The name 'GeneratedClass' does not exist in the current context [/home/user/tmp/CodeGenExample.csproj]
请求帮助我最好的猜测是我的
BeforeTargets="CoreCompile"
是错误的。我尝试了很多不同的值(抱歉,不记得哪些)我总是遇到像这样或另一个问题。这只是一个猜测。我做错了什么?