UE4 4.18.3 源码版 使用VS2017 BUG 及修复方法

前段时间用INVIDIA Gameworks,合编了一个4.18.3的整合版本。电脑系统刚重装,只安装了VS2017,使用VS2017编译引擎后发现一个小问题,具体如下:
使用VS2017编译版本引擎创建新的C++工程时 出现无法打开VisualStudio问题
因此,简单研究了UE4 与vs 调用之间的关系,大致总结如下:


  1. 非源码版引擎更改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.
    

    简单说,对于已经创建的项目,修改这个配置不再起作用,不过对于新建的项目,则会应用这些配置。

  2. 源码编译版引擎
    源码编译版引擎与上诉情况其实类似,但是对于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版本。但是胜在方便。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值