• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

逍遥流

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

Unreal插件 pragma optimize编译错误问题的排查与解决

Unreal各种编译模式与宏的对应关系

UE文档: https://docs.unrealengine.com/en-US/Programming/Development/BuildConfigurations

对应关系,仔细看下面这个函数就一目了然:

EBuildConfigurations::Type FApp::GetBuildConfiguration()
{
#if UE_BUILD_DEBUG
	return EBuildConfigurations::Debug;

#elif UE_BUILD_DEVELOPMENT
	return bIsDebugGame ? EBuildConfigurations::DebugGame : EBuildConfigurations::Development;

#elif UE_BUILD_SHIPPING
	return EBuildConfigurations::Shipping;

#elif UE_BUILD_TEST
	return EBuildConfigurations::Test;

#else
	return EBuildConfigurations::Unknown;
#endif
}

特别注意的是, Development模式和DebugGame模式对应的宏都是: UE_BUILD_DEVELOPMENT

每种编译模式都可以和Editor模式组合,区分Editor模式的宏是: WITH_EDITOR

例如,判断当前是否Development模式的唯一正确方法:

#include "Misc/App.h"
FApp::GetBuildConfiguration() == EBuildConfigurations::Development

pragma optimize编译错误问题背景

需要发布一版最新插件,因为要部署给用户用,编译模式必须是: Development Editor

然而发布的过程中,使用Debug模式可以编译出来,但是切换为Development Editor模式却有编译错误:

xxxxx.cpp: error C4426: optimization flags changed after including header, may be due to #pragma optimize()

听取同事的建议,将#pragma optimize("", on)切换为#pragma optimize("", off),也还是不能跳过这个编译错误

我把项目里的所有#pragma optimize都注释掉,也还是一样的错误。

排查过程

因为迫切需要发布最新插件,所以我下定决心排查下到底是什么问题。

我就开始排除大法,

  1. 首先,根据错误提示,问题肯定出在xxxxx.cpp里
  2. 我先怀疑是xxxxx.cpp里include不该include的头文件,所以先把所有include都干掉;结果还是有这个错误
  3. 继续缩小范围,xxxxx.cpp里所有的函数实现都注释掉,所有函数体直接return,结果还是有这个错误
  4. 最后一看,这个文件里除了空函数,就剩下了如下的宏:
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION

然后我就开始跟这个宏定义BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION,代码摘抄如下:


// SlateOptMacros.h
#define BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION BEGIN_FUNCTION_BUILD_OPTIMIZATION
#define END_SLATE_FUNCTION_BUILD_OPTIMIZATION   END_FUNCTION_BUILD_OPTIMIZATION

//Platform.h
#define BEGIN_FUNCTION_BUILD_OPTIMIZATION PRAGMA_DISABLE_OPTIMIZATION

//CoreMiscDefines.h
#define PRAGMA_DISABLE_OPTIMIZATION		PRAGMA_DISABLE_OPTIMIZATION_ACTUAL
#if UE_BUILD_DEBUG
	#define PRAGMA_ENABLE_OPTIMIZATION  PRAGMA_DISABLE_OPTIMIZATION_ACTUAL
#else
	#define PRAGMA_ENABLE_OPTIMIZATION  PRAGMA_ENABLE_OPTIMIZATION_ACTUAL
#endif

//WindowsPlatform.h
#if !defined(__clang__)
	#define PRAGMA_DISABLE_OPTIMIZATION_ACTUAL __pragma(optimize("",off))
	#define PRAGMA_ENABLE_OPTIMIZATION_ACTUAL  __pragma(optimize("",on))
#elif defined(_MSC_VER)		// Clang only supports __pragma with -fms-extensions
	#define PRAGMA_DISABLE_OPTIMIZATION_ACTUAL __pragma(clang optimize off)
	#define PRAGMA_ENABLE_OPTIMIZATION_ACTUAL  __pragma(clang optimize on)
#endif

阅读代码,发现BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION, 其实就相当于执行了一次#pragma optimize

当前编译用的是Development Editor模式,所以执行的是#pragma optimize("", on)

临时方案

由于背景中编译错误的意思就是: 在文件中xxxxx.cpp改变了#pragma optimize的值导致

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION会把#pragma optimize打开,所以我就在xxxxx.cpp的结尾加了行是#pragma optimize("", off),结果就可以编译通过了。

我接着仔细分析这个宏,因为BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION具体执行的on或off,取决于当前的编译模式。

因此,当编译模式改为Debug模式后,我加的这行又会造成编译错误;所以这不是最终方案

最终方案

  1. 在整个工程中搜索BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION,看其他地方是怎么用BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION的。

  2. 发现其他地方,只要写了BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION,都会有END_SLATE_FUNCTION_BUILD_OPTIMIZATION

  3. 于是我把#pragma optimize("", off)替换为END_SLATE_FUNCTION_BUILD_OPTIMIZATION,也是可以编译通过了。

  4. 跟了一下END_SLATE_FUNCTION_BUILD_OPTIMIZATION,发现他的逻辑和BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION是完全对称的

  5. 把插件中的其他#pragma optimize语句全部干掉,结果也是ok的

经验与反思

主要3条经验

  1. 解决C++编译问题,束手无策的时候可以试试排除大法

  2. 不要在工程里手写任何类似#pragma optimize的语句,因为这样写的话,切换UE的编译模式一定会有编译错误

  3. 一个文件里,加了BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION,千万别忘了加END_SLATE_FUNCTION_BUILD_OPTIMIZATION

Q: 之前同事的建议,将xxxxx.cpp的#pragma optimize("", on)切换为#pragma optimize("", off),也还是不能跳过这个编译错误的原因是什么?

A: 因为xxxxx.cpp里的#pragma optimize写在的文件的头部, 改完之后,先执行的为#pragma optimize("", off), 后执行的BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION,所以等于没改。

posted on 2021-03-07 22:41  逍遥流  阅读(445)  评论(1)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3