最初的问题是我有一个巨大的解决方案,其中项目具有不同的选项(例如x64或x86配置,是否允许使用不安全的代码等等)。 我正在尝试使用Roslyn(2.9.0)来使用DEBUG x64配置编译\解析该解决方案。某些项目的编译失败,因为仅应使用“ DEBUG x86”。
我使用“ DEBUG x64”配置创建一个测试解决方案。
Project A is a console application (DEBUG x64).
Project B is a library (DEBUG x86)
并编写此代码:
MSBuildLocator.RegisterDefaults();
_workspace = MSBuildWorkspace.Create(props);
_workspace.SkipUnrecognizedProjects = false;
_solution = _workspace.OpenSolutionAsync(solutionFilePath).Result;
var projectsGpaph = _solution.GetProjectDependencyGraph();
var projects = projectsGpaph.GetTopologicallySortedProjects();
未设置“道具”时
_workspace.Diagnostics为空,并且“项目”的顺序正确(库,然后是应用)
B: project.CompilationOptions.Platform is AnyCpu
A: project.CompilationOptions.Platform is AnyCpu32BitPreferred
将“道具”设置为
var props = new Dictionary<string, string>()
{
{"Configuration", "Debug"},
{"Platform", "x64"}
};
_workspace.Diagnostics为空,“项目”的顺序错误:
A: project.CompilationOptions.Platform is X64
B: project.CompilationOptions.Platform is X64
执行我的“ project.GetCompilationAsync()。Result”时引发了异常:
System.ArgumentException: 'Reference of type
'Microsoft.CodeAnalysis.UnresolvedMetadataReference' is not valid for this
compilation.
Parameter name: references[0]'
如何强制Roslyn考虑.sln \ .csproj设置?
答案 0 :(得分:2)
我认为答案是“不支持加载具体项目的编译选项”。
对于我的问题,我将其行为与Roslyn 2.7进行了比较:
使用Roslyn 2.7:
当我使用“任何CPU”配置时,GetTopologicallySortedProjects可以在该测试解决方案上正常工作,并且庞大的解决方案可以正确编译。
使用Roslyn 2.9:
我发现ProjectDependencyGraph :: _ referencesMap中的项目引用是错误的,并且看起来原因是不可变集合的错误实现。 当我编译庞大的解决方案(任何CPU)时,存在许多内部错误,因此:
System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: key
at System.Collections.Immutable.Requires.FailArgumentNullException(String parameterName)
at System.Collections.Immutable.Requires.NotNullAllowStructs[T](T value, String parameterName)
at System.Collections.Immutable.ImmutableDictionary`2.TryGetValue(TKey key, TValue& value)
at Microsoft.CodeAnalysis.MSBuild.CommandLineArgumentReader.ReadDebugInfo()
at Microsoft.CodeAnalysis.CSharp.CSharpCommandLineArgumentReader.ReadCore()
at Microsoft.CodeAnalysis.MSBuild.CommandLineArgumentReader.Read()
at Microsoft.CodeAnalysis.CSharp.CSharpCommandLineArgumentReader.Read(ProjectInstance project)
at Microsoft.CodeAnalysis.CSharp.CSharpProjectFile.ReadCommandLineArgs(ProjectInstance project)
at Microsoft.CodeAnalysis.MSBuild.ProjectFile.GetCommandLineArgs(ProjectInstance project)
at Microsoft.CodeAnalysis.MSBuild.ProjectFile.CreateProjectFileInfo(ProjectInstance project)
at Microsoft.CodeAnalysis.MSBuild.ProjectFile.<BuildProjectFileInfoAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.CodeAnalysis.MSBuild.ProjectFile.<GetProjectFileInfosAsync>d__16.MoveNext()
答案 1 :(得分:0)
当您尝试打开工作区中包含的所有属性时,它们将应用于所有解决方案的项目。查看loader,看看它如何open solution,以及如何will open每个项目并应用属性。
在当前的API中,您应该创建自己的解决方案,并手动更改所有项目的对您感兴趣的属性。不幸的是,我知道如何仅更改项目的Platform
,而不更改Configuration
,因此您需要将问题发布到roslyn home page。主持人,我将向您展示如何更改Platform
:
...
foreach (var project in _solution.Projects.ToList())
{
// NOTE: you will need to a little "function", that will be convert "x64" to Platform.X64 and so on
solution = solution.WithProjectCompilationOptions(project.Id, project.CompilationOptions.WithPlatform(Platform.X64));
}