当解决方案包含具有不同编译选项的项目时,如何使用Roslyn

问题描述 投票:3回答:2

最初的问题是我有一个巨大的解决方案,其中项目有不同的选项(例如,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设置?

roslyn
2个回答
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()

0
投票

当您尝试打开它时,工作空间中包含的所有属性都将应用于所有解决方案的项目。看看loader,看看它将如何open solution以及它如何will open每个项目和应用属性。

在当前的API中,您应该创建解决方案并手动更改所有项目的有趣属性。不幸的是,我知道如何仅更改项目的Platform,而不是Configuration,因此您需要将您的问题发布到roslyn home page。 Hovewer,我将展示你如何改变一个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));
}
© www.soinside.com 2019 - 2024. All rights reserved.