From 1486514645df9a7ea54a188ea2be620a3edd17f3 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Sun, 8 Jan 2023 21:16:15 +0100 Subject: [PATCH 01/20] Optimize 'libexec/build-monolith' on Linux minorly Build the symbol table after adding each file instead of continually rebuilding it. --- libexec/build-monolith | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libexec/build-monolith b/libexec/build-monolith index 62c916f..1114ee0 100755 --- a/libexec/build-monolith +++ b/libexec/build-monolith @@ -27,7 +27,8 @@ case "${platform}" in /usr/bin/find . -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs /usr/bin/ar -cq "${LIBV8_MONOLITH}" ;; "Linux") - find . -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs ar -cq "${LIBV8_MONOLITH}" + find . -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs ar -cqS "${LIBV8_MONOLITH}" + ranlib "${LIBV8_MONOLITH}" ;; *) echo "Unsupported platform: ${platform}" From 81a6c11f514747ca73bb309b268c0dff7665f770 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Mon, 9 Jan 2023 22:15:46 +0100 Subject: [PATCH 02/20] Ignore stubdata object This fixes an issue where functions that require ICU data segfault the process due to an unexpected lack of ICU data. The actual ICU data is provided by the icudt71_dat object. --- libexec/build-monolith | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libexec/build-monolith b/libexec/build-monolith index 1114ee0..d6eb436 100755 --- a/libexec/build-monolith +++ b/libexec/build-monolith @@ -21,13 +21,13 @@ platform=$(uname) rm -f "${LIBV8_MONOLITH}" case "${platform}" in "SunOS") - /usr/xpg4/bin/find . -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs ar cq "${LIBV8_MONOLITH}" + /usr/xpg4/bin/find . '(' '!' -path './icutools/deps/icu-small/source/stubdata/stubdata.o' ')' -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs ar cq "${LIBV8_MONOLITH}" ;; "Darwin") - /usr/bin/find . -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs /usr/bin/ar -cq "${LIBV8_MONOLITH}" + /usr/bin/find . '(' '!' -path './icutools/deps/icu-small/source/stubdata/stubdata.o' ')' -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs /usr/bin/ar -cq "${LIBV8_MONOLITH}" ;; "Linux") - find . -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs ar -cqS "${LIBV8_MONOLITH}" + find . '(' '!' -path './icutools/deps/icu-small/source/stubdata/stubdata.o' ')' -and '(' -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" ')' | sort | uniq | xargs ar -cqS "${LIBV8_MONOLITH}" ranlib "${LIBV8_MONOLITH}" ;; *) From 2419bde17a4ece17ecd4a944a32fcf5313dcc284 Mon Sep 17 00:00:00 2001 From: Sean Mann Date: Mon, 9 Jan 2023 22:10:10 -0800 Subject: [PATCH 03/20] googletest 'hello test' --- test/gtest/.gitignore | 14 ++++++++++++++ test/gtest/CMakeLists.txt | 28 ++++++++++++++++++++++++++++ test/gtest/hello_test.cc | 9 +++++++++ 3 files changed, 51 insertions(+) create mode 100644 test/gtest/.gitignore create mode 100644 test/gtest/CMakeLists.txt create mode 100644 test/gtest/hello_test.cc diff --git a/test/gtest/.gitignore b/test/gtest/.gitignore new file mode 100644 index 0000000..86201ed --- /dev/null +++ b/test/gtest/.gitignore @@ -0,0 +1,14 @@ +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +build +lib +bin diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt new file mode 100644 index 0000000..f8d6024 --- /dev/null +++ b/test/gtest/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.14) +project(gtest) + +# GoogleTest requires at least C++14 +set(CMAKE_CXX_STANDARD 14) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable( + hello_test + hello_test.cc +) +target_link_libraries( + hello_test + GTest::gtest_main +) + +include(GoogleTest) +gtest_discover_tests(hello_test) diff --git a/test/gtest/hello_test.cc b/test/gtest/hello_test.cc new file mode 100644 index 0000000..5a57e13 --- /dev/null +++ b/test/gtest/hello_test.cc @@ -0,0 +1,9 @@ +#include + +// Demonstrate some basic assertions. +TEST(HelloTest, BasicAssertions) { + // Expect two strings not to be equal. + EXPECT_STRNE("hello", "world"); + // Expect equality. + EXPECT_EQ(7 * 6, 42); +} From 5caeb09ac856f1b1d07134af0f6ee7d2aee94fa2 Mon Sep 17 00:00:00 2001 From: Sean Mann Date: Thu, 12 Jan 2023 21:56:30 -0800 Subject: [PATCH 04/20] get test to reference built libv8 --- test/gtest/CMakeLists.txt | 3 +++ test/gtest/hello_test.cc | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index f8d6024..e7f0740 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -15,6 +15,8 @@ FetchContent_MakeAvailable(googletest) enable_testing() +include_directories(${CMAKE_SOURCE_DIR}/../../vendor/v8/include/) + add_executable( hello_test hello_test.cc @@ -22,6 +24,7 @@ add_executable( target_link_libraries( hello_test GTest::gtest_main + ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a ) include(GoogleTest) diff --git a/test/gtest/hello_test.cc b/test/gtest/hello_test.cc index 5a57e13..525baac 100644 --- a/test/gtest/hello_test.cc +++ b/test/gtest/hello_test.cc @@ -1,7 +1,12 @@ #include +#include +#include + // Demonstrate some basic assertions. TEST(HelloTest, BasicAssertions) { + std::shared_ptr platform = v8::platform::NewDefaultPlatform(); + // Expect two strings not to be equal. EXPECT_STRNE("hello", "world"); // Expect equality. From 18ce6197124d3bea23a6cecee7b090cd40dc203e Mon Sep 17 00:00:00 2001 From: Sean Mann Date: Thu, 12 Jan 2023 22:35:33 -0800 Subject: [PATCH 05/20] actually use v8 in the test --- test/gtest/CMakeLists.txt | 8 +++--- test/gtest/Framework.h | 53 +++++++++++++++++++++++++++++++++++++++ test/gtest/c_v8_tests.cc | 18 +++++++++++++ test/gtest/hello_test.cc | 14 ----------- 4 files changed, 75 insertions(+), 18 deletions(-) create mode 100644 test/gtest/Framework.h create mode 100644 test/gtest/c_v8_tests.cc delete mode 100644 test/gtest/hello_test.cc diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index e7f0740..58f9876 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -18,14 +18,14 @@ enable_testing() include_directories(${CMAKE_SOURCE_DIR}/../../vendor/v8/include/) add_executable( - hello_test - hello_test.cc + c_v8_tests + c_v8_tests.cc ) target_link_libraries( - hello_test + c_v8_tests GTest::gtest_main ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a ) include(GoogleTest) -gtest_discover_tests(hello_test) +gtest_discover_tests(c_v8_tests) diff --git a/test/gtest/Framework.h b/test/gtest/Framework.h new file mode 100644 index 0000000..ed54c59 --- /dev/null +++ b/test/gtest/Framework.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include + +struct Framework { + typedef std::function basic_main; + typedef std::function iso_main; + typedef std::function&)> ctx_main; + + inline static void run(basic_main main) { + std::shared_ptr platform = v8::platform::NewDefaultPlatform(); + v8::V8::InitializePlatform(platform.get()); + v8::V8::Initialize(); + main(); + + v8::V8::Dispose(); + v8::V8::ShutdownPlatform(); + } + + inline static void runWithIsolateRaw(iso_main main) { + Framework::run([main]() -> void { + v8::Isolate::CreateParams p; + p.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); + v8::Isolate* iso = v8::Isolate::New(p); + + main(iso); + + iso->Dispose(); + delete p.array_buffer_allocator; + }); + } + + inline static void runWithIsolate(iso_main main) { + Framework::runWithIsolateRaw([main](v8::Isolate* iso) -> void { + v8::Locker lock { iso }; + v8::Isolate::Scope iScope { iso }; + v8::HandleScope hScope { iso }; + + main(iso); + }); + } + + inline static void runWithContext(ctx_main main) { + Framework::runWithIsolate([main](v8::Isolate* iso) -> void { + v8::Local ctx = v8::Context::New(iso); + v8::Context::Scope cScope { ctx }; + + main(ctx); + }); + } +}; \ No newline at end of file diff --git a/test/gtest/c_v8_tests.cc b/test/gtest/c_v8_tests.cc new file mode 100644 index 0000000..28d4345 --- /dev/null +++ b/test/gtest/c_v8_tests.cc @@ -0,0 +1,18 @@ +#include + +#include +#include + +#include "Framework.h" + +// Demonstrate some basic assertions. +TEST(FRLocaleTest, LocaleTests) { + Framework::runWithContext([](v8::Local& ctx) -> void { + v8::Local script = v8::Script::Compile(ctx, v8::String::NewFromUtf8Literal(ctx->GetIsolate(), "new Date('April 28 2021').toLocaleDateString('fr-FR');")).ToLocalChecked(); + v8::Local result = script->Run(ctx).ToLocalChecked(); + v8::Local resultStr = result->ToString(ctx).ToLocalChecked(); + v8::String::Utf8Value resultUTF8(ctx->GetIsolate(), resultStr); + + EXPECT_STREQ(*resultUTF8, "28/04/2021"); + }); +} diff --git a/test/gtest/hello_test.cc b/test/gtest/hello_test.cc deleted file mode 100644 index 525baac..0000000 --- a/test/gtest/hello_test.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#include -#include - -// Demonstrate some basic assertions. -TEST(HelloTest, BasicAssertions) { - std::shared_ptr platform = v8::platform::NewDefaultPlatform(); - - // Expect two strings not to be equal. - EXPECT_STRNE("hello", "world"); - // Expect equality. - EXPECT_EQ(7 * 6, 42); -} From 40e06d43e44603a35ac3927fd327b4d9db80b63f Mon Sep 17 00:00:00 2001 From: seanmakesgames Date: Fri, 13 Jan 2023 16:44:18 +0000 Subject: [PATCH 06/20] Add initial multi-platform support for test. Linking on Linux currently errors with `undefined reference to `'dlsym'` --- test/gtest/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index 58f9876..97143a9 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -24,8 +24,13 @@ add_executable( target_link_libraries( c_v8_tests GTest::gtest_main - ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a ) +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + target_link_libraries(c_v8_tests ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a) +else() + target_link_libraries(c_v8_tests ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-linux/libv8/obj/libv8_monolith.a) +endif() + include(GoogleTest) gtest_discover_tests(c_v8_tests) From c8f81d6197ef6d474f130f9daca88772e750b742 Mon Sep 17 00:00:00 2001 From: seanmakesgames Date: Sun, 15 Jan 2023 15:49:29 +0000 Subject: [PATCH 07/20] Add ctest to makefile --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 2fc1dca..670536c 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,9 @@ gem: pkg/libv8-node-$(VERSION)-$(CPU)-$(OS).gem test: test/$(CPU)-$(OS) +ctest: vendor/v8 + cd test/gtest && cmake -S . -B build && cd build && cmake --build . && ctest + src/node-v$(NODE_VERSION).tar.gz: ./libexec/download-node $(NODE_VERSION) From 41231c0cb994a2e360991afe3bf1449322726944 Mon Sep 17 00:00:00 2001 From: seanmakesgames Date: Sun, 15 Jan 2023 17:08:36 +0000 Subject: [PATCH 08/20] fix building test on linux on some build setups (including our codespace) --- test/gtest/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index 97143a9..b0d7e21 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -32,5 +32,8 @@ else() target_link_libraries(c_v8_tests ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-linux/libv8/obj/libv8_monolith.a) endif() +# This has to be after the v8 monolith for some build setups. +target_link_libraries(c_v8_tests dl) + include(GoogleTest) gtest_discover_tests(c_v8_tests) From c89843475a467a1a20e64dfe08499df8ce6d7b17 Mon Sep 17 00:00:00 2001 From: seanmakesgames Date: Sun, 15 Jan 2023 16:37:12 +0000 Subject: [PATCH 09/20] integrate test into actions --- .github/workflows/build.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 893ffa5..52dadb7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -118,6 +118,13 @@ jobs: - name: Inject V8 run: | ./libexec/inject-libv8 ${{ steps.set-metadata.outputs.NODE_VERSION }} + - name: Test V8 in C++ + run: | + cd test/gtest + cmake -S . -B build + cd build + cmake --build . + ./c_v8_tests - name: Build binary gem run: | bundle exec rake binary @@ -245,6 +252,9 @@ jobs: - name: Inject V8 run: | docker exec -w "${PWD}" ${{ steps.container.outputs.id }} ./libexec/inject-libv8 ${{ steps.set-metadata.outputs.NODE_VERSION }} + - name: Test V8 in C++ + run: | + docker exec -w "${PWD}" ${{ steps.container.outputs.id }} bash -c "cd test/gtest && cmake -S . -B build && cd build && cmake --build . && ctest" - name: Build binary gem run: | docker exec -w "${PWD}" ${{ steps.container.outputs.id }} bundle exec rake binary[${{ steps.platform.outputs.ruby_target_platform }}] From 112c4983c98aba87f7885cc9b755951df1ad1f52 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Mon, 16 Jan 2023 00:38:46 +0100 Subject: [PATCH 10/20] CI: Install CMake in docker container --- .github/workflows/build.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52dadb7..1ada9b3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -210,11 +210,15 @@ jobs: echo "::set-output name=id::$(cat container_id)" - name: Install Alpine system dependencies if: ${{ matrix.libc == 'musl' }} - run: docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apk add --no-cache build-base linux-headers bash python3 git curl tar + run: docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apk add --no-cache build-base linux-headers bash python3 git curl tar cmake + - name: Install Debian system dependencies + if: ${{ matrix.libc == 'gnu' }} + run: | + docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apt-get update + docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apt-get install -y cmake - name: Install Debian cross-compiler if: ${{ matrix.libc == 'gnu' && matrix.platform != 'amd64' }} run: | - docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apt-get update docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apt-get install -y binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - name: Checkout uses: actions/checkout@v2 From ba2e8cd324f15a38e7de5343319758f8c74c0e26 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Mon, 16 Jan 2023 23:45:38 +0100 Subject: [PATCH 11/20] Auto-detect vendor dir in GTest CMake Configuration --- test/gtest/CMakeLists.txt | 20 ++++++++++++++++---- test/gtest/check_glibc.c | 10 ++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 test/gtest/check_glibc.c diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index b0d7e21..915947c 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -26,12 +26,24 @@ target_link_libraries( GTest::gtest_main ) -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - target_link_libraries(c_v8_tests ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a) -else() - target_link_libraries(c_v8_tests ${CMAKE_SOURCE_DIR}/../../vendor/v8/x86_64-linux/libv8/obj/libv8_monolith.a) +string(TOLOWER ${CMAKE_SYSTEM_NAME} system_name) +string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} system_arch) + +set(vendor_arch "${system_arch}-${system_name}") + +if(${system_name} STREQUAL "linux") + try_compile(is_glibc ${CMAKE_BINARY_DIR}/check_glibc ${CMAKE_SOURCE_DIR}/check_glibc.c) + if(NOT is_glibc) + # assume non-glibc is musl-libc + string(APPEND vendor_arch "-musl") + endif() endif() +message(STATUS "Detected vendor architecture directory: ${vendor_arch}") + +# TODO?: Detect and support ruby-arch builds? +target_link_libraries(c_v8_tests ${CMAKE_SOURCE_DIR}/../../vendor/v8/${vendor_arch}/libv8/obj/libv8_monolith.a) + # This has to be after the v8 monolith for some build setups. target_link_libraries(c_v8_tests dl) diff --git a/test/gtest/check_glibc.c b/test/gtest/check_glibc.c new file mode 100644 index 0000000..38e7e4b --- /dev/null +++ b/test/gtest/check_glibc.c @@ -0,0 +1,10 @@ +#warning "This is not a source file -- it exists purely to allow CMake to distinguish between glibc and musl-libc. If you see this message, you are likely doing something incorrectly." + +#include + +#ifndef __GLIBC__ +#error "__GLIBC__ is undef -- not glibc!" +#endif + +int main() { } + From 0ed4d5bc9b95551cfe088812345d1652215528ae Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Wed, 18 Jan 2023 00:23:40 +0100 Subject: [PATCH 12/20] Use pathed archives on Linux Alpine Linux's `ar` program doesn't support having objects with the same name in the archive twice, so we have to use the GNU extension for including paths. This commit *should* honestly be split into multiple separate commits, but unfortunately pretty much all of these changes have to be applied as a unit or a build step fails. --- libexec/build-monolith | 4 ++-- libexec/inject-libv8 | 31 +++++++++++++++++++++++++++++-- libexec/platform | 21 +++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/libexec/build-monolith b/libexec/build-monolith index d6eb436..b6ffc15 100755 --- a/libexec/build-monolith +++ b/libexec/build-monolith @@ -27,8 +27,8 @@ case "${platform}" in /usr/bin/find . '(' '!' -path './icutools/deps/icu-small/source/stubdata/stubdata.o' ')' -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" | sort | uniq | xargs /usr/bin/ar -cq "${LIBV8_MONOLITH}" ;; "Linux") - find . '(' '!' -path './icutools/deps/icu-small/source/stubdata/stubdata.o' ')' -and '(' -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" ')' | sort | uniq | xargs ar -cqS "${LIBV8_MONOLITH}" - ranlib "${LIBV8_MONOLITH}" + find . '(' '!' -path './icutools/deps/icu-small/source/stubdata/stubdata.o' ')' -and '(' -path "./torque_*/**/*.o" -or -path "./v8*/**/*.o" -or -path "./icu*/**/*.o" ')' | sort | uniq | xargs ar -cqSP "${LIBV8_MONOLITH}" + ar -sP "${LIBV8_MONOLITH}" ;; *) echo "Unsupported platform: ${platform}" diff --git a/libexec/inject-libv8 b/libexec/inject-libv8 index 353d4ed..2142e1e 100755 --- a/libexec/inject-libv8 +++ b/libexec/inject-libv8 @@ -39,8 +39,35 @@ for lib in libv8_monolith.a; do mkdir -p "${dir}" rm -f "${dir}/${lib}" - echo "${BASEDIR}/out/${BUILDTYPE}/${lib} -> ${dir}/${lib}" - "${STRIP}" -S -x -o "${dir}/${lib}" "${lib}" + if [ "$STRIP_NEEDS_EXTRACT" = "y" ]; then + # manual extract/strip objects/build archive sequence + # because `strip` can't deal with these + # (presumably due to that folder issue mentioned below) + ( + tmpdir="$(mktemp -d)" + trap 'rm -r "$tmpdir"' EXIT + mkdir "$tmpdir/stage" + cd "$tmpdir/stage" + + # create folders named in `ar` archive (`ar -x` fails to create these) + "$AR" "$ARLISTFLAGS" "$BASEDIR/out/$BUILDTYPE/$lib" | while read -r path; do + dirname "$path" + done | uniq | xargs mkdir -p + "$AR" "$AREXTRACTFLAGS" "$BASEDIR/out/${BUILDTYPE}/$lib" + + # strip all objects + "$FIND" -type f -exec "$STRIP" -Sx {} + + + # rebuild the archive + "$FIND" -type f -exec "$AR" "$ARCOLLECTFLAGS" "../$lib" {} + + $ARBUILDSYMBOLS "../$lib" + mv "../$lib" "$dir/$lib" + ) + echo "${BASEDIR}/out/${BUILDTYPE}/${lib} -> ${dir}/${lib}" + else + echo "${BASEDIR}/out/${BUILDTYPE}/${lib} -> ${dir}/${lib}" + "${STRIP}" -S -x -o "${dir}/${lib}" "${lib}" + fi done mkdir -p "${top}/ext/libv8-node" diff --git a/libexec/platform b/libexec/platform index 582ec8b..91343aa 100755 --- a/libexec/platform +++ b/libexec/platform @@ -15,6 +15,14 @@ elif command -v cc >/dev/null 2>&1; then fi STRIP="${STRIP:-strip}" +AR="${AR:-ar}" +AREXTRACTFLAGS="${AREXTRACTFLAGS:--x}" +ARLISTFLAGS="${ARLISTFLAGS:--t}" +ARCOLLECTFLAGS="${ARCOLLECTFLAGS:-cqS}" +# this is the command to build the symbol table in an ar archive. +ARBUILDSYMBOLS="${ARBUILDSYMBOLS:-ranlib}" +FIND="${FIND:-find}" +STRIP_NEEDS_EXTRACT="${STRIP_NEEDS_EXTRACT:-n}" triple=$(${CC} -dumpmachine) host_platform="${triple}" @@ -63,6 +71,11 @@ case "${host_platform}" in CXX="${CXX:-/opt/local/gcc7/bin/g++}" STRIP="gstrip" ;; + *linux*) + STRIP_NEEDS_EXTRACT="y" + ARCOLLECTFLAGS="-cqSP" + ARBUILDSYMBOLS="${AR} -sP" + ;; esac if [ "${host_platform}" != "${target_platform}" ]; then @@ -146,6 +159,14 @@ export CC='${CC}' export CXX='${CXX}' host_platform='${host_platform}' target_platform='${target_platform}' +STRIP='$STRIP' +AR='$AR' +AREXTRACTFLAGS='$AREXTRACTFLAGS' +ARLISTFLAGS='$ARLISTFLAGS' +ARCOLLECTFLAGS='$ARCOLLECTFLAGS' +ARBUILDSYMBOLS='$ARBUILDSYMBOLS' +FIND='$FIND' +STRIP_NEEDS_EXTRACT='$STRIP_NEEDS_EXTRACT' EOF if [ -n "${CC_host:-}" ]; then cat < Date: Wed, 18 Jan 2023 17:01:49 +0100 Subject: [PATCH 13/20] Fix aarch64 cross-compile by dropping -msign-return-address on host --- libexec/build-libv8 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libexec/build-libv8 b/libexec/build-libv8 index 07bb500..c3303b9 100755 --- a/libexec/build-libv8 +++ b/libexec/build-libv8 @@ -38,5 +38,13 @@ ${CXX} -v make BUILDTYPE="${BUILDTYPE}" config.gypi make BUILDTYPE="${BUILDTYPE}" "out/Makefile" +# workaround for node specifying `-msign-return-address=all` in ALL `CFLAGS` for aarch64 builds +# (if the host isn't also aarch64, this flag causes a compiler error) + +# shellcheck disable=SC2154 # these variables are defined by `eval`ing the output of the platform script above +if [ "$host_platform" != "$target_platform" ] && [ "${target_platform%%-*}" = "aarch64" ]; then + find . -iname "*.host.mk" -exec sed -i '/-msign-return-address/d' {} ';' +fi + export PATH="${PWD}/out/tools/bin:${PATH}" make -j"${NJOBS}" -C out BUILDTYPE="${BUILDTYPE}" V=0 From 65bd31a1c727099c9577862e273ef6fcd5bef8d8 Mon Sep 17 00:00:00 2001 From: seanmakesgames Date: Wed, 18 Jan 2023 17:27:42 +0000 Subject: [PATCH 14/20] skip arm64 c test on mac and linux --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ada9b3..9b17683 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -119,6 +119,7 @@ jobs: run: | ./libexec/inject-libv8 ${{ steps.set-metadata.outputs.NODE_VERSION }} - name: Test V8 in C++ + if: matrix.platform != 'arm64' run: | cd test/gtest cmake -S . -B build @@ -257,6 +258,7 @@ jobs: run: | docker exec -w "${PWD}" ${{ steps.container.outputs.id }} ./libexec/inject-libv8 ${{ steps.set-metadata.outputs.NODE_VERSION }} - name: Test V8 in C++ + if: matrix.platform != 'arm64' run: | docker exec -w "${PWD}" ${{ steps.container.outputs.id }} bash -c "cd test/gtest && cmake -S . -B build && cd build && cmake --build . && ctest" - name: Build binary gem From 7943dc9bb1f65249f7200406f10d7b76d9bf6404 Mon Sep 17 00:00:00 2001 From: seanmakesgames Date: Thu, 19 Jan 2023 05:58:14 +0000 Subject: [PATCH 15/20] 2.6 is EOL -- remove and bump --- .github/workflows/build.yml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b17683..b772fc3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ jobs: rubocop: name: Lint (Rubocop) runs-on: ubuntu-20.04 - container: ruby:2.6 + container: ruby:2.7 steps: - name: Checkout uses: actions/checkout@v2 @@ -30,7 +30,7 @@ jobs: outputs: GEM_VERSION: ${{ steps.set-metadata.outputs.GEM_VERSION }} runs-on: ubuntu-20.04 - container: ruby:2.6 + container: ruby:2.7 steps: - name: Checkout uses: actions/checkout@v2 @@ -199,10 +199,10 @@ jobs: run: | case ${{ matrix.libc }} in gnu) - echo 'ruby:2.6' + echo 'ruby:2.7' ;; musl) - echo 'ruby:2.6-alpine' + echo 'ruby:2.7-alpine' ;; esac | tee container_image echo "::set-output name=image::$(cat container_image)" @@ -282,12 +282,6 @@ jobs: - amd64 # other platforms would need emulation, which is way too slow container: - - image: ruby:2.6 - version: '2.6' - libc: gnu - - image: ruby:2.6-alpine - version: '2.6' - libc: musl - image: ruby:2.7 version: '2.7' libc: gnu @@ -380,7 +374,6 @@ jobs: fail-fast: false matrix: version: - - '2.6' - '2.7' - '3.0' - '3.1' @@ -394,9 +387,6 @@ jobs: - gnu - musl include: - - version: '2.6' - platform: 'arm64' - libc: 'gnu' - version: '2.7' platform: 'arm64' libc: 'gnu' From 4d01c03624c2580f73ec15de7f748f9e25b6235c Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Sun, 22 Jan 2023 15:16:12 +0100 Subject: [PATCH 16/20] Force ruby platform when testing ruby gem --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b772fc3..522deb3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -322,6 +322,7 @@ jobs: run: gem install --verbose pkg/libv8-node-${{ needs.build-ruby.outputs.GEM_VERSION }}.gem - name: Test with mini_racer run: | + export BUNDLE_FORCE_RUBY_PLATFORM=y git clone https://github.com/rubyjs/mini_racer.git test/mini_racer --depth 1 cd test/mini_racer git fetch origin refs/pull/232/head From 4a0438102c01b061ad1583d2a41b71e5e010447a Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Mon, 23 Jan 2023 21:39:43 +0100 Subject: [PATCH 17/20] Call node configure script directly Let node figure out the snake business. --- libexec/build-libv8 | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libexec/build-libv8 b/libexec/build-libv8 index c3303b9..309c8e9 100755 --- a/libexec/build-libv8 +++ b/libexec/build-libv8 @@ -17,12 +17,6 @@ BUILDTYPE="${BUILDTYPE:-Release}" cd "${src}/node-v${version}" -if command -v python3 >/dev/null 2>&1; then - PYTHON="${PYTHON:-python3}" -else - PYTHON="${PYTHON:-python2}" -fi - configure_flags='--openssl-no-asm --without-npm --shared --with-intl=full-icu' eval "$("${libexec}/platform")" @@ -33,7 +27,7 @@ ${CC} -v ${CXX} -v # shellcheck disable=SC2086 -"${PYTHON}" configure ${configure_flags} +./configure ${configure_flags} make BUILDTYPE="${BUILDTYPE}" config.gypi make BUILDTYPE="${BUILDTYPE}" "out/Makefile" From 482ac9c8e3aeed30c1ad11e948ed5957005b3cff Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Tue, 24 Jan 2023 08:14:31 +0100 Subject: [PATCH 18/20] Patch v8 prefinalizer.h to add header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @​v8: If you use `std::exchange`, include the header for it? --- libexec/extract-node | 1 + patch/v8-prefinalizer-h-utility.patch | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 patch/v8-prefinalizer-h-utility.patch diff --git a/libexec/extract-node b/libexec/extract-node index e65662c..4f4ae54 100755 --- a/libexec/extract-node +++ b/libexec/extract-node @@ -32,6 +32,7 @@ cd "${src}/node-v${version}" #patch -p1 < "${top}"/patch/gyp-libv8_monolith.patch patch -p1 < "${top}"/patch/py2-icutrim.patch patch -p1 < "${top}"/patch/py2-genv8constants.patch +patch -p0 < "${top}"/patch/v8-prefinalizer-h-utility.patch # TODO: the following still fails on py3 so the above one forcing py2 is needed # patch -p1 < ../../py3-genv8constants.patch diff --git a/patch/v8-prefinalizer-h-utility.patch b/patch/v8-prefinalizer-h-utility.patch new file mode 100644 index 0000000..e85252c --- /dev/null +++ b/patch/v8-prefinalizer-h-utility.patch @@ -0,0 +1,10 @@ +--- deps/v8/src/heap/cppgc/prefinalizer-handler.h ++++ deps/v8/src/heap/cppgc/prefinalizer-handler.h +@@ -6,6 +6,7 @@ + #define V8_HEAP_CPPGC_PREFINALIZER_HANDLER_H_ + + #include ++#include + + #include "include/cppgc/prefinalizer.h" + From 9c85c0394dbbe8e0510ec8a5b6e97d13764d5bd3 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Tue, 24 Jan 2023 23:28:12 +0100 Subject: [PATCH 19/20] Pin Rubygems and Bundler --- .github/workflows/build.yml | 16 ++++++++++++++++ Dockerfile | 2 ++ 2 files changed, 18 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 522deb3..464d404 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,6 +32,10 @@ jobs: runs-on: ubuntu-20.04 container: ruby:2.7 steps: + - name: Update Rubygems and Bundler + run: | + gem update --system 3.3.26 + gem install bundler -v '~> 2.3.26' - name: Checkout uses: actions/checkout@v2 - name: Bundle @@ -221,6 +225,10 @@ jobs: if: ${{ matrix.libc == 'gnu' && matrix.platform != 'amd64' }} run: | docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apt-get install -y binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu + - name: Update Rubygems and Bundler + run: | + docker exec -w "${PWD}" ${{ steps.container.outputs.id }} gem update --system 3.3.26 + docker exec -w "${PWD}" ${{ steps.container.outputs.id }} gem install bundler -v '~> 2.3.26' - name: Checkout uses: actions/checkout@v2 - name: Bundle @@ -308,6 +316,10 @@ jobs: - name: Install Alpine system dependencies if: ${{ matrix.container.libc == 'musl' }} run: apk add --no-cache build-base linux-headers bash python3 git curl tar + - name: Update Rubygems and Bundler + run: | + gem update --system 3.3.26 + gem install bundler -v '~> 2.3.26' - name: Set metadata id: set-metadata run: | @@ -425,6 +437,10 @@ jobs: - name: Install Alpine system dependencies if: ${{ matrix.libc == 'musl' }} run: docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apk add --no-cache build-base git libstdc++ + - name: Update Rubygems and Bundler + run: | + docker exec -w "${PWD}" ${{ steps.container.outputs.id }} gem update --system 3.3.26 + docker exec -w "${PWD}" ${{ steps.container.outputs.id }} gem install bundler -v '~> 2.3.26' - name: Set metadata id: set-metadata run: | diff --git a/Dockerfile b/Dockerfile index dd68d46..1e4058f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,8 @@ FROM ruby:${RUBY_VERSION} RUN test ! -f /etc/alpine-release || apk add --no-cache build-base bash python2 python3 git curl tar +RUN gem update --system 3.3.26 && gem install bundler -v '~> 2.3.26' + RUN mkdir -p /code WORKDIR /code From 24cb98137548c23e09581ba1a063cd706a610a04 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Wed, 25 Jan 2023 03:08:58 +0100 Subject: [PATCH 20/20] Fix and bump Rubocop --- .rubocop.yml | 6 ++++++ Rakefile | 8 ++------ ext/libv8-node/builder.rb | 2 +- ext/libv8-node/location.rb | 2 +- libv8-node.gemspec | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a3ec089..e57f216 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,9 +1,12 @@ AllCops: + SuggestExtensions: false + NewCops: disable TargetRubyVersion: 2.0 Exclude: - src/**/* - pkg/**/* - vendor/**/* + - test/**/* Naming/FileName: Exclude: @@ -26,3 +29,6 @@ Style/WordArray: Style/PerlBackrefs: Enabled: false + +Gemspec/RequiredRubyVersion: + Enabled: false diff --git a/Rakefile b/Rakefile index ade35ea..99467ee 100644 --- a/Rakefile +++ b/Rakefile @@ -23,9 +23,7 @@ task :compile, [:platform] => [] do |_, args| local_platform = Gem::Platform.local target_platform = Gem::Platform.new(ENV['RUBY_TARGET_PLATFORM'] || args.to_h[:platform] || Gem::Platform.local) - if target_platform.os == 'darwin' - target_platform.instance_eval { @version = nil } - end + target_platform.instance_eval { @version = nil } if target_platform.os == 'darwin' puts "local platform: #{local_platform}" puts "target platform: #{target_platform}" @@ -46,9 +44,7 @@ task :binary, [:platform] => [:compile] do |_, args| local_platform = Gem::Platform.local.dup target_platform = Gem::Platform.new(ENV['RUBY_TARGET_PLATFORM'] || args.to_h[:platform] || Gem::Platform.local) - if target_platform.os == 'darwin' - target_platform.instance_eval { @version = nil } - end + target_platform.instance_eval { @version = nil } if target_platform.os == 'darwin' puts "local platform: #{local_platform}" puts "target platform: #{target_platform}" diff --git a/ext/libv8-node/builder.rb b/ext/libv8-node/builder.rb index 84eae98..dab2771 100644 --- a/ext/libv8-node/builder.rb +++ b/ext/libv8-node/builder.rb @@ -1,4 +1,4 @@ -unless $LOAD_PATH.include?(File.expand_path('../../lib', __dir__)) +unless $LOAD_PATH.include?(File.expand_path('../../lib', __dir__)) # rubocop:disable Style/IfUnlessModifier $LOAD_PATH.unshift(File.expand_path('../../lib', __dir__)) end require 'libv8/node/version' diff --git a/ext/libv8-node/location.rb b/ext/libv8-node/location.rb index 9b4cf68..07acff8 100644 --- a/ext/libv8-node/location.rb +++ b/ext/libv8-node/location.rb @@ -45,7 +45,7 @@ def configure(context = MkmfContext.new) def verify_installation! include_paths = Libv8::Node::Paths.include_paths - unless include_paths.detect { |p| Pathname(p).join('v8.h').exist? } + unless include_paths.detect { |p| Pathname(p).join('v8.h').exist? } # rubocop:disable Style/IfUnlessModifier raise(HeaderNotFound, "Unable to locate 'v8.h' in the libv8 header paths: #{include_paths.inspect}") end diff --git a/libv8-node.gemspec b/libv8-node.gemspec index 920f547..3c4f98b 100644 --- a/libv8-node.gemspec +++ b/libv8-node.gemspec @@ -1,4 +1,4 @@ -$LOAD_PATH.unshift File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift File.expand_path('lib', __dir__) require 'libv8/node/version' Gem::Specification.new do |s| @@ -23,5 +23,5 @@ Gem::Specification.new do |s| s.require_paths = ['lib', 'ext'] s.add_development_dependency 'rake', '~> 12' - s.add_development_dependency 'rubocop', '~> 0.50.0' + s.add_development_dependency 'rubocop', '~> 1.44.0' end