diff --git a/deps/libuv/build/gyp/.travis.yml b/deps/libuv/build/gyp/.travis.yml new file mode 100644 index 00000000..01555ffa --- /dev/null +++ b/deps/libuv/build/gyp/.travis.yml @@ -0,0 +1,11 @@ +language: cpp +compiler: + - clang +before_install: ./buildbot/travis-checkout.sh +script: ./buildbot/travis-test.sh +os: + - linux + - osx +branches: + only: + - master diff --git a/deps/libuv/build/gyp/AUTHORS b/deps/libuv/build/gyp/AUTHORS index 07887276..c93b785a 100644 --- a/deps/libuv/build/gyp/AUTHORS +++ b/deps/libuv/build/gyp/AUTHORS @@ -12,3 +12,5 @@ David J. Sankel Eric N. Vander Weele Tom Freudenberg Julien Brianceau +Refael Ackermann +Jiajie Hu diff --git a/deps/libuv/build/gyp/gyptest.py b/deps/libuv/build/gyp/gyptest.py index 98957e16..9930e78c 100755 --- a/deps/libuv/build/gyp/gyptest.py +++ b/deps/libuv/build/gyp/gyptest.py @@ -1,134 +1,19 @@ #!/usr/bin/env python - # Copyright (c) 2012 Google Inc. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -__doc__ = """ -gyptest.py -- test runner for GYP tests. -""" +"""gyptest.py -- test runner for GYP tests.""" +from __future__ import print_function + +import argparse +import math import os -import optparse -import shlex +import platform import subprocess import sys - -class CommandRunner(object): - """ - Executor class for commands, including "commands" implemented by - Python functions. - """ - verbose = True - active = True - - def __init__(self, dictionary={}): - self.subst_dictionary(dictionary) - - def subst_dictionary(self, dictionary): - self._subst_dictionary = dictionary - - def subst(self, string, dictionary=None): - """ - Substitutes (via the format operator) the values in the specified - dictionary into the specified command. - - The command can be an (action, string) tuple. In all cases, we - perform substitution on strings and don't worry if something isn't - a string. (It's probably a Python function to be executed.) - """ - if dictionary is None: - dictionary = self._subst_dictionary - if dictionary: - try: - string = string % dictionary - except TypeError: - pass - return string - - def display(self, command, stdout=None, stderr=None): - if not self.verbose: - return - if type(command) == type(()): - func = command[0] - args = command[1:] - s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args))) - if type(command) == type([]): - # TODO: quote arguments containing spaces - # TODO: handle meta characters? - s = ' '.join(command) - else: - s = self.subst(command) - if not s.endswith('\n'): - s += '\n' - sys.stdout.write(s) - sys.stdout.flush() - - def execute(self, command, stdout=None, stderr=None): - """ - Executes a single command. - """ - if not self.active: - return 0 - if type(command) == type(''): - command = self.subst(command) - cmdargs = shlex.split(command) - if cmdargs[0] == 'cd': - command = (os.chdir,) + tuple(cmdargs[1:]) - if type(command) == type(()): - func = command[0] - args = command[1:] - return func(*args) - else: - if stdout is sys.stdout: - # Same as passing sys.stdout, except python2.4 doesn't fail on it. - subout = None - else: - # Open pipe for anything else so Popen works on python2.4. - subout = subprocess.PIPE - if stderr is sys.stderr: - # Same as passing sys.stderr, except python2.4 doesn't fail on it. - suberr = None - elif stderr is None: - # Merge with stdout if stderr isn't specified. - suberr = subprocess.STDOUT - else: - # Open pipe for anything else so Popen works on python2.4. - suberr = subprocess.PIPE - p = subprocess.Popen(command, - shell=(sys.platform == 'win32'), - stdout=subout, - stderr=suberr) - p.wait() - if stdout is None: - self.stdout = p.stdout.read() - elif stdout is not sys.stdout: - stdout.write(p.stdout.read()) - if stderr not in (None, sys.stderr): - stderr.write(p.stderr.read()) - return p.returncode - - def run(self, command, display=None, stdout=None, stderr=None): - """ - Runs a single command, displaying it first. - """ - if display is None: - display = command - self.display(display) - return self.execute(command, stdout, stderr) - - -class Unbuffered(object): - def __init__(self, fp): - self.fp = fp - def write(self, arg): - self.fp.write(arg) - self.fp.flush() - def __getattr__(self, attr): - return getattr(self.fp, attr) - -sys.stdout = Unbuffered(sys.stdout) -sys.stderr = Unbuffered(sys.stderr) +import time def is_test_name(f): @@ -138,8 +23,6 @@ def is_test_name(f): def find_all_gyptest_files(directory): result = [] for root, dirs, files in os.walk(directory): - if '.svn' in dirs: - dirs.remove('.svn') result.extend([ os.path.join(root, f) for f in files if is_test_name(f) ]) result.sort() return result @@ -149,73 +32,68 @@ def main(argv=None): if argv is None: argv = sys.argv - usage = "gyptest.py [-ahlnq] [-f formats] [test ...]" - parser = optparse.OptionParser(usage=usage) - parser.add_option("-a", "--all", action="store_true", - help="run all tests") - parser.add_option("-C", "--chdir", action="store", default=None, - help="chdir to the specified directory") - parser.add_option("-f", "--format", action="store", default='', - help="run tests with the specified formats") - parser.add_option("-G", '--gyp_option', action="append", default=[], - help="Add -G options to the gyp command line") - parser.add_option("-l", "--list", action="store_true", - help="list available tests and exit") - parser.add_option("-n", "--no-exec", action="store_true", - help="no execute, just print the command line") - parser.add_option("--passed", action="store_true", - help="report passed tests") - parser.add_option("--path", action="append", default=[], - help="additional $PATH directory") - parser.add_option("-q", "--quiet", action="store_true", - help="quiet, don't print test command lines") - opts, args = parser.parse_args(argv[1:]) + parser = argparse.ArgumentParser() + parser.add_argument("-a", "--all", action="store_true", + help="run all tests") + parser.add_argument("-C", "--chdir", action="store", + help="change to directory") + parser.add_argument("-f", "--format", action="store", default='', + help="run tests with the specified formats") + parser.add_argument("-G", '--gyp_option', action="append", default=[], + help="Add -G options to the gyp command line") + parser.add_argument("-l", "--list", action="store_true", + help="list available tests and exit") + parser.add_argument("-n", "--no-exec", action="store_true", + help="no execute, just print the command line") + parser.add_argument("--path", action="append", default=[], + help="additional $PATH directory") + parser.add_argument("-q", "--quiet", action="store_true", + help="quiet, don't print anything unless there are failures") + parser.add_argument("-v", "--verbose", action="store_true", + help="print configuration info and test results.") + parser.add_argument('tests', nargs='*') + args = parser.parse_args(argv[1:]) - if opts.chdir: - os.chdir(opts.chdir) + if args.chdir: + os.chdir(args.chdir) - if opts.path: + if args.path: extra_path = [os.path.abspath(p) for p in opts.path] extra_path = os.pathsep.join(extra_path) os.environ['PATH'] = extra_path + os.pathsep + os.environ['PATH'] - if not args: - if not opts.all: + if not args.tests: + if not args.all: sys.stderr.write('Specify -a to get all tests.\n') return 1 - args = ['test'] + args.tests = ['test'] tests = [] - for arg in args: + for arg in args.tests: if os.path.isdir(arg): tests.extend(find_all_gyptest_files(os.path.normpath(arg))) else: if not is_test_name(os.path.basename(arg)): - print >>sys.stderr, arg, 'is not a valid gyp test name.' + print(arg, 'is not a valid gyp test name.', file=sys.stderr) sys.exit(1) tests.append(arg) - if opts.list: + if args.list: for test in tests: - print test + print(test) sys.exit(0) - CommandRunner.verbose = not opts.quiet - CommandRunner.active = not opts.no_exec - cr = CommandRunner() - os.environ['PYTHONPATH'] = os.path.abspath('test/lib') - if not opts.quiet: - sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH']) - passed = [] - failed = [] - no_result = [] + if args.verbose: + print_configuration_info() - if opts.format: - format_list = opts.format.split(',') + if args.gyp_option and not args.quiet: + print('Extra Gyp options: %s\n' % args.gyp_option) + + if args.format: + format_list = args.format.split(',') else: - # TODO: not duplicate this mapping from pylib/gyp/__init__.py format_list = { 'aix5': ['make'], 'freebsd7': ['make'], @@ -223,53 +101,143 @@ def main(argv=None): 'openbsd5': ['make'], 'cygwin': ['msvs'], 'win32': ['msvs', 'ninja'], + 'linux': ['make', 'ninja'], 'linux2': ['make', 'ninja'], 'linux3': ['make', 'ninja'], - 'darwin': ['make', 'ninja', 'xcode', 'xcode-ninja'], + + # TODO: Re-enable xcode-ninja. + # https://bugs.chromium.org/p/gyp/issues/detail?id=530 + # 'darwin': ['make', 'ninja', 'xcode', 'xcode-ninja'], + 'darwin': ['make', 'ninja', 'xcode'], }[sys.platform] - for format in format_list: - os.environ['TESTGYP_FORMAT'] = format - if not opts.quiet: - sys.stdout.write('TESTGYP_FORMAT=%s\n' % format) + gyp_options = [] + for option in args.gyp_option: + gyp_options += ['-G', option] - gyp_options = [] - for option in opts.gyp_option: - gyp_options += ['-G', option] - if gyp_options and not opts.quiet: - sys.stdout.write('Extra Gyp options: %s\n' % gyp_options) + runner = Runner(format_list, tests, gyp_options, args.verbose) + runner.run() - for test in tests: - status = cr.run([sys.executable, test] + gyp_options, - stdout=sys.stdout, - stderr=sys.stderr) - if status == 2: - no_result.append(test) - elif status: - failed.append(test) - else: - passed.append(test) + if not args.quiet: + runner.print_results() - if not opts.quiet: - def report(description, tests): - if tests: - if len(tests) == 1: - sys.stdout.write("\n%s the following test:\n" % description) - else: - fmt = "\n%s the following %d tests:\n" - sys.stdout.write(fmt % (description, len(tests))) - sys.stdout.write("\t" + "\n\t".join(tests) + "\n") - - if opts.passed: - report("Passed", passed) - report("Failed", failed) - report("No result from", no_result) - - if failed: + if runner.failures: return 1 else: return 0 +def print_configuration_info(): + print('Test configuration:') + if sys.platform == 'darwin': + sys.path.append(os.path.abspath('test/lib')) + import TestMac + print(' Mac %s %s' % (platform.mac_ver()[0], platform.mac_ver()[2])) + print(' Xcode %s' % TestMac.Xcode.Version()) + elif sys.platform == 'win32': + sys.path.append(os.path.abspath('pylib')) + import gyp.MSVSVersion + print(' Win %s %s\n' % platform.win32_ver()[0:2]) + print(' MSVS %s' % + gyp.MSVSVersion.SelectVisualStudioVersion().Description()) + elif sys.platform in ('linux', 'linux2'): + print(' Linux %s' % ' '.join(platform.linux_distribution())) + print(' Python %s' % platform.python_version()) + print(' PYTHONPATH=%s' % os.environ['PYTHONPATH']) + print() + + +class Runner(object): + def __init__(self, formats, tests, gyp_options, verbose): + self.formats = formats + self.tests = tests + self.verbose = verbose + self.gyp_options = gyp_options + self.failures = [] + self.num_tests = len(formats) * len(tests) + num_digits = len(str(self.num_tests)) + self.fmt_str = '[%%%dd/%%%dd] (%%s) %%s' % (num_digits, num_digits) + self.isatty = sys.stdout.isatty() and not self.verbose + self.env = os.environ.copy() + self.hpos = 0 + + def run(self): + run_start = time.time() + + i = 1 + for fmt in self.formats: + for test in self.tests: + self.run_test(test, fmt, i) + i += 1 + + if self.isatty: + self.erase_current_line() + + self.took = time.time() - run_start + + def run_test(self, test, fmt, i): + if self.isatty: + self.erase_current_line() + + msg = self.fmt_str % (i, self.num_tests, fmt, test) + self.print_(msg) + + start = time.time() + cmd = [sys.executable, test] + self.gyp_options + self.env['TESTGYP_FORMAT'] = fmt + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, env=self.env) + proc.wait() + took = time.time() - start + + stdout = proc.stdout.read().decode('utf8') + if proc.returncode == 2: + res = 'skipped' + elif proc.returncode: + res = 'failed' + self.failures.append('(%s) %s' % (test, fmt)) + else: + res = 'passed' + res_msg = ' %s %.3fs' % (res, took) + self.print_(res_msg) + + if (stdout and + not stdout.endswith('PASSED\n') and + not (stdout.endswith('NO RESULT\n'))): + print() + for l in stdout.splitlines(): + print(' %s' % l) + elif not self.isatty: + print() + + def print_(self, msg): + print(msg, end='') + index = msg.rfind('\n') + if index == -1: + self.hpos += len(msg) + else: + self.hpos = len(msg) - index + sys.stdout.flush() + + def erase_current_line(self): + print('\b' * self.hpos + ' ' * self.hpos + '\b' * self.hpos, end='') + sys.stdout.flush() + self.hpos = 0 + + def print_results(self): + num_failures = len(self.failures) + if num_failures: + print() + if num_failures == 1: + print("Failed the following test:") + else: + print("Failed the following %d tests:" % num_failures) + print("\t" + "\n\t".join(sorted(self.failures))) + print() + print('Ran %d tests in %.3fs, %d failed.' % (self.num_tests, self.took, + num_failures)) + print() + + if __name__ == "__main__": sys.exit(main()) diff --git a/deps/libuv/build/gyp/pylib/gyp/MSVSVersion.py b/deps/libuv/build/gyp/pylib/gyp/MSVSVersion.py index edaf6eed..44b958d5 100644 --- a/deps/libuv/build/gyp/pylib/gyp/MSVSVersion.py +++ b/deps/libuv/build/gyp/pylib/gyp/MSVSVersion.py @@ -13,12 +13,16 @@ import gyp import glob +def JoinPath(*args): + return os.path.normpath(os.path.join(*args)) + + class VisualStudioVersion(object): """Information regarding a version of Visual Studio.""" def __init__(self, short_name, description, solution_version, project_version, flat_sln, uses_vcxproj, - path, sdk_based, default_toolset=None): + path, sdk_based, default_toolset=None, compatible_sdks=None): self.short_name = short_name self.description = description self.solution_version = solution_version @@ -28,6 +32,9 @@ class VisualStudioVersion(object): self.path = path self.sdk_based = sdk_based self.default_toolset = default_toolset + compatible_sdks = compatible_sdks or [] + compatible_sdks.sort(key=lambda v: float(v.replace('v', '')), reverse=True) + self.compatible_sdks = compatible_sdks def ShortName(self): return self.short_name @@ -68,45 +75,59 @@ class VisualStudioVersion(object): of a user override.""" return self.default_toolset + def _SetupScriptInternal(self, target_arch): """Returns a command (with arguments) to be used to set up the environment.""" + assert target_arch in ('x86', 'x64'), "target_arch not supported" # If WindowsSDKDir is set and SetEnv.Cmd exists then we are using the # depot_tools build tools and should run SetEnv.Cmd to set up the # environment. The check for WindowsSDKDir alone is not sufficient because # this is set by running vcvarsall.bat. - assert target_arch in ('x86', 'x64') - sdk_dir = os.environ.get('WindowsSDKDir') - if sdk_dir: - setup_path = os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')) + sdk_dir = os.environ.get('WindowsSDKDir', '') + setup_path = JoinPath(sdk_dir, 'Bin', 'SetEnv.Cmd') if self.sdk_based and sdk_dir and os.path.exists(setup_path): return [setup_path, '/' + target_arch] - else: - # We don't use VC/vcvarsall.bat for x86 because vcvarsall calls - # vcvars32, which it can only find if VS??COMNTOOLS is set, which it - # isn't always. - if target_arch == 'x86': - if self.short_name >= '2013' and self.short_name[-1] != 'e' and ( - os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or - os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'): - # VS2013 and later, non-Express have a x64-x86 cross that we want - # to prefer. - return [os.path.normpath( - os.path.join(self.path, 'VC/vcvarsall.bat')), 'amd64_x86'] - # Otherwise, the standard x86 compiler. - return [os.path.normpath( - os.path.join(self.path, 'Common7/Tools/vsvars32.bat'))] + + is_host_arch_x64 = ( + os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or + os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64' + ) + + # For VS2017 (and newer) it's fairly easy + if self.short_name >= '2017': + script_path = JoinPath(self.path, + 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat') + + # Always use a native executable, cross-compiling if necessary. + host_arch = 'amd64' if is_host_arch_x64 else 'x86' + msvc_target_arch = 'amd64' if target_arch == 'x64' else 'x86' + arg = host_arch + if host_arch != msvc_target_arch: + arg += '_' + msvc_target_arch + + return [script_path, arg] + + # We try to find the best version of the env setup batch. + vcvarsall = JoinPath(self.path, 'VC', 'vcvarsall.bat') + if target_arch == 'x86': + if self.short_name >= '2013' and self.short_name[-1] != 'e' and \ + is_host_arch_x64: + # VS2013 and later, non-Express have a x64-x86 cross that we want + # to prefer. + return [vcvarsall, 'amd64_x86'] else: - assert target_arch == 'x64' - arg = 'x86_amd64' - # Use the 64-on-64 compiler if we're not using an express - # edition and we're running on a 64bit OS. - if self.short_name[-1] != 'e' and ( - os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or - os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'): - arg = 'amd64' - return [os.path.normpath( - os.path.join(self.path, 'VC/vcvarsall.bat')), arg] + # Otherwise, the standard x86 compiler. We don't use VC/vcvarsall.bat + # for x86 because vcvarsall calls vcvars32, which it can only find if + # VS??COMNTOOLS is set, which isn't guaranteed. + return [JoinPath(self.path, 'Common7', 'Tools', 'vsvars32.bat')] + elif target_arch == 'x64': + arg = 'x86_amd64' + # Use the 64-on-64 compiler if we're not using an express edition and + # we're running on a 64bit OS. + if self.short_name[-1] != 'e' and is_host_arch_x64: + arg = 'amd64' + return [vcvarsall, arg] def SetupScript(self, target_arch): script_data = self._SetupScriptInternal(target_arch) @@ -236,6 +257,16 @@ def _CreateVersion(name, path, sdk_based=False): if path: path = os.path.normpath(path) versions = { + '2017': VisualStudioVersion('2017', + 'Visual Studio 2017', + solution_version='12.00', + project_version='15.0', + flat_sln=False, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset='v141', + compatible_sdks=['v8.1', 'v10.0']), '2015': VisualStudioVersion('2015', 'Visual Studio 2015', solution_version='12.00', @@ -348,7 +379,6 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): A list of visual studio versions installed in descending order of usage preference. Base this on the registry and a quick check if devenv.exe exists. - Only versions 8-10 are considered. Possibilities are: 2005(e) - Visual Studio 2005 (8) 2008(e) - Visual Studio 2008 (9) @@ -356,6 +386,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): 2012(e) - Visual Studio 2012 (11) 2013(e) - Visual Studio 2013 (12) 2015 - Visual Studio 2015 (14) + 2017 - Visual Studio 2017 (15) Where (e) is e for express editions of MSVS and blank otherwise. """ version_to_year = { @@ -365,6 +396,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): '11.0': '2012', '12.0': '2013', '14.0': '2015', + '15.0': '2017' } versions = [] for version in versions_to_check: @@ -395,13 +427,18 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): # The old method above does not work when only SDK is installed. keys = [r'HKLM\Software\Microsoft\VisualStudio\SxS\VC7', - r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7'] + r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7', + r'HKLM\Software\Microsoft\VisualStudio\SxS\VS7', + r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VS7'] for index in range(len(keys)): path = _RegistryGetValue(keys[index], version) if not path: continue path = _ConvertToCygpath(path) - if version != '14.0': # There is no Express edition for 2015. + if version == '15.0': + if os.path.exists(path): + versions.append(_CreateVersion('2017', path)) + elif version != '14.0': # There is no Express edition for 2015. versions.append(_CreateVersion(version_to_year[version] + 'e', os.path.join(path, '..'), sdk_based=True)) @@ -420,7 +457,7 @@ def SelectVisualStudioVersion(version='auto', allow_fallback=True): if version == 'auto': version = os.environ.get('GYP_MSVS_VERSION', 'auto') version_map = { - 'auto': ('14.0', '12.0', '10.0', '9.0', '8.0', '11.0'), + 'auto': ('15.0', '14.0', '12.0', '10.0', '9.0', '8.0', '11.0'), '2005': ('8.0',), '2005e': ('8.0',), '2008': ('9.0',), @@ -432,6 +469,7 @@ def SelectVisualStudioVersion(version='auto', allow_fallback=True): '2013': ('12.0',), '2013e': ('12.0',), '2015': ('14.0',), + '2017': ('15.0',), } override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH') if override_path: diff --git a/deps/libuv/build/gyp/pylib/gyp/common.py b/deps/libuv/build/gyp/pylib/gyp/common.py index a1e1db5f..1b245ec7 100644 --- a/deps/libuv/build/gyp/pylib/gyp/common.py +++ b/deps/libuv/build/gyp/pylib/gyp/common.py @@ -429,6 +429,10 @@ def GetFlavor(params): return 'netbsd' if sys.platform.startswith('aix'): return 'aix' + if sys.platform.startswith('zos'): + return 'zos' + if sys.platform.startswith('os390'): + return 'zos' return 'linux' diff --git a/deps/libuv/build/gyp/pylib/gyp/easy_xml.py b/deps/libuv/build/gyp/pylib/gyp/easy_xml.py index bf949b6a..2522efb2 100644 --- a/deps/libuv/build/gyp/pylib/gyp/easy_xml.py +++ b/deps/libuv/build/gyp/pylib/gyp/easy_xml.py @@ -4,6 +4,7 @@ import re import os +import locale def XmlToString(content, encoding='utf-8', pretty=False): @@ -116,6 +117,10 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, if win32 and os.linesep != '\r\n': xml_string = xml_string.replace('\n', '\r\n') + default_encoding = locale.getdefaultlocale()[1] + if default_encoding and default_encoding.upper() != encoding.upper(): + xml_string = xml_string.decode(default_encoding).encode(encoding) + # Get the old content try: f = open(path, 'r') diff --git a/deps/libuv/build/gyp/pylib/gyp/generator/make.py b/deps/libuv/build/gyp/pylib/gyp/generator/make.py index e80ebaed..fb4f9185 100644 --- a/deps/libuv/build/gyp/pylib/gyp/generator/make.py +++ b/deps/libuv/build/gyp/pylib/gyp/generator/make.py @@ -232,6 +232,24 @@ cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSE """ +LINK_COMMANDS_OS390 = """\ +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) -Wl,DLL + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) -Wl,DLL +""" + + # Header of toplevel Makefile. # This should go into the build tree, but it's easier to keep it here for now. SHARED_HEADER = ("""\ @@ -295,7 +313,7 @@ CFLAGS.host ?= $(CPPFLAGS_host) $(CFLAGS_host) CXX.host ?= %(CXX.host)s CXXFLAGS.host ?= $(CPPFLAGS_host) $(CXXFLAGS_host) LINK.host ?= %(LINK.host)s -LDFLAGS.host ?= +LDFLAGS.host ?= $(LDFLAGS_host) AR.host ?= %(AR.host)s # Define a dir function that can handle spaces. @@ -315,7 +333,7 @@ dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) # We write to a dep file on the side first and then rename at the end # so we can't end up with a broken dep file. depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw +DEPFLAGS = %(makedep_args)s -MF $(depfile).raw # We have to fixup the deps output in a few ways. # (1) the file output should mention the proper .o file. @@ -2022,6 +2040,7 @@ def GenerateOutput(target_list, target_dicts, data, params): flock_command= 'flock' copy_archive_arguments = '-af' + makedep_arguments = '-MMD' header_params = { 'default_target': default_target, 'builddir': builddir_name, @@ -2032,6 +2051,7 @@ def GenerateOutput(target_list, target_dicts, data, params): 'extra_commands': '', 'srcdir': srcdir, 'copy_archive_args': copy_archive_arguments, + 'makedep_args': makedep_arguments, } if flavor == 'mac': flock_command = './gyp-mac-tool flock' @@ -2045,6 +2065,14 @@ def GenerateOutput(target_list, target_dicts, data, params): header_params.update({ 'link_commands': LINK_COMMANDS_ANDROID, }) + elif flavor == 'zos': + copy_archive_arguments = '-fPR' + makedep_arguments = '-qmakedep=gcc' + header_params.update({ + 'copy_archive_args': copy_archive_arguments, + 'makedep_args': makedep_arguments, + 'link_commands': LINK_COMMANDS_OS390, + }) elif flavor == 'solaris': header_params.update({ 'flock': './gyp-flock-tool flock', diff --git a/deps/libuv/build/gyp/pylib/gyp/generator/msvs.py b/deps/libuv/build/gyp/pylib/gyp/generator/msvs.py index 9daf4ec1..8fe9e5af 100644 --- a/deps/libuv/build/gyp/pylib/gyp/generator/msvs.py +++ b/deps/libuv/build/gyp/pylib/gyp/generator/msvs.py @@ -294,19 +294,31 @@ def _ConfigFullName(config_name, config_data): return '%s|%s' % (_ConfigBaseName(config_name, platform_name), platform_name) -def _ConfigWindowsTargetPlatformVersion(config_data): - ver = config_data.get('msvs_windows_sdk_version') - - for key in [r'HKLM\Software\Microsoft\Microsoft SDKs\Windows\%s', - r'HKLM\Software\Wow6432Node\Microsoft\Microsoft SDKs\Windows\%s']: - sdk_dir = MSVSVersion._RegistryGetValue(key % ver, 'InstallationFolder') - if not sdk_dir: - continue - version = MSVSVersion._RegistryGetValue(key % ver, 'ProductVersion') or '' - # Find a matching entry in sdk_dir\include. - names = sorted([x for x in os.listdir(r'%s\include' % sdk_dir) - if x.startswith(version)], reverse=True) - return names[0] +def _ConfigWindowsTargetPlatformVersion(config_data, version): + config_ver = config_data.get('msvs_windows_sdk_version') + vers = [config_ver] if config_ver else version.compatible_sdks + for ver in vers: + for key in [ + r'HKLM\Software\Microsoft\Microsoft SDKs\Windows\%s', + r'HKLM\Software\Wow6432Node\Microsoft\Microsoft SDKs\Windows\%s']: + sdk_dir = MSVSVersion._RegistryGetValue(key % ver, 'InstallationFolder') + if not sdk_dir: + continue + version = MSVSVersion._RegistryGetValue(key % ver, 'ProductVersion') or '' + # Find a matching entry in sdk_dir\include. + expected_sdk_dir=r'%s\include' % sdk_dir + names = sorted([x for x in (os.listdir(expected_sdk_dir) + if os.path.isdir(expected_sdk_dir) + else [] + ) + if x.startswith(version)], reverse=True) + if names: + return names[0] + else: + print >> sys.stdout, ( + 'Warning: No include files found for ' + 'detected Windows SDK version %s' % (version) + ) def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path, @@ -1715,14 +1727,17 @@ def _GetCopies(spec): src_bare = src[:-1] base_dir = posixpath.split(src_bare)[0] outer_dir = posixpath.split(src_bare)[1] - cmd = 'cd "%s" && xcopy /e /f /y "%s" "%s\\%s\\"' % ( - _FixPath(base_dir), outer_dir, _FixPath(dst), outer_dir) + fixed_dst = _FixPath(dst) + full_dst = '"%s\\%s\\"' % (fixed_dst, outer_dir) + cmd = 'mkdir %s 2>nul & cd "%s" && xcopy /e /f /y "%s" %s' % ( + full_dst, _FixPath(base_dir), outer_dir, full_dst) copies.append(([src], ['dummy_copies', dst], cmd, - 'Copying %s to %s' % (src, dst))) + 'Copying %s to %s' % (src, fixed_dst))) else: + fix_dst = _FixPath(cpy['destination']) cmd = 'mkdir "%s" 2>nul & set ERRORLEVEL=0 & copy /Y "%s" "%s"' % ( - _FixPath(cpy['destination']), _FixPath(src), _FixPath(dst)) - copies.append(([src], [dst], cmd, 'Copying %s to %s' % (src, dst))) + fix_dst, _FixPath(src), _FixPath(dst)) + copies.append(([src], [dst], cmd, 'Copying %s to %s' % (src, fix_dst))) return copies @@ -2664,7 +2679,7 @@ def _GetMSBuildProjectConfigurations(configurations): return [group] -def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): +def _GetMSBuildGlobalProperties(spec, version, guid, gyp_file_name): namespace = os.path.splitext(gyp_file_name)[0] properties = [ ['PropertyGroup', {'Label': 'Globals'}, @@ -2709,15 +2724,18 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): for configuration in spec['configurations'].itervalues(): platform_name = platform_name or _ConfigPlatform(configuration) msvs_windows_sdk_version = (msvs_windows_sdk_version or - _ConfigWindowsTargetPlatformVersion(configuration)) + _ConfigWindowsTargetPlatformVersion(configuration, version)) if platform_name and msvs_windows_sdk_version: break - - if platform_name == 'ARM': - properties[0].append(['WindowsSDKDesktopARMSupport', 'true']) if msvs_windows_sdk_version: properties[0].append(['WindowsTargetPlatformVersion', str(msvs_windows_sdk_version)]) + elif version.compatible_sdks: + raise GypError('%s requires any SDK of %s version, but none were found' % + (version.description, version.compatible_sdks)) + + if platform_name == 'ARM': + properties[0].append(['WindowsSDKDesktopARMSupport', 'true']) return properties @@ -2862,6 +2880,9 @@ def _GetMSBuildAttributes(spec, config, build_file): product_name = spec.get('product_name', '$(ProjectName)') target_name = prefix + product_name msbuild_attributes['TargetName'] = target_name + if 'TargetExt' not in msbuild_attributes and 'product_extension' in spec: + ext = spec.get('product_extension') + msbuild_attributes['TargetExt'] = '.' + ext if spec.get('msvs_external_builder'): external_out_dir = spec.get('msvs_external_builder_out_dir', '.') @@ -2916,6 +2937,9 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): attributes['OutputDirectory']) _AddConditionalProperty(properties, condition, 'TargetName', attributes['TargetName']) + if 'TargetExt' in attributes: + _AddConditionalProperty(properties, condition, 'TargetExt', + attributes['TargetExt']) if attributes.get('TargetPath'): _AddConditionalProperty(properties, condition, 'TargetPath', @@ -3268,6 +3292,9 @@ def _GetMSBuildProjectReferences(project): ['ReferenceOutputAssembly', 'false'] ] for config in dependency.spec.get('configurations', {}).itervalues(): + if config.get('msvs_use_library_dependency_inputs', 0): + project_ref.append(['UseLibraryDependencyInputs', 'true']) + break # If it's disabled in any config, turn it off in the reference. if config.get('msvs_2010_disable_uldi_when_referenced', 0): project_ref.append(['UseLibraryDependencyInputs', 'false']) @@ -3360,7 +3387,8 @@ def _GenerateMSBuildProject(project, options, version, generator_flags): }] content += _GetMSBuildProjectConfigurations(configurations) - content += _GetMSBuildGlobalProperties(spec, project.guid, project_file_name) + content += _GetMSBuildGlobalProperties(spec, version, project.guid, + project_file_name) content += import_default_section content += _GetMSBuildConfigurationDetails(spec, project.build_file) if spec.get('msvs_enable_winphone'): diff --git a/deps/libuv/build/gyp/pylib/gyp/generator/ninja.py b/deps/libuv/build/gyp/pylib/gyp/generator/ninja.py index 0555a4a9..6de87b70 100644 --- a/deps/libuv/build/gyp/pylib/gyp/generator/ninja.py +++ b/deps/libuv/build/gyp/pylib/gyp/generator/ninja.py @@ -1195,7 +1195,10 @@ class NinjaWriter(object): is_executable = spec['type'] == 'executable' # The ldflags config key is not used on mac or win. On those platforms # linker flags are set via xcode_settings and msvs_settings, respectively. - env_ldflags = os.environ.get('LDFLAGS', '').split() + if self.toolset == 'target': + env_ldflags = os.environ.get('LDFLAGS', '').split() + elif self.toolset == 'host': + env_ldflags = os.environ.get('LDFLAGS_host', '').split() if self.flavor == 'mac': ldflags = self.xcode_settings.GetLdflags(config_name, self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), @@ -2311,15 +2314,22 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, 'stamp', description='STAMP $out', command='%s gyp-win-tool stamp $out' % sys.executable) - master_ninja.rule( - 'copy', - description='COPY $in $out', - command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable) else: master_ninja.rule( 'stamp', description='STAMP $out', command='${postbuilds}touch $out') + if flavor == 'win': + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable) + elif flavor == 'zos': + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='rm -rf $out && cp -fRP $in $out') + else: master_ninja.rule( 'copy', description='COPY $in $out', diff --git a/deps/libuv/build/gyp/pylib/gyp/mac_tool.py b/deps/libuv/build/gyp/pylib/gyp/mac_tool.py index b0363cc3..0ad7e7a1 100755 --- a/deps/libuv/build/gyp/pylib/gyp/mac_tool.py +++ b/deps/libuv/build/gyp/pylib/gyp/mac_tool.py @@ -105,17 +105,21 @@ class MacTool(object): ibtool_section_re = re.compile(r'/\*.*\*/') ibtool_re = re.compile(r'.*note:.*is clipping its content') - ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE) + try: + stdout = subprocess.check_output(args) + except subprocess.CalledProcessError as e: + print(e.output) + raise current_section_header = None - for line in ibtoolout.stdout: + for line in stdout.splitlines(): if ibtool_section_re.match(line): current_section_header = line elif not ibtool_re.match(line): if current_section_header: - sys.stdout.write(current_section_header) + print(current_section_header) current_section_header = None - sys.stdout.write(line) - return ibtoolout.returncode + print(line) + return 0 def _ConvertToBinary(self, dest): subprocess.check_call([ diff --git a/deps/libuv/build/gyp/pylib/gyp/msvs_emulation.py b/deps/libuv/build/gyp/pylib/gyp/msvs_emulation.py index e4a85a96..6d5b5bd2 100644 --- a/deps/libuv/build/gyp/pylib/gyp/msvs_emulation.py +++ b/deps/libuv/build/gyp/pylib/gyp/msvs_emulation.py @@ -30,6 +30,10 @@ def QuoteForRspFile(arg): # works more or less because most programs (including the compiler, etc.) # use that function to handle command line arguments. + # Use a heuristic to try to find args that are paths, and normalize them + if arg.find('/') > 0 or arg.count('/') > 1: + arg = os.path.normpath(arg) + # For a literal quote, CommandLineToArgvW requires 2n+1 backslashes # preceding it, and results in n backslashes + the quote. So we substitute # in 2* what we match, +1 more, plus the quote. @@ -269,7 +273,8 @@ class MsvsSettings(object): def AdjustLibraries(self, libraries): """Strip -l from library if it's specified with that.""" libs = [lib[2:] if lib.startswith('-l') else lib for lib in libraries] - return [lib + '.lib' if not lib.endswith('.lib') else lib for lib in libs] + return [lib + '.lib' if not lib.lower().endswith('.lib') else lib + for lib in libs] def _GetAndMunge(self, field, path, default, prefix, append, map): """Retrieve a value from |field| at |path| or return |default|. If @@ -306,7 +311,10 @@ class MsvsSettings(object): # There's two levels of architecture/platform specification in VS. The # first level is globally for the configuration (this is what we consider # "the" config at the gyp level, which will be something like 'Debug' or - # 'Release_x64'), and a second target-specific configuration, which is an + # 'Release'), VS2015 and later only use this level + if self.vs_version.short_name >= 2015: + return config + # and a second target-specific configuration, which is an # override for the global one. |config| is remapped here to take into # account the local target-specific overrides to the global configuration. arch = self.GetArch(config) @@ -468,8 +476,10 @@ class MsvsSettings(object): prefix='/arch:') cflags.extend(['/FI' + f for f in self._Setting( ('VCCLCompilerTool', 'ForcedIncludeFiles'), config, default=[])]) - if self.vs_version.short_name in ('2013', '2013e', '2015'): - # New flag required in 2013 to maintain previous PDB behavior. + if self.vs_version.project_version >= 12.0: + # New flag introduced in VS2013 (project version 12.0) Forces writes to + # the program database (PDB) to be serialized through MSPDBSRV.EXE. + # https://msdn.microsoft.com/en-us/library/dn502518.aspx cflags.append('/FS') # ninja handles parallelism by itself, don't have the compiler do it too. cflags = filter(lambda x: not x.startswith('/MP'), cflags) @@ -529,7 +539,8 @@ class MsvsSettings(object): """Returns the .def file from sources, if any. Otherwise returns None.""" spec = self.spec if spec['type'] in ('shared_library', 'loadable_module', 'executable'): - def_files = [s for s in spec.get('sources', []) if s.endswith('.def')] + def_files = [s for s in spec.get('sources', []) + if s.lower().endswith('.def')] if len(def_files) == 1: return gyp_to_build_path(def_files[0]) elif len(def_files) > 1: diff --git a/util/wren.mk b/util/wren.mk index 490e3f86..f37fa82b 100644 --- a/util/wren.mk +++ b/util/wren.mk @@ -214,7 +214,7 @@ $(BUILD_DIR)/test/%.o: test/api/%.c $(OPT_HEADERS) $(MODULE_HEADERS) \ $(V) $(CC) -c $(CFLAGS) $(CLI_FLAGS) -o $@ $(FILE_FLAG) $< # Build libuv to a static library. -$(LIBUV): $(LIBUV_DIR)/build/gyp/gyp util/update_deps.py +$(LIBUV): @ printf "%10s %-30s %s\n" run util/build_libuv.py $(V) ./util/build_libuv.py $(LIBUV_ARCH)