[UE4][Android NDK]OpenSSL Linking Issues
keywords: UE4, Android NDK, OpenSSL, SSL, curl, libcurl.a, libssl.a, libcrypto.a
Issue 1: multiple definition of functions of ssl
Error log when building Android package:
D:/sdks/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: G:/EpicGames/UnrealEngine4.22/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(s23_clnt.o): multiple definition of 'ssl_fill_hello_random'
UATHelper: Packaging (Android (ASTC)): D:/sdks/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld:
UATHelper: Packaging (Android (ASTC)): D:/sdks/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: G:/EpicGames/UnrealEngine4.22/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(s3_both.o): multiple definition of 'ssl3_do_write'
UATHelper: Packaging (Android (ASTC)): D:/sdks/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld:
UATHelper: Packaging (Android (ASTC)): D:/sdks/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: G:/EpicGames/UnrealEngine4.22/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(s3_both.o): multiple definition of 'ssl3_output_cert_chain'
UATHelper: Packaging (Android (ASTC)): D:/sdks/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld:
UATHelper: Packaging (Android (ASTC)): D:/sdks/Android/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: G:/EpicGames/UnrealEngine4.22/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(s3_both.o): multiple definition of 'ssl_cert_type'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_unload_strings'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_put_error'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_get_state'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_clear_error'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_get_error'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_get_error_line'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_get_error_line_data'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_peek_error'
PackagingResults: Error: G:/EpicGames/UnrealEngine422_spatialos/Engine/Source/ThirdParty/libcurl/lib/Android/ARMv7/libcurl.a(err.o): multiple definition of 'ERR_peek_error_line'
Caused by:
The libcurl.a
that was included in engine has included openssl library.
libcurl.a
path:
\Engine\Source\ThirdParty\libcurl\lib\Android\ARM64\libcurl.a
Solution:
Replace libcurl.a
with a pure curl library.
Download curl sources:
https://github.com/dawnarc/libcurl_in_pure_llvm
Issue 2: undefined reference to ‘X509_STORE_CTX_get_chain’
Error log when building Android package:
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslCertificateManager.cpp:183: error: undefined reference to 'X509_STORE_CTX_get_chain'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslCertificateManager.cpp:184: error: undefined reference to 'sk_num'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslCertificateManager.cpp:211: error: undefined reference to 'sk_value'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:44: error: undefined reference to 'SSL_load_error_strings'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:46: error: undefined reference to 'SSL_library_init'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:47: error: undefined reference to 'OPENSSL_add_all_algorithms_noconf'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:66: error: undefined reference to 'EVP_cleanup'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:67: error: undefined reference to 'CRYPTO_cleanup_all_ex_data'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:68: error: undefined reference to 'ERR_free_strings'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:70: error: undefined reference to 'CONF_modules_free'
G:\EpicGames\UnrealEngine4.22\Engine\Source\Runtime\Online\SSL\Private/SslManager.cpp:82: error: undefined reference to 'SSLv23_client_method'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
Caused by:
OpenSSL version used in engine is too old, so new functions of ssl were not supported in UE4.
Old ssl library path:
\Engine\Source\ThirdParty\OpenSSL\1_0_2h\lib\Android\ARM64\libssl.a
Solution:
Modify building configuration.
Building configuration path:
\Engine\Source\ThirdParty\OpenSSL\OpenSSL.Build.cs
Origin:
else if (Target.Platform == UnrealTargetPlatform.Android)
{
string IncludePath = OpenSSL101sPath + "/include/Android";
PublicIncludePaths.Add(IncludePath);
// unneeded since included in libcurl
// string LibPath = Path.Combine(OpenSSL101sPath, "lib", PlatformSubdir);
//PublicLibraryPaths.Add(LibPath);
}
New:
else if (Target.Platform == UnrealTargetPlatform.Android)
{
string IncludePath = OpenSSL111Path + "/include/Android/ARMv7";
string LibraryPath = OpenSSL111Path + "/lib/Android";
PublicIncludePaths.Add(IncludePath);
PublicAdditionalLibraries.Add(LibraryPath + "/libssl.a");
PublicAdditionalLibraries.Add(LibraryPath + "/libcrypto.a");
}
then replace libssl.a
with new version building library.
destination directory:
\Engine\Source\ThirdParty\OpenSSL\1.1.1\Lib\Android
Download NDK library of 1.1.1 ssh:
https://github.com/leenjewel/openssl_for_ios_and_android/releases/tag/android_openssl-1.1.1a
Issue 3: expected unqualified-id uint32_t xor;
Error log when building Android package:
include\internal/constant_time_locl.h:274:18: error: expected unqualified-id uint32_t xor = *a ^ *b;
Caused by:
xor
is a keyword of Clang.
Solution:
Rename variables;
Issue 4: use of undeclared identifier ‘strtof_l’
Error log when building Android package:
D:/sdks/Android/android-ndk-r16b/sources/cxx-stl/llvm-libc++/include\locale(807,12): error: use of undeclared identifier 'strtof_l'
return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
^
D:/sdks/Android/android-ndk-r16b/sources/cxx-stl/llvm-libc++/include\locale(813,12): error: use of undeclared identifier 'strtod_l'; did you mean 'strtold_l'?
return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
^
D:/sdks\Android\android-ndk-r16b\sysroot\usr\include\stdlib.h(237,13): note: 'strtold_l' declared here
long double strtold_l(const char* __s, char** __end_ptr, locale_t __l) __INTRODUCED_IN(21);
^
2 errors generated.
Error: use of undeclared identifier 'strtof_l'
Error: use of undeclared identifier 'strtod_l'; did you mean 'strtold_l'?
Caused by:
NDK version is too old.
Solution:
Switch NDK version to newer versoin.
扛得住事儿,就是才华横溢。