Unreal.js-core icon indicating copy to clipboard operation
Unreal.js-core copied to clipboard

V8-7.4.288 is missing libtorque_base.a

Open getnamo opened this issue 5 years ago • 21 comments

https://github.com/ncsoft/Unreal.js-core/releases/tag/V8-7.4.288 (and 4.22 marketplace build) is missing libtorque_base.a for android (and iOS), but it's still referenced in the android build.cs section causing a linking error, what's the best way to build or download this file?

The V8 module is also not whitelisted so it will not get compiled and it will show up as missing when trying to load a script via Javascript Component on device.

getnamo avatar May 25 '19 00:05 getnamo

https://github.com/ncsoft/Unreal.js-core/commit/2c1d8d6cd99644282b8b4692b81a9eda247c7383 Fixed.

crocuis avatar May 25 '19 12:05 crocuis

That unfortunately doesn't fix it. I used a similar fix to see if it would work without that particular lib.

Compiling android for arm64 first resulted in a bunch of errors like these

In file included from .../Plugins/UnrealJS/Intermediate/Build/Android/UE4/Development/V8/Module.V8.cpp:7:
2>...\Plugins\UnrealJS\Source\V8\Private\JavascriptContext_Private.cpp(1337,3): error : ignoring return value of function declared with 'warn_unused_result' attribute [-Werror,-Wunused-result]
2>                  global->Set(ctx, V8_KeywordString(isolate(), "CreateClass"), FunctionTemplate::New(isolate(), fn, self)->GetFunction(ctx).ToLocalChecked());

which can be fixed with prepending void to each setting operation eg.

(void)global->Set(ctx, V8_KeywordString(isolate(), "CreateClass"), FunctionTemplate::New(isolate(), fn, self)->GetFunction(ctx).ToLocalChecked());

and a few const L char const casts to fix L use in android compile chain.

These fixes can be found here (https://github.com/getnamo/Unreal.js-core/commit/baacac70eadb146a8f07f0ce93ff3652cdc14917), pull https://github.com/ncsoft/Unreal.js-core/pull/44

That then brings the issue to the linker which stops with

2>  [1/3] Module.V8.cpp [arm64-es2]
2>  [2/3] TestProject-arm64-es2.so
2>  .../Plugins/Unreal.js-core/ThirdParty/v8/lib/Android/ARM64/libv8_base.a: error adding symbols: Malformed archive
2>clang++.exe : error : linker command failed with exit code 1 (use -v to see invocation)

Which is where I'm currently hitting a roadblock. Some possible follow ups: stack overflow similar question: https://stackoverflow.com/questions/55254088/malformed-archive-while-compiling-v8, google groups: https://groups.google.com/forum/#!topic/v8-users/WH_Az7NRG2k

Hints at maybe the libs were compiled are the 'thin' variant when they should be standalone/full type? What's your pipeline for compiling the android variants for v8?

Edit update: Looking at the file sizes compared to win64, mac, and iOS, the Linux and Android libs seem much much smaller in size (5MB Android vs 618MB win64 vs 2GB for iOS). It does hint at libs being compiled as a thin archive. Another link about building v8 for android on e.g. linux (https://gist.github.com/magmastonealex/a9158173828932def9ffb81672d6c578)

getnamo avatar May 26 '19 19:05 getnamo

Btw compiling for armv7 instead of arm64 gives these errors

UATHelper: Packaging (Android (ASTC)):     C:/NVPACK/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: cannot open C:/Users/.../TestProject/Plugins/Unreal.js-core/ThirdParty/v8/lib/Android/ARM64/v8_base/api.o: No such file o
r directory
UATHelper: Packaging (Android (ASTC)):     C:/NVPACK/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: cannot open C:/Users/.../TestProject/Plugins/Unreal.js-core/ThirdParty/v8/lib/Android/ARM64/v8_libplatform/default-platfo
rm.o: No such file or directory
UATHelper: Packaging (Android (ASTC)):     C:/NVPACK/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: cannot open C:/Users/.../TestProject/Plugins/Unreal.js-core/ThirdParty/v8/lib/Android/ARM64/inspector/v8-inspector-impl.o
: No such file or directory

and a ton of

UATHelper: Packaging (Android (ASTC)):     C:/Users/.../TestProject/Plugins/Unreal.js-core/ThirdParty/v8/include/v8.h:7457: error: undefined reference to 'v8::Isolate::Enter()'
UATHelper: Packaging (Android (ASTC)):     C:\Users\...\TestProject\Plugins\Unreal.js-core\Source\V8\Private/Delegates.cpp:304: error: undefined reference to 'v8::HandleScope::HandleScope(v8::Isolate*)'
UATHelper: Packaging (Android (ASTC)):     C:/Users/.../TestProject/Plugins/Unreal.js-core/ThirdParty/v8/include/v8.h:9716: error: undefined reference to 'v8::HandleScope::CreateHandle(v8::internal::Isolate*, unsigned int)'

Not sure if the more verbose errors points to this being a armv7 lib with missing links or arm64 lib built incorrectly (thin variant?).

Edit update: likely thin arm64 archive variant problem, see previous comment.

getnamo avatar May 26 '19 19:05 getnamo

I had same thin archive problem. After I removed thin archive option, there were bunch of link errors implying that stdlib is mismatching. Actually UE4 still uses libstdc++ on Android but v8 uses only libc++. Now I am trying to modify v8 build config to force using libstdc++.

nullbus avatar Jun 18 '19 09:06 nullbus

I managed to get it compiled and linked successfully, but still there is runtime crash during class exposure.

Here is my configuration and code modifications(arm64 only).

$ cat out/ReleaseAndroid/args.gn
v8_use_external_startup_data = false
v8_use_snapshot = false
v8_enable_i18n_support = false
is_debug = false
v8_static_library = true
is_component_build = false
target_os = "android"
target_cpu = "arm64"
v8_target_cpu = "arm64"
use_custom_libcxx = false         # important
use_custom_libcxx_for_host = true # important
diff --git a/config/android/BUILD.gn b/config/android/BUILD.gn
index b69d42b..1c4562e 100644
--- a/config/android/BUILD.gn
+++ b/config/android/BUILD.gn
@@ -105,9 +105,17 @@ config("runtime_library") {
   # arm-linux-androideabi-4.4.3 toolchain (circa Gingerbread) will exhibit
   # strange errors. The include ordering here is important; change with
   # caution.
-  cflags_cc = [ "-isystem" +
-                rebase_path("$android_ndk_root/sources/android/support/include",
-                            root_build_dir) ]
+  cflags_cc = [
+    "-isystem" +
+        rebase_path("$android_ndk_root/sources/android/support/include",
+                    root_build_dir),
+    "-isystem" +
+        rebase_path("$android_ndk_root/sources/cxx-stl/gnu-libstdc++/4.9/include",
+                    root_build_dir),
+    "-isystem" +
+        rebase_path("$android_ndk_root/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/include",
+                    root_build_dir),
+  ]

   defines = [
     "__GNU_SOURCE=1",  # Necessary for clone().
diff --git a/config/compiler/BUILD.gn b/config/compiler/BUILD.gn
index 402dac4..14a5a81 100644
--- a/config/compiler/BUILD.gn
+++ b/config/compiler/BUILD.gn
@@ -1456,7 +1456,8 @@ config("default_warnings") {

       # Don't warn about "maybe" uninitialized. Clang doesn't include this
       # in -Wall but gcc does, and it gives false positives.
-      cflags += [ "-Wno-maybe-uninitialized" ]
+      # cflags += [ "-Wno-maybe-uninitialized" ]
+      cflags += [ "-Wno-uninitialized" ]
       cflags += [ "-Wno-deprecated-declarations" ]

       # -Wcomment gives too many false positives in the case a
@@ -1709,7 +1710,7 @@ config("thin_archive") {
   # have a "thin archive" mode (it does accept -T, but it means truncating
   # archive names to 16 characters, which is not what we want).
   if ((is_posix && !is_nacl && !is_mac && !is_ios) || is_fuchsia) {
-    arflags = [ "-T" ]
+    # arflags = [ "-T" ]
   } else if (is_win && use_lld) {
     arflags = [ "/llvmlibthin" ]
   }

These build script modifications cause some compile errors but you can easily fix them except std::to_string. For gnustl it doesn't have std::to_string and there is no alternative so you need to write the implementation.

nullbus avatar Jun 20 '19 09:06 nullbus

Please update to https://github.com/ncsoft/Unreal.js/wiki/V8 :)

crocuis avatar Jun 20 '19 09:06 crocuis

I'd like to, but I should resolve existing runtime and other problems before posting whole solution. I think it takes some time...

nullbus avatar Jun 23 '19 02:06 nullbus

@nullbus got a link to the libstd++ build of v8 for arm64? I wouldn't mind looking into the runtime crashes to see if I can't help you identify what's missing.

Also do we know if v8 has to be jitless for android? https://v8.dev/blog/jitless, or is this not an issue?

getnamo avatar Jul 14 '19 00:07 getnamo

@getnamo I couldn't take this issue recently because of my business. I returned to this end of the week. If you want you can build libstdc++ version with modifications I mentioned above.

jitless mode is necessary for iOS, because it forbids writing on execution memory. I think jit would be working on most of Android devices.

nullbus avatar Jul 14 '19 11:07 nullbus

Here is updated modification.

diff --git a/config/BUILDCONFIG.gn b/config/BUILDCONFIG.gn
index 9e843f3..6e718e1 100644
--- a/config/BUILDCONFIG.gn
+++ b/config/BUILDCONFIG.gn
@@ -438,7 +438,6 @@ default_compiler_configs = [
   "//build/config/compiler:no_exceptions",
   "//build/config/compiler:no_rtti",
   "//build/config/compiler:runtime_library",
-  "//build/config/compiler:thin_archive",


   "//build/config/coverage:default_coverage",
   "//build/config/sanitizers:default_sanitizer_flags",
 ]
diff --git a/config/android/BUILD.gn b/config/android/BUILD.gn
index b69d42b..c2c0897 100644
--- a/config/android/BUILD.gn
+++ b/config/android/BUILD.gn
@@ -27,6 +27,9 @@ config("compiler") {
     # Forces full rebuilds on NDK rolls. To rebuild everything when NDK version
     # stays the same, increment the suffix number.
     "ANDROID_NDK_VERSION_ROLL=${android_ndk_version}_1",
+    "_GLIBCXX_USE_C99=1",
+    "_GLIBCXX_HAVE_WCSTOF=1",
+    "_GLIBCXX_USE_C99_MATH_TR1=1",
   ]

   if (current_cpu == "mips64el") {
@@ -109,6 +112,26 @@ config("runtime_library") {
                 rebase_path("$android_ndk_root/sources/android/support/include",
                             root_build_dir) ]

+  if (current_cpu == "arm") {
+    cflags_cc += [
+      "-isystem" +
+          rebase_path("$android_ndk_root/sources/cxx-stl/gnu-libstdc++/4.9/include",
+                      root_build_dir),
+      "-isystem" +
+          rebase_path("$android_ndk_root/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include",
+                      root_build_dir),
+    ]
+  } else if (current_cpu == "arm64") {
+    cflags_cc += [
+      "-isystem" +
+          rebase_path("$android_ndk_root/sources/cxx-stl/gnu-libstdc++/4.9/include",
+                      root_build_dir),
+      "-isystem" +
+          rebase_path("$android_ndk_root/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/include",
+                      root_build_dir),
+    ]
+  }
+
   defines = [
     "__GNU_SOURCE=1",  # Necessary for clone().
     "CHROMIUM_CXX_TWEAK_INLINES",  # Saves binary size.
diff --git a/config/compiler/BUILD.gn b/config/compiler/BUILD.gn
index 402dac4..ee3015a 100644
--- a/config/compiler/BUILD.gn
+++ b/config/compiler/BUILD.gn
@@ -1456,7 +1456,7 @@ config("default_warnings") {

       # Don't warn about "maybe" uninitialized. Clang doesn't include this
       # in -Wall but gcc does, and it gives false positives.
-      cflags += [ "-Wno-maybe-uninitialized" ]
+      cflags += [ "-Wno-uninitialized" ]
       cflags += [ "-Wno-deprecated-declarations" ]

       # -Wcomment gives too many false positives in the case a

With this edit, you don't have to change any other source code. But still I have runtime assertion failure.

And here is a link if you want to try on your project(arm64 only for now). ARM64.zip

nullbus avatar Jul 15 '19 08:07 nullbus

Anyway, it works well with non-debug library. I build it with ubuntu 16.04 image in docker and 7.4.288.28 version of v8. Here is it: v8prebuilt-7.4.288.28-Android.zip

But I noticed require function does not work properly in Android build. Since UE4 packages all assets into one .pak file and pak file's filesystem is very sensitive to path handling, I had to change this plugin's code a little bit. I'll make a PR about that.

nullbus avatar Jul 18 '19 02:07 nullbus

FYI V8-7.7.299 libs provided are still the thin variant types and will need to be updated with @nullbus script. From the looks of the lib sizes and compile tests this still affects both linux and android builds and returns with libv8_libplatform.a: error adding symbols: Malformed archive

getnamo avatar Sep 28 '19 21:09 getnamo

@nullbus. I also encountered the same problem, your solution doesn't work to my situation, btw my v8 version is 7.4.288, which version you used?

cooperkuo avatar Oct 09 '19 08:10 cooperkuo

I made a patch build for 4.23-android which uses the older 7.4.288 that nullbus shared: https://github.com/getnamo/Unreal.js-core/tree/UE4.23-V8-7.4.288

Hope it can be useful until we get the 7.7.299 android build working.

getnamo avatar Oct 09 '19 09:10 getnamo

@cooperkuo Which problem do you have? If it is runtime crash with binaries that I uploaded, it should be replaced to fixed one.

With pure V8 source, it needs one more fix like below:

diff --git a/src/api.cc b/src/api.cc
index 704c46aa68..33725e980f 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1347,7 +1347,7 @@ void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
   i::HandleScope scope(isolate);
   auto value_obj = Utils::OpenHandle(*value);
-  CHECK(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo());
+  // CHECK(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo());
   if (value_obj->IsObjectTemplateInfo()) {
     templ->set_serial_number(i::Smi::kZero);
     if (templ->IsFunctionTemplateInfo()) {

I believe that ncsoft's modified V8 already has that fix.

nullbus avatar Oct 09 '19 11:10 nullbus

BTW the company that I am working recently released a game which uses UnrealJS. I tried to use as higher v8 version as I could, but I had frequent crashes for Android at 7.7 and 7.6 version of v8. I couldn't figure out what's the problem. I am using 7.4 version now.

nullbus avatar Oct 09 '19 11:10 nullbus

@nullbus. The problem is a compile-time error, but the v8 source I use is the pure one (from google), which is version 7.4.288. Maybe different versions of source code (google's or ncsoft's) cause problems in different way.

The binaries you uploaded work perfectly for me, I have not encountered the runtime problem you mentioned. So I want to re-build libraries by myself with the solution you shared.

My gn configuration is same with yours:

$ cat out/arm-release/args.gn
v8_use_external_startup_data = false
v8_use_snapshot = false
v8_enable_i18n_support = false
is_debug = false
v8_static_library = true
is_component_build = false
target_os = "android"
target_cpu = "arm"
v8_target_cpu = "arm"
use_custom_libcxx = false
use_custom_libcxx_for_host = true

I compile by this command, of course the libraries it produces ain't complete, I think that is so called "thin_archive problem":

$ ninja -C out/arm-release v8 v8_libbase v8_libplatform v8_libsampler

My thin_archive problem is solved when I do such modification:

diff --git a/config/BUILDCONFIG.gn b/config/BUILDCONFIG.gn
index f89e7e831..9825d6b80 100644
--- a/config/BUILDCONFIG.gn
+++ b/config/BUILDCONFIG.gn
@@ -434,7 +434,7 @@ default_compiler_configs = [
   "//build/config/compiler:no_exceptions",
   "//build/config/compiler:no_rtti",
   "//build/config/compiler:runtime_library",
-  "//build/config/compiler:thin_archive",
+  # "//build/config/compiler:thin_archive",
   "//build/config/compiler:default_init_stack_vars",

Now problems come. If I'm right, I should now modify v8/build/config/android/BUILD.gn by the way you do, adding cflags_cc flags and others. But the version of android ndk my v8 source uses is 20 (when I executed gclient sync, gclient downloaded that for me), which has no gnu-libstdc++ under android ndk root directory:

$ cat third_party/android_ndk/source.properties
Pkg.Desc = Android NDK
Pkg.Revision = 20.0.5594570

So I directly compile v8 libraries (no compile time errors), then I encountered "a ton of undefined reference errors" when I embeded these libraries to Unreal Engine, this is one piece of them:

200119b0-3dec-4283-b63a-603a14b20853

Then I copy gnu-libstdc++ from ndk r17c into the ndk that v8 uses, and modify other gn files. Errors occurs when compiling v8 libraries, such as:

d0dd137c-3466-446e-b568-d85393dd4b53

Can you tell my which v8 source you used when compiled your posted v8 libraries (google's or ncsoft's), and the version of android ndk?

It's okay even if you used ncsoft's v8 source, I will try that one later, but it will be very nice if you have any idea to the problems I encountered 😄

cooperkuo avatar Oct 09 '19 12:10 cooperkuo

@cooperkuo did you run gclient sync after checking out 7.4.288 revision? I think ndk version from Google should less than 20. I can't remember exactly now but I think the version was 16 when I built these binaries.

And I built them from pure v8 source from Google.

nullbus avatar Oct 09 '19 12:10 nullbus

@nullbus It works! After checking out 7.4.288 release and running gclient sync, your solution works for me. Finally I got 32 and 64-bits libraries that run perfectly on my android device. Thanks a lot, you really solve my problem!! 🎉👍

cooperkuo avatar Oct 11 '19 18:10 cooperkuo

BTW the company that I am working recently released a game which uses UnrealJS. I tried to use as higher v8 version as I could, but I had frequent crashes for Android at 7.7 and 7.6 version of v8. I couldn't figure out what's the problem. I am using 7.4 version now.

What is this game name? Would be interesting to see any game using UnrealJS in production

friuns2 avatar Oct 04 '22 18:10 friuns2

What is this game name? Would be interesting to see any game using UnrealJS in production

One of published game using UnrealJS is 9M Pro Baseball but I'm not sure it is available outside Korea. But it also have Taiwan version. Most of UI code(UMG) is written in Typescript and it supports Android iOS, and Windows.

nullbus avatar Oct 10 '22 14:10 nullbus