Skip to content

Commit c817359

Browse files
alexcfyunggabylb
authored andcommitted
tools: support versioned node shared libraries 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). Co-authored-by: Gaby Baghdadi <[email protected]>
1 parent 55ceaec commit c817359

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

tools/install.py

+34
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):
@@ -133,6 +145,9 @@ def files(action):
133145
output_file = 'node'
134146
output_prefix = 'out/Release/'
135147

148+
if sys.platform == 'zos':
149+
action([output_prefix + output_file], 'bin/' + output_file)
150+
136151
if 'false' == variables.get('node_shared'):
137152
if is_windows:
138153
output_file += '.exe'
@@ -142,8 +157,27 @@ def files(action):
142157
else:
143158
output_file = 'lib' + output_file + '.' + variables.get('shlib_suffix')
144159

160+
if sys.platform == 'zos':
161+
output_prefix += 'lib.target/'
162+
145163
if 'false' == variables.get('node_shared'):
146164
action([output_prefix + output_file], 'bin/' + output_file)
165+
elif sys.platform == 'zos':
166+
# Install libnode.version.x
167+
action([output_prefix + output_file], 'lib/' + output_file)
168+
169+
# Create libnode.x that references libnode.so (for native node module compat)
170+
os.system(os.path.dirname(os.path.realpath(__file__)) + "/zos/" +
171+
"modifysidedeck.sh " + abspath(install_path, 'lib/' + output_file) +
172+
" " + abspath(install_path, 'lib/libnode.x') + " libnode.so")
173+
174+
# Install libnode.version.so
175+
so_name = 'libnode.' + re.sub(r'\.x$', '.so', variables.get('shlib_suffix'))
176+
action([output_prefix + so_name], 'lib/' + so_name)
177+
178+
# Create symlink of libnode.so -> libnode.version.so (for native node module compat)
179+
link_path = abspath(install_path, 'lib/libnode.so')
180+
try_symlink(so_name, link_path)
147181
else:
148182
action([output_prefix + output_file], 'lib/' + output_file)
149183

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)