diff mbox series

[meta-oe] nodejs: support cross compile without qemu user conditionally

Message ID 20240819022906.999604-1-hongxu.jia@windriver.com
State Accepted
Headers show
Series [meta-oe] nodejs: support cross compile without qemu user conditionally | expand

Commit Message

Jia, Hongxu Aug. 19, 2024, 2:29 a.m. UTC
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]
- Add missing native packages to fix library missing on host build
- Rework libatomic.patch, explicitly link to libatomic for clang
  conditionally

BTW, enable riscv64 build

[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.jia@windriver.com>
---
 .../nodejs/nodejs/libatomic.patch             | 86 +++++++++++++++----
 .../recipes-devtools/nodejs/nodejs_20.16.0.bb | 81 ++++++++++-------
 2 files changed, 121 insertions(+), 46 deletions(-)

Comments

Alexander Kanavin Aug. 19, 2024, 5:30 a.m. UTC | #1
This changes the build process significantly, and should be opt-in
with an option, rather than enforced on users (for whom qemu may be
working just fine).

Making two different ways to build also introduces the risk of only
one of them being tested, and the other regressing.

Also, the correct way out is to fix qemu-user, rather than finding
ways to build the whole stack without it.

Alex

On Mon, 19 Aug 2024 at 04:29, hongxu via lists.openembedded.org
<hongxu.jia=eng.windriver.com@lists.openembedded.org> wrote:
>
> 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]
> - Add missing native packages to fix library missing on host build
> - Rework libatomic.patch, explicitly link to libatomic for clang
>   conditionally
>
> BTW, enable riscv64 build
>
> [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.jia@windriver.com>
> ---
>  .../nodejs/nodejs/libatomic.patch             | 86 +++++++++++++++----
>  .../recipes-devtools/nodejs/nodejs_20.16.0.bb | 81 ++++++++++-------
>  2 files changed, 121 insertions(+), 46 deletions(-)
>
> diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> index cb0237309..bc51f99d8 100644
> --- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> +++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> @@ -1,21 +1,77 @@
> -Link mksnapshot with libatomic on x86
> +From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001
> +From: Hongxu Jia <hongxu.jia@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.khem@gmail.com>
> +Upstream-Status: Inappropriate [OE specific]
>
> +Signed-off-by: Hongxu Jia <hongxu.jia@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 fe7121156..34ec8ad80 100644
> --- a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
> +++ b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
> @@ -5,17 +5,16 @@ 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).*"
>  COMPATIBLE_MACHINE:mips64 = "(!.*mips64).*"
>
> -COMPATIBLE_HOST:riscv64 = "null"
>  COMPATIBLE_HOST:riscv32 = "null"
>  COMPATIBLE_HOST:powerpc = "null"
>
> @@ -24,15 +23,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 +62,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 +92,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 +104,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 +126,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,8 +175,31 @@ RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \
>  PACKAGES =+ "${PN}-systemtap"
>  FILES:${PN}-systemtap = "${datadir}/systemtap"
>
> -BBCLASSEXTEND = "native"
> +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")
> +
> +    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"))
> +}
>
> -# http://errors.yoctoproject.org/Errors/Details/766923/
> -# TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh: line 7: 252447 Illegal instruction     (core dumped) PSEUDO_UNLOAD=1 qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib "$@"
> -# TODO: Fix with gcc-14
> +BBCLASSEXTEND = "native"
> --
> 2.27.0
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#111844): https://lists.openembedded.org/g/openembedded-devel/message/111844
> Mute This Topic: https://lists.openembedded.org/mt/107974157/1686489
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [alex.kanavin@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Khem Raj Aug. 19, 2024, 4:05 p.m. UTC | #2
On Sun, Aug 18, 2024 at 7:29 PM hongxu via lists.openembedded.org
<hongxu.jia=eng.windriver.com@lists.openembedded.org> wrote:
>
> 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]
> - Add missing native packages to fix library missing on host build
> - Rework libatomic.patch, explicitly link to libatomic for clang
>   conditionally

Does this mean that upstream has stopped supporting 32bit hosts ?
if so, than I would follow the suite and disable building for 32bit machines
nodejs build in OE is quite unwieldy and this just makes it a bit
more. Is there a way
to improve qemu-user ? and why does riscv64 not work with existing
mechanism. if it is new
then separate that out into a different patch.

>
> BTW, enable riscv64 build
>
> [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.jia@windriver.com>
> ---
>  .../nodejs/nodejs/libatomic.patch             | 86 +++++++++++++++----
>  .../recipes-devtools/nodejs/nodejs_20.16.0.bb | 81 ++++++++++-------
>  2 files changed, 121 insertions(+), 46 deletions(-)
>
> diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> index cb0237309..bc51f99d8 100644
> --- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> +++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> @@ -1,21 +1,77 @@
> -Link mksnapshot with libatomic on x86
> +From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001
> +From: Hongxu Jia <hongxu.jia@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.khem@gmail.com>
> +Upstream-Status: Inappropriate [OE specific]
>
> +Signed-off-by: Hongxu Jia <hongxu.jia@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 fe7121156..34ec8ad80 100644
> --- a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
> +++ b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
> @@ -5,17 +5,16 @@ 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).*"
>  COMPATIBLE_MACHINE:mips64 = "(!.*mips64).*"
>
> -COMPATIBLE_HOST:riscv64 = "null"
>  COMPATIBLE_HOST:riscv32 = "null"
>  COMPATIBLE_HOST:powerpc = "null"
>
> @@ -24,15 +23,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 +62,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 +92,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 +104,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 +126,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,8 +175,31 @@ RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \
>  PACKAGES =+ "${PN}-systemtap"
>  FILES:${PN}-systemtap = "${datadir}/systemtap"
>
> -BBCLASSEXTEND = "native"
> +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")
> +
> +    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"))
> +}
>
> -# http://errors.yoctoproject.org/Errors/Details/766923/
> -# TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh: line 7: 252447 Illegal instruction     (core dumped) PSEUDO_UNLOAD=1 qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib "$@"
> -# TODO: Fix with gcc-14
> +BBCLASSEXTEND = "native"
> --
> 2.27.0
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#111844): https://lists.openembedded.org/g/openembedded-devel/message/111844
> Mute This Topic: https://lists.openembedded.org/mt/107974157/1997914
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [raj.khem@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Jia, Hongxu Aug. 21, 2024, 3:11 a.m. UTC | #3
On 8/20/24 00:05, Khem Raj wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> On Sun, Aug 18, 2024 at 7:29 PM hongxu via lists.openembedded.org
> <hongxu.jia=eng.windriver.com@lists.openembedded.org>  wrote:
>> 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]
>> - Add missing native packages to fix library missing on host build
>> - Rework libatomic.patch, explicitly link to libatomic for clang
>>    conditionally
> Does this mean that upstream has stopped supporting 32bit hosts ?

The nodejs does not support to build 32bit target on 64 bit host for 
cross compiling.

but the normally non-cross compiling, the 32bit build still supported by 
nodejs.

For GYP, while enabling cross compile, it simple duplicates sources as 
host and target,

so the bit specific source could not work if host and target have 
different bits

Ideally, nodejs should split bit source conditionally along with arch test

> if so, than I would follow the suite and disable building for 32bit machines
> nodejs build in OE is quite unwieldy and this just makes it a bit
> more. Is there a way
> to improve qemu-user ?

For qemu-user solution, it is just a workaround for cross compiling, and 
force the build depends on qemu

which made the maintainer of nodejs become a qemu expert.

For the segment fault on armv9, although I found the issue was caused by 
the commit via git bisect

https://github.com/qemu/qemu/commit/2521b6073b7b4b505533a941d4f9600f7585dc7

But it is hard to debug and fix it. The qemu rework it, no minor change

Another similar issue is 
http://errors.yoctoproject.org/Errors/Details/766923/

Although I do not met the issue on my build, but we may have similar 
issue on other BSPs

# http://errors.yoctoproject.org/Errors/Details/766923/ # 
TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh: 
line 7: 252447 Illegal instruction (core dumped) PSEUDO_UNLOAD=1 
qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L 
TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E 
LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib 
"$@" # TODO: Fix with gcc-14

//Hongxu




>   and why does riscv64 not work with existing
> mechanism. if it is new
> then separate that out into a different patch.

I could move riscv64 out

//Hongxu

>> BTW, enable riscv64 build
>>
>> [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.jia@windriver.com>
>> ---
>>   .../nodejs/nodejs/libatomic.patch             | 86 +++++++++++++++----
>>   .../recipes-devtools/nodejs/nodejs_20.16.0.bb | 81 ++++++++++-------
>>   2 files changed, 121 insertions(+), 46 deletions(-)
>>
>> diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
>> index cb0237309..bc51f99d8 100644
>> --- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
>> +++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
>> @@ -1,21 +1,77 @@
>> -Link mksnapshot with libatomic on x86
>> +From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001
>> +From: Hongxu Jia<hongxu.jia@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.khem@gmail.com>
>> +Upstream-Status: Inappropriate [OE specific]
>>
>> +Signed-off-by: Hongxu Jia<hongxu.jia@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 fe7121156..34ec8ad80 100644
>> --- a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
>> +++ b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
>> @@ -5,17 +5,16 @@ 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).*"
>>   COMPATIBLE_MACHINE:mips64 = "(!.*mips64).*"
>>
>> -COMPATIBLE_HOST:riscv64 = "null"
>>   COMPATIBLE_HOST:riscv32 = "null"
>>   COMPATIBLE_HOST:powerpc = "null"
>>
>> @@ -24,15 +23,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 +62,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 +92,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 +104,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 +126,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,8 +175,31 @@ RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \
>>   PACKAGES =+ "${PN}-systemtap"
>>   FILES:${PN}-systemtap = "${datadir}/systemtap"
>>
>> -BBCLASSEXTEND = "native"
>> +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")
>> +
>> +    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"))
>> +}
>>
>> -#http://errors.yoctoproject.org/Errors/Details/766923/
>> -# TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh: line 7: 252447 Illegal instruction     (core dumped) PSEUDO_UNLOAD=1 qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib "$@"
>> -# TODO: Fix with gcc-14
>> +BBCLASSEXTEND = "native"
>> --
>> 2.27.0
>>
>>
>>
>>
>>
>> -=-=-=-=-=-=-=-=-=-=-=-
>> Links: You receive all messages sent to this group.
>> View/Reply Online (#111853):https://lists.openembedded.org/g/openembedded-devel/message/111853
>> Mute This Topic:https://lists.openembedded.org/mt/107974157/3617049
>> Group Owner:openembedded-devel+owner@lists.openembedded.org
>> Unsubscribe:https://lists.openembedded.org/g/openembedded-devel/unsub  [hongxu.jia@eng.windriver.com]
>> -=-=-=-=-=-=-=-=-=-=-=-
>>
Jia, Hongxu Aug. 21, 2024, 3:35 a.m. UTC | #4
On 8/21/24 11:11, hongxu wrote:
> On 8/20/24 00:05, Khem Raj wrote:
>> CAUTION: This email comes from a non Wind River email account!
>> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>>
>> On Sun, Aug 18, 2024 at 7:29 PM hongxu vialists.openembedded.org  <https://urldefense.com/v3/__http://lists.openembedded.org__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jMO27Z59Q$>
>> <hongxu.jia=eng.windriver.com@lists.openembedded.org>  wrote:
>>> 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  <https://urldefense.com/v3/__http://v8-qemu-wrapper.sh__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jPia2TlrQ$>: 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]
>>> - Add missing native packages to fix library missing on host build
>>> - Rework libatomic.patch, explicitly link to libatomic for clang
>>>    conditionally
>> Does this mean that upstream has stopped supporting 32bit hosts ?
>
> The nodejs does not support to build 32bit target on 64 bit host for 
> cross compiling.
>
> but the normally non-cross compiling, the 32bit build still supported 
> by nodejs.
>
Here is the check for supported combinations of host and target 
architectures in nodejs

https://github.com/nodejs/node/blob/main/deps/v8/include/v8config.h#L923

//Hongxu

> For GYP, while enabling cross compile, it simple duplicates sources as 
> host and target,
>
> so the bit specific source could not work if host and target have 
> different bits
>
> Ideally, nodejs should split bit source conditionally along with arch test
>
>> if so, than I would follow the suite and disable building for 32bit machines
>> nodejs build in OE is quite unwieldy and this just makes it a bit
>> more. Is there a way
>> to improve qemu-user ?
>
> For qemu-user solution, it is just a workaround for cross compiling, 
> and force the build depends on qemu
>
> which made the maintainer of nodejs become a qemu expert.
>
> For the segment fault on armv9, although I found the issue was caused 
> by the commit via git bisect
>
> https://github.com/qemu/qemu/commit/2521b6073b7b4b505533a941d4f9600f7585dc7
>
> But it is hard to debug and fix it. The qemu rework it, no minor change
>
> Another similar issue is 
> http://errors.yoctoproject.org/Errors/Details/766923/
>
> Although I do not met the issue on my build, but we may have similar 
> issue on other BSPs
>
> # http://errors.yoctoproject.org/Errors/Details/766923/ # 
> TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh 
> <https://urldefense.com/v3/__http://v8-qemu-wrapper.sh__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jPia2TlrQ$>: 
> line 7: 252447 Illegal instruction (core dumped) PSEUDO_UNLOAD=1 
> qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L 
> TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot 
> -E 
> LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib 
> "$@" # TODO: Fix with gcc-14
>
> //Hongxu
>
>>   and why does riscv64 not work with existing
>> mechanism. if it is new
>> then separate that out into a different patch.
>
> I could move riscv64 out
>
> //Hongxu
>
>>> BTW, enable riscv64 build
>>>
>>> [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.jia@windriver.com>
>>> ---
>>>   .../nodejs/nodejs/libatomic.patch             | 86 +++++++++++++++----
>>>   .../recipes-devtools/nodejs/nodejs_20.16.0.bb  <https://urldefense.com/v3/__http://nodejs_20.16.0.bb__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jOOF7bs3A$>  | 81 ++++++++++-------
>>>   2 files changed, 121 insertions(+), 46 deletions(-)
>>>
>>> diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
>>> index cb0237309..bc51f99d8 100644
>>> --- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
>>> +++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
>>> @@ -1,21 +1,77 @@
>>> -Link mksnapshot with libatomic on x86
>>> +From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001
>>> +From: Hongxu Jia<hongxu.jia@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  <https://urldefense.com/v3/__http://module-compiler.cc__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jPcGtwzAw$>:(.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.khem@gmail.com>
>>> +Upstream-Status: Inappropriate [OE specific]
>>>
>>> +Signed-off-by: Hongxu Jia<hongxu.jia@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  <https://urldefense.com/v3/__http://nodejs_20.16.0.bb__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jOOF7bs3A$>  b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb  <https://urldefense.com/v3/__http://nodejs_20.16.0.bb__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jOOF7bs3A$>
>>> index fe7121156..34ec8ad80 100644
>>> --- a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb  <https://urldefense.com/v3/__http://nodejs_20.16.0.bb__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jOOF7bs3A$>
>>> +++ b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb  <https://urldefense.com/v3/__http://nodejs_20.16.0.bb__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jOOF7bs3A$>
>>> @@ -5,17 +5,16 @@ 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).*"
>>>   COMPATIBLE_MACHINE:mips64 = "(!.*mips64).*"
>>>
>>> -COMPATIBLE_HOST:riscv64 = "null"
>>>   COMPATIBLE_HOST:riscv32 = "null"
>>>   COMPATIBLE_HOST:powerpc = "null"
>>>
>>> @@ -24,15 +23,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 +62,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 +92,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 +104,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  <https://urldefense.com/v3/__http://v8-qemu-wrapper.sh__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jPia2TlrQ$>')
>>>       with open(wrapper_path, 'w') as wrapper_file:
>>>           wrapper_file.write("""#!/bin/sh
>>> @@ -138,6 +126,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,8 +175,31 @@ RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \
>>>   PACKAGES =+ "${PN}-systemtap"
>>>   FILES:${PN}-systemtap = "${datadir}/systemtap"
>>>
>>> -BBCLASSEXTEND = "native"
>>> +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")
>>> +
>>> +    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"))
>>> +}
>>>
>>> -#http://errors.yoctoproject.org/Errors/Details/766923/
>>> -# TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh  <https://urldefense.com/v3/__http://v8-qemu-wrapper.sh__;!!AjveYdw8EvQ!etOk8rfOj3A-XDMMofWAP2t84WiQ29Av7aoC3i273l0aTZ4ybzOTimxIUb5YTRnRK_Gu85xnqCX1nTow58E4wb4a6jPia2TlrQ$>: line 7: 252447 Illegal instruction     (core dumped) PSEUDO_UNLOAD=1 qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib "$@"
>>> -# TODO: Fix with gcc-14
>>> +BBCLASSEXTEND = "native"
>>> --
>>> 2.27.0
>>>
>>>
>>>
>>>
>>>
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#111874):https://lists.openembedded.org/g/openembedded-devel/message/111874
> Mute This Topic:https://lists.openembedded.org/mt/107974157/3617049
> Group Owner:openembedded-devel+owner@lists.openembedded.org
> Unsubscribe:https://lists.openembedded.org/g/openembedded-devel/unsub  [hongxu.jia@eng.windriver.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Khem Raj Aug. 21, 2024, 3:41 a.m. UTC | #5
I dropped this patch for another reason. Its failing the layer
compatibility, check for meta-xfce
see https://autobuilder.yoctoproject.org/typhoon/#/builders/88/builds/4056/steps/11/logs/stdio

On Tue, Aug 20, 2024 at 8:35 PM Hongxu Jia <hongxu.jia@windriver.com> wrote:
>
> On 8/21/24 11:11, hongxu wrote:
>
> On 8/20/24 00:05, Khem Raj wrote:
>
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> On Sun, Aug 18, 2024 at 7:29 PM hongxu via lists.openembedded.org
> <hongxu.jia=eng.windriver.com@lists.openembedded.org> wrote:
>
> 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]
> - Add missing native packages to fix library missing on host build
> - Rework libatomic.patch, explicitly link to libatomic for clang
>   conditionally
>
> Does this mean that upstream has stopped supporting 32bit hosts ?
>
> The nodejs does not support to build 32bit target on 64 bit host for cross compiling.
>
> but the normally non-cross compiling, the 32bit build still supported by nodejs.
>
> Here is the check for supported combinations of host and target architectures in nodejs
>
> https://github.com/nodejs/node/blob/main/deps/v8/include/v8config.h#L923
>
> //Hongxu
>
> For GYP, while enabling cross compile, it simple duplicates sources as host and target,
>
> so the bit specific source could not work if host and target have different bits
>
> Ideally, nodejs should split bit source conditionally along with arch test
>
> if so, than I would follow the suite and disable building for 32bit machines
> nodejs build in OE is quite unwieldy and this just makes it a bit
> more. Is there a way
> to improve qemu-user ?
>
> For qemu-user solution, it is just a workaround for cross compiling, and force the build depends on qemu
>
> which made the maintainer of nodejs become a qemu expert.
>
> For the segment fault on armv9, although I found the issue was caused by the commit via git bisect
>
> https://github.com/qemu/qemu/commit/2521b6073b7b4b505533a941d4f9600f7585dc7
>
> But it is hard to debug and fix it. The qemu rework it, no minor change
>
> Another similar issue is http://errors.yoctoproject.org/Errors/Details/766923/
>
> Although I do not met the issue on my build, but we may have similar issue on other BSPs
>
> # http://errors.yoctoproject.org/Errors/Details/766923/ # TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh: line 7: 252447 Illegal instruction (core dumped) PSEUDO_UNLOAD=1 qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib "$@" # TODO: Fix with gcc-14
>
> //Hongxu
>
>  and why does riscv64 not work with existing
> mechanism. if it is new
> then separate that out into a different patch.
>
> I could move riscv64 out
>
> //Hongxu
>
> BTW, enable riscv64 build
>
> [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.jia@windriver.com>
> ---
>  .../nodejs/nodejs/libatomic.patch             | 86 +++++++++++++++----
>  .../recipes-devtools/nodejs/nodejs_20.16.0.bb | 81 ++++++++++-------
>  2 files changed, 121 insertions(+), 46 deletions(-)
>
> diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> index cb0237309..bc51f99d8 100644
> --- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> +++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
> @@ -1,21 +1,77 @@
> -Link mksnapshot with libatomic on x86
> +From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001
> +From: Hongxu Jia <hongxu.jia@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.khem@gmail.com>
> +Upstream-Status: Inappropriate [OE specific]
>
> +Signed-off-by: Hongxu Jia <hongxu.jia@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 fe7121156..34ec8ad80 100644
> --- a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
> +++ b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
> @@ -5,17 +5,16 @@ 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).*"
>  COMPATIBLE_MACHINE:mips64 = "(!.*mips64).*"
>
> -COMPATIBLE_HOST:riscv64 = "null"
>  COMPATIBLE_HOST:riscv32 = "null"
>  COMPATIBLE_HOST:powerpc = "null"
>
> @@ -24,15 +23,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 +62,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 +92,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 +104,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 +126,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,8 +175,31 @@ RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \
>  PACKAGES =+ "${PN}-systemtap"
>  FILES:${PN}-systemtap = "${datadir}/systemtap"
>
> -BBCLASSEXTEND = "native"
> +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")
> +
> +    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"))
> +}
>
> -# http://errors.yoctoproject.org/Errors/Details/766923/
> -# TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh: line 7: 252447 Illegal instruction     (core dumped) PSEUDO_UNLOAD=1 qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib "$@"
> -# TODO: Fix with gcc-14
> +BBCLASSEXTEND = "native"
> --
> 2.27.0
>
>
>
>
>
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#111874): https://lists.openembedded.org/g/openembedded-devel/message/111874
> Mute This Topic: https://lists.openembedded.org/mt/107974157/3617049
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [hongxu.jia@eng.windriver.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
>
diff mbox series

Patch

diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
index cb0237309..bc51f99d8 100644
--- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
+++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch
@@ -1,21 +1,77 @@ 
-Link mksnapshot with libatomic on x86
+From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001
+From: Hongxu Jia <hongxu.jia@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.khem@gmail.com>
+Upstream-Status: Inappropriate [OE specific]
 
+Signed-off-by: Hongxu Jia <hongxu.jia@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 fe7121156..34ec8ad80 100644
--- a/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
+++ b/meta-oe/recipes-devtools/nodejs/nodejs_20.16.0.bb
@@ -5,17 +5,16 @@  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).*"
 COMPATIBLE_MACHINE:mips64 = "(!.*mips64).*"
 
-COMPATIBLE_HOST:riscv64 = "null"
 COMPATIBLE_HOST:riscv32 = "null"
 COMPATIBLE_HOST:powerpc = "null"
 
@@ -24,15 +23,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 +62,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 +92,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 +104,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 +126,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,8 +175,31 @@  RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \
 PACKAGES =+ "${PN}-systemtap"
 FILES:${PN}-systemtap = "${datadir}/systemtap"
 
-BBCLASSEXTEND = "native"
+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")
+
+    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"))
+}
 
-# http://errors.yoctoproject.org/Errors/Details/766923/
-# TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/node-v20.12.2/out/Release/v8-qemu-wrapper.sh: line 7: 252447 Illegal instruction     (core dumped) PSEUDO_UNLOAD=1 qemu-x86_64 -r 5.15 -cpu Nehalem,check=false -L TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot -E LD_LIBRARY_PATH=TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib:TOPDIR/tmp-glibc/work/core2-64-oe-linux/nodejs/20.12.2/recipe-sysroot/usr/lib "$@"
-# TODO: Fix with gcc-14
+BBCLASSEXTEND = "native"