diff --git a/tools/install.py b/tools/install.py index 47e9d8bd7a1ae5..5793b581f774db 100755 --- a/tools/install.py +++ b/tools/install.py @@ -7,6 +7,7 @@ import os import shutil import sys +import re # set at init time node_prefix = '/usr/local' # PREFIX variable from Makefile @@ -120,6 +121,17 @@ def corepack_files(action): # 'pnpx': 'dist/pnpx.js', }) + # On z/OS, we install node-gyp for convenience, as some vendors don't have + # external access and may want to build native addons. + if sys.platform == 'zos': + link_path = abspath(install_path, 'bin/node-gyp') + if action == uninstall: + action([link_path], 'bin/node-gyp') + elif action == install: + try_symlink('../lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js', link_path) + else: + assert 0 # unhandled action type + def subdir_files(path, dest, action): ret = {} for dirpath, dirnames, filenames in os.walk(path): @@ -141,6 +153,27 @@ def files(action): if is_windows: action([output_prefix + 'libnode.dll'], 'bin/libnode.dll') action([output_prefix + 'libnode.lib'], 'lib/libnode.lib') + elif sys.platform == 'zos': + # GYP will output to lib.target; see _InstallableTargetInstallPath + # function in tools/gyp/pylib/gyp/generator/make.py + output_prefix += 'lib.target/' + + output_lib = 'libnode.' + variables.get('shlib_suffix') + action([output_prefix + output_lib], 'lib/' + output_lib) + + # create libnode.x that references libnode.so (C++ addons compat) + os.system(os.path.dirname(os.path.realpath(__file__)) + + '/zos/modifysidedeck.sh ' + + abspath(install_path, 'lib/' + output_lib) + ' ' + + abspath(install_path, 'lib/libnode.x') + ' libnode.so') + + # install libnode.version.so + so_name = 'libnode.' + re.sub(r'\.x$', '.so', variables.get('shlib_suffix')) + action([output_prefix + so_name], 'lib/' + so_name) + + # create symlink of libnode.so -> libnode.version.so (C++ addons compat) + link_path = abspath(install_path, 'lib/libnode.so') + try_symlink(so_name, link_path) else: output_lib = 'libnode.' + variables.get('shlib_suffix') action([output_prefix + output_lib], 'lib/' + output_lib) diff --git a/tools/zos/modifysidedeck.sh b/tools/zos/modifysidedeck.sh new file mode 100755 index 00000000000000..a29a2386905134 --- /dev/null +++ b/tools/zos/modifysidedeck.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +if [ "$#" -ne 3 ] || ! [ -f "$1" ]; then + echo =========================== + echo "Script to modify sidedeck references to a new DLL name" + echo =========================== + echo "Usage: $0 originalsidedeck modifiedsidedeck newdllreference" >&2 + exit 1 +fi + +originalsidedeck=$1 +outputsidedeck=$2 +newdllname=$3 + +SCRIPT_DIR=$(dirname "$0") +ID=`date +%C%y%m%d_%H%M%S` +TMP="/tmp/sidedeck-$(basename "$0").$ID.tmp" +TMP2="/tmp/sidedeck-$(basename "$0").$ID.tmp.2" + +# Remove on exit/interrupt +trap '/bin/rm -rf "$TMP" "$TMP2" && exit' EXIT INT TERM QUIT HUP + +set -x +dd conv=unblock cbs=80 if="$originalsidedeck" of="$TMP" +chtag -tc 1047 "$TMP" +"$SCRIPT_DIR"/sdwrap.py -u -i "$TMP" -o "$TMP2" +chtag -tc 819 "$TMP2" +sed -e "s/\(^ IMPORT \(DATA\|CODE\)64,\)'[^']*'/\1'$newdllname'/g" "$TMP2" > "$TMP" +"$SCRIPT_DIR"/sdwrap.py -i "$TMP" -o "$TMP2" + +# Reformat sidedeck to be USS compatible +iconv -f ISO8859-1 -t IBM-1047 "$TMP2" > "$TMP" +dd conv=block cbs=80 if="$TMP" of="$outputsidedeck" diff --git a/tools/zos/sdwrap.py b/tools/zos/sdwrap.py new file mode 100755 index 00000000000000..5253d945f40892 --- /dev/null +++ b/tools/zos/sdwrap.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +import argparse +import sys + +def wrap(args): + l = args.input.readline(72) + firstline = True + while l: + if l[-1] == '\n': + if firstline: + outstr = "{}".format(l) + else: + outstr = " {}".format(l) + firstline = True + l = args.input.readline(72) + else: + if firstline: + outstr = "{:<71}*\n".format(l[:-1]) + firstline = False + else: + outstr = " {:<70}*\n".format(l[:-1]) + l = l[-1] + args.input.readline(70) + args.output.write(outstr) + + return 0 + +def unwrap(args): + l = args.input.readline() + firstline = True + while l: + if len(l) > 80: + print("Error: input line invalid (longer than 80 characters)", file=sys.stderr) + return 1 + if not firstline and l[0] != ' ': + print("Error: continuation line not start with blank", file=sys.stderr) + return 1 + + if len(l) > 71 and l[71] == '*': + if firstline: + args.output.write(l[:71]) + firstline = False + else: + args.output.write(l[1:71]) + else: + if firstline: + args.output.write(l) + else: + args.output.write(l[1:]) + firstline = True + l = args.input.readline() + return 0 + +def Main(): + parser = argparse.ArgumentParser(description="Wrap sidedeck source to card formats") + parser.add_argument("-u", "--unwrap", + help="Unwrap sidedeck cards to source formats instead", action="store_true", + default=False) + parser.add_argument("-i", "--input", help="input filename, default to stdin", + action="store", default=None) + parser.add_argument("-o", "--output", help="output filename, default to stdout", + action="store", default=None) + + args = parser.parse_args() + + if args.input is None: + args.input = sys.stdin + else: + args.input = open(args.input, 'r') + + if args.output is None: + args.output = sys.stdout + else: + args.output = open(args.output, 'w') + + if args.unwrap: + return unwrap(args) + + return wrap(args) + +if __name__ == '__main__': + sys.exit(Main())