我之前的文章 Build protobuf with MSVC on Windows 中介绍了在 Windows 上使用 MSVC 编译 Protobuf,最近的项目中有用到 Protobuf,就把 Protobuf 集成 UE4 做了一个插件,无需在系统和项目设置中添加任何环境变量以及文件包含,也不需要考虑 protobuf 的lib的链接,方便在项目中使用,并且对 UE 不兼容 cc 格式写了编辑器插件,.pb.cc都会被转换为pb.cpp。
Was only expecting C++ files to have CachedCPPEnvironments!
写了个插件在 UE 中使用 protobuf,在从 proto 文件生成 .cc/.h 之后编译报这个错误,分析了一下是 UBT 的代码文件类型不支持.cc。
1 2 3 4
1>------ Build started: Project: GWorld, Configuration: Development x64 ------ 1>Using 'git status' to determine working set for adaptive non-unity build (C:\Users\imzlp\Documents\Unreal Projects\GWorld). 1>UnrealBuildTool : error : Was only expecting C++ files to have CachedCPPEnvironments! 1>(see ../Programs/UnrealBuildTool/Log.txt for full exception trace)
publicboolIsActionOutdated(BuildConfiguration BuildConfiguration, UEBuildTarget Target, CPPHeaders Headers, Action RootAction, bool bIsAssemblingBuild, bool bNeedsFullCPPIncludeRescan, Dictionary<Action, bool> OutdatedActionDictionary, ActionHistory ActionHistory, Dictionary<UEBuildTarget, List<FileItem>> TargetToOutdatedPrerequisitesMap) { // ... // @todo ubtmake: we may be scanning more files than we need to here -- indirectly outdated files are bIsOutdated=true by this point (for example basemost includes when deeper includes are dirty) if (bIsOutdated && RootAction.ActionType == ActionType.Compile)// @todo ubtmake: Does this work with RC files? See above too. { Log.TraceVerbose("Outdated action: {0}", RootAction.StatusDescription); foreach (FileItem PrerequisiteItem in RootAction.PrerequisiteItems) { if (PrerequisiteItem.CachedIncludePaths != null) { if (!IsCPPFile(PrerequisiteItem)) { thrownew BuildException("Was only expecting C++ files to have CachedCPPEnvironments!"); } Log.TraceVerbose(" -> DEEP include scan: {0}", PrerequisiteItem.AbsolutePath);
List<FileItem> OutdatedPrerequisites; if (!TargetToOutdatedPrerequisitesMap.TryGetValue(Target, out OutdatedPrerequisites)) { OutdatedPrerequisites = new List<FileItem>(); TargetToOutdatedPrerequisitesMap.Add(Target, OutdatedPrerequisites); }
/// <summary> /// Checks if the specified file is a C++ source file /// </summary> /// <param name="FileItem">The file to check</param> /// <returns>True if this is a C++ source file</returns> privatestaticboolIsCPPFile(FileItem FileItem) { returnIsCPPImplementationFile(FileItem) || IsCPPIncludeFile(FileItem) || IsCPPResourceFile(FileItem); }
/// <summary> /// Checks if the specified file is a C++ source implementation file (e.g., .cpp) /// </summary> /// <param name="FileItem">The file to check</param> /// <returns>True if this is a C++ source file</returns> privatestaticboolIsCPPImplementationFile(FileItem FileItem) { return (FileItem.AbsolutePath.EndsWith(".cpp", StringComparison.InvariantCultureIgnoreCase) || FileItem.AbsolutePath.EndsWith(".c", StringComparison.InvariantCultureIgnoreCase) || FileItem.AbsolutePath.EndsWith(".mm", StringComparison.InvariantCultureIgnoreCase)); }
/// <summary> /// Checks if the specified file is a C++ source header file (e.g., .h or .inl) /// </summary> /// <param name="FileItem">The file to check</param> /// <returns>True if this is a C++ source file</returns> privatestaticboolIsCPPIncludeFile(FileItem FileItem) { return (FileItem.AbsolutePath.EndsWith(".h", StringComparison.InvariantCultureIgnoreCase) || FileItem.AbsolutePath.EndsWith(".hpp", StringComparison.InvariantCultureIgnoreCase) || FileItem.AbsolutePath.EndsWith(".inl", StringComparison.InvariantCultureIgnoreCase)); }
/// <summary> /// Checks if the specified file is a C++ resource file (e.g., .rc) /// </summary> /// <param name="FileItem">The file to check</param> /// <returns>True if this is a C++ source file</returns> privatestaticboolIsCPPResourceFile(FileItem FileItem) { return (FileItem.AbsolutePath.EndsWith(".rc", StringComparison.InvariantCultureIgnoreCase)); }