Repository navigation
Confusion about --partly-static build #951
Description
- Node.js Version: Trying to build 8.4.0
- OS: Debian 8
- Scope: install
I'm trying to build a partly static build node 8.4.0 on a Debian 8 machine to make sure it works on a Debian 7 machine, which includes lower version of glibc—2.13 as per the libc6 package information. Once I install and run node -v, it fails with an error:
node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by node)
When I tried out a fully-static build, this doesn't fail.
Details for the partly static build:
Here is the output of config.gypi
# Do not edit. Generated by the configure script.
{ 'target_defaults': { 'cflags': [],
'default_configuration': 'Release',
'defines': [],
'include_dirs': [],
'libraries': ['-static-libgcc', '-static-libstdc++']},
'variables': { 'asan': 0,
'coverage': 'false',
'debug_devtools': 'node',
'debug_http2': 'false',
'debug_nghttp2': 'false',
'force_dynamic_crt': 0,
'gas_version': '2.25',
'host_arch': 'x64',
'icu_data_file': 'icudt59l.dat',
'icu_data_in': '../../deps/icu-small/source/data/in/icudt59l.dat',
'icu_endianness': 'l',
'icu_gyp_path': 'tools/icu/icu-generic.gyp',
'icu_locales': 'en,root',
'icu_path': 'deps/icu-small',
'icu_small': 'true',
'icu_ver_major': '59',
'node_byteorder': 'little',
'node_enable_d8': 'false',
'node_enable_v8_vtunejit': 'false',
'node_install_npm': 'true',
'node_module_version': 57,
'node_no_browser_globals': 'false',
'node_prefix': '/usr',
'node_release_urlbase': '',
'node_shared': 'false',
'node_shared_cares': 'false',
'node_shared_http_parser': 'false',
'node_shared_libuv': 'false',
'node_shared_openssl': 'false',
'node_shared_zlib': 'false',
'node_tag': '',
'node_use_bundled_v8': 'true',
'node_use_dtrace': 'false',
'node_use_etw': 'false',
'node_use_lttng': 'false',
'node_use_openssl': 'true',
'node_use_perfctr': 'false',
'node_use_v8_platform': 'true',
'node_without_node_options': 'false',
'openssl_fips': '',
'openssl_no_asm': 0,
'shlib_suffix': 'so.57',
'target_arch': 'x64',
'uv_parent_path': '/deps/uv/',
'uv_use_dtrace': 'false',
'v8_enable_gdbjit': 0,
'v8_enable_i18n_support': 1,
'v8_enable_inspector': 0,
'v8_no_strict_aliasing': 1,
'v8_optimized_debug': 0,
'v8_promise_internal_field_count': 1,
'v8_random_seed': 0,
'v8_trace_maps': 0,
'v8_use_snapshot': 'false',
'want_separate_host_toolset': 0,
'want_separate_host_toolset_mkpeephole': 0}}
This the configure and make steps I used:
./configure --partly-static --without-inspector --prefix=/usr
make
make install DESTDIR=/tmp/nodejs
And then a packaging step to create a .deb package. The installation on a Debian 7 machine works fine, but when I run the node -v, it fails loading the Glibc library.
But if I build with the --fully-static build, with the same set of rest of the commands, it works fine. I'm probably missing something very fundamental here, but I'm unable to spot it.
One more thing I noticed is the fully static build size and partly static build sizes are suspicious:
56M /tmp/nodejs-fully-static.tar
59M /tmp/nodejs-partly-static.tar
Shouldn't the size of the fully static build be larger? 🤔
Activity
bnoordhuis commentedon Nov 6, 2017
I'll start off with a caveat: static builds don't work well with glibc. It's neigh on impossible to link its libc6.a in a completely static matter because it loads parts of itself dynamically at run-time. People usually link against a libc like musl instead.
Apropos
--partly-static, that statically links against libgcc (compiler intrinsics) and libstdc++ (the C++ runtime) but not libc (the C runtime), that's why you get that GLIBC_2.14 symbol error - glibc is not backwards compatible with itself, only forward-compatible.kgrz commentedon Nov 7, 2017
Thank you for the clarification Ben. I did get confused about the libs that were getting bundled.
Is this caveat valid even when doing a
--fully-staticbuild?bnoordhuis commentedon Nov 7, 2017
Yes. glibc loads (and therefore depends on)
/lib/libnss*.so.kgrz commentedon Nov 9, 2017
Trying to understand this correctly. I tried a fully-static build with compatible glibc, and took the resultant package and tried running
nodeand my app on it on deb 7. And it worked fine. Does that mean that these lazy depedencies codepaths were never touched?bnoordhuis commentedon Nov 9, 2017
Yes, or that the libnss libraries on the target system were API/ABI-compatible enough to work with the newer glibc - or that glibc was configured with
--enable-static-nss, but that's almost certainly not the case with a distro-provided glibc.A good litmus test is
node -p 'os.userInfo()'- you should be good when that prints something sensible, as opposed to segfaulting, aborting with a dynamic linker error, etc.