Skip to content

Commit ed45088

Browse files
alexcfyunggabylbzsw007
authored andcommitted
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 <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Co-authored-by: Gaby Baghdadi <[email protected]> Co-authored-by: Wayne Zhang <[email protected]>
1 parent e502c50 commit ed45088

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

tools/install.py

+33
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import shutil
99
import sys
10+
import re
1011

1112
# set at init time
1213
node_prefix = '/usr/local' # PREFIX variable from Makefile
@@ -120,6 +121,17 @@ def corepack_files(action):
120121
# 'pnpx': 'dist/pnpx.js',
121122
})
122123

124+
# On z/OS, we install node-gyp for convenience, as some vendors don't have
125+
# external access and may want to build native addons.
126+
if sys.platform == 'zos':
127+
link_path = abspath(install_path, 'bin/node-gyp')
128+
if action == uninstall:
129+
action([link_path], 'bin/node-gyp')
130+
elif action == install:
131+
try_symlink('../lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js', link_path)
132+
else:
133+
assert 0 # unhandled action type
134+
123135
def subdir_files(path, dest, action):
124136
ret = {}
125137
for dirpath, dirnames, filenames in os.walk(path):
@@ -141,6 +153,27 @@ def files(action):
141153
if is_windows:
142154
action([output_prefix + 'libnode.dll'], 'bin/libnode.dll')
143155
action([output_prefix + 'libnode.lib'], 'lib/libnode.lib')
156+
elif sys.platform == 'zos':
157+
# GYP will output to lib.target; see _InstallableTargetInstallPath
158+
# function in tools/gyp/pylib/gyp/generator/make.py
159+
output_prefix += 'lib.target/'
160+
161+
output_lib = 'libnode.' + variables.get('shlib_suffix')
162+
action([output_prefix + output_lib], 'lib/' + output_lib)
163+
164+
# create libnode.x that references libnode.so (C++ addons compat)
165+
os.system(os.path.dirname(os.path.realpath(__file__)) +
166+
'/zos/modifysidedeck.sh ' +
167+
abspath(install_path, 'lib/' + output_lib) + ' ' +
168+
abspath(install_path, 'lib/libnode.x') + ' libnode.so')
169+
170+
# install libnode.version.so
171+
so_name = 'libnode.' + re.sub(r'\.x$', '.so', variables.get('shlib_suffix'))
172+
action([output_prefix + so_name], 'lib/' + so_name)
173+
174+
# create symlink of libnode.so -> libnode.version.so (C++ addons compat)
175+
link_path = abspath(install_path, 'lib/libnode.so')
176+
try_symlink(so_name, link_path)
144177
else:
145178
output_lib = 'libnode.' + variables.get('shlib_suffix')
146179
action([output_prefix + output_lib], 'lib/' + output_lib)

tools/zos/modifysidedeck.sh

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/sh
2+
3+
if [ "$#" -ne 3 ] || ! [ -f "$1" ]; then
4+
echo ===========================
5+
echo "Script to modify sidedeck references to a new DLL name"
6+
echo ===========================
7+
echo "Usage: $0 originalsidedeck modifiedsidedeck newdllreference" >&2
8+
exit 1
9+
fi
10+
11+
originalsidedeck=$1
12+
outputsidedeck=$2
13+
newdllname=$3
14+
15+
SCRIPT_DIR=$(dirname "$0")
16+
ID=`date +%C%y%m%d_%H%M%S`
17+
TMP="/tmp/sidedeck-$(basename "$0").$ID.tmp"
18+
TMP2="/tmp/sidedeck-$(basename "$0").$ID.tmp.2"
19+
20+
# Remove on exit/interrupt
21+
trap '/bin/rm -rf "$TMP" "$TMP2" && exit' EXIT INT TERM QUIT HUP
22+
23+
set -x
24+
dd conv=unblock cbs=80 if="$originalsidedeck" of="$TMP"
25+
chtag -tc 1047 "$TMP"
26+
"$SCRIPT_DIR"/sdwrap.py -u -i "$TMP" -o "$TMP2"
27+
chtag -tc 819 "$TMP2"
28+
sed -e "s/\(^ IMPORT \(DATA\|CODE\)64,\)'[^']*'/\1'$newdllname'/g" "$TMP2" > "$TMP"
29+
"$SCRIPT_DIR"/sdwrap.py -i "$TMP" -o "$TMP2"
30+
31+
# Reformat sidedeck to be USS compatible
32+
iconv -f ISO8859-1 -t IBM-1047 "$TMP2" > "$TMP"
33+
dd conv=block cbs=80 if="$TMP" of="$outputsidedeck"

tools/zos/sdwrap.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import sys
5+
6+
def wrap(args):
7+
l = args.input.readline(72)
8+
firstline = True
9+
while l:
10+
if l[-1] == '\n':
11+
if firstline:
12+
outstr = "{}".format(l)
13+
else:
14+
outstr = " {}".format(l)
15+
firstline = True
16+
l = args.input.readline(72)
17+
else:
18+
if firstline:
19+
outstr = "{:<71}*\n".format(l[:-1])
20+
firstline = False
21+
else:
22+
outstr = " {:<70}*\n".format(l[:-1])
23+
l = l[-1] + args.input.readline(70)
24+
args.output.write(outstr)
25+
26+
return 0
27+
28+
def unwrap(args):
29+
l = args.input.readline()
30+
firstline = True
31+
while l:
32+
if len(l) > 80:
33+
print("Error: input line invalid (longer than 80 characters)", file=sys.stderr)
34+
return 1
35+
if not firstline and l[0] != ' ':
36+
print("Error: continuation line not start with blank", file=sys.stderr)
37+
return 1
38+
39+
if len(l) > 71 and l[71] == '*':
40+
if firstline:
41+
args.output.write(l[:71])
42+
firstline = False
43+
else:
44+
args.output.write(l[1:71])
45+
else:
46+
if firstline:
47+
args.output.write(l)
48+
else:
49+
args.output.write(l[1:])
50+
firstline = True
51+
l = args.input.readline()
52+
return 0
53+
54+
def Main():
55+
parser = argparse.ArgumentParser(description="Wrap sidedeck source to card formats")
56+
parser.add_argument("-u", "--unwrap",
57+
help="Unwrap sidedeck cards to source formats instead", action="store_true",
58+
default=False)
59+
parser.add_argument("-i", "--input", help="input filename, default to stdin",
60+
action="store", default=None)
61+
parser.add_argument("-o", "--output", help="output filename, default to stdout",
62+
action="store", default=None)
63+
64+
args = parser.parse_args()
65+
66+
if args.input is None:
67+
args.input = sys.stdin
68+
else:
69+
args.input = open(args.input, 'r')
70+
71+
if args.output is None:
72+
args.output = sys.stdout
73+
else:
74+
args.output = open(args.output, 'w')
75+
76+
if args.unwrap:
77+
return unwrap(args)
78+
79+
return wrap(args)
80+
81+
if __name__ == '__main__':
82+
sys.exit(Main())

0 commit comments

Comments
 (0)