highlight.js

Friday, September 8, 2023

Undefined Symbols in V8 Monolith

There are many applications and libraries acting as embedders to Google V8 JavaScript engine. My open source project Javet is one of them. When I was about to upgrade to V8 v11.7, the build was broken. I'd like to share the troubleshooting story in this post with you.

Undefined symbols absl::time_internal::cctz::local_time_zone()

The Javet build on V8 v11.7 worked well on Windows, Linux and Android, but failed on Mac x86_64 and arm64 with the following cmake error logs.

Undefined symbols for architecture x86_64:
  "_CFRelease", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFStringGetCString", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFStringGetLength", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFStringGetMaximumSizeForEncoding", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFTimeZoneCopyDefault", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFTimeZoneGetName", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
ld: symbol(s) not found for architecture x86_64

Undefined symbols for architecture arm64:
  "_CFRelease", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFStringGetCString", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFStringGetLength", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFStringGetMaximumSizeForEncoding", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFTimeZoneCopyDefault", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
  "_CFTimeZoneGetName", referenced from:
      absl::time_internal::cctz::local_time_zone() in libv8_monolith.a(time_zone_lookup.o)
ld: symbol(s) not found for architecture arm64

Analysis

V8 has a build target called v8_monolith which is for embedders. It usually has all the symbols built in libv8_monolith.a. However it forgets to include Abseil - C++ Common Libraries as the error log shows undefined symbols during the link phase.

So, the goal is to find or build those missing symbols for the linker to work properly.

Solution

After going over the official Abseil doc, I found the solution at Abseil CMake Build Instructions. Basically, I needed to add Abseil to the Javet CMakeList.txt so that the linker won't complain anymore.

add_subdirectory(${V8_DIR}/third_party/abseil-cpp ${V8_RELEASE_DIR}/third_party/abseil-cpp)
target_link_libraries(Javet PUBLIC absl::base absl::time)
  • ${V8_DIR} is the directory of the V8 source code.
  • ${V8_RELEASE_DIR} is the directory of the build target.
    • x86_64: ${V8_DIR}/out.gn/x64.release
    • arm64: ${V8_DIR}/out.gn/arm64.release

After this patch was applied, the build and test passed.

Cue Club 2 on Apple Silicon

It's been quite a long time for me not to play a decent snooker game since I replaced my Windows laptop with an Apple Silicon one. To be...