目录
一、错误描述
二、问题分析
三、解决方法
四、效果验证
五、后记
一、错误描述
采用IL2CPP生成的时候,出现了4个错误:
(1)Building Library\Bee\artifacts\WinPlayerBuildProgram\ei6vj\ku08_i_vm6.lump.obj failed with output:
(2)BuildFailedException: Incremental Player build failed!
(3)Build completed with a result of ‘Failed’ in 19 seconds (18657 ms)
(4)UnityEditor.BuildPlayerWindow+BuildMethodException: 3 errors
之前能成功生成的程序,就这样报错了。
二、问题分析
这个程序明明几个月前才编译过,为啥突然不行了,也在网上做了搜索,所得到的回答均不尽如人意,仔细思考,这种情况会不会跟本机环境有关?而容易出问题的地方更多是在IL转换成C++代码,然后编译生成的过程里,回到前述4个错误,后面3个,更多是描述问题的结果,第1个是问题关键,提示了在编译生成中间文件时出错了。
查看第一个错误:
Building Library\Bee\artifacts\WinPlayerBuildProgram\ei6vj\ku08_i_vm6.lump.obj failed with output:
可看到以下细节(该obj文件名可以是*_vm6.lump.obj,因中间文件名字可能变化):
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(71): error C2039: 'hash_compare': is not a member of 'stdext'
- C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.34.31933\include\iterator(1426): note: see declaration of 'stdext'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(71): error C2065: 'hash_compare': undeclared identifier
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(71): error C2275: 'Key': expected an expression instead of a type
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(38): error C2976: 'Il2CppReaderWriterLockedHashMap': too few template arguments
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(75): note: see declaration of 'Il2CppReaderWriterLockedHashMap'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(38): error C2974: 'Il2CppReaderWriterLockedHashMap': invalid template argument for 'HashFcn', type expected
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(75): note: see declaration of 'Il2CppReaderWriterLockedHashMap'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(38): error C2955: 'Il2CppReaderWriterLockedHashMap': use of class template requires template argument list
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(75): note: see declaration of 'Il2CppReaderWriterLockedHashMap'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(47): error C2955: 'Il2CppReaderWriterLockedHashMap': use of class template requires template argument list
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(75): note: see declaration of 'Il2CppReaderWriterLockedHashMap'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(385): error C2662: 'bool Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::TryGet(const Il2CppHashMap<Key,T,HashFcn,EqualKey,Alloc>::key_type &,T *)': cannot convert 'this' pointer from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc> &'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(385): note: Reason: cannot convert from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(385): note: Conversion requires a second user-defined-conversion operator or constructor
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(90): note: see declaration of 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::TryGet'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(385): note: while trying to match the argument list '(Il2CppClass *, Il2CppClass **)'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(438): error C2662: 'bool Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::Add(const Il2CppHashMap<Key,T,HashFcn,EqualKey,Alloc>::key_type &,const T &)': cannot convert 'this' pointer from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc> &'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(438): note: Reason: cannot convert from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(438): note: Conversion requires a second user-defined-conversion operator or constructor
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(102): note: see declaration of 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::Add'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(438): note: while trying to match the argument list '(Il2CppClass *, Il2CppClass *)'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): error C2955: 'Il2CppReaderWriterLockedHashMap': use of class template requires template argument list
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(75): note: see declaration of 'Il2CppReaderWriterLockedHashMap'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): error C2662: 'Il2CppHashMap<Key,T,HashFcn,EqualKey,Alloc>::iterator Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::UnlockedBegin(void)': cannot convert 'this' pointer from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc> &'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): note: Reason: cannot convert from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): note: Conversion requires a second user-defined-conversion operator or constructor
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(121): note: see declaration of 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::UnlockedBegin'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): note: while trying to match the argument list '()'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): error C2662: 'Il2CppHashMap<Key,T,HashFcn,EqualKey,Alloc>::iterator Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::UnlockedEnd(void)': cannot convert 'this' pointer from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc> &'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): note: Reason: cannot convert from 'PointerTypeMap' to 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): note: Conversion requires a second user-defined-conversion operator or constructor
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\utils\Il2CppHashMap.h(127): note: see declaration of 'Il2CppReaderWriterLockedHashMap<Key,T,HashFcn,EqualKey,Alloc>::UnlockedEnd'
- C:\Program Files\Unity\Hub\Editor\2022.1.22f1\Editor\Data\il2cpp\libil2cpp\vm\MetadataCache.cpp(1157): note: while trying to match the argument list '()'
- UnityEditor.BuildPlayerWindow:BuildPlayerAndRun ()
排除网上所说的UnityEditor导致的可能后,焦点就落在了STL上了,具体来说就是unordered_map替代hash_map这个问题。hash_map是一个非标准的STL容器,一般来说是要用unordered_map去替代它,但是IL2CPP是机器生成C++代码,修改自动生成代码不太现实,故得从错误忽略着手,如我们常用的宏定义:
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
因此,对于Unity3D,我们可以通过添加错误忽略的方法处理。
三、解决方法
(1)环境变量方法(修改_CL_值):
添加环境变量_CL_,变量值为/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS。在MSVC编译生成的时候加入“/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS”对
(2)临时改变CL编译选项:
在Unity3D项目中添加C#脚本(可任意位置添加),在预处理生成时,添加C++编译选项
“/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS”。
-
#if UNITY_EDITOR using System; using UnityEditor.Build; using UnityEditor.Build.Reporting; public class MsvcStdextWorkaround : IPreprocessBuildWithReport { const string kWorkaroundFlag = "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS"; public int callbackOrder => 0; public void OnPreprocessBuild(BuildReport report) { var clEnv = Environment.GetEnvironmentVariable("_CL_"); if (string.IsNullOrEmpty(clEnv)) { Environment.SetEnvironmentVariable("_CL_", kWorkaroundFlag); } else if (!clEnv.Contains(kWorkaroundFlag)) { clEnv += " " + kWorkaroundFlag; Environment.SetEnvironmentVariable("_CL_", clEnv); } } } #endif // UNITY_EDITOR
四、效果验证
忽略掉hash_map/unorder_map错误后,正确生成程序:
五、后记
在解决这个问题的时候,尝试了非百度的搜索引擎搜索前文中第一个错误,能在Unity3D官网寻找到解决办法。Unity3D官方论坛上说这是微软MSVC编译器(或者说Visual Studio)的一个BUG,但仔细思考,我反而认为问题还是在于应用标准STL容器unordered_map替代hash_map的问题,该问题的产生应该还是出在IL2CPP将Unity3D脚本生成的MSIL汇编转换为C++的过程中,对C#容器采用hash_map来“翻译”而导致。
参考链接:
(1)BUG: Unity 2022.1.22f1 with IL2CPP not working:https://forum.unity.com/threads/unity-2022-1-22f1-with-il2cpp-not-working.1359580/文章来源:https://www.toymoban.com/news/detail-780475.html
(2)BUG: IL2CPP error on Building for Windows: https://forum.unity.com/threads/il2cpp-error-on-building-for-windows.1351589/文章来源地址https://www.toymoban.com/news/detail-780475.html
到了这里,关于一次Unity3D IL2CPP 打包错误的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!