前段时间用INVIDIA Gameworks,合编了一个4.18.3的整合版本。电脑系统刚重装,只安装了VS2017,使用VS2017编译引擎后发现一个小问题,具体如下:
使用VS2017编译版本引擎创建新的C++工程时 出现无法打开VisualStudio问题
因此,简单研究了UE4 与vs 调用之间的关系,大致总结如下:
非源码版引擎更改VS版本
在已经创建工程的情况下,修改编辑器偏好设置中的source下SourceCodeAccess为VisualStudio2017即可更改。
更改后将在配置文件DefaultEditorPerProjectUserSettings.ini中创建一个新的配置项:[/Script/SourceCodeAccess.SourceCodeAccessSettings] PreferredAccessor=VisualStudio2017
依据此项配置信息,查看Engine/config下配置文件,不难找到BaseEditorPerProjectUserSettings.ini应该
就是默认创建工程时使用的配置文件了,因此复制上面配置项到BaseEditorPerProjectUserSettings.ini
即可将默认工程的VS版本设定为VS2017(VS2015同理)
同时,留意到文件头信息:This .ini file contains the defaults for many editor and engine "preferences". These preferences are saved to an EditorPerProjectUserSettings.ini file in the user's /<Game>/Saved/Config/ directory If you change the default for a preference in here, that change will *NOT* automatically propagate to users who already have saved preferences. The idea is that we must preserve If you add a new preference, the new key and value *WILL* be propagated to the user's EditorPerProjectUserSettings.ini file. After we load the user's existing settings, we'll merge in One easy technique for forcing a "reset" of an already-existing preference is to simply rename the variable for that preference. The config system will treat it as a newly-added key and will propagate the change to existing users' preferences.
简单说,对于已经创建的项目,修改这个配置不再起作用,不过对于新建的项目,则会应用这些配置。
源码编译版引擎
源码编译版引擎与上诉情况其实类似,但是对于4.18.3存在而外问题。
首先,在使用VS2017编译引擎后,创建新的C++工程时,存在BUG:无法打开VisualStudio
以下是解决历程:
查看报错信息得知,warning代码为:Couldn’t access module table
在\Engine\Plugins\Developer\VisualStudioSourceCodeAccess\Source\VisualStudioSourceCodeAccess\
Private\VisualStudioSourceCodeAccessor.cpp
中找到报错位置为AccessVisualStudioViaProcess()函数,经过查看,发现此函数是用于查看打开的VS项目路径
是否是之前工程路径,换言之,讲道理,不应该调用这个函数才对。
而后查看函数调用信息,找到出现问题的函数位置
FVisualStudioSourceCodeAccessor::OpenSolution()
以及 FVisualStudioSourceCodeAccessor::OpenSolutionAtPath()
之后调试发现一个有意思的问题:VSACCESSOR_HAS_DTE 这个宏定义为 0 也即是没有DTE
后面查看相关build文件如下:` bool bHasVisualStudioDTE; try { // Interrogate the Win32 registry string DTEKey = null; switch (Target.WindowsPlatform.Compiler) { case WindowsCompiler.VisualStudio2017: DTEKey = "VisualStudio.DTE.15.0"; break; case WindowsCompiler.VisualStudio2015: DTEKey = "VisualStudio.DTE.14.0"; break; } bHasVisualStudioDTE = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32).OpenSubKey(DTEKey) != null; } catch { bHasVisualStudioDTE = false; } if (bHasVisualStudioDTE) { Definitions.Add("VSACCESSOR_HAS_DTE=1"); } else { Definitions.Add("VSACCESSOR_HAS_DTE=0"); }`
据此,猜测问题可能有两个,一个是出现异常,另一个应该是Target.WindowsPlatform.Compiler为
WindowsCompiler.VisualStudio2015,
通过调试信息发现Target.WindowsPlatform.Compiler为WindowsCompiler.VisualStudio2015。
之后查看:
Engine\Source\Programs\UnrealBuildTool\ProjectFiles\VisualStudio\VCProjectFileGenerator.cs
发现VCProjectFileFormat ProjectFileFormat默认为default 也即是其应该在UBT工作时重新赋值。
之后几经辗转 找到赋值函数,为:WindowsCompiler GetDefaultCompiler()
其在\Engine\Source\Programs\UnrealBuildTool\Platform\Windows\UEBuildWindows.cs中
具体代码如下:internal static WindowsCompiler GetDefaultCompiler() { // If there's no specific compiler set, try to pick the matching compiler for the selected IDE object ProjectFormatObject; if (XmlConfig.TryGetValue(typeof(VCProjectFileGenerator), "Version", out ProjectFormatObject)) { VCProjectFileFormat ProjectFormat = (VCProjectFileFormat)ProjectFormatObject; if (ProjectFormat == VCProjectFileFormat.VisualStudio2017) { return WindowsCompiler.VisualStudio2017; } else if (ProjectFormat == VCProjectFileFormat.VisualStudio2015) { return WindowsCompiler.VisualStudio2015; } } // Second, default based on what's installed, test for 2015 first DirectoryReference VCInstallDir; if (TryGetVCInstallDir(WindowsCompiler.VisualStudio2015, out VCInstallDir)) { return WindowsCompiler.VisualStudio2015; } if (TryGetVCInstallDir(WindowsCompiler.VisualStudio2017, out VCInstallDir)) { return WindowsCompiler.VisualStudio2017; } // If we do have a Visual Studio installation, but we're missing just the C++ parts, warn about that. DirectoryReference VSInstallDir; if (TryGetVSInstallDir(WindowsCompiler.VisualStudio2015, out VSInstallDir)) { Log.TraceWarning("Visual Studio 2015 is installed, but is missing the C++ toolchain. Please verify that \"Common Tools for Visual C++ 2015\" are selected from the Visual Studio 2015 installation options."); } else if (TryGetVSInstallDir(WindowsCompiler.VisualStudio2017, out VSInstallDir)) { Log.TraceWarning("Visual Studio 2017 is installed, but is missing the C++ toolchain. Please verify that the \"VC++ 2017 toolset\" component is selected in the Visual Studio 2017 installation options."); } else { Log.TraceWarning("No Visual C++ installation was found. Please download and install Visual Studio 2015 with C++ components."); } // Finally, default to VS2015 anyway return WindowsCompiler.VisualStudio2015; }
不难看出 ,它首先从XML配置文件中找到默认设置,如果没有则开始尝试看查找VCInstall信息。不巧的是,它先测试VS2015。
虽然我没有安装VS2015 但是按照它的测试方法依旧显示成功,也即是能找到VS2015的 VCInstall信息
(个人猜想是由于VS2017兼容VS2015导致的)
于是,修改测试部分代码如下// Second, default based on what's installed, test for 2017 first DirectoryReference VCInstallDir; if (TryGetVCInstallDir(WindowsCompiler.VisualStudio2017, out VCInstallDir)) { return WindowsCompiler.VisualStudio2017; } if (TryGetVCInstallDir(WindowsCompiler.VisualStudio2015, out VCInstallDir)) { return WindowsCompiler.VisualStudio2015; }
也即是让他先尝试VS2017,结果显示也能找到
因此,修改此部分代码,即可。另外一种修改方式就是直接修改
Engine\Source\Programs\UnrealBuildTool\ProjectFiles\VisualStudio\VCProjectFileGenerator.cs中的
VCProjectFileFormat ProjectFileForma默认值为VCProjectFileFormat.VisualStudio2017;
如此修改之后存在问题则是无法通过配置文件修改VS版本。但是胜在方便。