Skip to content

Commit

Permalink
tools: support versioned node shared libs on z/OS
Browse files Browse the repository at this point in the history
The shared libraries will now be stores in lib.target as opposed to
obj.target, libnode.version.so, libnode.x (for npm backwards compat and
testing), and libnode.version.x (for builds). The install will also
include libnode.so link that points to libnode.version.so (this will be
used by native npms for backwards compat).

PR-URL: #42256
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Co-authored-by: Gaby Baghdadi <baghdadi@ca.ibm.com>
Co-authored-by: Wayne Zhang <shuowang.zhang@ibm.com>
  • Loading branch information
3 people authored and danielleadams committed Jul 26, 2022
1 parent e502c50 commit ed45088
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
33 changes: 33 additions & 0 deletions tools/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import shutil
import sys
import re

# set at init time
node_prefix = '/usr/local' # PREFIX variable from Makefile
Expand Down Expand Up @@ -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):
Expand All @@ -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)
Expand Down
33 changes: 33 additions & 0 deletions tools/zos/modifysidedeck.sh
Original file line number Diff line number Diff line change
@@ -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"
82 changes: 82 additions & 0 deletions tools/zos/sdwrap.py
Original file line number Diff line number Diff line change
@@ -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())

0 comments on commit ed45088

Please sign in to comment.