diff options
author | Hongxu Jia <hongxu.jia@windriver.com> | 2025-01-31 17:22:26 +0000 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2025-02-04 15:04:40 -0800 |
commit | d483bcbc30a4d28896e6333175ef50e337dc19bc (patch) | |
tree | fe25452ec8c4a6676f0ace42c4bff6b90c7c3b54 | |
parent | 87bd8bed70a6476d970bd3f9ce4be97b1221f61d (diff) | |
download | meta-openembedded-d483bcbc30a4d28896e6333175ef50e337dc19bc.tar.gz |
nodejs: support cross compile without qemu user conditionally
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.jia@windriver.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r-- | meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch | 85 | ||||
-rw-r--r-- | meta-oe/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 cb0237309e..6b7ccb8a98 100644 --- a/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch +++ b/meta-oe/recipes-devtools/nodejs/nodejs/libatomic.patch | |||
@@ -1,21 +1,76 @@ | |||
1 | Link mksnapshot with libatomic on x86 | 1 | From 15e751e4b79475fb34e4b32a3ca54119b20c564a Mon Sep 17 00:00:00 2001 |
2 | From: Hongxu Jia <hongxu.jia@windriver.com> | ||
3 | Date: Sat, 17 Aug 2024 21:33:18 +0800 | ||
4 | Subject: [PATCH] link libatomic for clang conditionally | ||
2 | 5 | ||
3 | Clang-12 on x86 emits atomic builtins | 6 | Clang emits atomic builtin, explicitly link libatomic conditionally: |
7 | - For target build, always link -latomic for clang as usual | ||
8 | - For host build, if host and target have same bit width, cross compiling | ||
9 | is enabled, and host toolchain is gcc which does not link -latomic; | ||
10 | if host and target have different bit width, no cross compiling, | ||
11 | host build is the same with target build that requires to link | ||
12 | -latomic; | ||
4 | 13 | ||
5 | Fixes | 14 | Fix: |
6 | | module-compiler.cc:(.text._ZN2v88internal4wasm12_GLOBAL__N_123ExecuteCompilationUnitsERKSt10shared_ptrINS2_22BackgroundCompileTokenEEPNS0_8CountersEiNS2_19CompileBaselineOnlyE+0x558): un | 15 | |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 |
7 | defined reference to `__atomic_load' | ||
8 | 16 | ||
9 | Upstream-Status: Pending | 17 | Upstream-Status: Inappropriate [OE specific] |
10 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
11 | 18 | ||
19 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
20 | --- | ||
21 | node.gyp | 13 ++++++++++++- | ||
22 | tools/v8_gypfiles/v8.gyp | 15 ++++++++++++--- | ||
23 | 2 files changed, 24 insertions(+), 4 deletions(-) | ||
24 | |||
25 | diff --git a/node.gyp b/node.gyp | ||
26 | index b425f443..f296f35c 100644 | ||
27 | --- a/node.gyp | ||
28 | +++ b/node.gyp | ||
29 | @@ -487,7 +487,18 @@ | ||
30 | ], | ||
31 | }], | ||
32 | ['OS == "linux" and llvm_version != "0.0"', { | ||
33 | - 'libraries': ['-latomic'], | ||
34 | + 'target_conditions': [ | ||
35 | + ['_toolset=="host"', { | ||
36 | + 'conditions': [ | ||
37 | + ['"<!(echo $HOST_AND_TARGET_SAME_WIDTH)"=="0"', { | ||
38 | + 'libraries': ['-latomic'], | ||
39 | + }], | ||
40 | + ], | ||
41 | + }], | ||
42 | + ['_toolset=="target"', { | ||
43 | + 'libraries': ['-latomic'], | ||
44 | + }], | ||
45 | + ], | ||
46 | }], | ||
47 | ], | ||
48 | }, | ||
49 | diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp | ||
50 | index b23263cf..dcabf4ca 100644 | ||
12 | --- a/tools/v8_gypfiles/v8.gyp | 51 | --- a/tools/v8_gypfiles/v8.gyp |
13 | +++ b/tools/v8_gypfiles/v8.gyp | 52 | +++ b/tools/v8_gypfiles/v8.gyp |
14 | @@ -1436,6 +1436,7 @@ | 53 | @@ -1100,9 +1100,18 @@ |
15 | { | 54 | # Platforms that don't have Compare-And-Swap (CAS) support need to link atomic library |
16 | 'target_name': 'mksnapshot', | 55 | # to implement atomic memory access |
17 | 'type': 'executable', | 56 | ['v8_current_cpu in ["mips64", "mips64el", "ppc", "arm", "riscv64", "loong64"]', { |
18 | + 'libraries': [ '-latomic' ], | 57 | - 'link_settings': { |
19 | 'dependencies': [ | 58 | - 'libraries': ['-latomic', ], |
20 | 'v8_base_without_compiler', | 59 | - }, |
21 | 'v8_compiler_for_mksnapshot', | 60 | + 'target_conditions': [ |
61 | + ['_toolset=="host"', { | ||
62 | + 'conditions': [ | ||
63 | + ['"<!(echo $HOST_AND_TARGET_SAME_WIDTH)"=="0"', { | ||
64 | + 'libraries': ['-latomic'], | ||
65 | + }], | ||
66 | + ], | ||
67 | + }], | ||
68 | + ['_toolset=="target"', { | ||
69 | + 'libraries': ['-latomic', ], | ||
70 | + }], | ||
71 | + ], | ||
72 | }], | ||
73 | ], | ||
74 | }, # v8_base_without_compiler | ||
75 | -- | ||
76 | 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 3517fe6dc7..55a9843314 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" | |||
5 | 5 | ||
6 | CVE_PRODUCT = "nodejs node.js" | 6 | CVE_PRODUCT = "nodejs node.js" |
7 | 7 | ||
8 | DEPENDS = "openssl file-replacement-native python3-packaging-native" | 8 | DEPENDS = "openssl openssl-native file-replacement-native python3-packaging-native" |
9 | DEPENDS:append:class-target = " qemu-native" | 9 | DEPENDS:append:class-target = " qemu-native" |
10 | DEPENDS:append:class-native = " c-ares-native" | 10 | DEPENDS:append:class-native = " c-ares-native" |
11 | 11 | ||
12 | inherit pkgconfig python3native qemu ptest | 12 | inherit pkgconfig python3native qemu ptest siteinfo |
13 | 13 | ||
14 | COMPATIBLE_MACHINE:armv4 = "(!.*armv4).*" | 14 | COMPATIBLE_MACHINE:armv4 = "(!.*armv4).*" |
15 | COMPATIBLE_MACHINE:armv5 = "(!.*armv5).*" | 15 | COMPATIBLE_MACHINE:armv5 = "(!.*armv5).*" |
@@ -24,15 +24,12 @@ SRC_URI = "http://nodejs.org/dist/v${PV}/node-v${PV}.tar.xz \ | |||
24 | file://0004-v8-don-t-override-ARM-CFLAGS.patch \ | 24 | file://0004-v8-don-t-override-ARM-CFLAGS.patch \ |
25 | file://system-c-ares.patch \ | 25 | file://system-c-ares.patch \ |
26 | file://0001-liftoff-Correct-function-signatures.patch \ | 26 | file://0001-liftoff-Correct-function-signatures.patch \ |
27 | file://libatomic.patch \ | ||
27 | file://run-ptest \ | 28 | file://run-ptest \ |
28 | " | 29 | " |
29 | |||
30 | SRC_URI:append:class-target = " \ | 30 | SRC_URI:append:class-target = " \ |
31 | file://0001-Using-native-binaries.patch \ | 31 | file://0001-Using-native-binaries.patch \ |
32 | " | 32 | " |
33 | SRC_URI:append:toolchain-clang:x86 = " \ | ||
34 | file://libatomic.patch \ | ||
35 | " | ||
36 | SRC_URI:append:toolchain-clang:powerpc64le = " \ | 33 | SRC_URI:append:toolchain-clang:powerpc64le = " \ |
37 | file://0001-ppc64-Do-not-use-mminimal-toc-with-clang.patch \ | 34 | file://0001-ppc64-Do-not-use-mminimal-toc-with-clang.patch \ |
38 | " | 35 | " |
@@ -66,28 +63,14 @@ ARCHFLAGS ?= "" | |||
66 | 63 | ||
67 | PACKAGECONFIG ??= "ares brotli icu zlib" | 64 | PACKAGECONFIG ??= "ares brotli icu zlib" |
68 | 65 | ||
69 | PACKAGECONFIG[ares] = "--shared-cares,,c-ares" | 66 | PACKAGECONFIG[ares] = "--shared-cares,,c-ares c-ares-native" |
70 | PACKAGECONFIG[brotli] = "--shared-brotli,,brotli" | 67 | PACKAGECONFIG[brotli] = "--shared-brotli,,brotli brotli-native" |
71 | PACKAGECONFIG[icu] = "--with-intl=system-icu,--without-intl,icu" | 68 | PACKAGECONFIG[icu] = "--with-intl=system-icu,--without-intl,icu icu-native" |
72 | PACKAGECONFIG[libuv] = "--shared-libuv,,libuv" | 69 | PACKAGECONFIG[libuv] = "--shared-libuv,,libuv" |
73 | PACKAGECONFIG[nghttp2] = "--shared-nghttp2,,nghttp2" | 70 | PACKAGECONFIG[nghttp2] = "--shared-nghttp2,,nghttp2" |
74 | PACKAGECONFIG[shared] = "--shared" | 71 | PACKAGECONFIG[shared] = "--shared" |
75 | PACKAGECONFIG[zlib] = "--shared-zlib,,zlib" | 72 | PACKAGECONFIG[zlib] = "--shared-zlib,,zlib" |
76 | 73 | ||
77 | # We don't want to cross-compile during target compile, | ||
78 | # and we need to use the right flags during host compile, | ||
79 | # too. | ||
80 | EXTRA_OEMAKE = "\ | ||
81 | CC.host='${CC} -pie -fPIE' \ | ||
82 | CFLAGS.host='${CPPFLAGS} ${CFLAGS}' \ | ||
83 | CXX.host='${CXX} -pie -fPIE' \ | ||
84 | CXXFLAGS.host='${CPPFLAGS} ${CXXFLAGS}' \ | ||
85 | LDFLAGS.host='${LDFLAGS}' \ | ||
86 | AR.host='${AR}' \ | ||
87 | \ | ||
88 | builddir_name=./ \ | ||
89 | " | ||
90 | |||
91 | EXTRANATIVEPATH += "file-native" | 74 | EXTRANATIVEPATH += "file-native" |
92 | 75 | ||
93 | python prune_sources() { | 76 | python prune_sources() { |
@@ -110,9 +93,11 @@ do_unpack[postfuncs] += "prune_sources" | |||
110 | # V8's JIT infrastructure requires binaries such as mksnapshot and | 93 | # V8's JIT infrastructure requires binaries such as mksnapshot and |
111 | # mkpeephole to be run in the host during the build. However, these | 94 | # mkpeephole to be run in the host during the build. However, these |
112 | # binaries must have the same bit-width as the target (e.g. a x86_64 | 95 | # binaries must have the same bit-width as the target (e.g. a x86_64 |
113 | # host targeting ARMv6 needs to produce a 32-bit binary). Instead of | 96 | # host targeting ARMv6 needs to produce a 32-bit binary). |
114 | # depending on a third Yocto toolchain, we just build those binaries | 97 | # 1. If host and target have the different bit width, run those |
115 | # for the target and run them on the host with QEMU. | 98 | # binaries for the target and run them on the host with QEMU. |
99 | # 2. If host and target have the same bit width, enable upstream | ||
100 | # cross crompile support and no QEMU | ||
116 | python do_create_v8_qemu_wrapper () { | 101 | python do_create_v8_qemu_wrapper () { |
117 | """Creates a small wrapper that invokes QEMU to run some target V8 binaries | 102 | """Creates a small wrapper that invokes QEMU to run some target V8 binaries |
118 | on the host.""" | 103 | on the host.""" |
@@ -120,6 +105,10 @@ python do_create_v8_qemu_wrapper () { | |||
120 | d.expand('${STAGING_DIR_HOST}${base_libdir}')] | 105 | d.expand('${STAGING_DIR_HOST}${base_libdir}')] |
121 | qemu_cmd = qemu_wrapper_cmdline(d, d.getVar('STAGING_DIR_HOST'), | 106 | qemu_cmd = qemu_wrapper_cmdline(d, d.getVar('STAGING_DIR_HOST'), |
122 | qemu_libdirs) | 107 | qemu_libdirs) |
108 | |||
109 | if d.getVar("HOST_AND_TARGET_SAME_WIDTH") == "1": | ||
110 | qemu_cmd = "" | ||
111 | |||
123 | wrapper_path = d.expand('${B}/v8-qemu-wrapper.sh') | 112 | wrapper_path = d.expand('${B}/v8-qemu-wrapper.sh') |
124 | with open(wrapper_path, 'w') as wrapper_file: | 113 | with open(wrapper_path, 'w') as wrapper_file: |
125 | wrapper_file.write("""#!/bin/sh | 114 | wrapper_file.write("""#!/bin/sh |
@@ -138,6 +127,14 @@ addtask create_v8_qemu_wrapper after do_configure before do_compile | |||
138 | 127 | ||
139 | LDFLAGS:append:x86 = " -latomic" | 128 | LDFLAGS:append:x86 = " -latomic" |
140 | 129 | ||
130 | export CC_host | ||
131 | export CFLAGS_host | ||
132 | export CXX_host | ||
133 | export CXXFLAGS_host | ||
134 | export LDFLAGS_host | ||
135 | export AR_host | ||
136 | export HOST_AND_TARGET_SAME_WIDTH | ||
137 | |||
141 | CROSS_FLAGS = "--cross-compiling" | 138 | CROSS_FLAGS = "--cross-compiling" |
142 | CROSS_FLAGS:class-native = "--no-cross-compiling" | 139 | CROSS_FLAGS:class-native = "--no-cross-compiling" |
143 | 140 | ||
@@ -179,4 +176,35 @@ RDEPENDS:${PN}-npm = "bash python3-core python3-shell python3-datetime \ | |||
179 | PACKAGES =+ "${PN}-systemtap" | 176 | PACKAGES =+ "${PN}-systemtap" |
180 | FILES:${PN}-systemtap = "${datadir}/systemtap" | 177 | FILES:${PN}-systemtap = "${datadir}/systemtap" |
181 | 178 | ||
179 | do_configure[prefuncs] += "set_gyp_variables" | ||
180 | do_compile[prefuncs] += "set_gyp_variables" | ||
181 | do_install[prefuncs] += "set_gyp_variables" | ||
182 | python set_gyp_variables () { | ||
183 | if d.getVar("HOST_AND_TARGET_SAME_WIDTH") == "0": | ||
184 | # We don't want to cross-compile during target compile, | ||
185 | # and we need to use the right flags during host compile, | ||
186 | # too. | ||
187 | d.setVar("CC_host", d.getVar("CC") + " -pie -fPIE") | ||
188 | d.setVar("CFLAGS_host", d.getVar("CFLAGS")) | ||
189 | d.setVar("CXX_host", d.getVar("CXX") + " -pie -fPIE") | ||
190 | d.setVar("CXXFLAGS_host", d.getVar("CXXFLAGS")) | ||
191 | d.setVar("LDFLAGS_host", d.getVar("LDFLAGS")) | ||
192 | d.setVar("AR_host", d.getVar("AR")) | ||
193 | elif d.getVar("HOST_AND_TARGET_SAME_WIDTH") == "1": | ||
194 | # Enable upstream cross crompile support | ||
195 | d.setVar("CC_host", d.getVar("BUILD_CC")) | ||
196 | d.setVar("CFLAGS_host", d.getVar("BUILD_CFLAGS")) | ||
197 | d.setVar("CXX_host", d.getVar("BUILD_CXX")) | ||
198 | d.setVar("CXXFLAGS_host", d.getVar("BUILD_CXXFLAGS")) | ||
199 | d.setVar("LDFLAGS_host", d.getVar("BUILD_LDFLAGS")) | ||
200 | d.setVar("AR_host", d.getVar("BUILD_AR")) | ||
201 | } | ||
202 | python __anonymous () { | ||
203 | # 32 bit target and 64 bit host (x86-64 or aarch64) have different bit width | ||
204 | if d.getVar("SITEINFO_BITS") == "32" and "64" in d.getVar("BUILD_ARCH"): | ||
205 | d.setVar("HOST_AND_TARGET_SAME_WIDTH", "0") | ||
206 | else: | ||
207 | d.setVar("HOST_AND_TARGET_SAME_WIDTH", "1") | ||
208 | } | ||
209 | |||
182 | BBCLASSEXTEND = "native" | 210 | BBCLASSEXTEND = "native" |