From 1167f85d963bf6a7c66450540cbd65975ff403a0 Mon Sep 17 00:00:00 2001 From: Gaby Baghdadi Date: Thu, 1 Oct 2026 16:52:45 -0400 Subject: [PATCH 1/3] build: update configure.py for z/OS - Compile gen/icudt*.c instead of .S. - Check required environment variables and configure.py args are set. - Remove no-longer needed variables. Signed-off-by: Gaby Baghdadi --- configure.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/configure.py b/configure.py index e769236cebe8..062a5b8a8907 100755 --- a/configure.py +++ b/configure.py @@ -848,7 +848,7 @@ static_optgroup.add_argument('--static-zoslib-gyp', action='store', dest='static_zoslib_gyp', - help='path to zoslib.gyp file for includes and to link to static zoslib library') + help='path to zoslib.gyp file for includes and to link to static zoslib libraries') parser.add_argument('--tag', action='store', @@ -1865,12 +1865,13 @@ def configure_mips(o, target_arch): o['variables']['v8_host_byteorder'] = host_byteorder def configure_zos(o): - o['variables']['node_static_zoslib'] = b(True) - if options.static_zoslib_gyp: - # Apply to all Node.js components for now - o['variables']['zoslib_include_dir'] = Path(options.static_zoslib_gyp).parent / 'include' + if 'ZOSLIB_INCLUDES' in os.environ and os.environ['ZOSLIB_INCLUDES']: + o['variables']['zoslib_include_dir'] = os.environ['ZOSLIB_INCLUDES'] o['include_dirs'] += [o['variables']['zoslib_include_dir']] else: + raise Exception('Environment variable ZOSLIB_INCLUDES= is required.') + + if not options.static_zoslib_gyp: raise Exception('--static-zoslib-gyp= is required.') def clang_version_ge(version_checked): @@ -2795,8 +2796,8 @@ def icu_download(path): icu_config['variables']['icu_asm_ext'] = 'S' icu_config['variables']['icu_asm_opts'] = [ '-a', 'xlc' ] elif sys.platform == 'zos': - icu_config['variables']['icu_asm_ext'] = 'S' - icu_config['variables']['icu_asm_opts'] = [ '-a', 'zos' ] + icu_config['variables']['icu_asm_ext'] = 'c' + icu_config['variables']['icu_asm_opts'] = [] else: # assume GCC-compatible asm is OK icu_config['variables']['icu_asm_ext'] = 'S' From 40e320cfeddebec199fe918c4c351ec86966759f Mon Sep 17 00:00:00 2001 From: Gaby Baghdadi Date: Thu, 1 Oct 2026 16:53:46 -0400 Subject: [PATCH 2/3] build: update common.gypi for z/OS - Don't use icu data file on z/OS; use libnode's bundled ICU data. - Include required defines, cflags, ldflags, and remove unsupported ones, following switch to clang compiler. - Remove _ALL_SOURCE, as _POSIX_C_SOURCE and _POSIX_SOURCE already enable all required library functions (in deps/uv/CMakeLists.txt, only _OPEN_SYS is required to enable setgroups (in grp.h) instead of _ALL_SOURCE); also remove dup _OPEN_SYS_SOCK_IPV6. - Add -D_EXT to defines (for setenv, and vsam.js' `__KEY_*` macros). - Add _POSIX_C_SOURCE=200809L to enable at least `utimensat`. - Add clang option -mzos-target=zosv2r5 also to ldflags, otherwise the default LE dataset is used that may not be for the current target. - Add -m64 to ldflags, otherwise ld passes `AMODE=31,LIST,..` to the binder, causing unresolved symbols if the non-64 suffixed version of the compiler was used (e.g. ibm-clang instead of ibm-clang64). - Add zoslib/include-wrappers/c++ in include_dirs for custom aligned new and delete operators. Signed-off-by: Gaby Baghdadi --- common.gypi | 58 ++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/common.gypi b/common.gypi index ce50adc016ea..96a8125f7dda 100644 --- a/common.gypi +++ b/common.gypi @@ -129,10 +129,6 @@ ['OS=="linux" or OS=="openharmony"', { 'node_section_ordering_info%': '' }], - ['OS == "zos"', { - # use ICU data file on z/OS - 'icu_use_data_file_flag%': 1 - }] ], }, @@ -227,11 +223,7 @@ # pull in V8's postmortem metadata 'ldflags': [ '-Wl,-z,allextract' ] }], - ['OS=="zos"', { - # increase performance, number from experimentation - 'cflags': [ '-qINLINE=::150:100000' ] - }], - ['OS!="mac" and OS!="win" and OS!="zos"', { + ['OS!="mac" and OS!="win"', { # -fno-omit-frame-pointer is necessary for the --perf_basic_prof # flag to work correctly. perf(1) gets confused about JS stack # frames otherwise, even with --call-graph dwarf. @@ -485,7 +477,7 @@ [ 'target_arch=="arm64"', { 'msvs_configuration_platform': 'arm64', }], - ['asan == 1 and OS != "mac" and OS != "zos"', { + ['asan == 1 and OS != "mac"', { 'cflags+': [ '-fno-omit-frame-pointer', '-fsanitize=address', @@ -513,7 +505,7 @@ }], ], }], - ['ubsan == 1 and OS != "mac" and OS != "zos"', { + ['ubsan == 1 and OS != "mac"', { 'cflags+': [ '-fno-omit-frame-pointer', '-fsanitize=undefined', @@ -596,11 +588,11 @@ 'NOMINMAX', ], }], - [ 'OS in "linux freebsd openbsd solaris aix os400 openharmony"', { + [ 'OS in "linux freebsd openbsd solaris aix os400 openharmony zos"', { 'cflags': [ '-pthread' ], 'ldflags': [ '-pthread' ], }], - [ 'OS in "linux freebsd openbsd solaris android aix os400 cloudabi openharmony"', { + [ 'OS in "linux freebsd openbsd solaris android aix os400 cloudabi openharmony zos"', { 'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', ], 'cflags_cc': [ '-fno-rtti', @@ -619,6 +611,9 @@ 'cflags': [ '-I/usr/local/include' ], 'ldflags': [ '-Wl,-z,wxneeded' ], }], + [ 'OS=="zos"', { + 'ldflags!': [ '-rdynamic' ], + }], ['_toolset=="host"', { 'conditions': [ [ 'host_arch=="ia32"', { @@ -837,6 +832,8 @@ }], ['OS == "zos"', { 'defines': [ + 'ZOSLIB_OVERRIDE_CLIB', + 'ZOSLIB_ALIGNED_NEWDEL', '_XOPEN_SOURCE_EXTENDED', '_XOPEN_SOURCE=600', '_UNIX03_THREADS', @@ -844,40 +841,37 @@ '_UNIX03_SOURCE', '_OPEN_SYS_SOCK_IPV6', '_OPEN_SYS_FILE_EXT=1', + '_POSIX_C_SOURCE=200809L', '_POSIX_SOURCE', '_OPEN_SYS', '_OPEN_SYS_IF_EXT', - '_OPEN_SYS_SOCK_IPV6', '_OPEN_MSGQ_EXT', '_LARGE_TIME_API', - '_ALL_SOURCE', '_AE_BIMODAL=1', - '__IBMCPP_TR1__', + '_EXT', 'NODE_PLATFORM="os390"', 'PATH_MAX=1024', '_ENHANCED_ASCII_EXT=0xFFFFFFFF', - '_Export=extern', - '__static_assert=static_assert', ], 'cflags': [ - '-q64', - '-Wc,DLL', - '-Wa,GOFF', - '-qARCH=10', - '-qASCII', - '-qTUNE=12', - '-qENUM=INT', - '-qEXPORTALL', - '-qASM', - ], - 'cflags_cc': [ - '-qxclang=-std=c++14', + '-fno-short-enums', + '-fno-xl-pragma-pack', + '-fstack-protector', + '-fvisibility=default', + '-fzos-le-char-mode=ascii', + '-m64', + '-march=z14', + '-mzos-target=zosv2r5', ], 'ldflags': [ - '-q64', + '-m64', + '-mzos-target=zosv2r5', ], # for addons due to v8config.h include of "zos-base.h": - 'include_dirs': ['<(zoslib_include_dir)'], + 'include_dirs': [ + '<(zoslib_include_dir)', + '<(zoslib_include_dir)/include-wrappers/c++', + ], }], ], } From e3b0b2d4db79fc040bd7567cc52985699966cfbf Mon Sep 17 00:00:00 2001 From: Gaby Baghdadi Date: Fri, 2 Oct 2026 09:57:13 -0400 Subject: [PATCH 3/3] build: use dict.get() in configure.py Signed-off-by: Gaby Baghdadi --- configure.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index 062a5b8a8907..acda6a16c96c 100755 --- a/configure.py +++ b/configure.py @@ -1865,8 +1865,8 @@ def configure_mips(o, target_arch): o['variables']['v8_host_byteorder'] = host_byteorder def configure_zos(o): - if 'ZOSLIB_INCLUDES' in os.environ and os.environ['ZOSLIB_INCLUDES']: - o['variables']['zoslib_include_dir'] = os.environ['ZOSLIB_INCLUDES'] + if os.environ.get('ZOSLIB_INCLUDES'): + o['variables']['zoslib_include_dir'] = os.environ.get('ZOSLIB_INCLUDES') o['include_dirs'] += [o['variables']['zoslib_include_dir']] else: raise Exception('Environment variable ZOSLIB_INCLUDES= is required.')