bnoordhuis / v8-cmake

The V8 JavaScript engine, but built with CMake instead of GN - WIP
BSD 3-Clause "New" or "Revised" License
189 stars 54 forks source link

Support shared library build #60

Open bnoordhuis opened 1 year ago

bnoordhuis commented 1 year ago

Warning: stream-of-consciousness live debugging blurb

Shared library support should in theory be as simple as removing STATIC from the add_library() stanzas and let users pass -DBUILD_SHARED_LIBS=ON to cmake but in practice in results in "multiple definition" linker errors:

[ 25%] Linking CXX shared library libv8_base_without_compiler.so
/usr/bin/ld: CMakeFiles/v8_base_without_compiler.dir/v8/src/deoptimizer/deoptimizer-cfi-empty.cc.o: in function `v8::internal::Deoptimizer::IsValidReturnAddress(unsigned long, v8::internal::Isolate*)':
/home/bnoordhuis/src/v8-cmake/main/v8/src/deoptimizer/deoptimizer-cfi-empty.cc:11: multiple definition of `v8::internal::Deoptimizer::IsValidReturnAddress(unsigned long, v8::internal::Isolate*)'; CMakeFiles/v8_base_without_compiler.dir/v8/src/deoptimizer/deoptimizer-cfi-builtins.cc.o:/home/bnoordhuis/src/v8-cmake/main/v8/src/deoptimizer/deoptimizer-cfi-builtins.cc:45: first defined here
/usr/bin/ld: CMakeFiles/v8-adler32.dir/v8/third_party/zlib/adler32.c.o: in function `Cr_z_adler32_z':
/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:72: multiple definition of `Cr_z_adler32_z'; CMakeFiles/v8_base_without_compiler.dir/v8/third_party/zlib/adler32.c.o:/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:72: first defined here
/usr/bin/ld: CMakeFiles/v8-adler32.dir/v8/third_party/zlib/adler32.c.o: in function `Cr_z_adler32':
/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:166: multiple definition of `Cr_z_adler32'; CMakeFiles/v8_base_without_compiler.dir/v8/third_party/zlib/adler32.c.o:/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:166: first defined here
/usr/bin/ld: CMakeFiles/v8-adler32.dir/v8/third_party/zlib/adler32.c.o: in function `Cr_z_adler32_combine':
/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:204: multiple definition of `Cr_z_adler32_combine'; CMakeFiles/v8_base_without_compiler.dir/v8/third_party/zlib/adler32.c.o:/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:204: first defined here
/usr/bin/ld: CMakeFiles/v8-adler32.dir/v8/third_party/zlib/adler32.c.o: in function `Cr_z_adler32_combine64':
/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:212: multiple definition of `Cr_z_adler32_combine64'; CMakeFiles/v8_base_without_compiler.dir/v8/third_party/zlib/adler32.c.o:/home/bnoordhuis/src/v8-cmake/main/v8/third_party/zlib/adler32.c:212: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/v8_base_without_compiler.dir/build.make:10222: libv8_base_without_compiler.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:237: CMakeFiles/v8_base_without_compiler.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

Applying this change fixes that particular error...

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 19c739a1..a71a99e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -407,11 +407,11 @@ add_library(v8_base_without_compiler
   v8/src/trap-handler/handler-outside.cc
   v8/src/trap-handler/handler-shared.cc
   v8/src/temporal/temporal-parser.cc
+  v8/third_party/zlib/adler32.c
   ${utils-sources}
   ${wasm-sources}
   ${zone-sources}
   ${zlib-sources}
-  $<TARGET_OBJECTS:v8-adler32>
 )

 if (WIN32)

But subsequently...

/usr/bin/ld: CMakeFiles/v8_base_without_compiler.dir/v8/src/deoptimizer/deoptimizer-cfi-empty.cc.o: in function `v8::internal::Deoptimizer::IsValidReturnAddress(unsigned long, v8
::internal::Isolate*)':
/home/bnoordhuis/src/v8-cmake/main/v8/src/deoptimizer/deoptimizer-cfi-empty.cc:11: multiple definition of `v8::internal::Deoptimizer::IsValidReturnAddress(unsigned long, v8::inte
rnal::Isolate*)'; CMakeFiles/v8_base_without_compiler.dir/v8/src/deoptimizer/deoptimizer-cfi-builtins.cc.o:/home/bnoordhuis/src/v8-cmake/main/v8/src/deoptimizer/deoptimizer-cfi-b
uiltins.cc:45: first defined here

Which indeed is defined in multiple places:

$ git grep -n '^bool Deoptimizer::IsValidReturnAddress'
v8/src/deoptimizer/deoptimizer-cfi-builtins.cc:45:bool Deoptimizer::IsValidReturnAddress(Address address, Isolate* isolate) {
v8/src/deoptimizer/deoptimizer-cfi-empty.cc:11:bool Deoptimizer::IsValidReturnAddress(Address address, Isolate* isolate) {

My guess is the static library build hides the fact that there are indeed multiple symbols with the same name

bnoordhuis commented 1 year ago

I've been chipping away at this but I'm reasonably convinced by now that the "glob all the files" approach is bust. It works for static library builds but mostly by accident. Shared builds aren't so forgiving.