天天看點

Unreal Engine 4:編譯打包Android應用問題彙總

 本文對編譯打包Android應用遇到的問題進行彙總。使用的環境:

android-ndk-r12b

-std=c++14

STL=gnu-libstdc++

目錄

1、error: undefined reference to 'typeinfo for ACharacter'

2、error: exception handling was disabled in PCH file but is currently enabled

3、編譯時總是報waring C4668

4、warning: '__GLIBC__' is not defined, evaluates to 0 [-Wundef]

5、編譯時報"變量重定義"

6、warning: declaration shadows a field of 'BaseAndExponent' [-Wshadow],>

7、error: #pragma once in main file [-Werror,-Wpragma-once-outside-header]

8、gettid() not found

9、error: 'auto_ptr' is deprecated [-Werror,-Wdeprecated-declarations]

10、error: no member named 'to_string' in namespace 'std'

11、Unable to start program UE4.exe error

12、error: illegal character encoding in string literal

13、error: no member named 'stoi' in namespace 'std'

14、Cook failed

15、error: initializer on function does not look like a pure-specifier

16、 error: declaration of 'MODE' shadows template parameter

17、error: explicit specialization of 'getTypeName' in class scope

18、/cryptopp/include/misc.h(1849,9) :  error: use of undeclared identifier 'bswap_16'

19、error: lambda capture 'LocalMapLayoutForCapture' is not used [-Werror,-Wunused-lambda-capture]

20、如何屏蔽螢幕上的 joysticks

21、touch事件觸發了兩次

22、XXX has an inappropriate outermost, it was probably saved with a deprecated outer

1、error: undefined reference to 'typeinfo for ACharacter'

UATHelper: Packaging (Android (ETC1)):   AndroidProject/Module.AndroidProject.cpp-armv7-es2.o:D:/projects/AndroidProject/Intermediate/Build/Android/AndroidProject/Development/AndroidProject/Module.AndroidProject.cpp:typeinfo for AAndroidProjectCharacter: error: undefined reference to 'typeinfo for ACharacter'

UE4引擎中的代碼都是禁用exception和RTTI功能的,如果在使用了UObject的代碼中打開了RTTI,編譯時會報上述錯誤。

如果代碼中要使用throw、typeid()、dynamic_cast()等這些exception和RTII功能應該辦?

(1).将這一部分代碼編譯成第三方動态庫,編譯時打開exception和RTII功能,并且這些第三方提供給外部調用的接口頭檔案中不要有使用了exception和RTII功能的代碼。

(2).将這一部分代碼用單獨的Module封裝,在這個Module不要使用任何用到UObject及其相關子類的代碼。這個Module中單獨打開exception和RTII功能進行編譯。

PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
// 開啟RTTI,支援typeid()
bUseRTTI = true;
// 開啟後支援throw exception
bEnableExceptions = true;           

2、error: exception handling was disabled in PCH file but is currently enabled

 這個問題是由于在生成編譯指令時生成了一個-include "C:/Epic Games/UE_4.18/Engine/Intermediate/Build/Android/UE4/Development/Engine/SharedPCH.Engine.RTTI-armv7-es2.h"

而SharedPCH.Engine.RTTI-armv7-es2.h這個檔案不存在,是以就報錯了。但報錯資訊自身又不對,是以一開始很難找到原因。

暫時的修改方式是不讓UBT生成這條指令:

在C:\Epic Games\UE_4.18\Engine\Source\Programs\UnrealBuildTool\Platform\Android\AndroidToolChain.cs檔案中

注釋掉如下代碼行:

PCHArguments += string.Format(" -include \"{0}\"", InlineArchName(BasePCHName, Arch, GPUArchitecture));            

3、編譯時總是報waring C4668

在C:\Epic Games\UE_4.18\Engine\Source\Programs\UnrealBuildTool\Platform\Windows\VCToolChain.cs中找到

Arguments.Add("/w44668");           

将其改成

Arguments.Add("/wd4668");           

4、warning: '__GLIBC__' is not defined, evaluates to 0 [-Wundef]

在如下檔案中

C:\Epic Games\UE_4.18\Engine\Source\Programs\UnrealBuildTool\Platform\Android\AndroidToolChain.cs

注釋掉

Result += " -Wundef" + (CompileEnvironment.bUndefinedIdentifierWarningsAsErrors ? "" : " -Wno-error=undef");           

5、編譯時報"變量重定義"

在*.Build.cs檔案中添加如下屬性:

// 如果不設定成true,則編譯時會将32個源檔案作為一批全成一個源碼檔案進行編譯,容易出現"變量重定義"等許多問題
bFasterWithoutUnity = true;           

另外,UBT中提供MinSourceFilesForUnityBuildOverride這個參數可以設定一批有多少個源檔案可以合并,但試過後發現沒起作用。

6、warning: declaration shadows a field of 'BaseAndExponent<T, E>' [-Wshadow]

在*.Build.cs檔案中添加如下屬性:

bEnableShadowVariableWarnings = false;           

7、error: #pragma once in main file [-Werror,-Wpragma-once-outside-header]

将*.cpp檔案中的#pragma once去掉

8、gettid() not found

将如下檔案

C:\Epic Games\UE_4.18\Engine\Source\Runtime\Core\Public\Android\AndroidTLS.h中的

return static_cast<uint32>(gettid());
//      return pthread_self();           

修改成

//  return static_cast<uint32>(gettid());
    return pthread_self();           

9、error: 'auto_ptr<msgpack::v1::zone>' is deprecated [-Werror,-Wdeprecated-declarations]

這個錯是說auto_ptr已經棄用了,如果使用了已棄用的API,就會報這個錯。

解決方法,添加

Result += " -Wno-deprecated";            

到如下檔案:

C:\Epic Games\UE_4.18\Engine\Source\Programs\UnrealBuildTool\Platform\Android\AndroidToolChain.cs的如下方法中

string GetCLArguments_Global(CppCompileEnvironment CompileEnvironment, string Architecture)           

10、error: no member named 'to_string' in namespace 'std'

Android NDK中預設使用gnu-libstdc++,而其中的<string>中不包含to_string方法。可能使用std::stringstream替代:

#include <string>
#include <sstream>

class CharTools {
public:
    template<typename T>
    static std::string to_string(T val) {
        std::stringstream ss;
        ss << val;
        return ss.str();
    };
};           

11、Unable to start program UE4.exe error

To fix the issue, you have to right click the game solution from your solution explorer and select the option "Set as StartUp Project" and that should highlight the game solution. Cntrl-F5 will then work.

https://answers.unrealengine.com/questions/218266/unable-to-start-program-ue4exe-error.html

12、error: illegal character encoding in string literal

當TEXT()方法中包含中文字元串時會報這個錯。将代碼源檔案格式調整為UTF-8

13、error: no member named 'stoi' in namespace 'std'

<string>中不包含std::stoi, std::stol, std::stoll, std::stof, std::stod, std::stold

使用如下庫中的函數替代

<cstdlib>

atoi, atol, atoll, atof

std::stoi        atoi

std::stol        atol

std::stoll        atoll

std::stof        atof

std::stod        atof

std::stold        atof

14、Cook failed

[2019.01.16-08.18.14:329][147]UATHelper: Packaging (Android (ETC1)): Took 79.729s to run UE4Editor-Cmd.exe, ExitCode=1

[2019.01.16-08.18.14:330][147]UATHelper: Packaging (Android (ETC1)): Cook failed. Deleting cooked data.

[2019.01.16-08.18.14:992][148]UATHelper: Packaging (Android (ETC1)): ERROR: Cook failed.

将<ProjectName>/Saved下的内容全部删除

将<ProjectName>/Intermediate下除ProjectFiles目錄外的其它的内容全部删除

然後重新編譯

15、error: initializer on function does not look like a pure-specifier

純虛函數的預設方法體要分别寫在頭檔案和定義檔案中,clang++不支援将它們都寫在頭檔案中

// ValueBoxType.h
class ValueBoxType {
    public:
        virtual ~ValueBoxType() = 0 {};
};           

改成:

// ValueBoxType.h
class ValueBoxType {
    public:
        virtual ~ValueBoxType() = 0;
};

// ValueBoxType.cpp
ValueBoxType::~ValueBoxType() {
};           

16、 error: declaration of 'MODE' shadows template parameter

類模闆和類中的方法模闆使用了相同的模闆變量名時

17、error: explicit specialization of 'getTypeName' in class scope

函數特化時要在.h檔案中聲明,要在.cpp檔案中定義

18、/cryptopp/include/misc.h(1849,9) :  error: use of undeclared identifier 'bswap_16'

如果使用了第三方庫cryptopp,則會報上面的錯。修改方式為注釋掉misc.h中的一行:

#if defined(__GNUC__) && defined(__linux__)

//#define CRYPTOPP_BYTESWAP_AVAILABLE

#include <byteswap.h>

#endif

19、error: lambda capture 'LocalMapLayoutForCapture' is not used [-Werror,-Wunused-lambda-capture]

在如下檔案中

C:\Epic Games\UE_4.18\Engine\Source\Programs\UnrealBuildTool\Platform\Android\AndroidToolChain.cs

将如下代碼行

Result += " -Wno-unused-lambda-capture";             

注釋掉。

20、如何屏蔽螢幕上的 joysticks

Project Settings:

Engine     -> Input        -> Moblie                 ->  Default Touch Interface (clear)

21、touch事件觸發了兩次

Project Settings:

Engine     -> Input        -> Mouse Properties       ->  Use Mouse for touch   (Disable)

Engine     -> Input        -> Moblie                 ->  Always show touch interface (Disable)

22、XXX has an inappropriate outermost, it was probably saved with a deprecated outer

具體錯誤資訊如下:

LogLinker: Error: HOTRELOADED_SceneGameMode_0 has an inappropriate outermost, it was probably saved with a deprecated outer (file: /Projects/Content/Widget/W_Error.uasset) 

這個問題是由于W_Error.uasset中使用的SceneGameMode發生改動造成的。解決方式:删除W_Error中所有用到的SceneGameMode,然後重新建立SceneGameMode即可。

繼續閱讀