我是 .Net Core 的新手,我正在尝试基于它构建一个构建系统。作为该项目的一部分,我创建了一个抽象类,它详细说明了构建任务应实现的内容,并将其填充到共享库中。
可执行项目引用该库并扫描项目目录以查找特殊命名的目录,然后检查是否有任何.cs
文件在那里。加载这些脚本,然后使用通过提供的工具尝试编译Microsoft.CodeAnalysis
和朋友。
有了这个背景,我在编译阶段遇到了一个奇怪的问题:
如果我尝试向编译过程提供包含抽象类的共享库作为参考,则会收到以下错误:
失败的 CS0012:类型“对象”是在一个未定义的程序集中定义的
参考。您必须添加对程序集“mscorlib”的引用,
版本=4.0.0.0,文化=中性,PublicKeyToken=7cec85d7bea7798e'。
接下来是一堆关于预定义类型的抱怨:
CS0518:未定义或导入预定义类型“System.Boolean”
CS0518:未定义或导入预定义类型“System.Boolean”
CS0518:未定义或导入预定义类型“System.Void”...
等等等等
但是,如果我省略引用,而是将每个共享库的源文件解析为语法树并将它们传递给编译过程,则整个过程会成功,并且我会得到一个返回的内存中程序集,我可以从中提取类型并实例化。
我已经阅读了谷歌提供的有关此错误的所有内容,但我不知所措。有人可以告诉我为什么会发生这种情况,并为我如何实现简单链接到公共共享库的最初目标提供额外的互联网积分吗?
相关代码
CSharpParseOptions parseOptions = CSharpParseOptions.Default;
SyntaxTree jobSyntaxTree = CSharpSyntaxTree.ParseText(scriptContents, parseOptions);
string generatedAssemblyName = Path.GetRandomFileName();
var referencedAssemblies = Assembly.GetEntryAssembly().GetReferencedAssemblies();
foreach(var referencedAssembly in referencedAssemblies)
{
var rfas = Assembly.Load(referencedAssembly);
references.Add(MetadataReference.CreateFromFile(rfas.Location));
}
var op = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
CSharpCompilation compilation = CSharpCompilation.Create(
generatedAssemblyName,
syntaxTrees: new[] { jobSyntaxTree },
references: references,
options: op);
var ms = new MemoryStream();
EmitOptions emitOptions = new EmitOptions();
EmitResult result = compilation.Emit(ms);
if(result.Success)
{
// Yay
}
else
{
// Boo-hoo
}
共享库的 Project.json 文件
{
"title": "BuildBotCore",
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": false,
"preserveCompilationContext": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"System.Runtime": "4.1.0",
"System.Runtime.Loader": "4.0.0",
"Microsoft.NETCore.Portable.Compatibility": "1.0.1"
},
"frameworks": {
"netcoreapp1.0": {
"imports": "netcore50",
"buildOptions": {
"preserveCompilationContext": true
}
}
},
"configurations": {
"Debug": {
"buildOptions": {
"define": [
"DEBUG",
"TRACE"
],
"optimize": false,
"preserveCompilationContext": true
}
},
"Release": {
"buildOptions": {
"define": [
"RELEASE",
"TRACE"
],
"optimize": true,
"preserveCompilationContext": true
}
}
}
}
主要可执行文件的 Project.json
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"System.Runtime": "4.1.0",
"Microsoft.CodeAnalysis.CSharp": "1.3.2",
"System.Runtime.Loader": "4.0.0",
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"BuildBotCore": "1.0.0-*"
},
"frameworks": {
"netcoreapp1.0": {
"imports": "netcore50",
"buildOptions": {
"preserveCompilationContext": true
}
}
},
"configurations": {
"Debug": {
"buildOptions": {
"define": [
"DEBUG",
"TRACE"
],
"optimize": false,
"preserveCompilationContext": true
}
},
"Release": {
"buildOptions": {
"define": [
"RELEASE",
"TRACE"
],
"optimize": true,
"preserveCompilationContext": true
}
}
}
}