mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
999e7d7b44
Ref: https://github.com/nodejs/node-gyp/issues/2233 Ref: https://github.com/nodejs/gyp-next/pull/69 PR-URL: https://github.com/nodejs/node/pull/35635 Refs: https://github.com/nodejs/gyp-next/releases/tag/v0.6.0 Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rod Vagg <rod@vagg.org>
236 lines
6.9 KiB
Python
Executable File
236 lines
6.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from __future__ import print_function
|
|
|
|
import ast
|
|
import errno
|
|
import os
|
|
import shutil
|
|
import sys
|
|
|
|
# set at init time
|
|
node_prefix = '/usr/local' # PREFIX variable from Makefile
|
|
install_path = '' # base target directory (DESTDIR + PREFIX from Makefile)
|
|
target_defaults = None
|
|
variables = None
|
|
|
|
def abspath(*args):
|
|
path = os.path.join(*args)
|
|
return os.path.abspath(path)
|
|
|
|
def load_config():
|
|
s = open('config.gypi').read()
|
|
return ast.literal_eval(s)
|
|
|
|
def try_unlink(path):
|
|
try:
|
|
os.unlink(path)
|
|
except OSError as e:
|
|
if e.errno != errno.ENOENT: raise
|
|
|
|
def try_symlink(source_path, link_path):
|
|
print('symlinking %s -> %s' % (source_path, link_path))
|
|
try_unlink(link_path)
|
|
try_mkdir_r(os.path.dirname(link_path))
|
|
os.symlink(source_path, link_path)
|
|
|
|
def try_mkdir_r(path):
|
|
try:
|
|
os.makedirs(path)
|
|
except OSError as e:
|
|
if e.errno != errno.EEXIST: raise
|
|
|
|
def try_rmdir_r(path):
|
|
path = abspath(path)
|
|
while path.startswith(install_path):
|
|
try:
|
|
os.rmdir(path)
|
|
except OSError as e:
|
|
if e.errno == errno.ENOTEMPTY: return
|
|
if e.errno == errno.ENOENT: return
|
|
raise
|
|
path = abspath(path, '..')
|
|
|
|
def mkpaths(path, dst):
|
|
if dst.endswith('/'):
|
|
target_path = abspath(install_path, dst, os.path.basename(path))
|
|
else:
|
|
target_path = abspath(install_path, dst)
|
|
return path, target_path
|
|
|
|
def try_copy(path, dst):
|
|
source_path, target_path = mkpaths(path, dst)
|
|
print('installing %s' % target_path)
|
|
try_mkdir_r(os.path.dirname(target_path))
|
|
try_unlink(target_path) # prevent ETXTBSY errors
|
|
return shutil.copy2(source_path, target_path)
|
|
|
|
def try_remove(path, dst):
|
|
source_path, target_path = mkpaths(path, dst)
|
|
print('removing %s' % target_path)
|
|
try_unlink(target_path)
|
|
try_rmdir_r(os.path.dirname(target_path))
|
|
|
|
def install(paths, dst):
|
|
for path in paths:
|
|
try_copy(path, dst)
|
|
|
|
def uninstall(paths, dst):
|
|
for path in paths:
|
|
try_remove(path, dst)
|
|
|
|
def npm_files(action):
|
|
target_path = 'lib/node_modules/npm/'
|
|
|
|
# don't install npm if the target path is a symlink, it probably means
|
|
# that a dev version of npm is installed there
|
|
if os.path.islink(abspath(install_path, target_path)): return
|
|
|
|
# npm has a *lot* of files and it'd be a pain to maintain a fixed list here
|
|
# so we walk its source directory instead...
|
|
for dirname, subdirs, basenames in os.walk('deps/npm', topdown=True):
|
|
subdirs[:] = [subdir for subdir in subdirs if subdir != 'test']
|
|
paths = [os.path.join(dirname, basename) for basename in basenames]
|
|
action(paths, target_path + dirname[9:] + '/')
|
|
|
|
# create/remove symlink
|
|
link_path = abspath(install_path, 'bin/npm')
|
|
if action == uninstall:
|
|
action([link_path], 'bin/npm')
|
|
elif action == install:
|
|
try_symlink('../lib/node_modules/npm/bin/npm-cli.js', link_path)
|
|
else:
|
|
assert 0 # unhandled action type
|
|
|
|
# create/remove symlink
|
|
link_path = abspath(install_path, 'bin/npx')
|
|
if action == uninstall:
|
|
action([link_path], 'bin/npx')
|
|
elif action == install:
|
|
try_symlink('../lib/node_modules/npm/bin/npx-cli.js', link_path)
|
|
else:
|
|
assert 0 # unhandled action type
|
|
|
|
def subdir_files(path, dest, action):
|
|
ret = {}
|
|
for dirpath, dirnames, filenames in os.walk(path):
|
|
files_in_path = [dirpath + '/' + f for f in filenames if f.endswith('.h')]
|
|
ret[dest + dirpath.replace(path, '')] = files_in_path
|
|
for subdir, files_in_path in ret.items():
|
|
action(files_in_path, subdir + '/')
|
|
|
|
def files(action):
|
|
is_windows = sys.platform == 'win32'
|
|
output_file = 'node'
|
|
output_prefix = 'out/Release/'
|
|
|
|
if 'false' == variables.get('node_shared'):
|
|
if is_windows:
|
|
output_file += '.exe'
|
|
else:
|
|
if is_windows:
|
|
output_file += '.dll'
|
|
else:
|
|
output_file = 'lib' + output_file + '.' + variables.get('shlib_suffix')
|
|
|
|
if 'false' == variables.get('node_shared'):
|
|
action([output_prefix + output_file], 'bin/' + output_file)
|
|
else:
|
|
action([output_prefix + output_file], 'lib/' + output_file)
|
|
|
|
if 'true' == variables.get('node_use_dtrace'):
|
|
action(['out/Release/node.d'], 'lib/dtrace/node.d')
|
|
|
|
# behave similarly for systemtap
|
|
action(['src/node.stp'], 'share/systemtap/tapset/')
|
|
|
|
action(['deps/v8/tools/gdbinit'], 'share/doc/node/')
|
|
action(['deps/v8/tools/lldb_commands.py'], 'share/doc/node/')
|
|
|
|
if 'freebsd' in sys.platform or 'openbsd' in sys.platform:
|
|
action(['doc/node.1'], 'man/man1/')
|
|
else:
|
|
action(['doc/node.1'], 'share/man/man1/')
|
|
|
|
if 'true' == variables.get('node_install_npm'): npm_files(action)
|
|
|
|
headers(action)
|
|
|
|
def headers(action):
|
|
def ignore_inspector_headers(files_arg, dest):
|
|
inspector_headers = [
|
|
'deps/v8/include/v8-inspector.h',
|
|
'deps/v8/include/v8-inspector-protocol.h'
|
|
]
|
|
files_arg = [name for name in files_arg if name not in inspector_headers]
|
|
action(files_arg, dest)
|
|
|
|
action([
|
|
'common.gypi',
|
|
'config.gypi',
|
|
'src/node.h',
|
|
'src/node_api.h',
|
|
'src/js_native_api.h',
|
|
'src/js_native_api_types.h',
|
|
'src/node_api_types.h',
|
|
'src/node_buffer.h',
|
|
'src/node_object_wrap.h',
|
|
'src/node_version.h',
|
|
], 'include/node/')
|
|
|
|
# Add the expfile that is created on AIX
|
|
if sys.platform.startswith('aix'):
|
|
action(['out/Release/node.exp'], 'include/node/')
|
|
|
|
subdir_files('deps/v8/include', 'include/node/', ignore_inspector_headers)
|
|
|
|
if 'false' == variables.get('node_shared_libuv'):
|
|
subdir_files('deps/uv/include', 'include/node/', action)
|
|
|
|
if 'true' == variables.get('node_use_openssl') and \
|
|
'false' == variables.get('node_shared_openssl'):
|
|
subdir_files('deps/openssl/openssl/include/openssl', 'include/node/openssl/', action)
|
|
subdir_files('deps/openssl/config/archs', 'include/node/openssl/archs', action)
|
|
subdir_files('deps/openssl/config', 'include/node/openssl', action)
|
|
|
|
if 'false' == variables.get('node_shared_zlib'):
|
|
action([
|
|
'deps/zlib/zconf.h',
|
|
'deps/zlib/zlib.h',
|
|
], 'include/node/')
|
|
|
|
def run(args):
|
|
global node_prefix, install_path, target_defaults, variables
|
|
|
|
# chdir to the project's top-level directory
|
|
os.chdir(abspath(os.path.dirname(__file__), '..'))
|
|
|
|
conf = load_config()
|
|
variables = conf['variables']
|
|
target_defaults = conf['target_defaults']
|
|
|
|
# argv[2] is a custom install prefix for packagers (think DESTDIR)
|
|
# argv[3] is a custom install prefix (think PREFIX)
|
|
# Difference is that dst_dir won't be included in shebang lines etc.
|
|
dst_dir = args[2] if len(args) > 2 else ''
|
|
|
|
if len(args) > 3:
|
|
node_prefix = args[3]
|
|
|
|
# install_path thus becomes the base target directory.
|
|
install_path = dst_dir + node_prefix + '/'
|
|
|
|
cmd = args[1] if len(args) > 1 else 'install'
|
|
|
|
if os.environ.get('HEADERS_ONLY'):
|
|
if cmd == 'install': return headers(install)
|
|
if cmd == 'uninstall': return headers(uninstall)
|
|
else:
|
|
if cmd == 'install': return files(install)
|
|
if cmd == 'uninstall': return files(uninstall)
|
|
|
|
raise RuntimeError('Bad command: %s\n' % cmd)
|
|
|
|
if __name__ == '__main__':
|
|
run(sys.argv[:])
|