Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add x64-gcc-10.3.0-glibc-2.28 #2

Merged
merged 1 commit into from
Mar 31, 2023

Conversation

richardlau
Copy link
Collaborator

For Node.js 20 we're planning to update to building with gcc 10.

Refs: https://github.com/orgs/nodejs/discussions/45892
Refs: nodejs/node#47067


This is my first time using crosstool-ng. I basically copied the config for x64-gcc-8.3.0-glibc-2.28, edited the gcc version and then loaded the modified config into crosstool-ng, saved it and then built (all inside crosstool-ng's own Ubuntu 18.04 Docker container).

I've locally tested this cross compiler, copied the built binary over to Node.js' armv7l containers and was able to run the binary on Ubuntu 20.04. Unfortunately Debian 10 fails:

iojs@b0ab782bd453:~$ ./node-gcc-10.3.0
./node-gcc-10.3.0: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./node-gcc-10.3.0)
iojs@b0ab782bd453:~$

It looks like version of libstdc++ is closely tied to GCC version:

and Debian 10 only provides gcc up to 8. I haven't been able to test Debian 11, but since the default gcc in Debian 11 is 10.2 it'll probably work.
(AFAICT fixing glibc to 2.28 has worked and it's the C++ stuff that is affected.)

@rvagg
Copy link
Owner

rvagg commented Mar 31, 2023

It looks like version of libstdc++ is closely tied to GCC version:

yeah ... and no devtools goodies available to deal with that either, so you have to pick your compromise and be done with it.

The process you described - copying the existing and using crosstool-ng to adjust it, is how I would have done it too. I didn't know there was a 1.25, I think last time I ran this I was forced to use an unreleased version prior to that release.

Here's the diff of the most interesting bits of the config from the 8.3.0 one:

(hidden due to verbosity)
3c3
< # crosstool-NG  Configuration
---
> # crosstool-NG 1.25.0 Configuration
8c8,10
< CT_CONFIGURE_has_curl=y
---
> CT_CONFIGURE_has_meson=y
> CT_CONFIGURE_has_ninja=y
> CT_CONFIGURE_has_rsync=y
20,21d21
< CT_CONFIGURE_has_cvs=y
< CT_CONFIGURE_has_git=y
27,28c27,31
< CT_CONFIG_VERSION_CURRENT="3"
< CT_CONFIG_VERSION="3"
---
> CT_VERSION="1.25.0"
> CT_VCHECK=""
> CT_CONFIG_VERSION_ENV="4"
> CT_CONFIG_VERSION_CURRENT="4"
> CT_CONFIG_VERSION="4"
50a54
> CT_BUILD_DIR="${CT_BUILD_TOP_DIR}/build"
63d66
< # CT_DOWNLOAD_AGENT_CURL is not set
98a102
> CT_EXTRA_CXXFLAGS_FOR_BUILD=""
159c166
< CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA"
---
> CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR C6X M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC PRU RISCV S390 SH SPARC X86 XTENSA"
263a273,275
> CT_LINUX_USE_WWW_KERNEL_ORG=y
> CT_LINUX_USE="LINUX"
295,296c322
< CT_LINUX_VERSION="4.4.174"
---
> CT_LINUX_VERSION="4.4.302"
301a328,331
> CT_LINUX_5_12_or_older=y
> CT_LINUX_older_than_5_12=y
> CT_LINUX_5_3_or_older=y
> CT_LINUX_older_than_5_3=y
308a339
> CT_KERNEL_DEP_RSYNC=y
366,370c405,406
< CT_BINUTILS_later_than_2_25=y
< CT_BINUTILS_2_25_or_later=y
< CT_BINUTILS_REQUIRE_2_25_or_later=y
< CT_BINUTILS_later_than_2_23=y
< CT_BINUTILS_2_23_or_later=y
---
> CT_BINUTILS_later_than_2_26=y
> CT_BINUTILS_2_26_or_later=y
375,378d410
< CT_BINUTILS_HAS_HASH_STYLE=y
< CT_BINUTILS_HAS_GOLD=y
< CT_BINUTILS_HAS_PLUGINS=y
< CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
384a417
> CT_BINUTILS_DETERMINISTIC_ARCHIVES=y
435a474,481
> CT_GLIBC_2_34_or_older=y
> CT_GLIBC_older_than_2_34=y
> CT_GLIBC_2_32_or_older=y
> CT_GLIBC_older_than_2_32=y
> CT_GLIBC_2_31_or_older=y
> CT_GLIBC_older_than_2_31=y
> CT_GLIBC_2_30_or_older=y
> CT_GLIBC_older_than_2_30=y
437a484,485
> CT_GLIBC_2_28_or_later=y
> CT_GLIBC_2_28_or_older=y
457a506
> CT_GLIBC_SPARC_ALLOW_V7=y
475c524
< CT_GLIBC_MIN_KERNEL="4.4.174"
---
> CT_GLIBC_MIN_KERNEL="4.4.302"
482c531,532
< CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
---
> CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC_NG"
496,498c547
< CT_CC_CORE_PASSES_NEEDED=y
< CT_CC_CORE_PASS_1_NEEDED=y
< CT_CC_CORE_PASS_2_NEEDED=y
---
> CT_CC_CORE_NEEDED=y
529c578,581
< CT_GCC_V_8=y
---
> CT_GCC_V_10=y
534,535c586
< CT_GCC_VERSION="8.3.0"
---
> CT_GCC_VERSION="10.3.0"
540a592,599
> CT_GCC_11_or_older=y
> CT_GCC_older_than_11=y
> CT_GCC_later_than_10=y
> CT_GCC_10_or_later=y
> CT_GCC_later_than_9=y
> CT_GCC_9_or_later=y
> CT_GCC_later_than_8=y
> CT_GCC_8_or_later=y
550,551d608
< CT_GCC_later_than_4_8=y
< CT_GCC_4_8_or_later=y
578a636
> CT_CC_GCC_TM_CLONE_REGISTRY=m
588,590c646,648
< CT_CC_GCC_DEC_FLOAT_AUTO=y
---
> CT_CC_GCC_DEC_FLOATS_AUTO=y
591a650
> CT_CC_GCC_DEC_FLOATS=""
641a704,705
> CT_GETTEXT_0_21_or_older=y
> CT_GETTEXT_older_than_0_21=y
664,668d727
< CT_GMP_later_than_5_1_0=y
< CT_GMP_5_1_0_or_later=y
< CT_GMP_later_than_5_0_0=y
< CT_GMP_5_0_0_or_later=y
< CT_GMP_REQUIRE_5_0_0_or_later=y
700,708d761
< CT_ISL_REQUIRE_0_15_or_later=y
< CT_ISL_later_than_0_14=y
< CT_ISL_0_14_or_later=y
< CT_ISL_REQUIRE_0_14_or_later=y
< CT_ISL_later_than_0_13=y
< CT_ISL_0_13_or_later=y
< CT_ISL_later_than_0_12=y
< CT_ISL_0_12_or_later=y
< CT_ISL_REQUIRE_0_12_or_later=y
782,784d834
< CT_MPFR_later_than_3_0_0=y
< CT_MPFR_3_0_0_or_later=y
< CT_MPFR_REQUIRE_3_0_0_or_later=y
803c853
< CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)"
---
> CT_NCURSES_MIRRORS="https://invisible-mirror.net/archives/ncurses $(CT_Mirrors GNU ncurses)"
816c866
< CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB"
---
> CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP GNUPRUMCU ISL LIBELF LIBICONV MPC MPFR NCURSES NEWLIB_NANO PICOLIBC ZLIB"

The only two things I'd flag as interesting are the kernel version and binutils bump. Does it give the option to change min kernel version, and is it possible with 10.3 to go back to kernel 4.4.174? Or is 4.4.302 the lowest we can get? The binutils bump from 2.25 to 2.26 is interesting too, was that a forced decision or was that optional? Generally I've tried to keep versions as low as possible while getting a functional toolchain, and it mostly does that work for you in limiting your options so I imagine these were both forced decisions.

I'm fine with this if you are, I'll give you commit access to this repo so I'm not blocking for getting things like this in.

@richardlau
Copy link
Collaborator Author

The process you described - copying the existing and using crosstool-ng to adjust it, is how I would have done it too. I didn't know there was a 1.25, I think last time I ran this I was forced to use an unreleased version prior to that release.
...
The only two things I'd flag as interesting are the kernel version and binutils bump. Does it give the option to change min kernel version, and is it possible with 10.3 to go back to kernel 4.4.174? Or is 4.4.302 the lowest we can get? The binutils bump from 2.25 to 2.26 is interesting too, was that a forced decision or was that optional? Generally I've tried to keep versions as low as possible while getting a functional toolchain, and it mostly does that work for you in limiting your options so I imagine these were both forced decisions.

With crosstool-ng 1.25:

@richardlau
Copy link
Collaborator Author

In terms of Linux kernel I'm not too concerned. Our current BUILDING.md lists kernel >=4.18 for armv7 with a footnote

Older kernel versions may work. However official Node.js release binaries are built on RHEL 8 systems with kernel 4.18.

("Built on RHEL 8" is true as we're cross compiling on a RHEL8 x64 host.)
Even Node.js 12 had Linux kernel for armv7 listed as >=4.14 (nodejs/node#26714).

@richardlau
Copy link
Collaborator Author

richardlau commented Mar 31, 2023

Oh, in terms of binutils, both x64-gcc-8.3.0-glibc-2.28.config and the x64-gcc-10.3.0-glibc-2.28.config in this PR are actually on 2.28.1 -- the confusion/diff is probably because crosstool-ng moved the lowest supported binutils to 2.26 and renamed some of their variables:

# CT_BINUTILS_V_2_32 is not set
# CT_BINUTILS_V_2_31 is not set
# CT_BINUTILS_V_2_30 is not set
# CT_BINUTILS_V_2_29 is not set
CT_BINUTILS_V_2_28=y
# CT_BINUTILS_V_2_27 is not set
# CT_BINUTILS_V_2_26 is not set
# CT_BINUTILS_NO_VERSIONS is not set
CT_BINUTILS_VERSION="2.28.1"

# CT_BINUTILS_V_2_38 is not set
# CT_BINUTILS_V_2_37 is not set
# CT_BINUTILS_V_2_36 is not set
# CT_BINUTILS_V_2_35 is not set
# CT_BINUTILS_V_2_34 is not set
# CT_BINUTILS_V_2_33 is not set
# CT_BINUTILS_V_2_32 is not set
# CT_BINUTILS_V_2_31 is not set
# CT_BINUTILS_V_2_30 is not set
# CT_BINUTILS_V_2_29 is not set
CT_BINUTILS_V_2_28=y
# CT_BINUTILS_V_2_27 is not set
# CT_BINUTILS_V_2_26 is not set
CT_BINUTILS_VERSION="2.28.1"

@richardlau richardlau merged commit 2e82ef5 into rvagg:master Mar 31, 2023
@richardlau richardlau deleted the gcc-10.3.0-glibc-2.28 branch March 31, 2023 16:28
@richardlau
Copy link
Collaborator Author

richardlau commented Mar 31, 2023

and Debian 10 only provides gcc up to 8. I haven't been able to test Debian 11, but since the default gcc in Debian 11 is 10.2 it'll probably work. (AFAICT fixing glibc to 2.28 has worked and it's the C++ stuff that is affected.)

I've now been able to test armv7 Debian 11 and that is okay with the cross-compiled Node.js 20.0.0-pre binary compiled with the toolchain from this PR.

Also the 10-buster image from https://hub.docker.com/r/arm32v7/gcc can run the generated binary -- that ends up linking at runtime to gcc 10's libstdc++ instead of the system one:

root@test-equinix-ubuntu2004-docker-arm64-1:~# docker run -it -v /tmp/gcc-test/:/tmp/node/ node-ci:test-equinix-debian10_container-armv7l-1 ldd /tmp/node/node-gcc-10.3.0
WARNING: The requested image's platform (linux/arm/v7) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
/tmp/node/node-gcc-10.3.0: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by /tmp/node/node-gcc-10.3.0)
        libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xf7a4a000)
        libatomic.so.1 => /usr/lib/arm-linux-gnueabihf/libatomic.so.1 (0xf7a33000)
        libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0xf7928000)
        libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xf78ad000)
        libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xf7884000)
        libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xf785f000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xf7765000)
        /lib/ld-linux-armhf.so.3 (0xf7a5d000)
root@test-equinix-ubuntu2004-docker-arm64-1:~# docker run -it -v /tmp/gcc-test/:/tmp/node/ arm32v7/gcc:10-buster ldd /tmp/node/node-gcc-10.3.0
WARNING: The requested image's platform (linux/arm/v7) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
        libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xf7d3c000)
        libatomic.so.1 => /usr/local/lib/libatomic.so.1 (0xf7d25000)
        libstdc++.so.6 => /usr/local/lib/libstdc++.so.6 (0xf7be2000)
        libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xf7b67000)
        libgcc_s.so.1 => /usr/local/lib/libgcc_s.so.1 (0xf7b3c000)
        libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xf7b17000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xf7a1d000)
        /lib/ld-linux-armhf.so.3 (0xf7d4f000)
root@test-equinix-ubuntu2004-docker-arm64-1:~#

richardlau added a commit to nodejs/build that referenced this pull request Apr 3, 2023
Update RHEL 8 container used for cross compiling for armv7.
Add logic to select gcc 10 toolchain for Node.js 20 onwards.
Install gcc-toolset-10 host compiler.

Refs: rvagg/rpi-newer-crosstools#2
Refs: https://github.com/orgs/nodejs/discussions/45892
Refs: nodejs/node#47067
targos pushed a commit to targos/nodejs-build that referenced this pull request Apr 7, 2023
Update RHEL 8 container used for cross compiling for armv7.
Add logic to select gcc 10 toolchain for Node.js 20 onwards.
Install gcc-toolset-10 host compiler.

Refs: rvagg/rpi-newer-crosstools#2
Refs: https://github.com/orgs/nodejs/discussions/45892
Refs: nodejs/node#47067
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants