Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V8-7.4.288 is missing libtorque_base.a #43

Open
getnamo opened this issue May 25, 2019 · 21 comments
Open

V8-7.4.288 is missing libtorque_base.a #43

getnamo opened this issue May 25, 2019 · 21 comments

Comments

@getnamo
Copy link
Contributor

getnamo commented May 25, 2019

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.

@crocuis
Copy link
Contributor

crocuis commented May 25, 2019

2c1d8d6 Fixed.

@getnamo
Copy link
Contributor Author

getnamo commented May 26, 2019

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 (getnamo@baacac7), 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
Copy link
Contributor Author

getnamo commented May 26, 2019

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.

@nullbus
Copy link
Contributor

nullbus commented Jun 18, 2019

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
Copy link
Contributor

nullbus commented Jun 20, 2019

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.

@crocuis
Copy link
Contributor

crocuis commented Jun 20, 2019

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

@nullbus
Copy link
Contributor

nullbus commented Jun 23, 2019

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

@getnamo
Copy link
Contributor Author

getnamo commented Jul 14, 2019

@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?

@nullbus
Copy link
Contributor

nullbus commented Jul 14, 2019

@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
Copy link
Contributor

nullbus commented Jul 15, 2019

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
Copy link
Contributor

nullbus commented Jul 18, 2019

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.

@getnamo
Copy link
Contributor Author

getnamo commented Sep 28, 2019

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

@cooperkuo
Copy link

cooperkuo commented Oct 9, 2019

@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?

@getnamo
Copy link
Contributor Author

getnamo commented Oct 9, 2019

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.

@nullbus
Copy link
Contributor

nullbus commented Oct 9, 2019

@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
Copy link
Contributor

nullbus commented Oct 9, 2019

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.

@cooperkuo
Copy link

cooperkuo commented Oct 9, 2019

@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 😄

@nullbus
Copy link
Contributor

nullbus commented Oct 9, 2019

@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.

@cooperkuo
Copy link

@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!! 🎉👍

@friuns2
Copy link

friuns2 commented Oct 4, 2022

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

@nullbus
Copy link
Contributor

nullbus commented Oct 10, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants