From: Hongxu Jia <hongxu....@windriver.com> Due to the scope of supported BSPs by qemu-user is limited, such as a segment fault on armv9 after qemu apply commit [target/arm: Convert LDAPR/STLR (imm) to decodetree][1] ``` |tmp-glibc/work/neoversen2-crypto-wrs-linux/nodejs/20.5.1/node-v20.5.1/out/ Release/v8-qemu-wrapper.sh: line 7: 3179613 Segmentation fault (core dumped) PSEUDO_UNLOAD=1 qemu-aarch64 -r 5.15 -L tmp-glibc/work/neoversen2-crypto-wrs-linux/ nodejs/20.5.1/recipe-sysroot -E LD_LIBRARY_PATH=tmp-glibc/work/neoversen2-crypto-wrs-linux/ nodejs/20.5.1/recipe-sysroot/usr/lib64:tmp-glibc/work/neoversen2-crypto-wrs-linux/ nodejs/20.5.1/recipe-sysroot/usr/lib64 "$@" ```
Upstream nodejs have cross compile support, but it needs host and target have same bit width (e.g. a x86_64 host targeting arrch64 to produce a 64-bit binary). So: 1. If host and target have different bit width, build with QEMU user as usual; 2. If host and target have same bit width, enable notejs cross compile support: - The build tools of nodejs is GYP[2], set CC_host, CFLAGS_host, CXX_host, CXXFLAGS_host, LDFLAGS_host, AR_host for host build which is separated with target build [3] - Satisfy layer compatibility, set GYP variables in prefuncs of do_configure, do_compile and do_install other than in recipe parsing - Add missing native packages to fix library missing on host build - Rework libatomic.patch, explicitly link to libatomic for clang conditionally [1] https://github.com/qemu/qemu/commit/2521b6073b7b4b505533a941d4f9600f7585dc78 [2] https://github.com/nodejs/node-gyp [3] https://github.com/nodejs/node-gyp/blob/main/gyp/docs/UserDocumentation.md#cross-compiling Signed-off-by: Hongxu Jia <hongxu....@windriver.com> Signed-off-by: Khem Raj <raj.k...@gmail.com> Signed-off-by: Archana Polampalli <archana.polampa...@windriver.com> --- .../nodejs/nodejs/libatomic.patch | 85 +++++++++++++++---- .../recipes-devtools/nodejs/nodejs_20.16.0.bb | 80 +++++++++++------ 2 files changed, 124 insertions(+), 41 deletions(-) diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch index cb0237309..6b7ccb8a9 100644 --- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch +++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch @@ -1,21 +1,76 @@ -Link mksnapshot with libatomic on x86 +From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001 +From: Hongxu Jia <hongxu....@windriver.com> +Date: Sat, 17 Aug 2024 21:33:18 +0800 +Subject: [PATCH] link libatomic for clang conditionally -Clang-12 on x86 emits atomic builtins +Clang emits atomic builtin, explicitly link libatomic conditionally: +- For target build, always link -latomic for clang as usual +- For host build, if host and target have same bit width, cross compiling + is enabled, and host toolchain is gcc which does not link -latomic; + if host and target have different bit width, no cross compiling, + host build is the same with target build that requires to link + -latomic; -Fixes -| module-compiler.cc:(.text._ZN2v88internal4wasm12_GLOBAL__N_123ExecuteCompilationUnitsERKSt10shared_ptrINS2_22BackgroundCompileTokenEEPNS0_8CountersEiNS2_19CompileBaselineOnlyE+0x558): un -defined reference to `__atomic_load' +Fix: +|tmp-glibc/work/core2-64-wrs-linux/nodejs/20.13.0/node-v20.13.0/out/Release/node_js2c: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory -Upstream-Status: Pending -Signed-off-by: Khem Raj <raj.k...@gmail.com> +Upstream-Status: Inappropriate [OE specific] +Signed-off-by: Hongxu Jia <hongxu....@windriver.com> +--- + node.gyp | 13 ++++++++++++- + tools/v8_gypfiles/v8.gyp | 15 ++++++++++++--- + 2 files changed, 24 insertions(+), 4 deletions(-) + +diff --git a/node.gyp b/node.gyp +index b425f443..f296f35c 100644 +--- a/node.gyp ++++ b/node.gyp +@@ -487,7 +487,18 @@ + ], + }], + ['OS == "linux" and llvm_version != "0.0"', { +- 'libraries': ['-latomic'], ++ 'target_conditions': [ ++ ['_toolset=="host"', { ++ 'conditions': [ ++ ['"<!(echo $HOST_AND_TARGET_SAME_WIDTH)"=="0"', { ++ 'libraries': ['-latomic'], ++ }], ++ ], ++ }], ++ ['_toolset=="target"', { ++ 'libraries': ['-latomic'], ++ }], ++ ], + }], + ], + }, +diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp +index b23263cf..dcabf4ca 100644 --- a/tools/v8_gypfiles/v8.gyp +++ b/tools/v8_gypfiles/v8.gyp -@@ -1436,6 +1436,7 @@ - { - 'target_name': 'mksnapshot', - 'type': 'executable', -+ 'libraries': [ '-latomic' ], - 'dependencies': [ - 'v8_base_without_compiler', - 'v8_compiler_for_mksnapshot', +@@ -1100,9 +1100,18 @@ + # Platforms that don't have Compare-And-Swap (CAS) support need to link atomic library + # to implement atomic memory access + ['v8_current_cpu in ["mips64", "mips64el", "ppc", "arm", "riscv64", "loong64"]', { +- 'link_settings': { +- 'libraries': ['-latomic', ], +- }, ++ 'target_conditions': [ ++ ['_toolset=="host"', { ++ 'conditions': [ ++ ['"<!(echo $HOST_AND_TARGET_SAME_WIDTH)"=="0"', { ++ 'libraries': ['-latomic'], ++ }], ++ ], ++ }], ++ ['_toolset=="target"', { ++ 'libraries': ['-latomic', ], ++ }], ++ ], + }], + ], + }, # v8_base_without_compiler +-- +2.35.5 diff --git a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb index 3517fe6dc..55a984331 100644 --- a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb +++ b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb @@ -5,11 +5,11 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=cef54676c547a5bbab44aa8be3be9ef7" CVE_PRODUCT = "nodejs node.js" -DEPENDS = "openssl file-replacement-native python3-packaging-native" +DEPENDS = "openssl openssl-native file-replacement-native python3-packaging-native" DEPENDS:append:class-target = " qemu-native" DEPENDS:append:class-native = " c-ares-native" -inherit pkgconfig python3native qemu ptest +inherit pkgconfig python3native qemu ptest siteinfo COMPATIBLE_MACHINE:armv4 = "(!.*armv4).*" COMPATIBLE_MACHINE:armv5 = "(!.*armv5).*" @@ -24,15 +24,12 @@ SRC_URI = "http://nodejs.org/dist/v${PV}/node-v${PV}.tar.xz \ file://0004-v8-don-t-override-ARM-CFLAGS.patch \ file://system-c-ares.patch \ file://0001-liftoff-Correct-function-signatures.patch \ + file://libatomic.patch \ file://run-ptest \ " - SRC_URI:append:class-target = " \ file://0001-Using-native-binaries.patch \ " -SRC_URI:append:toolchain-clang:x86 = " \ - file://libatomic.patch \ - " SRC_URI:append:toolchain-clang:powerpc64le = " \ file://0001-ppc64-Do-not-use-mminimal-toc-with-clang.patch \ " @@ -66,28 +63,14 @@ ARCHFLAGS ?= "" PACKAGECONFIG ??= "ares brotli icu zlib" -PACKAGECONFIG[ares] = "--shared-cares,,c-ares" -PACKAGECONFIG[brotli] = "--shared-brotli,,brotli" -PACKAGECONFIG[icu] = "--with-intl=system-icu,--without-intl,icu" +PACKAGECONFIG[ares] = "--shared-cares,,c-ares c-ares-native" +PACKAGECONFIG[brotli] = "--shared-brotli,,brotli brotli-native" +PACKAGECONFIG[icu] = "--with-intl=system-icu,--without-intl,icu icu-native" PACKAGECONFIG[libuv] = "--shared-libuv,,libuv" PACKAGECONFIG[nghttp2] = "--shared-nghttp2,,nghttp2" PACKAGECONFIG[shared] = "--shared" PACKAGECONFIG[zlib] = "--shared-zlib,,zlib" -# We don't want to cross-compile during target compile, -# and we need to use the right flags during host compile, -# too. -EXTRA_OEMAKE = "\ - CC.host='${CC} -pie -fPIE' \ - CFLAGS.host='${CPPFLAGS} ${CFLAGS}' \ - CXX.host='${CXX} -pie -fPIE' \ - CXXFLAGS.host='${CPPFLAGS} ${CXXFLAGS}' \ - LDFLAGS.host='${LDFLAGS}' \ - AR.host='${AR}' \ - \ - builddir_name=./ \ -" - EXTRANATIVEPATH += "file-native" python prune_sources() { @@ -110,9 +93,11 @@ do_unpack[postfuncs] += "prune_sources" # V8's JIT infrastructure requires binaries such as mksnapshot and # mkpeephole to be run in the host during the build. However, these # binaries must have the same bit-width as the target (e.g. a x86_64 -# host targeting ARMv6 needs to produce a 32-bit binary). Instead of -# depending on a third Yocto toolchain, we just build those binaries -# for the target and run them on the host with QEMU. +# host targeting ARMv6 needs to produce a 32-bit binary). +# 1. If host and target have the different bit width, run those +# binaries for the target and run them on the host with QEMU. +# 2. If host and target have the same bit width, enable upstream +# cross crompile support and no QEMU python do_create_v8_qemu_wrapper () { """Creates a small wrapper that invokes QEMU to run some target V8 binaries on the host.""" @@ -120,6 +105,10 @@ python do_create_v8_qemu_wrapper () { d.expand('${STAGING_DIR_HOST}${base_libdir}')] qemu_cmd = qemu_wrapper_cmdline(d, d.getVar('STAGING_DIR_HOST'), qemu_libdirs) + + if d.getVar("HOST_AND_TARGET_SAME_WIDTH") == "1": + qemu_cmd = "" + wrapper_path = d.expand('${B}/v8-qemu-wrapper.sh') with open(wrapper_path, 'w') as wrapper_file: wrapper_file.write("""#!/bin/sh @@ -138,6 +127,14 @@ addtask create_v8_qemu_wrapper after do_configure before do_compile LDFLAGS:append:x86 = " -latomic" +export CC_host +export CFLAGS_host +export CXX_host +export CXXFLAGS_host +export LDFLAGS_host +export AR_host +export HOST_AND_TARGET_SAME_WIDTH + CROSS_FLAGS = "--cross-compiling" CROSS_FLAGS:class-native = "--no-cross-compiling" @@ -179,4 +176,35 @@ RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \ PACKAGES =+ "${PN}-systemtap" FILES:${PN}-systemtap = "${datadir}/systemtap" +do_configure[prefuncs] += "set_gyp_variables" +do_compile[prefuncs] += "set_gyp_variables" +do_install[prefuncs] += "set_gyp_variables" +python set_gyp_variables () { + if d.getVar("HOST_AND_TARGET_SAME_WIDTH") == "0": + # We don't want to cross-compile during target compile, + # and we need to use the right flags during host compile, + # too. + d.setVar("CC_host", d.getVar("CC") + " -pie -fPIE") + d.setVar("CFLAGS_host", d.getVar("CFLAGS")) + d.setVar("CXX_host", d.getVar("CXX") + " -pie -fPIE") + d.setVar("CXXFLAGS_host", d.getVar("CXXFLAGS")) + d.setVar("LDFLAGS_host", d.getVar("LDFLAGS")) + d.setVar("AR_host", d.getVar("AR")) + elif d.getVar("HOST_AND_TARGET_SAME_WIDTH") == "1": + # Enable upstream cross crompile support + d.setVar("CC_host", d.getVar("BUILD_CC")) + d.setVar("CFLAGS_host", d.getVar("BUILD_CFLAGS")) + d.setVar("CXX_host", d.getVar("BUILD_CXX")) + d.setVar("CXXFLAGS_host", d.getVar("BUILD_CXXFLAGS")) + d.setVar("LDFLAGS_host", d.getVar("BUILD_LDFLAGS")) + d.setVar("AR_host", d.getVar("BUILD_AR")) +} +python __anonymous () { + # 32 bit target and 64 bit host (x86-64 or aarch64) have different bit width + if d.getVar("SITEINFO_BITS") == "32" and "64" in d.getVar("BUILD_ARCH"): + d.setVar("HOST_AND_TARGET_SAME_WIDTH", "0") + else: + d.setVar("HOST_AND_TARGET_SAME_WIDTH", "1") +} + BBCLASSEXTEND = "native" -- 2.40.0
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#113818): https://lists.openembedded.org/g/openembedded-devel/message/113818 Mute This Topic: https://lists.openembedded.org/mt/109572650/21656 Group Owner: openembedded-devel+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-