Skip to content
Permalink
Browse files
tools: support versioned node shared libs on z/OS
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 ed45088c148b8a79e0fd07de1abec5842ab742d2
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
@@ -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)
@@ -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"
@@ -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.