From df291fefec2e944eb1cc6d57f58ba29d1f7eb148 Mon Sep 17 00:00:00 2001 From: alexcfyung Date: Thu, 6 Jan 2022 10:54:32 -0500 Subject: [PATCH] build: start build on z/OS Update configure.py, Makefile, and common.gypi to get the build started on z/OS. Co-authored-by: Gaby Baghdadi Co-authored-by: Wayne Zhang PR-URL: https://github.com/nodejs/node/pull/41273 Reviewed-By: Richard Lau Reviewed-By: Michael Dawson Reviewed-By: Ujjwal Sharma --- Makefile | 10 ++++++++++ common.gypi | 56 +++++++++++++++++++++++++++++++++++++++++++++++++--- configure.py | 35 +++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index e25baa475bfa24..a2ffd0652a6696 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,9 @@ TEST_CI_ARGS ?= STAGINGSERVER ?= node-www LOGLEVEL ?= silent OSTYPE := $(shell uname -s | tr '[:upper:]' '[:lower:]') +ifeq ($(findstring os/390,$OSTYPE),os/390) +OSTYPE ?= os390 +endif ARCHTYPE := $(shell uname -m | tr '[:upper:]' '[:lower:]') COVTESTS ?= test-cov COV_SKIP_TESTS ?= core_line_numbers.js,testFinalizer.js,test_function/test.js @@ -824,6 +827,9 @@ endif # ifeq ($(DISTTYPE),release) DISTTYPEDIR ?= $(DISTTYPE) RELEASE=$(shell sed -ne 's/\#define NODE_VERSION_IS_RELEASE \([01]\)/\1/p' src/node_version.h) PLATFORM=$(shell uname | tr '[:upper:]' '[:lower:]') +ifeq ($(findstring os/390,$PLATFORM),os/390) +PLATFORM ?= os390 +endif NPMVERSION=v$(shell cat deps/npm/package.json | grep '"version"' | sed 's/^[^:]*: "\([^"]*\)",.*/\1/') UNAME_M=$(shell uname -m) @@ -845,6 +851,9 @@ else ifeq ($(findstring s390,$(UNAME_M)),s390) DESTCPU ?= s390 else +ifeq ($(findstring OS/390,$(shell uname -s)),OS/390) +DESTCPU ?= s390x +else ifeq ($(findstring arm64,$(UNAME_M)),arm64) DESTCPU ?= arm64 else @@ -872,6 +881,7 @@ endif endif endif endif +endif ifeq ($(DESTCPU),x64) ARCH=x64 else diff --git a/common.gypi b/common.gypi index b6e8ddd8bd349a..6f1a7a0e3c7f4d 100644 --- a/common.gypi +++ b/common.gypi @@ -109,6 +109,10 @@ }], ['OS=="linux"', { 'node_section_ordering_info%': '' + }], + ['OS == "zos"', { + # use ICU data file on z/OS + 'icu_use_data_file_flag%': 1 }] ], }, @@ -200,7 +204,11 @@ # pull in V8's postmortem metadata 'ldflags': [ '-Wl,-z,allextract' ] }], - ['OS!="mac" and OS!="win"', { + ['OS=="zos"', { + # increase performance, number from experimentation + 'cflags': [ '-qINLINE=::150:100000' ] + }], + ['OS!="mac" and OS!="win" and OS!="zos"', { 'cflags': [ '-fno-omit-frame-pointer' ], }], ['OS=="linux"', { @@ -327,7 +335,7 @@ [ 'target_arch=="arm64"', { 'msvs_configuration_platform': 'arm64', }], - ['asan == 1 and OS != "mac"', { + ['asan == 1 and OS != "mac" and OS != "zos"', { 'cflags+': [ '-fno-omit-frame-pointer', '-fsanitize=address', @@ -419,7 +427,7 @@ 'cflags': [ '-m64', '-mminimal-toc' ], 'ldflags': [ '-m64' ], }], - [ 'target_arch=="s390x"', { + [ 'target_arch=="s390x" and OS=="linux"', { 'cflags': [ '-m64', '-march=z196' ], 'ldflags': [ '-m64', '-march=z196' ], }], @@ -566,6 +574,48 @@ 'OPENSSL_NO_ASM', ], }], + ['OS == "zos"', { + 'defines': [ + '_XOPEN_SOURCE_EXTENDED', + '_XOPEN_SOURCE=600', + '_UNIX03_THREADS', + '_UNIX03_WITHDRAWN', + '_UNIX03_SOURCE', + '_OPEN_SYS_SOCK_IPV6', + '_OPEN_SYS_FILE_EXT=1', + '_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__', + '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', + ], + 'ldflags': [ + '-q64', + ], + }], ], } } diff --git a/configure.py b/configure.py index 817bcbf8bfc570..3209c5a6472986 100755 --- a/configure.py +++ b/configure.py @@ -62,6 +62,9 @@ "Flags that allows you to control whether you want to build against " "built-in dependencies or its shared representations. If necessary, " "provide multiple libraries with comma.") +static_optgroup = parser.add_argument_group("Static libraries", + "Flags that allows you to control whether you want to build against " + "additional static libraries.") intl_optgroup = parser.add_argument_group("Internationalization", "Flags that lets you enable i18n features in Node.js as well as which " "library you want to build against.") @@ -413,6 +416,13 @@ parser.add_argument_group(shared_optgroup) +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 libray') + +parser.add_argument_group(static_optgroup) + parser.add_argument('--systemtap-includes', action='store', dest='systemtap_includes', @@ -859,7 +869,11 @@ def try_check_compiler(cc, lang): proc.stdin.write(b'__clang__ __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ ' b'__clang_major__ __clang_minor__ __clang_patchlevel__') - values = (to_utf8(proc.communicate()[0]).split() + ['0'] * 7)[0:7] + if sys.platform == 'zos': + values = (to_utf8(proc.communicate()[0]).split('\n')[-2].split() + ['0'] * 7)[0:7] + else: + values = (to_utf8(proc.communicate()[0]).split() + ['0'] * 7)[0:7] + is_clang = values[0] == '1' gcc_version = tuple(map(int, values[1:1+3])) clang_version = tuple(map(int, values[4:4+3])) if is_clang else None @@ -1046,6 +1060,8 @@ def is_arm_hard_float_abi(): def host_arch_cc(): """Host architecture check using the CC command.""" + if sys.platform.startswith('zos'): + return 's390x' k = cc_macros(os.environ.get('CC_host')) matchup = { @@ -1131,6 +1147,14 @@ def configure_mips(o, target_arch): host_byteorder = 'little' if target_arch in ('mipsel', 'mips64el') else 'big' 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['include_dirs'] += [os.path.dirname(options.static_zoslib_gyp) + '/include'] + else: + raise Exception('--static-zoslib-gyp= is required.') + def clang_version_ge(version_checked): for compiler in [(CC, 'c'), (CXX, 'c++')]: ok, is_clang, clang_version, gcc_version = \ @@ -1200,6 +1224,8 @@ def configure_node(o): configure_arm(o) elif target_arch in ('mips', 'mipsel', 'mips64el'): configure_mips(o, target_arch) + elif sys.platform == 'zos': + configure_zos(o) if flavor == 'aix': o['variables']['node_target_type'] = 'static_library' @@ -1312,6 +1338,8 @@ def configure_node(o): shlib_suffix = '%s.dylib' elif sys.platform.startswith('aix'): shlib_suffix = '%s.a' + elif sys.platform.startswith('zos'): + shlib_suffix = '%s.x' else: shlib_suffix = 'so.%s' if '%s' in shlib_suffix: @@ -1402,6 +1430,8 @@ def configure_v8(o): o['variables']['test_isolation_mode'] = 'noop' # Needed by d8.gyp. if options.without_bundled_v8 and options.enable_d8: raise Exception('--enable-d8 is incompatible with --without-bundled-v8.') + if options.static_zoslib_gyp: + o['variables']['static_zoslib_gyp'] = options.static_zoslib_gyp def configure_openssl(o): @@ -1805,6 +1835,9 @@ def icu_download(path): elif sys.platform.startswith('aix'): 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' ] else: # assume GCC-compatible asm is OK icu_config['variables']['icu_asm_ext'] = 'S'