Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorForrest L Norvell <forrest@npmjs.com>2015-05-28 22:39:08 +0300
committerForrest L Norvell <forrest@npmjs.com>2015-05-28 23:41:54 +0300
commitb72de41c5cc9f0c46d3fa8f062c75bd273641474 (patch)
tree1246b2e3b1086aef189e419bfdddcb63c60568e6 /node_modules/node-gyp
parent14aceddaf15f8310b6ec29c2c7dafac7695ca22b (diff)
node-gyp@2.0.0
* update to newer gyp * add delayed load hook to allow renaming binary at runtime * add license to package.json * support for newer Visual Studio
Diffstat (limited to 'node_modules/node-gyp')
-rw-r--r--node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch35
-rw-r--r--node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch36
-rw-r--r--node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch39
-rw-r--r--node_modules/node-gyp/History.md21
-rw-r--r--node_modules/node-gyp/README.md15
-rw-r--r--node_modules/node-gyp/addon.gypi56
-rw-r--r--node_modules/node-gyp/gyp/PRESUBMIT.py27
-rw-r--r--node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml466
-rwxr-xr-xnode_modules/node-gyp/gyp/buildbot/buildbot_run.py123
-rw-r--r--node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS6
-rw-r--r--node_modules/node-gyp/gyp/buildbot/commit_queue/README3
-rw-r--r--node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json16
-rw-r--r--node_modules/node-gyp/gyp/codereview.settings10
-rwxr-xr-xnode_modules/node-gyp/gyp/gyp2
-rw-r--r--node_modules/node-gyp/gyp/gyp_dummy.c7
-rwxr-xr-xnode_modules/node-gyp/gyp/gyptest.py6
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py2
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py90
-rwxr-xr-xnode_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py3
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py33
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py73
-rwxr-xr-xnode_modules/node-gyp/gyp/pylib/gyp/__init__.py15
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/common.py82
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py5
-rwxr-xr-xnode_modules/node-gyp/gyp/pylib/gyp/flock_tool.py7
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py569
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/android.py247
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py6
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py179
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py7
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/make.py59
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py309
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py471
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py21
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py66
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/input.py714
-rwxr-xr-xnode_modules/node-gyp/gyp/pylib/gyp/input_test.py14
-rwxr-xr-xnode_modules/node-gyp/gyp/pylib/gyp/mac_tool.py114
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py198
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py46
-rwxr-xr-xnode_modules/node-gyp/gyp/pylib/gyp/win_tool.py39
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py396
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py270
-rw-r--r--node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py164
-rw-r--r--node_modules/node-gyp/gyp/pylintrc307
-rw-r--r--node_modules/node-gyp/gyp/tools/emacs/gyp.el49
-rwxr-xr-xnode_modules/node-gyp/gyp/tools/pretty_sln.py7
-rw-r--r--node_modules/node-gyp/lib/build.js2
-rw-r--r--node_modules/node-gyp/lib/configure.js14
-rw-r--r--node_modules/node-gyp/lib/install.js16
-rw-r--r--node_modules/node-gyp/lib/rebuild.js2
-rw-r--r--node_modules/node-gyp/node_modules/glob/node_modules/minimatch/LICENSE32
-rw-r--r--node_modules/node-gyp/node_modules/glob/node_modules/minimatch/browser.js403
-rw-r--r--node_modules/node-gyp/node_modules/glob/node_modules/minimatch/minimatch.js401
-rw-r--r--node_modules/node-gyp/node_modules/glob/node_modules/minimatch/package.json33
-rw-r--r--node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/LICENSE36
-rw-r--r--node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/README.md6
-rw-r--r--node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/package.json32
-rw-r--r--node_modules/node-gyp/node_modules/minimatch/package.json3
-rw-r--r--node_modules/node-gyp/node_modules/path-array/.npmignore1
-rw-r--r--node_modules/node-gyp/node_modules/path-array/.travis.yml6
-rw-r--r--node_modules/node-gyp/node_modules/path-array/History.md22
-rw-r--r--node_modules/node-gyp/node_modules/path-array/README.md92
-rw-r--r--node_modules/node-gyp/node_modules/path-array/index.js137
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.npmignore1
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.travis.yml5
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/History.md39
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/Makefile11
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/README.md156
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/component.json22
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/index.js180
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/.npmignore6
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/History.md195
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Makefile36
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Readme.md188
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/bower.json28
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/browser.js168
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/component.json19
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/debug.js197
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node.js209
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/.npmignore5
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/History.md66
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/LICENSE20
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/README.md35
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/index.js125
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/package.json48
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/package.json73
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/package.json57
-rw-r--r--node_modules/node-gyp/node_modules/path-array/node_modules/array-index/test.js76
-rw-r--r--node_modules/node-gyp/node_modules/path-array/package.json55
-rw-r--r--node_modules/node-gyp/node_modules/path-array/test/test.js68
-rw-r--r--node_modules/node-gyp/node_modules/tar/package.json3
-rw-r--r--node_modules/node-gyp/package.json23
-rw-r--r--node_modules/node-gyp/src/win_delay_load_hook.c33
94 files changed, 6878 insertions, 1937 deletions
diff --git a/node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch b/node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch
new file mode 100644
index 000000000..694913f59
--- /dev/null
+++ b/node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch
@@ -0,0 +1,35 @@
+From 9b5e8dc426ada891d67d27b09acc73122ab46849 Mon Sep 17 00:00:00 2001
+From: Nathan Rajlich <nathan@tootallnate.net>
+Date: Wed, 14 Nov 2012 16:48:52 -0800
+Subject: [PATCH 1/3] gyp: always install into $PRODUCT_DIR
+
+---
+ gyp/pylib/gyp/generator/make.py | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py
+index b88a433..9b3e4e3 100644
+--- a/gyp/pylib/gyp/generator/make.py
++++ b/gyp/pylib/gyp/generator/make.py
+@@ -1888,11 +1888,13 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
+ """Returns the location of the final output for an installable target."""
+ # Xcode puts shared_library results into PRODUCT_DIR, and some gyp files
+ # rely on this. Emulate this behavior for mac.
+- if (self.type == 'shared_library' and
+- (self.flavor != 'mac' or self.toolset != 'target')):
+- # Install all shared libs into a common directory (per toolset) for
+- # convenient access with LD_LIBRARY_PATH.
+- return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias)
++
++ # XXX(TooTallNate): disabling this code since we don't want this behavior...
++ #if (self.type == 'shared_library' and
++ # (self.flavor != 'mac' or self.toolset != 'target')):
++ # # Install all shared libs into a common directory (per toolset) for
++ # # convenient access with LD_LIBRARY_PATH.
++ # return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias)
+ return '$(builddir)/' + self.alias
+
+
+--
+2.3.2 (Apple Git-55)
+
diff --git a/node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch b/node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch
new file mode 100644
index 000000000..d1c5cac71
--- /dev/null
+++ b/node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch
@@ -0,0 +1,36 @@
+From 511840e82116662aa825088fb8a52a9f799f7767 Mon Sep 17 00:00:00 2001
+From: Nathan Rajlich <nathan@tootallnate.net>
+Date: Wed, 14 Nov 2012 16:54:04 -0800
+Subject: [PATCH 2/3] gyp: apply https://codereview.chromium.org/11361103/
+
+---
+ gyp/pylib/gyp/generator/msvs.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py
+index d8e0872..c59aea1 100644
+--- a/gyp/pylib/gyp/generator/msvs.py
++++ b/gyp/pylib/gyp/generator/msvs.py
+@@ -2720,6 +2720,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', '.')
+@@ -2773,6 +2776,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',
+--
+2.3.2 (Apple Git-55)
+
diff --git a/node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch b/node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch
new file mode 100644
index 000000000..673a3ddd3
--- /dev/null
+++ b/node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch
@@ -0,0 +1,39 @@
+From 0cd9f08a6d4f4be6643001b6c3b5ad40e094bdcc Mon Sep 17 00:00:00 2001
+From: Nathan Zadoks <nathan@nathan7.eu>
+Date: Tue, 2 Jul 2013 11:07:16 -0700
+Subject: [PATCH 3/3] gyp: don't use links at all, just copy the files instead
+
+---
+ gyp/pylib/gyp/generator/make.py | 2 +-
+ gyp/pylib/gyp/generator/ninja.py | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py
+index 9b3e4e3..b3f8a2b 100644
+--- a/gyp/pylib/gyp/generator/make.py
++++ b/gyp/pylib/gyp/generator/make.py
+@@ -372,7 +372,7 @@ cmd_touch = touch $@
+
+ quiet_cmd_copy = COPY $@
+ # send stderr to /dev/null to ignore messages when linking directories.
+-cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@")
++cmd_copy = rm -rf "$@" && cp -af "$<" "$@"
+
+ %(link_commands)s
+ """
+diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py
+index 7461814..c2951a4 100644
+--- a/gyp/pylib/gyp/generator/ninja.py
++++ b/gyp/pylib/gyp/generator/ninja.py
+@@ -2020,7 +2020,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
+ master_ninja.rule(
+ 'copy',
+ description='COPY $in $out',
+- command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)')
++ command='rm -rf $out && cp -af $in $out')
+ master_ninja.newline()
+
+ all_targets = set()
+--
+2.3.2 (Apple Git-55)
+
diff --git a/node_modules/node-gyp/History.md b/node_modules/node-gyp/History.md
new file mode 100644
index 000000000..f4d6d9d51
--- /dev/null
+++ b/node_modules/node-gyp/History.md
@@ -0,0 +1,21 @@
+
+2.0.0 / 2015-05-24
+==================
+
+ * configure: check for python2 executable by default, fallback to python
+ * configure: don't clobber existing $PYTHONPATH
+ * configure: use "path-array" for PYTHONPATH
+ * gyp: fix for non-acsii userprofile name on Windows
+ * gyp: always install into $PRODUCT_DIR
+ * gyp: apply https://codereview.chromium.org/11361103/
+ * gyp: don't use links at all, just copy the files instead
+ * gyp: update gyp to e1c8fcf7
+ * Updated README.md with updated Windows build info
+ * Show URL when a download fails
+ * package: add a "license" field
+ * move HMODULE m declaration to top
+ * Only add "-undefined dynamic_lookup" to loadable_module targets
+ * win: optionally allow node.exe/iojs.exe to be renamed
+ * Avoid downloading shasums if using tarPath
+ * Add target name preprocessor define: `NODE_GYP_MODULE_NAME`
+ * Show better error message in case of bad network settings
diff --git a/node_modules/node-gyp/README.md b/node_modules/node-gyp/README.md
index 53d5da247..57191b4b2 100644
--- a/node_modules/node-gyp/README.md
+++ b/node_modules/node-gyp/README.md
@@ -38,13 +38,22 @@ You will also need to install:
* A proper C/C++ compiler toolchain, like GCC
* On Windows:
* [Python][windows-python] ([`v2.7.3`][windows-python-v2.7.3] recommended, `v3.x.x` is __*not*__ supported)
+ * Make sure that you have a PYTHON environment variable, and it is set to drive:\path\to\python.exe not to a folder.
* Windows XP/Vista/7:
* Microsoft Visual Studio C++ 2010 ([Express][msvc2010] version works well)
- * For 64-bit builds of node and native modules you will _**also**_ need the [Windows 7 64-bit SDK][win7sdk]
* If the install fails, try uninstalling any C++ 2010 x64&x86 Redistributable that you have installed first.
- * If you get errors that the 64-bit compilers are not installed you may also need the [compiler update for the Windows SDK 7.1]
+ * If you get errors that the 64-bit compilers are not installed you may also need the [compiler update for the Windows SDK 7.1]
* Windows 7/8:
- * Microsoft Visual Studio C++ 2012/13 for Windows Desktop ([Express][msvc2012] version works well)
+ * Microsoft Visual Studio C++ 2012 for Windows Desktop ([Express][msvc2012] version works well)
+ * Microsoft Visual Studio C++ 2013 will also work.
+ * All Windows Versions
+ * For 64-bit builds of node and native modules you will _**also**_ need the [Windows 7 64-bit SDK][win7sdk]
+ * You may need to run one of the following commands if your build complains about WindowsSDKDir not being set, and you are sure you have already installed the SDK:
+
+```
+call "C:\Program Files\Microsoft SDKs\Windows\v7.1\bin\Setenv.cmd" /Release /x86
+call "C:\Program Files\Microsoft SDKs\Windows\v7.1\bin\Setenv.cmd" /Release /x64
+```
If you have multiple Python versions installed, you can identify which Python
version `node-gyp` uses by setting the '--python' variable:
diff --git a/node_modules/node-gyp/addon.gypi b/node_modules/node-gyp/addon.gypi
index 0b81fab20..7f6264ac6 100644
--- a/node_modules/node-gyp/addon.gypi
+++ b/node_modules/node-gyp/addon.gypi
@@ -1,29 +1,65 @@
{
'target_defaults': {
'type': 'loadable_module',
+ 'win_delay_load_hook': 'false',
'product_prefix': '',
+
'include_dirs': [
'<(node_root_dir)/src',
'<(node_root_dir)/deps/uv/include',
'<(node_root_dir)/deps/v8/include'
],
+ 'defines': [
+ 'NODE_GYP_MODULE_NAME=>(_target_name)'
+ ],
'target_conditions': [
['_type=="loadable_module"', {
'product_extension': 'node',
- 'defines': [ 'BUILDING_NODE_EXTENSION' ],
+ 'defines': [
+ 'BUILDING_NODE_EXTENSION'
+ ],
+ 'xcode_settings': {
+ 'OTHER_LDFLAGS': [
+ '-undefined dynamic_lookup'
+ ],
+ },
}],
+
['_type=="static_library"', {
# set to `1` to *disable* the -T thin archive 'ld' flag.
# older linkers don't support this flag.
'standalone_static_library': '<(standalone_static_library)'
}],
+
+ ['_win_delay_load_hook=="true"', {
+ # If the addon specifies `'win_delay_load_hook': 'true'` in its
+ # binding.gyp, link a delay-load hook into the DLL. This hook ensures
+ # that the addon will work regardless of whether the node/iojs binary
+ # is named node.exe, iojs.exe, or something else.
+ 'conditions': [
+ [ 'OS=="win"', {
+ 'sources': [
+ 'src/win_delay_load_hook.c',
+ ],
+ 'msvs_settings': {
+ 'VCLinkerTool': {
+ 'DelayLoadDLLs': [ 'iojs.exe', 'node.exe' ],
+ # Don't print a linker warning when no imports from either .exe
+ # are used.
+ 'AdditionalOptions': [ '/ignore:4199' ],
+ },
+ },
+ }],
+ ],
+ }],
],
'conditions': [
[ 'OS=="mac"', {
- 'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
- 'libraries': [ '-undefined dynamic_lookup' ],
+ 'defines': [
+ '_DARWIN_USE_64_BIT_INODE=1'
+ ],
'xcode_settings': {
'DYLIB_INSTALL_NAME_BASE': '@rpath'
},
@@ -44,12 +80,18 @@
'-lDelayImp.lib',
'-l"<(node_root_dir)/$(ConfigurationName)/node.lib"'
],
- # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent<T>'
- # needs to have dll-interface to be used by clients of class 'node::ObjectWrap'
- 'msvs_disabled_warnings': [ 4251 ],
+ 'msvs_disabled_warnings': [
+ # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent<T>'
+ # needs to have dll-interface to be used by
+ # clients of class 'node::ObjectWrap'
+ 4251
+ ],
}, {
# OS!="win"
- 'defines': [ '_LARGEFILE_SOURCE', '_FILE_OFFSET_BITS=64' ],
+ 'defines': [
+ '_LARGEFILE_SOURCE',
+ '_FILE_OFFSET_BITS=64'
+ ],
}],
[ 'OS=="freebsd" or OS=="openbsd" or OS=="solaris" or (OS=="linux" and target_arch!="ia32")', {
'cflags': [ '-fPIC' ],
diff --git a/node_modules/node-gyp/gyp/PRESUBMIT.py b/node_modules/node-gyp/gyp/PRESUBMIT.py
index 9c474eb2b..abec27b3e 100644
--- a/node_modules/node-gyp/gyp/PRESUBMIT.py
+++ b/node_modules/node-gyp/gyp/PRESUBMIT.py
@@ -16,8 +16,6 @@ PYLINT_BLACKLIST = [
'test/lib/TestCmd.py',
'test/lib/TestCommon.py',
'test/lib/TestGyp.py',
- # Needs style fix.
- 'pylib/gyp/generator/xcode.py',
]
@@ -25,6 +23,10 @@ PYLINT_DISABLED_WARNINGS = [
# TODO: fix me.
# Many tests include modules they don't use.
'W0611',
+ # Possible unbalanced tuple unpacking with sequence.
+ 'W0632',
+ # Attempting to unpack a non-sequence.
+ 'W0633',
# Include order doesn't properly include local files?
'F0401',
# Some use of built-in names.
@@ -40,6 +42,10 @@ PYLINT_DISABLED_WARNINGS = [
'W0613',
# String has no effect (docstring in wrong place).
'W0105',
+ # map/filter on lambda could be replaced by comprehension.
+ 'W0110',
+ # Use of eval.
+ 'W0123',
# Comma not followed by space.
'C0324',
# Access to a protected member.
@@ -56,6 +62,8 @@ PYLINT_DISABLED_WARNINGS = [
'E1101',
# Dangerous default {}.
'W0102',
+ # Cyclic import.
+ 'R0401',
# Others, too many to sort.
'W0201', 'W0232', 'E1103', 'W0621', 'W0108', 'W0223', 'W0231',
'R0201', 'E0101', 'C0321',
@@ -116,5 +124,16 @@ def CheckChangeOnCommit(input_api, output_api):
return report
-def GetPreferredTrySlaves():
- return ['gyp-win32', 'gyp-win64', 'gyp-linux', 'gyp-mac', 'gyp-android']
+TRYBOTS = [
+ 'gyp-win32',
+ 'gyp-win64',
+ 'gyp-linux',
+ 'gyp-mac',
+ 'gyp-android'
+]
+
+
+def GetPreferredTryMasters(_, change):
+ return {
+ 'tryserver.nacl': { t: set(['defaulttests']) for t in TRYBOTS },
+ }
diff --git a/node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml b/node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml
new file mode 100644
index 000000000..bd73b303c
--- /dev/null
+++ b/node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest>
+ <remote name="aosp"
+ fetch=".."
+ review="https://android-review.googlesource.com/" />
+ <default revision="master"
+ remote="aosp"
+ sync-j="4" />
+
+ <project groups="device,flo" name="device/asus/deb" revision="0ce3a783d549d023ddc553a04fed717ffb2ff533" />
+ <project groups="device,flo" name="device/asus/flo" revision="55ea79b11f9f82b2aa03f44a3429112fc5c06d07" />
+ <project groups="device,flo" name="device/asus/flo-kernel" revision="6d74123947016999ae62d9c3067ae97782fdba21" />
+ <project groups="device,grouper" name="device/asus/grouper" revision="78fe48f44e90ef3a7eceab5465dbad63cd16ce88" />
+ <project groups="device,grouper" name="device/asus/tilapia" revision="e5033bc80764067cbb1c9dc3970f0718e35ae8c7" />
+ <project name="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30" />
+ <project groups="pdk" name="device/generic/armv7-a-neon" revision="8bcf4b7a6380b26c2b42dae00dd8443de2a8e12c" />
+ <project groups="pdk" name="device/generic/common" revision="11c092a6cbfcf6207f07a9a8e3398e747e7f5461" />
+ <project groups="pdk" name="device/generic/goldfish" revision="638ee524f83053613c47ddea22c4bf98a0175c2f" />
+ <project groups="pdk" name="device/generic/mini-emulator-armv7-a-neon" revision="2a7ade61377b7906187ab46b5859c896baa0ab0e" />
+ <project groups="pdk" name="device/generic/mini-emulator-mips" revision="2ff06dda649ba43507a911057f7854a3373ef7d6" />
+ <project groups="pdk" name="device/generic/mini-emulator-x86" revision="a2f05b8c5259c232be5b029b2d5e721ba3f70917" />
+ <project groups="pdk" name="device/generic/mips" revision="dd06e7883227cc68bb1206584c8e3a768e49d02d" />
+ <project name="device/generic/qemu" revision="bd2543e810f3fa56e9dcfe301b893832534c85db" />
+ <project groups="pdk" name="device/generic/x86" revision="f111878fb41e2bdf4eb092d1edf0eb53cc5d0153" />
+ <project groups="device" name="device/google/accessory/arduino" revision="abc5159a3ca9dbb5c7e364a1eab99901a4440ac5" />
+ <project groups="device" name="device/google/accessory/demokit" revision="7dfe7f89a3b174709c773fe319531006e46440d9" />
+ <project groups="device,hammerhead" name="device/lge/hammerhead" revision="ec229bf178b891cc18552833f2de743acf390a7c" />
+ <project groups="device,hammerhead" name="device/lge/hammerhead-kernel" revision="a1dc58be96e7a71496e3e89079ac704930f982f2" />
+ <project groups="device,mako" name="device/lge/mako" revision="7e5f0f313819ffa3b45cd4208ab552f446c33936" />
+ <project groups="device,mako" name="device/lge/mako-kernel" revision="b7de901b8cb86036e9b92b3b6f188b45a524b125" />
+ <project groups="pdk" name="device/sample" revision="096f9eb5763fd2766fcbbe4f6b9da51c87f61797" />
+ <project groups="device,manta" name="device/samsung/manta" revision="78fe248ddb214aca2215df46be83882dc50c9283" />
+ <project groups="pdk" name="platform/abi/cpp" path="abi/cpp" revision="a0f99286d0909f7a30b0bee742bec2a0b62c4dd0" />
+ <project name="platform/art" path="art" revision="36b111c7d3d635e262114dabde4c26952c7dcbe6" />
+ <project groups="pdk" name="platform/bionic" path="bionic" revision="36bacd237de931c48714d1a8aa4aa9522283e407" />
+ <project name="platform/bootable/bootloader/legacy" path="bootable/bootloader/legacy" revision="3c491d6efb8ff2534a6934702760a6273f197918" />
+ <project name="platform/bootable/diskinstaller" path="bootable/diskinstaller" revision="ca40959a8caafa0df6a5c3d845e2afe6b252093f" />
+ <project groups="pdk" name="platform/bootable/recovery" path="bootable/recovery" revision="974fe112ae6df95ca6d49688d6e3e459d87e16de" />
+ <project groups="pdk" name="platform/build" path="build" revision="d23798bfdc9bb34909177c3c5f06f0c97cc9897e" >
+ <copyfile dest="Makefile" src="core/root.mk"/>
+ </project>
+ <project groups="cts" name="platform/cts" path="cts" revision="e15e8f846e19816e18ee3293c5b99f78463be28e" />
+ <project name="platform/dalvik" path="dalvik" revision="fb5b0d5bc46bce9c8ed6b1150498d6e145811a7d" />
+ <project name="platform/developers/build" path="developers/build" revision="75c5c41b06f045c3304b1b19d8250f04a8da8f10" />
+ <project name="platform/developers/demos" path="developers/demos" revision="64526120cd8da89bcb9a48acf95307d2c172a6e8" />
+ <project name="platform/developers/docs" path="developers/docs" revision="c0b835ddd9acc27176dc9a0f7d1aa2faf5d51806" />
+ <project name="platform/developers/samples/android" path="developers/samples/android" revision="dea82fa23f038d66bd9cfdff2afb8ef22add1c4f" />
+ <project name="platform/development" path="development" revision="0efeb2c66bff9b36feecd9315d14d2afb46e4669" />
+ <project name="platform/docs/source.android.com" path="docs/source.android.com" revision="c4795fa0df2c5fb4832ae65482944e8e5400e4f6" />
+ <project groups="pdk" name="platform/external/aac" path="external/aac" revision="35f30c5ab8089f38681d2fdd416c00aebef5a7ff" />
+ <project name="platform/external/android-clat" path="external/android-clat" revision="18921713780edb45ceef327d5fcf3387818300f3" />
+ <project name="platform/external/android-mock" path="external/android-mock" revision="4fe497660c2e939300dc5b743d662aef458b1726" />
+ <project name="platform/external/ant-glob" path="external/ant-glob" revision="0f189400fd2a36bf11bfb058e7f3917eb7ed163a" />
+ <project name="platform/external/antlr" path="external/antlr" revision="47997265eeb7d954a32ece693bbe6dab740872dd" />
+ <project name="platform/external/apache-harmony" path="external/apache-harmony" revision="6942e08fdbbd8402c9deabb0f60c8c871194b244" />
+ <project name="platform/external/apache-http" path="external/apache-http" revision="85ed0e10781c3c57343300a02556dd5131c450aa" />
+ <project name="platform/external/apache-qp" path="external/apache-qp" revision="64ea622b23e6612eb8e7dcae6bfd4314beb022a8" />
+ <project name="platform/external/apache-xml" path="external/apache-xml" revision="00ee83ff1bd827a852065986ed0da7a3ded57a55" />
+ <project name="platform/external/arduino" path="external/arduino" revision="d06daf9bbc46838400461eb8e15842974e38d82a" />
+ <project groups="pdk" name="platform/external/bison" path="external/bison" revision="c2418b886165add7f5a31fc5609f0ce2d004a90e" />
+ <project name="platform/external/blktrace" path="external/blktrace" revision="d345431f16b8f76f30a58193ff2b26d5853e1109" />
+ <project groups="pdk" name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="3b4040093ddf0e0025d0dd034aa65078bb695514" />
+ <project name="platform/external/bouncycastle" path="external/bouncycastle" revision="234720ebe66540a53cff98b2448dddbc884bd09f" />
+ <project groups="pdk" name="platform/external/bsdiff" path="external/bsdiff" revision="6f503758fad2cbcf8359e8f0af32e4d79a2a48ae" />
+ <project groups="pdk" name="platform/external/bzip2" path="external/bzip2" revision="1cb636bd8e9e5cdfd5d5b2909a122f6e80db62de" />
+ <project name="platform/external/ceres-solver" path="external/ceres-solver" revision="399f7d09e0c45af54b77b4ab9508d6f23759b927" />
+ <project groups="pdk" name="platform/external/checkpolicy" path="external/checkpolicy" revision="c66ac590eebc731f6021f267ebea208e87d8f04f" />
+ <project name="platform/external/chromium" path="external/chromium" revision="f294081d501ad98b7d7f50bc73f291063caf2c5f" />
+ <project name="platform/external/chromium-libpac" path="external/chromium-libpac" revision="09cf45bf5a650fe1abd50b9d61c2670a62f62767" />
+ <project groups="pdk" name="platform/external/chromium-trace" path="external/chromium-trace" revision="8252ae6b83ea65cf871e7981e981da07379f5a0f" />
+ <project name="platform/external/chromium_org" path="external/chromium_org" revision="43165a58c6167882aabb62f470c4e4d21f807d79" />
+ <project name="platform/external/chromium_org/sdch/open-vcdiff" path="external/chromium_org/sdch/open-vcdiff" revision="6d634da5463d9bc5fc88f86aec1d2ac4fe6f612e" />
+ <project name="platform/external/chromium_org/testing/gtest" path="external/chromium_org/testing/gtest" revision="65df883d09205766c521f2e6c126f4070a423141" />
+ <project name="platform/external/chromium_org/third_party/WebKit" path="external/chromium_org/third_party/WebKit" revision="a25b4978c2c50d573391a6d56a0e8ad35f52ffc8" />
+ <project name="platform/external/chromium_org/third_party/angle" path="external/chromium_org/third_party/angle" revision="8b77c2b2231f7d895979f6341e1ad1964a654ce4" />
+ <project name="platform/external/chromium_org/third_party/boringssl/src" path="external/chromium_org/third_party/boringssl/src" revision="85fb7432d3c851200342dd982b211f8dac860687" />
+ <project name="platform/external/chromium_org/third_party/brotli/src" path="external/chromium_org/third_party/brotli/src" revision="96f298ac43a9216b251d6c3264d8f5ada89e107f" />
+ <project name="platform/external/chromium_org/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille" path="external/chromium_org/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille" revision="bb4c72f1deb0b8b2b0468b0bf1050462ebcf6135" />
+ <project name="platform/external/chromium_org/third_party/freetype" path="external/chromium_org/third_party/freetype" revision="dc263f2ee2786739da036911ed8b29c07a639ab9" />
+ <project name="platform/external/chromium_org/third_party/icu" path="external/chromium_org/third_party/icu" revision="85e5871666cade1bb4b53f0cebfae53bc7d8d1f2" />
+ <project name="platform/external/chromium_org/third_party/leveldatabase/src" path="external/chromium_org/third_party/leveldatabase/src" revision="d4e10f2a91f5de7bd17adcdbd80c54b19ab336fe" />
+ <project name="platform/external/chromium_org/third_party/libaddressinput/src" path="external/chromium_org/third_party/libaddressinput/src" revision="7127f6844fac19d7610e34f4f7e03398fcd95531" />
+ <project name="platform/external/chromium_org/third_party/libjingle/source/talk" path="external/chromium_org/third_party/libjingle/source/talk" revision="8fd7b6a4d9e6757c5e1ff50147e6089979bf6701" />
+ <project name="platform/external/chromium_org/third_party/libphonenumber/src/phonenumbers" path="external/chromium_org/third_party/libphonenumber/src/phonenumbers" revision="de6af28b9f9f34a31ffb7772b7510fd215a0814e" />
+ <project name="platform/external/chromium_org/third_party/libphonenumber/src/resources" path="external/chromium_org/third_party/libphonenumber/src/resources" revision="8f194ead1ebd76ebb28b7e2dfc0a7baddc62bb22" />
+ <project name="platform/external/chromium_org/third_party/libsrtp" path="external/chromium_org/third_party/libsrtp" revision="5eddd5b3436aa8b2c7eb1f3c6db154281c6b91c5" />
+ <project name="platform/external/chromium_org/third_party/libvpx" path="external/chromium_org/third_party/libvpx" revision="c20d6540c47e427470c5a56b35fea3c5e9098748" />
+ <project name="platform/external/chromium_org/third_party/libyuv" path="external/chromium_org/third_party/libyuv" revision="6e77b766a9eb7889c1a10cab978705ffe03ff3e7" />
+ <project name="platform/external/chromium_org/third_party/mesa/src" path="external/chromium_org/third_party/mesa/src" revision="e70a8ff30d20e1bf6bb5c06b5cd7bd4ea9ae20e1" />
+ <project name="platform/external/chromium_org/third_party/openmax_dl" path="external/chromium_org/third_party/openmax_dl" revision="83d0254a412b93e81b06a354b90fb627408b4ec8" />
+ <project name="platform/external/chromium_org/third_party/openssl" path="external/chromium_org/third_party/openssl" revision="c2a9402712e13e15fcae2b17ec0cbecb816ef52e" />
+ <project name="platform/external/chromium_org/third_party/opus/src" path="external/chromium_org/third_party/opus/src" revision="e383b38591b010ab08ebddf1fd8d821796bd961a" />
+ <project name="platform/external/chromium_org/third_party/ots" path="external/chromium_org/third_party/ots" revision="4d6e4ddc4b0db2023b1380236c33aa04a7e9e927" />
+ <project name="platform/external/chromium_org/third_party/sfntly/cpp/src" path="external/chromium_org/third_party/sfntly/cpp/src" revision="2bac2ec7167835b214bfe42e762cd2ce6cf8cf1a" />
+ <project name="platform/external/chromium_org/third_party/skia" path="external/chromium_org/third_party/skia" revision="2d75d0865c7bac54bf5e234855609d0f628388b7" />
+ <project name="platform/external/chromium_org/third_party/smhasher/src" path="external/chromium_org/third_party/smhasher/src" revision="09e3094b8ab52bb1ad9ab8c8351d99df50327b67" />
+ <project name="platform/external/chromium_org/third_party/usrsctp/usrsctplib" path="external/chromium_org/third_party/usrsctp/usrsctplib" revision="ed9a6fb519aa7606cab965b2c4218756e849ddb6" />
+ <project name="platform/external/chromium_org/third_party/webrtc" path="external/chromium_org/third_party/webrtc" revision="8b45a80ec9c21b148a5674d3a23ca5fa70981f71" />
+ <project name="platform/external/chromium_org/third_party/yasm/source/patched-yasm" path="external/chromium_org/third_party/yasm/source/patched-yasm" revision="0f308c9bc9aa3258a0e90285b9d4e69bbb5b0a73" />
+ <project name="platform/external/chromium_org/tools/grit" path="external/chromium_org/tools/grit" revision="4ad93ed16c8ae7742fd7c34c83036b8d03c21fb9" />
+ <project name="platform/external/chromium_org/tools/gyp" path="external/chromium_org/tools/gyp" revision="9c42a79388ce87185ad04cb02047c1e56ac5e066" />
+ <project name="platform/external/chromium_org/v8" path="external/chromium_org/v8" revision="db865e6839e98cc9d07609bf81bb6610117ba6ff" />
+ <project groups="pdk" name="platform/external/clang" path="external/clang" revision="070ed154a0a8bc2c0fd4fb9b8a86a0f1218e6dfa" />
+ <project groups="pdk" name="platform/external/compiler-rt" path="external/compiler-rt" revision="c185902e393cd71823258016ead1b315ed062b24" />
+ <project name="platform/external/conscrypt" path="external/conscrypt" revision="26163c268a6d2625384b87e907afad8ef19f9a47" />
+ <project name="platform/external/dexmaker" path="external/dexmaker" revision="2b528c4b156f2de5c641875b98e59e0b09ebaccd" />
+ <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="03baf5eab896198b5060d287af3fd60d360bf48f" />
+ <project groups="pdk" name="platform/external/dnsmasq" path="external/dnsmasq" revision="7674911bc9d10adf57c2c2d15d0c641b48e4afe6" />
+ <project name="platform/external/doclava" path="external/doclava" revision="b9d279d8f9c29a3044d13482846efb21f27b5df4" />
+ <project groups="pdk" name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="721f3bc56989b5f4101e646a02d598ddb4a7ff6e" />
+ <project name="platform/external/easymock" path="external/easymock" revision="c9a234086537e5fd820b110bbd99e3cdc695004c" />
+ <project name="platform/external/eclipse-basebuilder" path="external/eclipse-basebuilder" revision="6134da6347cc997e0cf2921aaadfb46f21c05d85" />
+ <project name="platform/external/eclipse-windowbuilder" path="external/eclipse-windowbuilder" revision="a5f3ee137e94737538ec3bdf9b3716765d178c17" />
+ <project name="platform/external/eigen" path="external/eigen" revision="b015e75e8c7ba1ab4ddb91e9372a57e76f3fd159" />
+ <project name="platform/external/elfutils" path="external/elfutils" revision="38ecac0276825a9463803485440646582e477e78" />
+ <project name="platform/external/embunit" path="external/embunit" revision="336b7c65098af0d1be69f2db55f4e75342d73b3f" />
+ <project name="platform/external/emma" path="external/emma" revision="daacd02a6b9f7a3e82bdf1cc5b84db85ed59edb1" />
+ <project name="platform/external/esd" path="external/esd" revision="224a67f2683a7ee997179fc5dd16115e39987b0f" />
+ <project groups="pdk" name="platform/external/expat" path="external/expat" revision="907ec055718996baf36961e7f47f8447e49b3865" />
+ <project name="platform/external/eyes-free" path="external/eyes-free" revision="16bd4c7a4d1bfe229068b637614dad7c48dd2ceb" />
+ <project name="platform/external/f2fs-tools" path="external/f2fs-tools" revision="00dc8a1c6c87acf687e64e66cfc2fd7ca28e646e" />
+ <project name="platform/external/fdlibm" path="external/fdlibm" revision="c831c726067e0d8a05362e710e2405f0eff81e07" />
+ <project name="platform/external/fio" path="external/fio" revision="6f4e805b805f1ab3025482e471147bb51efa99bd" />
+ <project groups="pdk" name="platform/external/flac" path="external/flac" revision="7f32dd57579bdff88e46e1e403154be0b99165da" />
+ <project groups="pdk" name="platform/external/freetype" path="external/freetype" revision="899c67b6cfcd2010784fbf08c5415af16c526e0c" />
+ <project name="platform/external/fsck_msdos" path="external/fsck_msdos" revision="17a1471db8c528cd9d44ec4385d2eb3614138856" />
+ <project name="platform/external/ganymed-ssh2" path="external/ganymed-ssh2" revision="d3724dabc1cfbacd105fe6c422b4dcba80e4fb2d" />
+ <project groups="pdk" name="platform/external/gcc-demangle" path="external/gcc-demangle" revision="9241386b62c353302c2f9eccda0672685b252b4d" />
+ <project name="platform/external/genext2fs" path="external/genext2fs" revision="e11a9c7fe6f1cef99aad2f25afaea37b72fe9f93" />
+ <project name="platform/external/giflib" path="external/giflib" revision="621696a283c0ce34956417f760f1005fadcd12ae" />
+ <project name="platform/external/google-diff-match-patch" path="external/google-diff-match-patch" revision="cecbe12841337860291c2d6a5728b681ec5fca2a" />
+ <project name="platform/external/google-fonts/carrois-gothic-sc" path="external/google-fonts/carrois-gothic-sc" revision="0062a10458d4c357f3082d66bcb129d11913aaae" />
+ <project name="platform/external/google-fonts/coming-soon" path="external/google-fonts/coming-soon" revision="2c5cb418c690815545bbb0316eae5fd33b9fc859" />
+ <project name="platform/external/google-fonts/dancing-script" path="external/google-fonts/dancing-script" revision="7b6623bd54cee3e48ae8a4f477f616366643cc78" />
+ <project name="platform/external/grub" path="external/grub" revision="33a4e7e4cfa81dc21d37091515891859ef3ab934" />
+ <project groups="pdk" name="platform/external/gtest" path="external/gtest" revision="fa3c26b862ca17c0d2db67606226b49d1648b4bf" />
+ <project name="platform/external/guava" path="external/guava" revision="5e6db342fc75b1945298142530f2d1d1861bce73" />
+ <project name="platform/external/hamcrest" path="external/hamcrest" revision="ba28ac1e0386f26d9a45be5ed16fc9c598b27e70" />
+ <project name="platform/external/harfbuzz" path="external/harfbuzz" revision="7a08026033b424da3b7022ebcce35f033949df8b" />
+ <project name="platform/external/harfbuzz_ng" path="external/harfbuzz_ng" revision="3e537b48a7b56c742ecf3c2ed24ff15fcb73f575" />
+ <project name="platform/external/hyphenation" path="external/hyphenation" revision="bfa84834dfeb7fe8d058c2e7e07b5981451ddf82" />
+ <project name="platform/external/icu" path="external/icu" revision="3c09e2ebbdae6000f3bd471c34d055bc1913f7e4" />
+ <project groups="pdk" name="platform/external/icu4c" path="external/icu4c" revision="e5311394ca22b280da41cd17059288dab3fb1ea6" />
+ <project groups="pdk" name="platform/external/iproute2" path="external/iproute2" revision="5d4c86892885ae1bc12e0e157b35ef44e8ba81bd" />
+ <project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="f4cb1ee4b00abbfb6f968dc25818c23b4b47e584" />
+ <project name="platform/external/iptables" path="external/iptables" revision="e3928b77f18db0fdc615693017c6c15eb71bf4e0" />
+ <project name="platform/external/iputils" path="external/iputils" revision="1c7c426ab377c3a005a36d612ebbb16de86fb7d4" />
+ <project name="platform/external/jack" path="external/jack" revision="5ceb2025ac5d25ed48183ac2d3dac4691fe761fb" />
+ <project name="platform/external/javasqlite" path="external/javasqlite" revision="b8501bdeb0b7e39a0d82f2a96ad382c05a763b22" />
+ <project name="platform/external/javassist" path="external/javassist" revision="9566207cff5871c672fac1f0d4332d93292036d7" />
+ <project name="platform/external/jdiff" path="external/jdiff" revision="e4694302d6a3786c64d954e0b3cf42786283bd3c" />
+ <project name="platform/external/jemalloc" path="external/jemalloc" revision="615fe54259e545c33275753a316c2bfd1198b4f0" />
+ <project groups="pdk" name="platform/external/jhead" path="external/jhead" revision="871af5c305ce1d3087e58fae091c60c359f5fa45" />
+ <project name="platform/external/jmdns" path="external/jmdns" revision="f4eb7466d5c09098f9dc54137ed3235e3c43fc9f" />
+ <project name="platform/external/jmonkeyengine" path="external/jmonkeyengine" revision="a6b44658eb1c55295f132a36233a11aa2bd8f9cf" />
+ <project groups="pdk" name="platform/external/jpeg" path="external/jpeg" revision="213197252c8c4825f6572c651126c22067025fe9" />
+ <project name="platform/external/jsilver" path="external/jsilver" revision="739060b01245f1dc5f1800949b3c30c291253cff" />
+ <project name="platform/external/jsr305" path="external/jsr305" revision="a82868820d6350811b9ddfde4bf8ed5016084269" />
+ <project name="platform/external/junit" path="external/junit" revision="8f312e0c3d6dff30d015d2c85fdaae0a39220fd6" />
+ <project name="platform/external/kernel-headers" path="external/kernel-headers" revision="8b663ef01dcaadfe1dec7ba826e5cd1cf0bb2c91" />
+ <project name="platform/external/libcap-ng" path="external/libcap-ng" revision="1d1011a3c5049a7f9eef99d22f3704e4367579cc" />
+ <project name="platform/external/libcxx" path="external/libcxx" revision="a9aa30b5d18422fce29a42ce1a704bc5f28febde" />
+ <project name="platform/external/libcxxabi" path="external/libcxxabi" revision="87a9be28aceed80250cd1d1a47eb8afa0ee67b51" />
+ <project name="platform/external/libcxxrt" path="external/libcxxrt" revision="d1ee2b2a4946a073596514462d7629373d22fb27" />
+ <project name="platform/external/libexif" path="external/libexif" revision="25d371312cee1452a2adcf8b7f6cad6267bda32d" />
+ <project name="platform/external/libffi" path="external/libffi" revision="385ba8b006b9995456d3c9283fd20dded90809cc" />
+ <project groups="pdk" name="platform/external/libgsm" path="external/libgsm" revision="50761abed8f4734970874165b386cfd4d9599db4" />
+ <project groups="pdk" name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb" />
+ <project name="platform/external/libmtp" path="external/libmtp" revision="7075348937f6a8c9d9211942fcb6c376f4227776" />
+ <project groups="pdk" name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="46abb3dcf960058e48d1444b6a11cc7e84912339" />
+ <project groups="pdk" name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="15d81f71a668b3092549c6b7f83694bf680d9c49" />
+ <project name="platform/external/libnl" path="external/libnl" revision="99debfa4c01b49c9b470884cc56f81fcdee0fa1f" />
+ <project groups="pdk" name="platform/external/libnl-headers" path="external/libnl-headers" revision="52c926a9de955fa2d987bf8c5d4a1304b5a2a611" />
+ <project name="platform/external/libogg" path="external/libogg" revision="ec0b24fb1468abe37be4164a6feb16568e036bde" />
+ <project name="platform/external/libpcap" path="external/libpcap" revision="9dab0cd7430a4d23e0a7752fb13b941692171c3d" />
+ <project name="platform/external/libphonenumber" path="external/libphonenumber" revision="485e6d5c6e48a1fc43cc0a090e687c723dac056c" />
+ <project groups="pdk" name="platform/external/libpng" path="external/libpng" revision="48b7ba25a15a9eae83d366c02475539725d035d0" />
+ <project name="platform/external/libppp" path="external/libppp" revision="706e567fc5ff6b79738a5f470e5aa7b2cae76459" />
+ <project name="platform/external/libseccomp-helper" path="external/libseccomp-helper" revision="e87019943a8b5a7cd0880910f671c37b240d5754" />
+ <project groups="pdk" name="platform/external/libselinux" path="external/libselinux" revision="da4208c8808e6a62fcfe848343abd3e2f3b339cc" />
+ <project groups="pdk" name="platform/external/libsepol" path="external/libsepol" revision="d26204e7d0a3be178a97d4920b82007e05a2a632" />
+ <project name="platform/external/libssh2" path="external/libssh2" revision="2bb40f2445cab3ba588efb29e1835cdba2b27248" />
+ <project name="platform/external/libunwind" path="external/libunwind" revision="b3436a3feed4dcb22dafc8f7818b742cacaddd1d" />
+ <project name="platform/external/libusb" path="external/libusb" revision="2801917fe150393d4f4a354165fe89550ae22613" />
+ <project name="platform/external/libusb-compat" path="external/libusb-compat" revision="94867ba54eb7faa8efca81cf2214d00bb9143d27" />
+ <project name="platform/external/libvorbis" path="external/libvorbis" revision="de559619fd4dd0d2d9608436696fd44bdf74eba8" />
+ <project groups="pdk" name="platform/external/libvpx" path="external/libvpx" revision="d64f247f64fbb814c9ecf06a56bcb0948bfca21f" />
+ <project name="platform/external/libxml2" path="external/libxml2" revision="399e808f940777d18efe377bd34f738dc84729e0" />
+ <project name="platform/external/libxslt" path="external/libxslt" revision="98f5140c33273d3bd67ca03566f8417406001016" />
+ <project groups="libyuv" name="platform/external/libyuv" path="external/libyuv" revision="482a582884351288fb701532359652970b1ba7c0" />
+ <project name="platform/external/linux-tools-perf" path="external/linux-tools-perf" revision="3e1937964f6c183eb6a0000e2dca27fc3a419ca2" />
+ <project name="platform/external/littlemock" path="external/littlemock" revision="328b01eada8965cd38feea884d4080c31e3763b0" />
+ <project groups="pdk" name="platform/external/llvm" path="external/llvm" revision="c4c1f81ae1b07138df50e0459631abf3082bda9c" />
+ <project name="platform/external/ltrace" path="external/ltrace" revision="82ae18484c7b6a8af05354caf6de3a7f1ac5fcf9" />
+ <project name="platform/external/lzma" path="external/lzma" revision="19cf4f773361c09e47a2ffe1613d66cbf632227f" />
+ <project name="platform/external/marisa-trie" path="external/marisa-trie" revision="629ed059b1e85cd8e4de363d8b3dc53c15c3e08a" />
+ <project name="platform/external/markdown" path="external/markdown" revision="6f2e3554ae38cc90518d32e02cb57d05988270a6" />
+ <project groups="pdk" name="platform/external/mdnsresponder" path="external/mdnsresponder" revision="b25c2507ecc3f674e3b4f0a770acf9ad8fd874d0" />
+ <project name="platform/external/mesa3d" path="external/mesa3d" revision="97d3f36a59ea448fa77e47a90bf04f1254670542" />
+ <project name="platform/external/messageformat" path="external/messageformat" revision="180a28770171075aa484729a69d14c7cf0c93fcf" />
+ <project groups="pdk" name="platform/external/mksh" path="external/mksh" revision="2a54bce0ae98f53f0b867e949b26d081691e1493" />
+ <project name="platform/external/mockito" path="external/mockito" revision="4d0dcd53b27a243baf72ee0b127b188a058b318d" />
+ <project name="platform/external/mockwebserver" path="external/mockwebserver" revision="2f7659c426de53122ee7922b0981058a900124a7" />
+ <project name="platform/external/mp4parser" path="external/mp4parser" revision="16051e950485c6b62127c0446a760111de1a0cb9" />
+ <project name="platform/external/mtpd" path="external/mtpd" revision="5ea8006691664b7e6d46d6a6dc889eac91b7fe37" />
+ <project name="platform/external/naver-fonts" path="external/naver-fonts" revision="3bba7d2430bc3ec8105678a27f03fb080f0f8384" />
+ <project name="platform/external/netcat" path="external/netcat" revision="444644cfa9a2f3002863caa168fb2d6b34dfd1e8" />
+ <project name="platform/external/netperf" path="external/netperf" revision="38e47cd883738cb84bdb47a7d263f14f14062d7b" />
+ <project name="platform/external/neven" path="external/neven" revision="504ee5ccaabd8bce4da3430b0f4e9714ac2a8e6c" />
+ <project name="platform/external/nfacct" path="external/nfacct" revision="6f7aae0264821b44e9fe80fb5596c525d3e2f475" />
+ <project name="platform/external/nist-pkits" path="external/nist-pkits" revision="b7a53ad5a587926cb880d9bb6f3d51657596474c" />
+ <project name="platform/external/nist-sip" path="external/nist-sip" revision="b23dbfce7ea84c39cea75b612868a5832cb9af2b" />
+ <project name="platform/external/noto-fonts" path="external/noto-fonts" revision="90372d894b5d9c9f2a111315d2eb3b8de1979ee4" />
+ <project name="platform/external/oauth" path="external/oauth" revision="bc170f58de82000ed6460f111686a850a1890c07" />
+ <project name="platform/external/objenesis" path="external/objenesis" revision="2a7655c0d503fcf5989098f65bf89eae78c32e5a" />
+ <project name="platform/external/okhttp" path="external/okhttp" revision="4909663c795d974d0d4b0e2d1ebd6e179486c897" />
+ <project name="platform/external/open-vcdiff" path="external/open-vcdiff" revision="6d29f2f083baf8250db94ed0b4807e513a84163d" />
+ <project name="platform/external/opencv" path="external/opencv" revision="4a99e243b42afcb885d036bb451eb3c2739275b6" />
+ <project name="platform/external/openfst" path="external/openfst" revision="b7434caa51427a0f5ab5c807e1a92d6ca2af8884" />
+ <project name="platform/external/openssh" path="external/openssh" revision="3c335c9fb9c12375ad62748fa1d1e5ebe4710c94" />
+ <project groups="pdk" name="platform/external/openssl" path="external/openssl" revision="cfe73257599ae4baae3ffb50c2c841d9249d2d16" />
+ <project name="platform/external/oprofile" path="external/oprofile" revision="3722f1053f4cab90c4daf61451713a2d61d79c71" />
+ <project name="platform/external/owasp/sanitizer" path="external/owasp/sanitizer" revision="6a304233f9f2010821a5a1dd40e2832b68353a3c" />
+ <project name="platform/external/pcre" path="external/pcre" revision="993a14b71c8e7af03eb929d44a444137393a5324" />
+ <project name="platform/external/pixman" path="external/pixman" revision="afd5bbd8074cedec8544d07920fa06786d5a4f08" />
+ <project name="platform/external/ppp" path="external/ppp" revision="8b58d9bd02e2c55f547fafbe9ba55b1160665761" />
+ <project groups="pdk-java" name="platform/external/proguard" path="external/proguard" revision="3fd19dba2bdc0c4b64afda4d75836e1dcf7abf97" />
+ <project groups="pdk" name="platform/external/protobuf" path="external/protobuf" revision="95d99df4574c28debcf9646056a0350ff44bc7c9" />
+ <project name="platform/external/qemu" path="external/qemu" revision="539e1f25ecbfe80814dba2ea77feb22087b9d53b" />
+ <project name="platform/external/qemu-pc-bios" path="external/qemu-pc-bios" revision="20349dae98d7de09a7e390d4a706c64f1db6edc2" />
+ <project name="platform/external/regex-re2" path="external/regex-re2" revision="0d4c52358a1af421705c54bd8a9fdd8a30558a2e" />
+ <project name="platform/external/replicaisland" path="external/replicaisland" revision="99e2e54c5d036048caf09bb05eea0969de093104" />
+ <project name="platform/external/robolectric" path="external/robolectric" revision="6bf395c984ed3f69711663b006aeffbb0f7e8a90" />
+ <project groups="pdk" name="platform/external/safe-iop" path="external/safe-iop" revision="aa0725fb1da35e47676b6da30009322eb5ed59be" />
+ <project groups="pdk" name="platform/external/scrypt" path="external/scrypt" revision="dde037b82e5cd6215244e3240dbaad417928eafa" />
+ <project groups="pdk" name="platform/external/sepolicy" path="external/sepolicy" revision="21ada26daea538397029396099dce865267bae2f" />
+ <project name="platform/external/sfntly" path="external/sfntly" revision="6723e5241a45c6de224c96384a595a1bf5bc5449" />
+ <project name="platform/external/sil-fonts" path="external/sil-fonts" revision="795a2f4339f8a82d6cff187e2a77bb01d5911aac" />
+ <project name="platform/external/skia" path="external/skia" revision="d6f2c76fdb9b0469261fa2db0b29ed48c7ac38b5" />
+ <project name="platform/external/smack" path="external/smack" revision="d7955ce24d294fb2014c59d11fca184471056f44" />
+ <project name="platform/external/smali" path="external/smali" revision="5fd395796e215a80c722815bf180728948868f18" />
+ <project groups="pdk" name="platform/external/sonivox" path="external/sonivox" revision="c0723d864b10fbd6c5cbbfa65e886c5e9eb3aafd" />
+ <project groups="pdk" name="platform/external/speex" path="external/speex" revision="eaa4765b8cc6a6dd5ee0d26dc1b61a1044817f32" />
+ <project groups="pdk" name="platform/external/sqlite" path="external/sqlite" revision="50af37d784661b2d54c8e043de52ffc4f02a1a50" />
+ <project name="platform/external/srec" path="external/srec" revision="540e7ee8dbf1d7ee72ef45c92efbebcb89bf6d1a" />
+ <project name="platform/external/srtp" path="external/srtp" revision="98bd63b48a31b4633cdfdc8138577dfa6d8dd2a6" />
+ <project groups="pdk" name="platform/external/stlport" path="external/stlport" revision="dc05ca5be2319f74b41cb429ea50f30fceff4ace" />
+ <project name="platform/external/strace" path="external/strace" revision="a2adbed6e2d3ce85ebb167e16ae370681a8b5188" />
+ <project name="platform/external/stressapptest" path="external/stressapptest" revision="0956427aa995561acb4471764158ae057a36dad5" />
+ <project name="platform/external/svox" path="external/svox" revision="ad0a55bd0e13a27ed11034346eee9c47e3684ef2" />
+ <project name="platform/external/syspatch" path="external/syspatch" revision="358a4f86b8c2cb3d3f879a37f6773dd09d4b77b0" />
+ <project name="platform/external/tagsoup" path="external/tagsoup" revision="a97828cb3f8f3a1af8470e55d3c5cd62d6a7cb4c" />
+ <project name="platform/external/tcpdump" path="external/tcpdump" revision="de49cdcfddf36f2b41ef3278e98a8a550a189952" />
+ <project name="platform/external/timezonepicker-support" path="external/timezonepicker-support" revision="99e91a76fd74bad10266623d67cdb98d011f709e" />
+ <project groups="pdk" name="platform/external/tinyalsa" path="external/tinyalsa" revision="653e7a4015341c87b4d55ec9a94ec7bdee044f6f" />
+ <project groups="pdk" name="platform/external/tinycompress" path="external/tinycompress" revision="aeee2c6a19b9d3765f72bc79555005786a424233" />
+ <project groups="pdk" name="platform/external/tinyxml" path="external/tinyxml" revision="f065a8058659c0e6c5a5ccddcdb4faf0fe645cd0" />
+ <project groups="pdk" name="platform/external/tinyxml2" path="external/tinyxml2" revision="c74b546f5af36968ffa56d7fd4529f4273b96f48" />
+ <project groups="pdk" name="platform/external/tremolo" path="external/tremolo" revision="0fec2aefa8143c83df43752bb0218dfa371cc57e" />
+ <project groups="pdk" name="platform/external/valgrind" path="external/valgrind" revision="893257d6c86a18cc5cf6c92528b7027f327dca70" />
+ <project name="platform/external/vixl" path="external/vixl" revision="e1ab25cde167109efb28fa6a86d5c2c80b762d58" />
+ <project name="platform/external/webp" path="external/webp" revision="0db01fc3411621bec473d50db0071fd2a225962e" />
+ <project groups="pdk" name="platform/external/webrtc" path="external/webrtc" revision="d62aeac391d16d4953a12120c0ff614ccde02a30" />
+ <project groups="pdk" name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="88ef20ce4facae68a3e6b05429bb9f3f73a93996" />
+ <project name="platform/external/xdelta3" path="external/xdelta3" revision="52d9c642e6a307c43881f20a4ed1c10e947234ba" />
+ <project name="platform/external/xmlwriter" path="external/xmlwriter" revision="e95d92246ee35273dde2bee8b00485cc14c12be5" />
+ <project name="platform/external/xmp_toolkit" path="external/xmp_toolkit" revision="42ea4dc6d1fc2206a7778029070ed9213e3b0fbf" />
+ <project groups="pdk" name="platform/external/yaffs2" path="external/yaffs2" revision="a2cff2275e1b501ff478b03757d6e4f05fddc2db" />
+ <project groups="pdk" name="platform/external/zlib" path="external/zlib" revision="8d977782c1cfe9d75cc9a464439c2ff1e27e1665" />
+ <project name="platform/external/zxing" path="external/zxing" revision="7620644768ffc235607b3a94671e49518c18686f" />
+ <project groups="pdk" name="platform/frameworks/av" path="frameworks/av" revision="a018cd4926460f8f5ab30a9a11df9775572d8620" />
+ <project name="platform/frameworks/base" path="frameworks/base" revision="6a58309e734086a21580dd8d9175ac1817ca3ab2" />
+ <project groups="pdk" name="platform/frameworks/compile/libbcc" path="frameworks/compile/libbcc" revision="3fc91521640692f844aece8b1743c4df702d1c66" />
+ <project groups="pdk" name="platform/frameworks/compile/mclinker" path="frameworks/compile/mclinker" revision="e673be8f0526f9cbc83093fb579c0f76de9e4e3c" />
+ <project groups="pdk" name="platform/frameworks/compile/slang" path="frameworks/compile/slang" revision="c957dd47b0a0705a686896b26cd1859d25824552" />
+ <project name="platform/frameworks/ex" path="frameworks/ex" revision="3696df848aa7c574f913c97c3bf415b634934048" />
+ <project name="platform/frameworks/mff" path="frameworks/mff" revision="b9669b8540a1e5c953374d53b115514335e23c27" />
+ <project name="platform/frameworks/ml" path="frameworks/ml" revision="b020ad88ca28ada76a596b5dcc7e6c2854fcc132" />
+ <project name="platform/frameworks/multidex" path="frameworks/multidex" revision="590a07e63868f0a1da311ff22b4a9f35eb48a865" />
+ <project groups="pdk" name="platform/frameworks/native" path="frameworks/native" revision="e8878921db4a51ff5d4e75d9c8958d889a048603" />
+ <project name="platform/frameworks/opt/calendar" path="frameworks/opt/calendar" revision="03b18577f8f8f799e87a62b8e03889ddacf6daa2" />
+ <project name="platform/frameworks/opt/carddav" path="frameworks/opt/carddav" revision="f08aa2df132dd8dc32a0013d3750137d9dd9280a" />
+ <project name="platform/frameworks/opt/colorpicker" path="frameworks/opt/colorpicker" revision="720a40ae24d526268b3c0f2dd8497b5df2cc6f23" />
+ <project name="platform/frameworks/opt/datetimepicker" path="frameworks/opt/datetimepicker" revision="8a1c55baaf5ced7a98b196c689ccdd59238f6e58" />
+ <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="709f713ebcd62c61defc270d945810efca179621" />
+ <project name="platform/frameworks/opt/inputmethodcommon" path="frameworks/opt/inputmethodcommon" revision="df9dd39c2047992a43b64e13bb0fc348a1630f3b" />
+ <project name="platform/frameworks/opt/mailcommon" path="frameworks/opt/mailcommon" revision="1537812900e59f875cfea0483f0ae261b16d3e4b" />
+ <project name="platform/frameworks/opt/mms" path="frameworks/opt/mms" revision="64817e848552fd0a429a3e026b7b1562103c56bb" />
+ <project name="platform/frameworks/opt/net/voip" path="frameworks/opt/net/voip" revision="0f722c7f09ce67e058eb1cfaabf1d85f1abdf797" />
+ <project name="platform/frameworks/opt/photoviewer" path="frameworks/opt/photoviewer" revision="8c32972911bf73babdb01d30267f57255e242d78" />
+ <project groups="pdk" name="platform/frameworks/opt/telephony" path="frameworks/opt/telephony" revision="93faaed9056491c551ef7046e9e1de7d6397e95c" />
+ <project name="platform/frameworks/opt/timezonepicker" path="frameworks/opt/timezonepicker" revision="3820b87bfbc86d066e9093e78254e1f3728ad77d" />
+ <project name="platform/frameworks/opt/vcard" path="frameworks/opt/vcard" revision="5907243e6cf0603adf266ebfa7ee5ee465b9c596" />
+ <project name="platform/frameworks/opt/widget" path="frameworks/opt/widget" revision="466e0e0307b3f6aa4f4be3d9419b5996bd389da5" />
+ <project groups="pdk" name="platform/frameworks/rs" path="frameworks/rs" revision="ad0544fdf918e64cec05d1c98588880f10b09220" />
+ <project name="platform/frameworks/support" path="frameworks/support" revision="f05c07d3528765076adc16337a1f68f1700955dc" />
+ <project name="platform/frameworks/testing" path="frameworks/testing" revision="5c8e0271db889518f5969b142a37faa01a4ee54d" />
+ <project name="platform/frameworks/volley" path="frameworks/volley" revision="0e406003b5d434d8f16d7d6ad97d446060b788e6" />
+ <project name="platform/frameworks/webview" path="frameworks/webview" revision="6ed700e171cb2ee3303c08a1db2abc0e56fd307a" />
+ <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="a62c3572e60ae0446632de15418a65089cccf551" />
+ <project name="platform/hardware/akm" path="hardware/akm" revision="32838ef838d1341aa8b77022869b801fb0bbb26c" />
+ <project groups="pdk" name="platform/hardware/broadcom/libbt" path="hardware/broadcom/libbt" revision="55ddd0cce019e88829f92b2fe4e17d5869daa9b9" />
+ <project groups="broadcom_wlan" name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="47a3b8f496e6d2a836ac6b7268e5626c969542ec" />
+ <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="0f5bc7cd710fac85377621a8b9a4c364af80605f" />
+ <project groups="pdk" name="platform/hardware/libhardware" path="hardware/libhardware" revision="3e618a6aa10c783d1536f20edfc3347939cfa18e" />
+ <project groups="pdk" name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="4c20a09e8684657448f0bc97a2da4e56c94d484e" />
+ <project groups="qcom" name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="d47ff224c7b24933c701acae8d5e4c98a1bc80af" />
+ <project groups="qcom" name="platform/hardware/qcom/bt" path="hardware/qcom/bt" revision="cf314a462ba06f4bd3352d5d4630edcf6edbbe97" />
+ <project groups="qcom" name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="fbf72e519ec5fe2f2720b1a3d119e2d69e172e34" />
+ <project groups="qcom" name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="0a611c6ae11b65fec5ada5ecaa0893541db34156" />
+ <project groups="qcom" name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="70d36107318e1d3f7abf62a56279b3f9da3ff000" />
+ <project groups="qcom" name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="1208a868bcb0ffaa650a7e68b51031254c775d39" />
+ <project groups="qcom_msm8960" name="platform/hardware/qcom/msm8960" path="hardware/qcom/msm8960" revision="ca38ed098b05a79d20e852348f27d7c40a53f801" />
+ <project groups="qcom_msm8x74" name="platform/hardware/qcom/msm8x74" path="hardware/qcom/msm8x74" revision="0c6844ea9ee14fd7bbfd6af0bcc6b6b682f46d1c" />
+ <project groups="qcom" name="platform/hardware/qcom/power" path="hardware/qcom/power" revision="ff9f4538c09399030fa73e3e65a167852cb91e8f" />
+ <project groups="qcom" name="platform/hardware/qcom/sensors" path="hardware/qcom/sensors" revision="07c5bcdb36158e22d33bac02eecd83d4ff1fb2f8" />
+ <project groups="qcom_wlan" name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="daa321b0ad8c10b454dc28d7e6dadc72196a8c7a" />
+ <project groups="pdk" name="platform/hardware/ril" path="hardware/ril" revision="eb2a93458204a928edfe36f043ddb48cf5575143" />
+ <project groups="exynos5" name="platform/hardware/samsung_slsi/exynos5" path="hardware/samsung_slsi/exynos5" revision="d7bd354358ecfb1e52afb3da4fc586c0822c696a" />
+ <project name="platform/hardware/ti/omap3" path="hardware/ti/omap3" revision="949aad363a9cc794f9ac8fd42338ae1678e50bc1" />
+ <project groups="omap4" name="platform/hardware/ti/omap4xxx" path="hardware/ti/omap4xxx" revision="c32caab84ff9edc1489ed6c8079c7d252caafc4d" />
+ <project name="platform/libcore" path="libcore" revision="d343e35535a99bad32eea0defc8a3e9c23c9967f" />
+ <project groups="pdk-java" name="platform/libnativehelper" path="libnativehelper" revision="b37e11d07dec2d49b576709ae8e0568a9daabd07" />
+ <project name="platform/ndk" path="ndk" revision="f584f76882baf374166cf12b99cd5f3dbdf3b6b9" />
+ <project name="platform/packages/apps/BasicSmsReceiver" path="packages/apps/BasicSmsReceiver" revision="80327793c4b4ebf4a6a53b72e46c477afe18f135" />
+ <project name="platform/packages/apps/Bluetooth" path="packages/apps/Bluetooth" revision="7efa9db2129c99475684a2e44c4fb89cce3134bc" />
+ <project name="platform/packages/apps/Browser" path="packages/apps/Browser" revision="fe4083510dc773911651456f150bf5432f81a6c0" />
+ <project name="platform/packages/apps/Calculator" path="packages/apps/Calculator" revision="6c7521bb685c9b7b7c36f2077612d4b1a0e808d4" />
+ <project name="platform/packages/apps/Calendar" path="packages/apps/Calendar" revision="2d72f6bed6a0eeaddbda08393063fe873c1c7922" />
+ <project name="platform/packages/apps/Camera" path="packages/apps/Camera" revision="b0e357d548fb8d10896200add2b932199a96a2ea" />
+ <project name="platform/packages/apps/Camera2" path="packages/apps/Camera2" revision="ece4866dc575b956801f6dab2d6c4923e272c5fa" />
+ <project name="platform/packages/apps/CellBroadcastReceiver" path="packages/apps/CellBroadcastReceiver" revision="21d8baf492007cc01545905de33ecefe5d947843" />
+ <project name="platform/packages/apps/CertInstaller" path="packages/apps/CertInstaller" revision="483a188feda6e9d311aef437d28f30e1fb6afeb0" />
+ <project name="platform/packages/apps/Contacts" path="packages/apps/Contacts" revision="24a4f48dc5c768188143648e267889477e4185e8" />
+ <project name="platform/packages/apps/ContactsCommon" path="packages/apps/ContactsCommon" revision="6ce4a3bc083a7dbcc7ffa2bebff242638d7f8e61" />
+ <project name="platform/packages/apps/DeskClock" path="packages/apps/DeskClock" revision="d3bfe9223f3e70271813f48b8ef5500c3a90c0b3" />
+ <project name="platform/packages/apps/Dialer" path="packages/apps/Dialer" revision="5cb300ef50e9942eef746319dd1b1b6e7c2c05e2" />
+ <project name="platform/packages/apps/Email" path="packages/apps/Email" revision="22766dcf6a44416b2972c053739472317017257d" />
+ <project name="platform/packages/apps/Exchange" path="packages/apps/Exchange" revision="ab03a7f9b197b6ffcc390dd5fb589067a5161148" />
+ <project name="platform/packages/apps/Gallery" path="packages/apps/Gallery" revision="9595006a3347c08e6b8e31d679903bb8f77a343d" />
+ <project name="platform/packages/apps/Gallery2" path="packages/apps/Gallery2" revision="9cde04ed08f3a5201a007d78b3c89f43fb3003e0" />
+ <project name="platform/packages/apps/HTMLViewer" path="packages/apps/HTMLViewer" revision="7498890092c388dc59ca932e09ec79dd568b1a19" />
+ <project name="platform/packages/apps/InCallUI" path="packages/apps/InCallUI" revision="d968d1a28dae45229b1be9f05bef8df13821e94d" />
+ <project name="platform/packages/apps/KeyChain" path="packages/apps/KeyChain" revision="e6243f79f3ce6daeb2d8d879e6e1a684ffc1b2fc" />
+ <project name="platform/packages/apps/Launcher2" path="packages/apps/Launcher2" revision="31569f6dbd44d443ff54c460b733e62fc37d2319" />
+ <project name="platform/packages/apps/Launcher3" path="packages/apps/Launcher3" revision="3a9f3a7806a0153865415d6207c6812915d3f6b1" />
+ <project name="platform/packages/apps/LegacyCamera" path="packages/apps/LegacyCamera" revision="d9b5d8941d1ec47ff391da2b8cc8ec90f902062f" />
+ <project name="platform/packages/apps/Mms" path="packages/apps/Mms" revision="e770738ea4389afddb0b4e6c69749f9456ed0f48" />
+ <project name="platform/packages/apps/Music" path="packages/apps/Music" revision="bfca689bb6605cfcd1e0c1781c707735efb7444e" />
+ <project name="platform/packages/apps/MusicFX" path="packages/apps/MusicFX" revision="aaa2f99caac6f088b23de55fe2eb1e8ee305b1fb" />
+ <project name="platform/packages/apps/Nfc" path="packages/apps/Nfc" revision="f62a9a00a13ba333e88cb9e8ce2553d6acf708ad" />
+ <project name="platform/packages/apps/OneTimeInitializer" path="packages/apps/OneTimeInitializer" revision="01e429c08e51291315890de9677151a7e0b6ad35" />
+ <project name="platform/packages/apps/PackageInstaller" path="packages/apps/PackageInstaller" revision="212398024b4491276ef00cf7fcd829c89200b6ba" />
+ <project name="platform/packages/apps/Phone" path="packages/apps/Phone" revision="bf4ec5b1258628bfa6a82aa0d80f348a77bbf194" />
+ <project name="platform/packages/apps/PhoneCommon" path="packages/apps/PhoneCommon" revision="16f62c5ab5c21981e63d678187ad4b44e686332b" />
+ <project name="platform/packages/apps/Protips" path="packages/apps/Protips" revision="325232e344b257a3c236ead2adc60c7378f226c0" />
+ <project name="platform/packages/apps/Provision" path="packages/apps/Provision" revision="78ca0db658fe6253d506916e36319e620476f809" />
+ <project name="platform/packages/apps/QuickSearchBox" path="packages/apps/QuickSearchBox" revision="cfb7af6652a7fbcc0f86341edfe14dc316c9ff37" />
+ <project name="platform/packages/apps/Settings" path="packages/apps/Settings" revision="2abbacb7d46657e5863eb2ef0035521ffc41a0a8" />
+ <project name="platform/packages/apps/SmartCardService" path="packages/apps/SmartCardService" revision="29eae320a4bd222b5ff1c092f84f1aebba88d0b7" />
+ <project name="platform/packages/apps/SoundRecorder" path="packages/apps/SoundRecorder" revision="b0e671faf142fa0b933b4f1cd7d186b1f37ebe46" />
+ <project name="platform/packages/apps/SpareParts" path="packages/apps/SpareParts" revision="4db997871e3f4c3f84660815096e5276b47c5c91" />
+ <project name="platform/packages/apps/SpeechRecorder" path="packages/apps/SpeechRecorder" revision="536aa74ff3a77186bef29dc9333a34688fa59d13" />
+ <project name="platform/packages/apps/Stk" path="packages/apps/Stk" revision="115b75461f8e1fb432fe1a892549ca1c96cef497" />
+ <project name="platform/packages/apps/Tag" path="packages/apps/Tag" revision="f830b07335bd2dd794b84507b5390f7d893fe428" />
+ <project name="platform/packages/apps/TvSettings" path="packages/apps/TvSettings" revision="24e45eaf3b4badaf02e449e7f6d07c72e743f521" />
+ <project name="platform/packages/apps/UnifiedEmail" path="packages/apps/UnifiedEmail" revision="d4537c907920f4470b70e91c187ef7a0b31632db" />
+ <project name="platform/packages/apps/VideoEditor" path="packages/apps/VideoEditor" revision="a49ea28e1628f507ae3a564215664c29c5fa1215" />
+ <project name="platform/packages/apps/VoiceDialer" path="packages/apps/VoiceDialer" revision="72df4532dfca9a82e8aef55fcdfce3026d3d3312" />
+ <project name="platform/packages/experimental" path="packages/experimental" revision="588c7cda9c62fb77d23bc089a63cba8a96bc9ffb" />
+ <project name="platform/packages/inputmethods/LatinIME" path="packages/inputmethods/LatinIME" revision="159474f2ae5d13308ca1b92b8a5ccd809ec6a450" />
+ <project name="platform/packages/inputmethods/OpenWnn" path="packages/inputmethods/OpenWnn" revision="59aefa242169b7a51c2381daee58ff22fd1834ce" />
+ <project name="platform/packages/inputmethods/PinyinIME" path="packages/inputmethods/PinyinIME" revision="49aebad1c1cfbbcaa9288ffed5161e79e57c3679" />
+ <project name="platform/packages/providers/ApplicationsProvider" path="packages/providers/ApplicationsProvider" revision="3347f31bd268ca3153abe5def9361f625bd73efd" />
+ <project name="platform/packages/providers/CalendarProvider" path="packages/providers/CalendarProvider" revision="20360f2fdd7ad2de1234b7ed61e3ea120f0dc635" />
+ <project name="platform/packages/providers/ContactsProvider" path="packages/providers/ContactsProvider" revision="6ac2395324c0e7539434b7c68ec738f867d7ed37" />
+ <project name="platform/packages/providers/DownloadProvider" path="packages/providers/DownloadProvider" revision="90e7485d68095b5fc5044dd1bc6cd4dfc485eaa3" />
+ <project name="platform/packages/providers/MediaProvider" path="packages/providers/MediaProvider" revision="501b93fb00db86fe4fb53dc000f6f11587afe4b0" />
+ <project name="platform/packages/providers/PartnerBookmarksProvider" path="packages/providers/PartnerBookmarksProvider" revision="96d0a80af45923767baf449fc8c735c2f71d64ae" />
+ <project name="platform/packages/providers/TelephonyProvider" path="packages/providers/TelephonyProvider" revision="91e705bc7662192ea33f2bac6b0a6c79fc9bc7ab" />
+ <project name="platform/packages/providers/UserDictionaryProvider" path="packages/providers/UserDictionaryProvider" revision="361f35b7b1fe758d93e0952536a298b2ed045a89" />
+ <project name="platform/packages/screensavers/Basic" path="packages/screensavers/Basic" revision="4b5d9d8bea733c4e5876541831f27bf40588b516" />
+ <project name="platform/packages/screensavers/PhotoTable" path="packages/screensavers/PhotoTable" revision="a5e0fee8e923cfc8682eb4431bc3997ed15f649a" />
+ <project name="platform/packages/screensavers/WebView" path="packages/screensavers/WebView" revision="6e0a80f6faed6191acc8ce1b6c79eada09e9e042" />
+ <project name="platform/packages/services/Telephony" path="packages/services/Telephony" revision="aa156251eb0414b8c6546c98769789dc28b38140" />
+ <project name="platform/packages/wallpapers/Basic" path="packages/wallpapers/Basic" revision="2e1d8404b87caf13cde644959f28213f2db09843" />
+ <project name="platform/packages/wallpapers/Galaxy4" path="packages/wallpapers/Galaxy4" revision="34b31b45e75b2e73a770fef1a2f9a862b10f1a57" />
+ <project name="platform/packages/wallpapers/HoloSpiral" path="packages/wallpapers/HoloSpiral" revision="63b75996a7cfb713a6a6feb5c774ba4b46c7d6eb" />
+ <project name="platform/packages/wallpapers/LivePicker" path="packages/wallpapers/LivePicker" revision="8082f92e76774607d62412e8e1191dd940f055ba" />
+ <project name="platform/packages/wallpapers/MagicSmoke" path="packages/wallpapers/MagicSmoke" revision="f01ea4c07914010d52a42130acb7e67d4306fbda" />
+ <project name="platform/packages/wallpapers/MusicVisualization" path="packages/wallpapers/MusicVisualization" revision="72fbcf3a8e4ebee42c36a5887432ca823ef0e4e5" />
+ <project name="platform/packages/wallpapers/NoiseField" path="packages/wallpapers/NoiseField" revision="7d3e52a18a1255baffd7c0675a465f1b85b99f56" />
+ <project name="platform/packages/wallpapers/PhaseBeam" path="packages/wallpapers/PhaseBeam" revision="0da76f35378677f1102e0be218ce1993c0e528b6" />
+ <project groups="pdk" name="platform/pdk" path="pdk" revision="d440d4219412981df7ef90bed65acf29b2e7ea6a" />
+ <project name="platform/prebuilts/android-emulator" path="prebuilts/android-emulator" revision="d6a246c24accff42eb433f5e39d14cb24faf1e58" />
+ <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/3.1" path="prebuilts/clang/darwin-x86/3.1" revision="426233405bef3c7c825095ab14256c3773894b9b" />
+ <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/3.2" path="prebuilts/clang/darwin-x86/3.2" revision="af856d77b3cbb1f6afccdc531bee991403c28907" />
+ <project groups="darwin,arm" name="platform/prebuilts/clang/darwin-x86/arm/3.3" path="prebuilts/clang/darwin-x86/arm/3.3" revision="54acc51e28850485e380b55916868a4e1ff17998" />
+ <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/host/3.4" path="prebuilts/clang/darwin-x86/host/3.4" revision="a798fe00dbd92ad4e5f7123a2e2bc1d805db04f6" />
+ <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/host/3.5" path="prebuilts/clang/darwin-x86/host/3.5" revision="ce812d27fb78972e71482e93241b9770ca54845d" />
+ <project groups="darwin,mips" name="platform/prebuilts/clang/darwin-x86/mips/3.3" path="prebuilts/clang/darwin-x86/mips/3.3" revision="da3dad928542362835082b2eda44e4dc315d65bb" />
+ <project groups="darwin,x86" name="platform/prebuilts/clang/darwin-x86/x86/3.3" path="prebuilts/clang/darwin-x86/x86/3.3" revision="f67a83f35e30f92b312fbee852184c3f6dc38f34" />
+ <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde" />
+ <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8" />
+ <project groups="linux,arm" name="platform/prebuilts/clang/linux-x86/arm/3.3" path="prebuilts/clang/linux-x86/arm/3.3" revision="2f6d2db9e2af3507d132cf5d286a42fe1d47f7bc" />
+ <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.4" path="prebuilts/clang/linux-x86/host/3.4" revision="fae26a039f79d780ddedcad07f164d9e6c05fc87" />
+ <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="485ffdc99707f81f4201e85bbbb937f23e1e04aa" />
+ <project groups="linux,mips" name="platform/prebuilts/clang/linux-x86/mips/3.3" path="prebuilts/clang/linux-x86/mips/3.3" revision="51f8e2760628588fe268438d612d942c30d13fb2" />
+ <project groups="linux,x86" name="platform/prebuilts/clang/linux-x86/x86/3.3" path="prebuilts/clang/linux-x86/x86/3.3" revision="017a8a67f92a66b29ab17772e50642a7b9d0f8e6" />
+ <project name="platform/prebuilts/devtools" path="prebuilts/devtools" revision="be724be535ea50585d8c625b768ccb63aacd2926" />
+ <project groups="pdk" name="platform/prebuilts/eclipse" path="prebuilts/eclipse" revision="cf9f78f8cf41b16edf9f712598a42743d5cea4af" />
+ <project groups="notdefault,eclipse" name="platform/prebuilts/eclipse-build-deps" path="prebuilts/eclipse-build-deps" revision="ceb739d6a7c10f5fb5a6cf6e1f702453b1361ad3" />
+ <project groups="notdefault,eclipse" name="platform/prebuilts/eclipse-build-deps-sources" path="prebuilts/eclipse-build-deps-sources" revision="8b7d8f6033ffe2d22905d10cf6d57d5bdcbe519b" />
+ <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.8" revision="a261d38eaebb7ff406a6bb60237b36fc61714d46" />
+ <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" revision="32d722d66d7a935a8b6f8e6ab2d5d8bf0e9e0986" />
+ <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8" revision="6d08ca9f45ff685648fd13c75bf5cac4b11c19bb" />
+ <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.8" revision="264394c23b2686ce52cd4ffb116ced127aa7f8fc" />
+ <project groups="pdk,darwin" name="platform/prebuilts/gcc/darwin-x86/host/headers" path="prebuilts/gcc/darwin-x86/host/headers" revision="4ac4f7cc41cf3c9e36fc3d6cf37fd1cfa9587a68" />
+ <project groups="pdk,darwin" name="platform/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" path="prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" revision="8834958755acc291d126ba7ee38ac731d04f9c9e" />
+ <project groups="pdk,darwin,mips" name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.8" path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.8" revision="3b5bef47de8017ff39ef5bfbe801e3fa6b272fab" />
+ <project name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" revision="367a6529b0cc9f5ac5ca69226f583420563fd473" />
+ <project groups="pdk,darwin,mips" name="platform/prebuilts/gcc/darwin-x86/mips/mipsel-linux-android-4.8" path="prebuilts/gcc/darwin-x86/mips/mipsel-linux-android-4.8" revision="ba97180acd4251d3acf08530faa4a724af74abd3" />
+ <project groups="pdk,darwin,x86" name="platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.8" revision="c3c37a54f07d51a50e17d63dbf1d92da343f45ce" />
+ <project name="platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" revision="a7c5a1df753fd3a24494d5e1fe00211048be5c1d" />
+ <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="7334f0a7a872700d0aaf00bea75917c077c45530" />
+ <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" revision="a3f0180676c6b6cd9c664704f86855d3404ae4dd" />
+ <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a" />
+ <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="d9735fc81434f2af2c44d86ca57740c673c8d9bc" />
+ <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="eb5c9f0ae36bf964f6855bde54e1b387e2c26bb6" />
+ <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="1b0544da652fda90a41a1f69889d6b137ce20fb9" />
+ <project name="platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" revision="2725a175a32032fb9a63e247c176ecc3d448ea27" />
+ <project groups="pdk,linux,mips" name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.8" path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.8" revision="38586de6b44714b4adcf21119fe6b267e33f3ca6" />
+ <project name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" revision="eabc7ae8ed527ee3d4517196732fa3f3e8939a28" />
+ <project groups="pdk,linux,mips" name="platform/prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.8" path="prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.8" revision="c06b9b305c365163c99d4ffba49ac37ce2716024" />
+ <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="e08fa7e57a573a9baa5ccd8d4b8d73cc871f9b48" />
+ <project name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" revision="e99278016e6285363bc20d1b35d4b9b5c4e8b0a0" />
+ <project name="platform/prebuilts/gradle-plugin" path="prebuilts/gradle-plugin" revision="e7814a3cbb96742ff74505a1fc152cb534fbf2f9" />
+ <project name="platform/prebuilts/maven_repo/android" path="prebuilts/maven_repo/android" revision="0dbe3df0f057de9e83e599b9be2ca866c673130d" />
+ <project groups="pdk" name="platform/prebuilts/misc" path="prebuilts/misc" revision="3cc2e316acf9da501479bbfd85159407239994d2" />
+ <project groups="pdk" name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="7a8bc5c36d519c41de61765ff94245f56c4bed7a" />
+ <project groups="darwin" name="platform/prebuilts/python/darwin-x86/2.7.5" path="prebuilts/python/darwin-x86/2.7.5" revision="2bdd4fd418614c7c0101147d02199d0e47c4980e" />
+ <project groups="linux" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="6fbc8802b3b68d24a4ee83f164b22490cf702ff2" />
+ <project groups="pdk" name="platform/prebuilts/qemu-kernel" path="prebuilts/qemu-kernel" revision="5f91f38eac40a8465f3a7e4aa298a75afcf2936a" />
+ <project name="platform/prebuilts/runtime" path="prebuilts/runtime" revision="56e663b8ec9cd0df9ce5afdc7b7d56460faf44c8" />
+ <project groups="pdk" name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="52043ca65e06bc84779dd8d3e55e72ad04bcef59" />
+ <project groups="pdk,tools" name="platform/prebuilts/tools" path="prebuilts/tools" revision="130c3d0a1a484d617531d75ddd50714f68213cbb" />
+ <project name="platform/sdk" path="sdk" revision="1af9ef83f5f6c6fd9202d5bdd8d4248a4eb855aa" />
+ <project groups="pdk" name="platform/system/core" path="system/core" revision="cddc97cb3a927d179a42e0fec77f0d267fcd74d1" />
+ <project groups="pdk" name="platform/system/extras" path="system/extras" revision="97ed949ec7bef088ca3d06fb7b5f3bdad9a5103c" />
+ <project name="platform/system/keymaster" path="system/keymaster" revision="7a70abbf29293b30bb1e7ed3a58deb40f8774a53" />
+ <project groups="pdk" name="platform/system/media" path="system/media" revision="77f0f32b32adc5ba1134e7a68e4d907c4f695eb6" />
+ <project groups="pdk" name="platform/system/netd" path="system/netd" revision="f5d949ef0991737af9daa7ba702cc2ec638e435b" />
+ <project groups="pdk" name="platform/system/security" path="system/security" revision="0387a7fd23021b904612101b727a2060847f6169" />
+ <project groups="pdk" name="platform/system/vold" path="system/vold" revision="c0c2867518eed4539444434c95fad8185a6ac08e" />
+ <project groups="notdefault,tools" name="platform/tools/adt/eclipse" path="tools/adt/eclipse" revision="ede2ed86419bb4c78428f1ac09825b1a247d8e24" />
+ <project groups="notdefault,tools" name="platform/tools/adt/idea" path="tools/adt/idea" revision="50a5da1af3e851df7aff37c291541000685bcad4" />
+ <project groups="notdefault,tools" name="platform/tools/base" path="tools/base" revision="4dc06057ba77596807e2d28c715719f240f71549" />
+ <project groups="notdefault,tools" name="platform/tools/build" path="tools/build" revision="69c4b95102b4b9862bfba68b3eaf5b7537a705ee" />
+ <project groups="notdefault,tools" name="platform/tools/emulator" path="tools/emulator" revision="c427e5d5227ba9413307670a5d758d9ced394a7e" />
+ <project groups="tools" name="platform/tools/external/fat32lib" path="tools/external/fat32lib" revision="3880776e41ff7def06e351720f2d162f88b58a03" />
+ <project groups="tools" name="platform/tools/external/gradle" path="tools/external/gradle" revision="842b7a27df8606faa29b0875a13270701eb78dd8" />
+ <project groups="notdefault,tools" name="platform/tools/idea" path="tools/idea" revision="12356153d01fcde14dd3a06948cfded92c20d068" />
+ <project groups="notdefault,motodev" name="platform/tools/motodev" path="tools/motodev" revision="69989786cefbde82527960a1e100ec9afba46a98" />
+ <project groups="notdefault,tools" name="platform/tools/studio/cloud" path="tools/studio/cloud" revision="839eb097c5fc73f91a722f1457a2e8e11eb4e1a5" />
+ <project groups="notdefault,tools" name="platform/tools/swt" path="tools/swt" revision="aaf3131b0e4b15d39156a6e94e5da06b0183d61d" />
+</manifest>
diff --git a/node_modules/node-gyp/gyp/buildbot/buildbot_run.py b/node_modules/node-gyp/gyp/buildbot/buildbot_run.py
index 979073c77..f46ab1822 100755
--- a/node_modules/node-gyp/gyp/buildbot/buildbot_run.py
+++ b/node_modules/node-gyp/gyp/buildbot/buildbot_run.py
@@ -7,6 +7,7 @@
"""Argument-less script to select what to run on the buildbots."""
+import filecmp
import os
import shutil
import subprocess
@@ -30,7 +31,8 @@ OUT_DIR = os.path.join(TRUNK_DIR, 'out')
def CallSubProcess(*args, **kwargs):
"""Wrapper around subprocess.call which treats errors as build exceptions."""
- retcode = subprocess.call(*args, **kwargs)
+ with open(os.devnull) as devnull_fd:
+ retcode = subprocess.call(stdin=devnull_fd, *args, **kwargs)
if retcode != 0:
print '@@@STEP_EXCEPTION@@@'
sys.exit(1)
@@ -49,10 +51,6 @@ def PrepareCmake():
print '@@@BUILD_STEP Initialize CMake checkout@@@'
os.mkdir(CMAKE_DIR)
- CallSubProcess(['git', 'config', '--global', 'user.name', 'trybot'])
- CallSubProcess(['git', 'config', '--global',
- 'user.email', 'chrome-bot@google.com'])
- CallSubProcess(['git', 'config', '--global', 'color.ui', 'false'])
print '@@@BUILD_STEP Sync CMake@@@'
CallSubProcess(
@@ -73,41 +71,96 @@ def PrepareCmake():
CallSubProcess( ['make', 'cmake'], cwd=CMAKE_DIR)
+_ANDROID_SETUP = 'source build/envsetup.sh && lunch full-eng'
+
+
def PrepareAndroidTree():
"""Prepare an Android tree to run 'android' format tests."""
if os.environ['BUILDBOT_CLOBBER'] == '1':
print '@@@BUILD_STEP Clobber Android checkout@@@'
shutil.rmtree(ANDROID_DIR)
- # The release of Android we use is static, so there's no need to do anything
- # if the directory already exists.
- if os.path.isdir(ANDROID_DIR):
+ # (Re)create the directory so that the following steps will succeed.
+ if not os.path.isdir(ANDROID_DIR):
+ os.mkdir(ANDROID_DIR)
+
+ # We use a manifest from the gyp project listing pinned revisions of AOSP to
+ # use, to ensure that we test against a stable target. This needs to be
+ # updated to pick up new build system changes sometimes, so we must test if
+ # it has changed.
+ manifest_filename = 'aosp_manifest.xml'
+ gyp_manifest = os.path.join(BUILDBOT_DIR, manifest_filename)
+ android_manifest = os.path.join(ANDROID_DIR, '.repo', 'manifests',
+ manifest_filename)
+ manifest_is_current = (os.path.isfile(android_manifest) and
+ filecmp.cmp(gyp_manifest, android_manifest))
+ if not manifest_is_current:
+ # It's safe to repeat these steps, so just do them again to make sure we are
+ # in a good state.
+ print '@@@BUILD_STEP Initialize Android checkout@@@'
+ CallSubProcess(
+ ['repo', 'init',
+ '-u', 'https://android.googlesource.com/platform/manifest',
+ '-b', 'master',
+ '-g', 'all,-notdefault,-device,-darwin,-mips,-x86'],
+ cwd=ANDROID_DIR)
+ shutil.copy(gyp_manifest, android_manifest)
+
+ print '@@@BUILD_STEP Sync Android@@@'
+ CallSubProcess(['repo', 'sync', '-j4', '-m', manifest_filename],
+ cwd=ANDROID_DIR)
+
+ # If we already built the system image successfully and didn't sync to a new
+ # version of the source, skip running the build again as it's expensive even
+ # when there's nothing to do.
+ system_img = os.path.join(ANDROID_DIR, 'out', 'target', 'product', 'generic',
+ 'system.img')
+ if manifest_is_current and os.path.isfile(system_img):
return
- print '@@@BUILD_STEP Initialize Android checkout@@@'
- os.mkdir(ANDROID_DIR)
- CallSubProcess(['git', 'config', '--global', 'user.name', 'trybot'])
- CallSubProcess(['git', 'config', '--global',
- 'user.email', 'chrome-bot@google.com'])
- CallSubProcess(['git', 'config', '--global', 'color.ui', 'false'])
+ print '@@@BUILD_STEP Build Android@@@'
CallSubProcess(
- ['repo', 'init',
- '-u', 'https://android.googlesource.com/platform/manifest',
- '-b', 'android-4.2.1_r1',
- '-g', 'all,-notdefault,-device,-darwin,-mips,-x86'],
+ ['/bin/bash',
+ '-c', '%s && make -j4' % _ANDROID_SETUP],
cwd=ANDROID_DIR)
- print '@@@BUILD_STEP Sync Android@@@'
- CallSubProcess(['repo', 'sync', '-j4'], cwd=ANDROID_DIR)
- print '@@@BUILD_STEP Build Android@@@'
+def StartAndroidEmulator():
+ """Start an android emulator from the built android tree."""
+ print '@@@BUILD_STEP Start Android emulator@@@'
+
+ CallSubProcess(['/bin/bash', '-c',
+ '%s && adb kill-server ' % _ANDROID_SETUP],
+ cwd=ANDROID_DIR)
+
+ # If taskset is available, use it to force adbd to run only on one core, as,
+ # sadly, it improves its reliability (see crbug.com/268450).
+ adbd_wrapper = ''
+ with open(os.devnull, 'w') as devnull_fd:
+ if subprocess.call(['which', 'taskset'], stdout=devnull_fd) == 0:
+ adbd_wrapper = 'taskset -c 0'
+ CallSubProcess(['/bin/bash', '-c',
+ '%s && %s adb start-server ' % (_ANDROID_SETUP, adbd_wrapper)],
+ cwd=ANDROID_DIR)
+
+ subprocess.Popen(
+ ['/bin/bash', '-c',
+ '%s && emulator -no-window' % _ANDROID_SETUP],
+ cwd=ANDROID_DIR)
CallSubProcess(
- ['/bin/bash',
- '-c', 'source build/envsetup.sh && lunch full-eng && make -j4'],
+ ['/bin/bash', '-c',
+ '%s && adb wait-for-device' % _ANDROID_SETUP],
cwd=ANDROID_DIR)
-def GypTestFormat(title, format=None, msvs_version=None):
+def StopAndroidEmulator():
+ """Stop all android emulators."""
+ print '@@@BUILD_STEP Stop Android emulator@@@'
+ # If this fails, it's because there is no emulator running.
+ subprocess.call(['pkill', 'emulator.*'])
+
+
+def GypTestFormat(title, format=None, msvs_version=None, tests=[]):
"""Run the gyp tests for a given format, emitting annotator tags.
See annotator docs at:
@@ -126,19 +179,18 @@ def GypTestFormat(title, format=None, msvs_version=None):
if msvs_version:
env['GYP_MSVS_VERSION'] = msvs_version
command = ' '.join(
- [sys.executable, 'trunk/gyptest.py',
+ [sys.executable, 'gyp/gyptest.py',
'--all',
'--passed',
'--format', format,
'--path', CMAKE_BIN_DIR,
- '--chdir', 'trunk'])
+ '--chdir', 'gyp'] + tests)
if format == 'android':
# gyptest needs the environment setup from envsetup/lunch in order to build
# using the 'android' backend, so this is done in a single shell.
retcode = subprocess.call(
['/bin/bash',
- '-c', 'source build/envsetup.sh && lunch full-eng && cd %s && %s'
- % (ROOT_DIR, command)],
+ '-c', '%s && cd %s && %s' % (_ANDROID_SETUP, ROOT_DIR, command)],
cwd=ANDROID_DIR, env=env)
else:
retcode = subprocess.call(command, cwd=ROOT_DIR, env=env, shell=True)
@@ -160,7 +212,11 @@ def GypBuild():
# The Android gyp bot runs on linux so this must be tested first.
if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-android':
PrepareAndroidTree()
- retcode += GypTestFormat('android')
+ StartAndroidEmulator()
+ try:
+ retcode += GypTestFormat('android')
+ finally:
+ StopAndroidEmulator()
elif sys.platform.startswith('linux'):
retcode += GypTestFormat('ninja')
retcode += GypTestFormat('make')
@@ -173,8 +229,13 @@ def GypBuild():
elif sys.platform == 'win32':
retcode += GypTestFormat('ninja')
if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-win64':
- retcode += GypTestFormat('msvs-2010', format='msvs', msvs_version='2010')
- retcode += GypTestFormat('msvs-2012', format='msvs', msvs_version='2012')
+ retcode += GypTestFormat('msvs-ninja-2013', format='msvs-ninja',
+ msvs_version='2013',
+ tests=[
+ r'test\generator-output\gyptest-actions.py',
+ r'test\generator-output\gyptest-relocate.py',
+ r'test\generator-output\gyptest-rules.py'])
+ retcode += GypTestFormat('msvs-2013', format='msvs', msvs_version='2013')
else:
raise Exception('Unknown platform')
if retcode:
diff --git a/node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS b/node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS
new file mode 100644
index 000000000..b269c198b
--- /dev/null
+++ b/node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+bradnelson@chromium.org
+bradnelson@google.com
+iannucci@chromium.org
+scottmg@chromium.org
+thakis@chromium.org
diff --git a/node_modules/node-gyp/gyp/buildbot/commit_queue/README b/node_modules/node-gyp/gyp/buildbot/commit_queue/README
new file mode 100644
index 000000000..942849788
--- /dev/null
+++ b/node_modules/node-gyp/gyp/buildbot/commit_queue/README
@@ -0,0 +1,3 @@
+cq_config.json describes the trybots that must pass in order
+to land a change through the commit queue.
+Comments are here as the file is strictly JSON.
diff --git a/node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json b/node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json
new file mode 100644
index 000000000..bbf20e394
--- /dev/null
+++ b/node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json
@@ -0,0 +1,16 @@
+{
+ "trybots": {
+ "launched": {
+ "tryserver.nacl": {
+ "gyp-presubmit": ["defaulttests"],
+ "gyp-android": ["defaulttests"],
+ "gyp-linux": ["defaulttests"],
+ "gyp-mac": ["defaulttests"],
+ "gyp-win32": ["defaulttests"],
+ "gyp-win64": ["defaulttests"]
+ }
+ },
+ "triggered": {
+ }
+ }
+}
diff --git a/node_modules/node-gyp/gyp/codereview.settings b/node_modules/node-gyp/gyp/codereview.settings
index a04a2440d..faf37f114 100644
--- a/node_modules/node-gyp/gyp/codereview.settings
+++ b/node_modules/node-gyp/gyp/codereview.settings
@@ -1,10 +1,10 @@
# This file is used by gcl to get repository specific information.
CODE_REVIEW_SERVER: codereview.chromium.org
CC_LIST: gyp-developer@googlegroups.com
-VIEW_VC: http://code.google.com/p/gyp/source/detail?r=
-TRY_ON_UPLOAD: True
+VIEW_VC: https://chromium.googlesource.com/external/gyp/+/
+TRY_ON_UPLOAD: False
TRYSERVER_PROJECT: gyp
-TRYSERVER_PATCHLEVEL: 0
-TRYSERVER_ROOT: trunk
+TRYSERVER_PATCHLEVEL: 1
+TRYSERVER_ROOT: gyp
TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-nacl
-
+PROJECT: gyp
diff --git a/node_modules/node-gyp/gyp/gyp b/node_modules/node-gyp/gyp/gyp
index b53a6dde8..1b8b9bdfb 100755
--- a/node_modules/node-gyp/gyp/gyp
+++ b/node_modules/node-gyp/gyp/gyp
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/node_modules/node-gyp/gyp/gyp_dummy.c b/node_modules/node-gyp/gyp/gyp_dummy.c
deleted file mode 100644
index fb55bbc78..000000000
--- a/node_modules/node-gyp/gyp/gyp_dummy.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Copyright (c) 2009 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. */
-
-int main() {
- return 0;
-}
diff --git a/node_modules/node-gyp/gyp/gyptest.py b/node_modules/node-gyp/gyp/gyptest.py
index 8f3ee0ffb..8e4fc47d5 100755
--- a/node_modules/node-gyp/gyp/gyptest.py
+++ b/node_modules/node-gyp/gyp/gyptest.py
@@ -13,7 +13,7 @@ import optparse
import subprocess
import sys
-class CommandRunner:
+class CommandRunner(object):
"""
Executor class for commands, including "commands" implemented by
Python functions.
@@ -117,7 +117,7 @@ class CommandRunner:
return self.execute(command, stdout, stderr)
-class Unbuffered:
+class Unbuffered(object):
def __init__(self, fp):
self.fp = fp
def write(self, arg):
@@ -224,7 +224,7 @@ def main(argv=None):
'win32': ['msvs', 'ninja'],
'linux2': ['make', 'ninja'],
'linux3': ['make', 'ninja'],
- 'darwin': ['make', 'ninja', 'xcode'],
+ 'darwin': ['make', 'ninja', 'xcode', 'xcode-ninja'],
}[sys.platform]
for format in format_list:
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py
index 845dcb063..593f0e5b0 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py
@@ -172,7 +172,7 @@ class MSVSProject(MSVSSolutionEntry):
#------------------------------------------------------------------------------
-class MSVSSolution:
+class MSVSSolution(object):
"""Visual Studio solution."""
def __init__(self, path, version, entries=None, variants=None,
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py
index 0c9532d8e..dde0e0709 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""Code to validate and convert settings of the Microsoft build tools.
+r"""Code to validate and convert settings of the Microsoft build tools.
This file contains code to validate and convert settings of the Microsoft
build tools. The function ConvertToMSBuildSettings(), ValidateMSVSSettings(),
@@ -314,7 +314,14 @@ def _MSBuildOnly(tool, name, setting_type):
name: the name of the setting.
setting_type: the type of this setting.
"""
+
+ def _Translate(value, msbuild_settings):
+ # Let msbuild-only properties get translated as-is from msvs_settings.
+ tool_settings = msbuild_settings.setdefault(tool.msbuild_name, {})
+ tool_settings[name] = value
+
_msbuild_validators[tool.msbuild_name][name] = setting_type.ValidateMSBuild
+ _msvs_to_msbuild_converters[tool.msvs_name][name] = _Translate
def _ConvertedToAdditionalOption(tool, msvs_name, flag):
@@ -367,6 +374,35 @@ fix_vc_macro_slashes_regex = re.compile(
r'(\$\((?:%s)\))(?:[\\/]+)' % "|".join(fix_vc_macro_slashes_regex_list)
)
+# Regular expression to detect keys that were generated by exclusion lists
+_EXCLUDED_SUFFIX_RE = re.compile('^(.*)_excluded$')
+
+
+def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr):
+ """Verify that 'setting' is valid if it is generated from an exclusion list.
+
+ If the setting appears to be generated from an exclusion list, the root name
+ is checked.
+
+ Args:
+ setting: A string that is the setting name to validate
+ settings: A dictionary where the keys are valid settings
+ error_msg: The message to emit in the event of error
+ stderr: The stream receiving the error messages.
+ """
+ # This may be unrecognized because it's an exclusion list. If the
+ # setting name has the _excluded suffix, then check the root name.
+ unrecognized = True
+ m = re.match(_EXCLUDED_SUFFIX_RE, setting)
+ if m:
+ root_setting = m.group(1)
+ unrecognized = root_setting not in settings
+
+ if unrecognized:
+ # We don't know this setting. Give a warning.
+ print >> stderr, error_msg
+
+
def FixVCMacroSlashes(s):
"""Replace macros which have excessive following slashes.
@@ -388,11 +424,11 @@ def ConvertVCMacrosToMSBuild(s):
if '$' in s:
replace_map = {
'$(ConfigurationName)': '$(Configuration)',
- '$(InputDir)': '%(RootDir)%(Directory)',
+ '$(InputDir)': '%(RelativeDir)',
'$(InputExt)': '%(Extension)',
'$(InputFileName)': '%(Filename)%(Extension)',
'$(InputName)': '%(Filename)',
- '$(InputPath)': '%(FullPath)',
+ '$(InputPath)': '%(Identity)',
'$(ParentName)': '$(ProjectFileName)',
'$(PlatformName)': '$(Platform)',
'$(SafeInputName)': '%(Filename)',
@@ -429,10 +465,12 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr):
print >> stderr, ('Warning: while converting %s/%s to MSBuild, '
'%s' % (msvs_tool_name, msvs_setting, e))
else:
- # We don't know this setting. Give a warning.
- print >> stderr, ('Warning: unrecognized setting %s/%s '
- 'while converting to MSBuild.' %
- (msvs_tool_name, msvs_setting))
+ _ValidateExclusionSetting(msvs_setting,
+ msvs_tool,
+ ('Warning: unrecognized setting %s/%s '
+ 'while converting to MSBuild.' %
+ (msvs_tool_name, msvs_setting)),
+ stderr)
else:
print >> stderr, ('Warning: unrecognized tool %s while converting to '
'MSBuild.' % msvs_tool_name)
@@ -483,8 +521,12 @@ def _ValidateSettings(validators, settings, stderr):
print >> stderr, ('Warning: for %s/%s, %s' %
(tool_name, setting, e))
else:
- print >> stderr, ('Warning: unrecognized setting %s/%s' %
- (tool_name, setting))
+ _ValidateExclusionSetting(setting,
+ tool_validators,
+ ('Warning: unrecognized setting %s/%s' %
+ (tool_name, setting)),
+ stderr)
+
else:
print >> stderr, ('Warning: unrecognized tool %s' % tool_name)
@@ -496,6 +538,7 @@ _midl = _Tool('VCMIDLTool', 'Midl')
_rc = _Tool('VCResourceCompilerTool', 'ResourceCompile')
_lib = _Tool('VCLibrarianTool', 'Lib')
_manifest = _Tool('VCManifestTool', 'Manifest')
+_masm = _Tool('MASM', 'MASM')
_AddTool(_compile)
@@ -504,6 +547,7 @@ _AddTool(_midl)
_AddTool(_rc)
_AddTool(_lib)
_AddTool(_manifest)
+_AddTool(_masm)
# Add sections only found in the MSBuild settings.
_msbuild_validators[''] = {}
_msbuild_validators['ProjectReference'] = {}
@@ -567,7 +611,8 @@ _Same(_compile, 'BrowseInformation',
_Same(_compile, 'CallingConvention',
_Enumeration(['Cdecl', # /Gd
'FastCall', # /Gr
- 'StdCall'])) # /Gz
+ 'StdCall', # /Gz
+ 'VectorCall'])) # /Gv
_Same(_compile, 'CompileAs',
_Enumeration(['Default',
'CompileAsC', # /TC
@@ -581,7 +626,12 @@ _Same(_compile, 'DebugInformationFormat',
_Same(_compile, 'EnableEnhancedInstructionSet',
_Enumeration(['NotSet',
'StreamingSIMDExtensions', # /arch:SSE
- 'StreamingSIMDExtensions2'])) # /arch:SSE2
+ 'StreamingSIMDExtensions2', # /arch:SSE2
+ 'AdvancedVectorExtensions', # /arch:AVX (vs2012+)
+ 'NoExtensions', # /arch:IA32 (vs2012+)
+ # This one only exists in the new msbuild format.
+ 'AdvancedVectorExtensions2', # /arch:AVX2 (vs2013r2+)
+ ]))
_Same(_compile, 'ErrorReporting',
_Enumeration(['None', # /errorReport:none
'Prompt', # /errorReport:prompt
@@ -836,13 +886,6 @@ _Moved(_link, 'UseLibraryDependencyInputs', 'ProjectReference', _boolean)
# MSVS options not found in MSBuild.
_MSVSOnly(_link, 'OptimizeForWindows98', _newly_boolean)
_MSVSOnly(_link, 'UseUnicodeResponseFiles', _boolean)
-# These settings generate correctly in the MSVS output files when using
-# e.g. DelayLoadDLLs! or AdditionalDependencies! to exclude files from
-# configuration entries, but result in spurious artifacts which can be
-# safely ignored here. See crbug.com/246570
-_MSVSOnly(_link, 'AdditionalLibraryDirectories_excluded', _folder_list)
-_MSVSOnly(_link, 'DelayLoadDLLs_excluded', _file_list)
-_MSVSOnly(_link, 'AdditionalDependencies_excluded', _file_list)
# MSBuild options not found in MSVS.
_MSBuildOnly(_link, 'BuildingInIDE', _boolean)
@@ -991,9 +1034,6 @@ _Same(_lib, 'TargetMachine', _target_machine_enumeration)
# ProjectReference. We may want to validate that they are consistent.
_Moved(_lib, 'LinkLibraryDependencies', 'ProjectReference', _boolean)
-# TODO(jeanluc) I don't think these are genuine settings but byproducts of Gyp.
-_MSVSOnly(_lib, 'AdditionalLibraryDirectories_excluded', _folder_list)
-
_MSBuildOnly(_lib, 'DisplayLibrary', _string) # /LIST Visible='false'
_MSBuildOnly(_lib, 'ErrorReporting',
_Enumeration([], new=['PromptImmediately', # /ERRORREPORT:PROMPT
@@ -1049,3 +1089,11 @@ _MSBuildOnly(_manifest, 'ManifestFromManagedAssembly',
_MSBuildOnly(_manifest, 'OutputResourceManifests', _string) # /outputresource
_MSBuildOnly(_manifest, 'SuppressDependencyElement', _boolean) # /nodependency
_MSBuildOnly(_manifest, 'TrackerLogDirectory', _folder_name)
+
+
+# Directives for MASM.
+# See "$(VCTargetsPath)\BuildCustomizations\masm.xml" for the schema of the
+# MSBuild MASM settings.
+
+# Options that have the same name in MSVS and MSBuild.
+_Same(_masm, 'UseSafeExceptionHandlers', _boolean) # /safeseh
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py
index 4e06da3bb..d24dcac4d 100755
--- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py
@@ -109,6 +109,7 @@ class TestSequenceFunctions(unittest.TestCase):
'ZZXYZ': 'bogus'},
'VCLinkerTool': {
'AdditionalDependencies': 'file1;file2',
+ 'AdditionalDependencies_excluded': 'file3',
'AdditionalLibraryDirectories': 'folder1;folder2',
'AdditionalManifestDependencies': 'file1;file2',
'AdditionalOptions': 'a string1',
@@ -266,7 +267,7 @@ class TestSequenceFunctions(unittest.TestCase):
'Warning: for VCCLCompilerTool/BrowseInformation, '
"invalid literal for int() with base 10: 'fdkslj'",
'Warning: for VCCLCompilerTool/CallingConvention, '
- 'index value (-1) not in expected range [0, 3)',
+ 'index value (-1) not in expected range [0, 4)',
'Warning: for VCCLCompilerTool/DebugInformationFormat, '
'converted value for 2 not specified.',
'Warning: unrecognized setting VCCLCompilerTool/Enableprefast',
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py
index 62e8d260d..0b32e9118 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py
@@ -8,10 +8,12 @@ import copy
import os
-_TARGET_TYPE_EXT = {
- 'executable': '.exe',
- 'loadable_module': '.dll',
- 'shared_library': '.dll',
+# A dictionary mapping supported target types to extensions.
+TARGET_TYPE_EXT = {
+ 'executable': 'exe',
+ 'loadable_module': 'dll',
+ 'shared_library': 'dll',
+ 'static_library': 'lib',
}
@@ -109,15 +111,16 @@ def ShardTargets(target_list, target_dicts):
new_target_dicts[t] = target_dicts[t]
# Shard dependencies.
for t in new_target_dicts:
- dependencies = copy.copy(new_target_dicts[t].get('dependencies', []))
- new_dependencies = []
- for d in dependencies:
- if d in targets_to_shard:
- for i in range(targets_to_shard[d]):
- new_dependencies.append(_ShardName(d, i))
- else:
- new_dependencies.append(d)
- new_target_dicts[t]['dependencies'] = new_dependencies
+ for deptype in ('dependencies', 'dependencies_original'):
+ dependencies = copy.copy(new_target_dicts[t].get(deptype, []))
+ new_dependencies = []
+ for d in dependencies:
+ if d in targets_to_shard:
+ for i in range(targets_to_shard[d]):
+ new_dependencies.append(_ShardName(d, i))
+ else:
+ new_dependencies.append(d)
+ new_target_dicts[t][deptype] = new_dependencies
return (new_target_list, new_target_dicts)
@@ -156,7 +159,7 @@ def _GetPdbPath(target_dict, config_name, vars):
pdb_base = target_dict.get('product_name', target_dict['target_name'])
- pdb_base = '%s%s.pdb' % (pdb_base, _TARGET_TYPE_EXT[target_dict['type']])
+ pdb_base = '%s.%s.pdb' % (pdb_base, TARGET_TYPE_EXT[target_dict['type']])
pdb_path = vars['PRODUCT_DIR'] + '/' + pdb_base
return pdb_path
@@ -264,4 +267,4 @@ def InsertLargePdbShims(target_list, target_dicts, vars):
# Update the original target to depend on the shim target.
target_dict.setdefault('dependencies', []).append(full_shim_target_name)
- return (target_list, target_dicts) \ No newline at end of file
+ return (target_list, target_dicts)
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py
index 03b6d8ad4..92e583fd6 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py
@@ -138,7 +138,7 @@ def _RegistryQueryBase(sysdir, key, value):
def _RegistryQuery(key, value=None):
- """Use reg.exe to read a particular key through _RegistryQueryBase.
+ r"""Use reg.exe to read a particular key through _RegistryQueryBase.
First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If
that fails, it falls back to System32. Sysnative is available on Vista and
@@ -165,8 +165,33 @@ def _RegistryQuery(key, value=None):
return text
+def _RegistryGetValueUsingWinReg(key, value):
+ """Use the _winreg module to obtain the value of a registry key.
+
+ Args:
+ key: The registry key.
+ value: The particular registry value to read.
+ Return:
+ contents of the registry key's value, or None on failure. Throws
+ ImportError if _winreg is unavailable.
+ """
+ import _winreg
+ try:
+ root, subkey = key.split('\\', 1)
+ assert root == 'HKLM' # Only need HKLM for now.
+ with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey:
+ return _winreg.QueryValueEx(hkey, value)[0]
+ except WindowsError:
+ return None
+
+
def _RegistryGetValue(key, value):
- """Use reg.exe to obtain the value of a registry key.
+ """Use _winreg or reg.exe to obtain the value of a registry key.
+
+ Using _winreg is preferable because it solves an issue on some corporate
+ environments where access to reg.exe is locked down. However, we still need
+ to fallback to reg.exe for the case where the _winreg module is not available
+ (for example in cygwin python).
Args:
key: The registry key.
@@ -174,6 +199,12 @@ def _RegistryGetValue(key, value):
Return:
contents of the registry key's value, or None on failure.
"""
+ try:
+ return _RegistryGetValueUsingWinReg(key, value)
+ except ImportError:
+ pass
+
+ # Fallback to reg.exe if we fail to import _winreg.
text = _RegistryQuery(key, value)
if not text:
return None
@@ -184,19 +215,6 @@ def _RegistryGetValue(key, value):
return match.group(1)
-def _RegistryKeyExists(key):
- """Use reg.exe to see if a key exists.
-
- Args:
- key: The registry key to check.
- Return:
- True if the key exists
- """
- if not _RegistryQuery(key):
- return False
- return True
-
-
def _CreateVersion(name, path, sdk_based=False):
"""Sets up MSVS project generation.
@@ -207,6 +225,15 @@ def _CreateVersion(name, path, sdk_based=False):
if path:
path = os.path.normpath(path)
versions = {
+ '2015': VisualStudioVersion('2015',
+ 'Visual Studio 2015',
+ solution_version='12.00',
+ project_version='14.0',
+ flat_sln=False,
+ uses_vcxproj=True,
+ path=path,
+ sdk_based=sdk_based,
+ default_toolset='v140'),
'2013': VisualStudioVersion('2013',
'Visual Studio 2013',
solution_version='13.00',
@@ -316,7 +343,8 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
2008(e) - Visual Studio 2008 (9)
2010(e) - Visual Studio 2010 (10)
2012(e) - Visual Studio 2012 (11)
- 2013(e) - Visual Studio 2013 (11)
+ 2013(e) - Visual Studio 2013 (12)
+ 2015 - Visual Studio 2015 (14)
Where (e) is e for express editions of MSVS and blank otherwise.
"""
version_to_year = {
@@ -325,6 +353,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
'10.0': '2010',
'11.0': '2012',
'12.0': '2013',
+ '14.0': '2015',
}
versions = []
for version in versions_to_check:
@@ -361,13 +390,14 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
if not path:
continue
path = _ConvertToCygpath(path)
- versions.append(_CreateVersion(version_to_year[version] + 'e',
- os.path.join(path, '..'), sdk_based=True))
+ if 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))
return versions
-def SelectVisualStudioVersion(version='auto'):
+def SelectVisualStudioVersion(version='auto', allow_fallback=True):
"""Select which version of Visual Studio projects to generate.
Arguments:
@@ -379,7 +409,7 @@ def SelectVisualStudioVersion(version='auto'):
if version == 'auto':
version = os.environ.get('GYP_MSVS_VERSION', 'auto')
version_map = {
- 'auto': ('10.0', '12.0', '9.0', '8.0', '11.0'),
+ 'auto': ('14.0', '12.0', '10.0', '9.0', '8.0', '11.0'),
'2005': ('8.0',),
'2005e': ('8.0',),
'2008': ('9.0',),
@@ -390,6 +420,7 @@ def SelectVisualStudioVersion(version='auto'):
'2012e': ('11.0',),
'2013': ('12.0',),
'2013e': ('12.0',),
+ '2015': ('14.0',),
}
override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH')
if override_path:
@@ -401,6 +432,8 @@ def SelectVisualStudioVersion(version='auto'):
version = str(version)
versions = _DetectVisualStudioVersions(version_map[version], 'e' in version)
if not versions:
+ if not allow_fallback:
+ raise ValueError('Could not locate Visual Studio installation.')
if version == 'auto':
# Default to 2005 if we couldn't find anything
return _CreateVersion('2005', None)
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/__init__.py b/node_modules/node-gyp/gyp/pylib/gyp/__init__.py
index 30edea567..ac6d918b8 100755
--- a/node_modules/node-gyp/gyp/pylib/gyp/__init__.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/__init__.py
@@ -59,7 +59,6 @@ def Load(build_files, format, default_variables={},
if params is None:
params = {}
- flavor = None
if '-' in format:
format, params['flavor'] = format.split('-', 1)
@@ -69,6 +68,7 @@ def Load(build_files, format, default_variables={},
# named WITH_CAPITAL_LETTERS to provide a distinct "best practice" namespace,
# avoiding collisions with user and automatic variables.
default_variables['GENERATOR'] = format
+ default_variables['GENERATOR_FLAVOR'] = params.get('flavor', '')
# Format can be a custom python file, or by default the name of a module
# within gyp.generator.
@@ -371,7 +371,7 @@ def gyp_main(args):
if options.use_environment:
generate_formats = os.environ.get('GYP_GENERATORS', [])
if generate_formats:
- generate_formats = re.split('[\s,]', generate_formats)
+ generate_formats = re.split(r'[\s,]', generate_formats)
if generate_formats:
options.formats = generate_formats
else:
@@ -493,14 +493,13 @@ def gyp_main(args):
'gyp_binary': sys.argv[0],
'home_dot_gyp': home_dot_gyp,
'parallel': options.parallel,
- 'root_targets': options.root_targets}
+ 'root_targets': options.root_targets,
+ 'target_arch': cmdline_default_variables.get('target_arch', '')}
# Start with the default variables from the command line.
- [generator, flat_list, targets, data] = Load(build_files, format,
- cmdline_default_variables,
- includes, options.depth,
- params, options.check,
- options.circular_check)
+ [generator, flat_list, targets, data] = Load(
+ build_files, format, cmdline_default_variables, includes, options.depth,
+ params, options.check, options.circular_check)
# TODO(mark): Pass |data| for now because the generator needs a list of
# build files that came in. In the future, maybe it should just accept
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/common.py b/node_modules/node-gyp/gyp/pylib/gyp/common.py
index f9c6c6f3a..b6875e43e 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/common.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/common.py
@@ -4,6 +4,7 @@
from __future__ import with_statement
+import collections
import errno
import filecmp
import os.path
@@ -328,7 +329,7 @@ def WriteOnDiff(filename):
the target if it differs (on close).
"""
- class Writer:
+ class Writer(object):
"""Wrapper around file which only covers the target if it differs."""
def __init__(self):
# Pick temporary file.
@@ -472,6 +473,72 @@ def uniquer(seq, idfun=None):
return result
+# Based on http://code.activestate.com/recipes/576694/.
+class OrderedSet(collections.MutableSet):
+ def __init__(self, iterable=None):
+ self.end = end = []
+ end += [None, end, end] # sentinel node for doubly linked list
+ self.map = {} # key --> [key, prev, next]
+ if iterable is not None:
+ self |= iterable
+
+ def __len__(self):
+ return len(self.map)
+
+ def __contains__(self, key):
+ return key in self.map
+
+ def add(self, key):
+ if key not in self.map:
+ end = self.end
+ curr = end[1]
+ curr[2] = end[1] = self.map[key] = [key, curr, end]
+
+ def discard(self, key):
+ if key in self.map:
+ key, prev_item, next_item = self.map.pop(key)
+ prev_item[2] = next_item
+ next_item[1] = prev_item
+
+ def __iter__(self):
+ end = self.end
+ curr = end[2]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[2]
+
+ def __reversed__(self):
+ end = self.end
+ curr = end[1]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[1]
+
+ # The second argument is an addition that causes a pylint warning.
+ def pop(self, last=True): # pylint: disable=W0221
+ if not self:
+ raise KeyError('set is empty')
+ key = self.end[1][0] if last else self.end[2][0]
+ self.discard(key)
+ return key
+
+ def __repr__(self):
+ if not self:
+ return '%s()' % (self.__class__.__name__,)
+ return '%s(%r)' % (self.__class__.__name__, list(self))
+
+ def __eq__(self, other):
+ if isinstance(other, OrderedSet):
+ return len(self) == len(other) and list(self) == list(other)
+ return set(self) == set(other)
+
+ # Extensions to the recipe.
+ def update(self, iterable):
+ for i in iterable:
+ if i not in self:
+ self.add(i)
+
+
class CycleError(Exception):
"""An exception raised when an unexpected cycle is detected."""
def __init__(self, nodes):
@@ -481,7 +548,7 @@ class CycleError(Exception):
def TopologicallySorted(graph, get_edges):
- """Topologically sort based on a user provided edge definition.
+ r"""Topologically sort based on a user provided edge definition.
Args:
graph: A list of node names.
@@ -519,3 +586,14 @@ def TopologicallySorted(graph, get_edges):
for node in sorted(graph):
Visit(node)
return ordered_nodes
+
+def CrossCompileRequested():
+ # TODO: figure out how to not build extra host objects in the
+ # non-cross-compile case when this is enabled, and enable unconditionally.
+ return (os.environ.get('GYP_CROSSCOMPILE') or
+ os.environ.get('AR_host') or
+ os.environ.get('CC_host') or
+ os.environ.get('CXX_host') or
+ os.environ.get('AR_target') or
+ os.environ.get('CC_target') or
+ os.environ.get('CXX_target'))
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py
index bf949b6ac..2b0bb60cb 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py
@@ -115,6 +115,11 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False,
xml_string = XmlToString(content, encoding, pretty)
if win32 and os.linesep != '\r\n':
xml_string = xml_string.replace('\n', '\r\n')
+
+ try:
+ xml_string = xml_string.encode(encoding)
+ except Exception:
+ xml_string = unicode(xml_string, 'latin-1').encode(encoding)
# Get the old content
try:
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py
index 3e7efff26..b38d8660f 100755
--- a/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py
@@ -40,7 +40,12 @@ class FlockTool(object):
# with EBADF, that's why we use this F_SETLK
# hack instead.
fd = os.open(lockfile, os.O_WRONLY|os.O_NOCTTY|os.O_CREAT, 0666)
- op = struct.pack('hhllhhl', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
+ if sys.platform.startswith('aix'):
+ # Python on AIX is compiled with LARGEFILE support, which changes the
+ # struct size.
+ op = struct.pack('hhIllqq', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
+ else:
+ op = struct.pack('hhllhhl', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
fcntl.fcntl(fd, fcntl.F_SETLK, op)
return subprocess.call(cmd_list)
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py
new file mode 100644
index 000000000..15b80ef97
--- /dev/null
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py
@@ -0,0 +1,569 @@
+# Copyright (c) 2014 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.
+
+"""
+This script is intended for use as a GYP_GENERATOR. It takes as input (by way of
+the generator flag config_path) the path of a json file that dictates the files
+and targets to search for. The following keys are supported:
+files: list of paths (relative) of the files to search for.
+targets: list of targets to search for. The target names are unqualified.
+
+The following is output:
+error: only supplied if there is an error.
+targets: the set of targets passed in via targets that either directly or
+ indirectly depend upon the set of paths supplied in files.
+build_targets: minimal set of targets that directly depend on the changed
+ files and need to be built. The expectation is this set of targets is passed
+ into a build step.
+status: outputs one of three values: none of the supplied files were found,
+ one of the include files changed so that it should be assumed everything
+ changed (in this case targets and build_targets are not output) or at
+ least one file was found.
+invalid_targets: list of supplied targets thare were not found.
+
+If the generator flag analyzer_output_path is specified, output is written
+there. Otherwise output is written to stdout.
+"""
+
+import gyp.common
+import gyp.ninja_syntax as ninja_syntax
+import json
+import os
+import posixpath
+import sys
+
+debug = False
+
+found_dependency_string = 'Found dependency'
+no_dependency_string = 'No dependencies'
+# Status when it should be assumed that everything has changed.
+all_changed_string = 'Found dependency (all)'
+
+# MatchStatus is used indicate if and how a target depends upon the supplied
+# sources.
+# The target's sources contain one of the supplied paths.
+MATCH_STATUS_MATCHES = 1
+# The target has a dependency on another target that contains one of the
+# supplied paths.
+MATCH_STATUS_MATCHES_BY_DEPENDENCY = 2
+# The target's sources weren't in the supplied paths and none of the target's
+# dependencies depend upon a target that matched.
+MATCH_STATUS_DOESNT_MATCH = 3
+# The target doesn't contain the source, but the dependent targets have not yet
+# been visited to determine a more specific status yet.
+MATCH_STATUS_TBD = 4
+
+generator_supports_multiple_toolsets = gyp.common.CrossCompileRequested()
+
+generator_wants_static_library_dependencies_adjusted = False
+
+generator_default_variables = {
+}
+for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR',
+ 'LIB_DIR', 'SHARED_LIB_DIR']:
+ generator_default_variables[dirname] = '!!!'
+
+for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
+ 'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
+ 'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX',
+ 'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
+ 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX',
+ 'CONFIGURATION_NAME']:
+ generator_default_variables[unused] = ''
+
+
+def _ToGypPath(path):
+ """Converts a path to the format used by gyp."""
+ if os.sep == '\\' and os.altsep == '/':
+ return path.replace('\\', '/')
+ return path
+
+
+def _ResolveParent(path, base_path_components):
+ """Resolves |path|, which starts with at least one '../'. Returns an empty
+ string if the path shouldn't be considered. See _AddSources() for a
+ description of |base_path_components|."""
+ depth = 0
+ while path.startswith('../'):
+ depth += 1
+ path = path[3:]
+ # Relative includes may go outside the source tree. For example, an action may
+ # have inputs in /usr/include, which are not in the source tree.
+ if depth > len(base_path_components):
+ return ''
+ if depth == len(base_path_components):
+ return path
+ return '/'.join(base_path_components[0:len(base_path_components) - depth]) + \
+ '/' + path
+
+
+def _AddSources(sources, base_path, base_path_components, result):
+ """Extracts valid sources from |sources| and adds them to |result|. Each
+ source file is relative to |base_path|, but may contain '..'. To make
+ resolving '..' easier |base_path_components| contains each of the
+ directories in |base_path|. Additionally each source may contain variables.
+ Such sources are ignored as it is assumed dependencies on them are expressed
+ and tracked in some other means."""
+ # NOTE: gyp paths are always posix style.
+ for source in sources:
+ if not len(source) or source.startswith('!!!') or source.startswith('$'):
+ continue
+ # variable expansion may lead to //.
+ org_source = source
+ source = source[0] + source[1:].replace('//', '/')
+ if source.startswith('../'):
+ source = _ResolveParent(source, base_path_components)
+ if len(source):
+ result.append(source)
+ continue
+ result.append(base_path + source)
+ if debug:
+ print 'AddSource', org_source, result[len(result) - 1]
+
+
+def _ExtractSourcesFromAction(action, base_path, base_path_components,
+ results):
+ if 'inputs' in action:
+ _AddSources(action['inputs'], base_path, base_path_components, results)
+
+
+def _ToLocalPath(toplevel_dir, path):
+ """Converts |path| to a path relative to |toplevel_dir|."""
+ if path == toplevel_dir:
+ return ''
+ if path.startswith(toplevel_dir + '/'):
+ return path[len(toplevel_dir) + len('/'):]
+ return path
+
+
+def _ExtractSources(target, target_dict, toplevel_dir):
+ # |target| is either absolute or relative and in the format of the OS. Gyp
+ # source paths are always posix. Convert |target| to a posix path relative to
+ # |toplevel_dir_|. This is done to make it easy to build source paths.
+ base_path = posixpath.dirname(_ToLocalPath(toplevel_dir, _ToGypPath(target)))
+ base_path_components = base_path.split('/')
+
+ # Add a trailing '/' so that _AddSources() can easily build paths.
+ if len(base_path):
+ base_path += '/'
+
+ if debug:
+ print 'ExtractSources', target, base_path
+
+ results = []
+ if 'sources' in target_dict:
+ _AddSources(target_dict['sources'], base_path, base_path_components,
+ results)
+ # Include the inputs from any actions. Any changes to these affect the
+ # resulting output.
+ if 'actions' in target_dict:
+ for action in target_dict['actions']:
+ _ExtractSourcesFromAction(action, base_path, base_path_components,
+ results)
+ if 'rules' in target_dict:
+ for rule in target_dict['rules']:
+ _ExtractSourcesFromAction(rule, base_path, base_path_components, results)
+
+ return results
+
+
+class Target(object):
+ """Holds information about a particular target:
+ deps: set of Targets this Target depends upon. This is not recursive, only the
+ direct dependent Targets.
+ match_status: one of the MatchStatus values.
+ back_deps: set of Targets that have a dependency on this Target.
+ visited: used during iteration to indicate whether we've visited this target.
+ This is used for two iterations, once in building the set of Targets and
+ again in _GetBuildTargets().
+ name: fully qualified name of the target.
+ requires_build: True if the target type is such that it needs to be built.
+ See _DoesTargetTypeRequireBuild for details.
+ added_to_compile_targets: used when determining if the target was added to the
+ set of targets that needs to be built.
+ in_roots: true if this target is a descendant of one of the root nodes.
+ is_executable: true if the type of target is executable."""
+ def __init__(self, name):
+ self.deps = set()
+ self.match_status = MATCH_STATUS_TBD
+ self.back_deps = set()
+ self.name = name
+ # TODO(sky): I don't like hanging this off Target. This state is specific
+ # to certain functions and should be isolated there.
+ self.visited = False
+ self.requires_build = False
+ self.added_to_compile_targets = False
+ self.in_roots = False
+ self.is_executable = False
+
+
+class Config(object):
+ """Details what we're looking for
+ files: set of files to search for
+ targets: see file description for details."""
+ def __init__(self):
+ self.files = []
+ self.targets = set()
+
+ def Init(self, params):
+ """Initializes Config. This is a separate method as it raises an exception
+ if there is a parse error."""
+ generator_flags = params.get('generator_flags', {})
+ config_path = generator_flags.get('config_path', None)
+ if not config_path:
+ return
+ try:
+ f = open(config_path, 'r')
+ config = json.load(f)
+ f.close()
+ except IOError:
+ raise Exception('Unable to open file ' + config_path)
+ except ValueError as e:
+ raise Exception('Unable to parse config file ' + config_path + str(e))
+ if not isinstance(config, dict):
+ raise Exception('config_path must be a JSON file containing a dictionary')
+ self.files = config.get('files', [])
+ self.targets = set(config.get('targets', []))
+
+
+def _WasBuildFileModified(build_file, data, files, toplevel_dir):
+ """Returns true if the build file |build_file| is either in |files| or
+ one of the files included by |build_file| is in |files|. |toplevel_dir| is
+ the root of the source tree."""
+ if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files:
+ if debug:
+ print 'gyp file modified', build_file
+ return True
+
+ # First element of included_files is the file itself.
+ if len(data[build_file]['included_files']) <= 1:
+ return False
+
+ for include_file in data[build_file]['included_files'][1:]:
+ # |included_files| are relative to the directory of the |build_file|.
+ rel_include_file = \
+ _ToGypPath(gyp.common.UnrelativePath(include_file, build_file))
+ if _ToLocalPath(toplevel_dir, rel_include_file) in files:
+ if debug:
+ print 'included gyp file modified, gyp_file=', build_file, \
+ 'included file=', rel_include_file
+ return True
+ return False
+
+
+def _GetOrCreateTargetByName(targets, target_name):
+ """Creates or returns the Target at targets[target_name]. If there is no
+ Target for |target_name| one is created. Returns a tuple of whether a new
+ Target was created and the Target."""
+ if target_name in targets:
+ return False, targets[target_name]
+ target = Target(target_name)
+ targets[target_name] = target
+ return True, target
+
+
+def _DoesTargetTypeRequireBuild(target_dict):
+ """Returns true if the target type is such that it needs to be built."""
+ # If a 'none' target has rules or actions we assume it requires a build.
+ return target_dict['type'] != 'none' or \
+ target_dict.get('actions') or target_dict.get('rules')
+
+
+def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files,
+ build_files):
+ """Returns a tuple of the following:
+ . A dictionary mapping from fully qualified name to Target.
+ . A list of the targets that have a source file in |files|.
+ . Set of root Targets reachable from the the files |build_files|.
+ This sets the |match_status| of the targets that contain any of the source
+ files in |files| to MATCH_STATUS_MATCHES.
+ |toplevel_dir| is the root of the source tree."""
+ # Maps from target name to Target.
+ targets = {}
+
+ # Targets that matched.
+ matching_targets = []
+
+ # Queue of targets to visit.
+ targets_to_visit = target_list[:]
+
+ # Maps from build file to a boolean indicating whether the build file is in
+ # |files|.
+ build_file_in_files = {}
+
+ # Root targets across all files.
+ roots = set()
+
+ # Set of Targets in |build_files|.
+ build_file_targets = set()
+
+ while len(targets_to_visit) > 0:
+ target_name = targets_to_visit.pop()
+ created_target, target = _GetOrCreateTargetByName(targets, target_name)
+ if created_target:
+ roots.add(target)
+ elif target.visited:
+ continue
+
+ target.visited = True
+ target.requires_build = _DoesTargetTypeRequireBuild(
+ target_dicts[target_name])
+ target.is_executable = target_dicts[target_name]['type'] == 'executable'
+
+ build_file = gyp.common.ParseQualifiedTarget(target_name)[0]
+ if not build_file in build_file_in_files:
+ build_file_in_files[build_file] = \
+ _WasBuildFileModified(build_file, data, files, toplevel_dir)
+
+ if build_file in build_files:
+ build_file_targets.add(target)
+
+ # If a build file (or any of its included files) is modified we assume all
+ # targets in the file are modified.
+ if build_file_in_files[build_file]:
+ print 'matching target from modified build file', target_name
+ target.match_status = MATCH_STATUS_MATCHES
+ matching_targets.append(target)
+ else:
+ sources = _ExtractSources(target_name, target_dicts[target_name],
+ toplevel_dir)
+ for source in sources:
+ if source in files:
+ print 'target', target_name, 'matches', source
+ target.match_status = MATCH_STATUS_MATCHES
+ matching_targets.append(target)
+ break
+
+ # Add dependencies to visit as well as updating back pointers for deps.
+ for dep in target_dicts[target_name].get('dependencies', []):
+ targets_to_visit.append(dep)
+
+ created_dep_target, dep_target = _GetOrCreateTargetByName(targets, dep)
+ if not created_dep_target:
+ roots.discard(dep_target)
+
+ target.deps.add(dep_target)
+ dep_target.back_deps.add(target)
+
+ return targets, matching_targets, roots & build_file_targets
+
+
+def _GetUnqualifiedToTargetMapping(all_targets, to_find):
+ """Returns a mapping (dictionary) from unqualified name to Target for all the
+ Targets in |to_find|."""
+ result = {}
+ if not to_find:
+ return result
+ to_find = set(to_find)
+ for target_name in all_targets.keys():
+ extracted = gyp.common.ParseQualifiedTarget(target_name)
+ if len(extracted) > 1 and extracted[1] in to_find:
+ to_find.remove(extracted[1])
+ result[extracted[1]] = all_targets[target_name]
+ if not to_find:
+ return result
+ return result
+
+
+def _DoesTargetDependOn(target):
+ """Returns true if |target| or any of its dependencies matches the supplied
+ set of paths. This updates |matches| of the Targets as it recurses.
+ target: the Target to look for."""
+ if target.match_status == MATCH_STATUS_DOESNT_MATCH:
+ return False
+ if target.match_status == MATCH_STATUS_MATCHES or \
+ target.match_status == MATCH_STATUS_MATCHES_BY_DEPENDENCY:
+ return True
+ for dep in target.deps:
+ if _DoesTargetDependOn(dep):
+ target.match_status = MATCH_STATUS_MATCHES_BY_DEPENDENCY
+ return True
+ target.match_status = MATCH_STATUS_DOESNT_MATCH
+ return False
+
+
+def _GetTargetsDependingOn(possible_targets):
+ """Returns the list of Targets in |possible_targets| that depend (either
+ directly on indirectly) on the matched targets.
+ possible_targets: targets to search from."""
+ found = []
+ for target in possible_targets:
+ if _DoesTargetDependOn(target):
+ found.append(target)
+ return found
+
+
+def _AddBuildTargets(target, roots, add_if_no_ancestor, result):
+ """Recurses through all targets that depend on |target|, adding all targets
+ that need to be built (and are in |roots|) to |result|.
+ roots: set of root targets.
+ add_if_no_ancestor: If true and there are no ancestors of |target| then add
+ |target| to |result|. |target| must still be in |roots|.
+ result: targets that need to be built are added here."""
+ if target.visited:
+ return
+
+ target.visited = True
+ target.in_roots = not target.back_deps and target in roots
+
+ for back_dep_target in target.back_deps:
+ _AddBuildTargets(back_dep_target, roots, False, result)
+ target.added_to_compile_targets |= back_dep_target.added_to_compile_targets
+ target.in_roots |= back_dep_target.in_roots
+
+ # Always add 'executable' targets. Even though they may be built by other
+ # targets that depend upon them it makes detection of what is going to be
+ # built easier.
+ if target.in_roots and \
+ (target.is_executable or
+ (not target.added_to_compile_targets and
+ (add_if_no_ancestor or target.requires_build))):
+ result.add(target)
+ target.added_to_compile_targets = True
+
+
+def _GetBuildTargets(matching_targets, roots):
+ """Returns the set of Targets that require a build.
+ matching_targets: targets that changed and need to be built.
+ roots: set of root targets in the build files to search from."""
+ result = set()
+ for target in matching_targets:
+ _AddBuildTargets(target, roots, True, result)
+ return result
+
+
+def _WriteOutput(params, **values):
+ """Writes the output, either to stdout or a file is specified."""
+ if 'error' in values:
+ print 'Error:', values['error']
+ if 'status' in values:
+ print values['status']
+ if 'targets' in values:
+ values['targets'].sort()
+ print 'Supplied targets that depend on changed files:'
+ for target in values['targets']:
+ print '\t', target
+ if 'invalid_targets' in values:
+ values['invalid_targets'].sort()
+ print 'The following targets were not found:'
+ for target in values['invalid_targets']:
+ print '\t', target
+ if 'build_targets' in values:
+ values['build_targets'].sort()
+ print 'Targets that require a build:'
+ for target in values['build_targets']:
+ print '\t', target
+
+ output_path = params.get('generator_flags', {}).get(
+ 'analyzer_output_path', None)
+ if not output_path:
+ print json.dumps(values)
+ return
+ try:
+ f = open(output_path, 'w')
+ f.write(json.dumps(values) + '\n')
+ f.close()
+ except IOError as e:
+ print 'Error writing to output file', output_path, str(e)
+
+
+def _WasGypIncludeFileModified(params, files):
+ """Returns true if one of the files in |files| is in the set of included
+ files."""
+ if params['options'].includes:
+ for include in params['options'].includes:
+ if _ToGypPath(include) in files:
+ print 'Include file modified, assuming all changed', include
+ return True
+ return False
+
+
+def _NamesNotIn(names, mapping):
+ """Returns a list of the values in |names| that are not in |mapping|."""
+ return [name for name in names if name not in mapping]
+
+
+def _LookupTargets(names, mapping):
+ """Returns a list of the mapping[name] for each value in |names| that is in
+ |mapping|."""
+ return [mapping[name] for name in names if name in mapping]
+
+
+def CalculateVariables(default_variables, params):
+ """Calculate additional variables for use in the build (called by gyp)."""
+ flavor = gyp.common.GetFlavor(params)
+ if flavor == 'mac':
+ default_variables.setdefault('OS', 'mac')
+ elif flavor == 'win':
+ default_variables.setdefault('OS', 'win')
+ # Copy additional generator configuration data from VS, which is shared
+ # by the Windows Ninja generator.
+ import gyp.generator.msvs as msvs_generator
+ generator_additional_non_configuration_keys = getattr(msvs_generator,
+ 'generator_additional_non_configuration_keys', [])
+ generator_additional_path_sections = getattr(msvs_generator,
+ 'generator_additional_path_sections', [])
+
+ gyp.msvs_emulation.CalculateCommonVariables(default_variables, params)
+ else:
+ operating_system = flavor
+ if flavor == 'android':
+ operating_system = 'linux' # Keep this legacy behavior for now.
+ default_variables.setdefault('OS', operating_system)
+
+
+def GenerateOutput(target_list, target_dicts, data, params):
+ """Called by gyp as the final stage. Outputs results."""
+ config = Config()
+ try:
+ config.Init(params)
+ if not config.files:
+ raise Exception('Must specify files to analyze via config_path generator '
+ 'flag')
+
+ toplevel_dir = _ToGypPath(os.path.abspath(params['options'].toplevel_dir))
+ if debug:
+ print 'toplevel_dir', toplevel_dir
+
+ if _WasGypIncludeFileModified(params, config.files):
+ result_dict = { 'status': all_changed_string,
+ 'targets': list(config.targets) }
+ _WriteOutput(params, **result_dict)
+ return
+
+ all_targets, matching_targets, roots = _GenerateTargets(
+ data, target_list, target_dicts, toplevel_dir, frozenset(config.files),
+ params['build_files'])
+
+ unqualified_mapping = _GetUnqualifiedToTargetMapping(all_targets,
+ config.targets)
+ invalid_targets = None
+ if len(unqualified_mapping) != len(config.targets):
+ invalid_targets = _NamesNotIn(config.targets, unqualified_mapping)
+
+ if matching_targets:
+ search_targets = _LookupTargets(config.targets, unqualified_mapping)
+ matched_search_targets = _GetTargetsDependingOn(search_targets)
+ # Reset the visited status for _GetBuildTargets.
+ for target in all_targets.itervalues():
+ target.visited = False
+ build_targets = _GetBuildTargets(matching_targets, roots)
+ matched_search_targets = [gyp.common.ParseQualifiedTarget(target.name)[1]
+ for target in matched_search_targets]
+ build_targets = [gyp.common.ParseQualifiedTarget(target.name)[1]
+ for target in build_targets]
+ else:
+ matched_search_targets = []
+ build_targets = []
+
+ result_dict = { 'targets': matched_search_targets,
+ 'status': found_dependency_string if matching_targets else
+ no_dependency_string,
+ 'build_targets': build_targets}
+ if invalid_targets:
+ result_dict['invalid_targets'] = invalid_targets
+ _WriteOutput(params, **result_dict)
+
+ except Exception as e:
+ _WriteOutput(params, error=str(e))
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py
index 41346e2b1..ad6eff6d1 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py
@@ -50,12 +50,14 @@ generator_supports_multiple_toolsets = True
generator_additional_non_configuration_keys = [
# Boolean to declare that this target does not want its name mangled.
'android_unmangled_name',
+ # Map of android build system variables to set.
+ 'aosp_build_settings',
]
generator_additional_path_sections = []
generator_extra_sources_for_rules = []
-SHARED_FOOTER = """\
+ALL_MODULES_FOOTER = """\
# "gyp_all_modules" is a concatenation of the "gyp_all_modules" targets from
# all the included sub-makefiles. This is just here to clarify.
gyp_all_modules:
@@ -66,33 +68,6 @@ header = """\
"""
-android_standard_include_paths = set([
- # JNI_H_INCLUDE in build/core/binary.mk
- 'dalvik/libnativehelper/include/nativehelper',
- # from SRC_HEADERS in build/core/config.mk
- 'system/core/include',
- 'hardware/libhardware/include',
- 'hardware/libhardware_legacy/include',
- 'hardware/ril/include',
- 'dalvik/libnativehelper/include',
- 'frameworks/native/include',
- 'frameworks/native/opengl/include',
- 'frameworks/base/include',
- 'frameworks/base/opengl/include',
- 'frameworks/base/native/include',
- 'external/skia/include',
- # TARGET_C_INCLUDES in build/core/combo/TARGET_linux-arm.mk
- 'bionic/libc/arch-arm/include',
- 'bionic/libc/include',
- 'bionic/libstdc++/include',
- 'bionic/libc/kernel/common',
- 'bionic/libc/kernel/arch-arm',
- 'bionic/libm/include',
- 'bionic/libm/include/arm',
- 'bionic/libthread_db/include',
- ])
-
-
# Map gyp target types to Android module classes.
MODULE_CLASSES = {
'static_library': 'STATIC_LIBRARIES',
@@ -133,7 +108,7 @@ class AndroidMkWriter(object):
self.android_top_dir = android_top_dir
def Write(self, qualified_target, relative_target, base_path, output_filename,
- spec, configs, part_of_all):
+ spec, configs, part_of_all, write_alias_target, sdk_version):
"""The main entry point: writes a .mk file for a single target.
Arguments:
@@ -144,6 +119,9 @@ class AndroidMkWriter(object):
output_filename: output .mk file name to write
spec, configs: gyp info
part_of_all: flag indicating this target is part of 'all'
+ write_alias_target: flag indicating whether to create short aliases for
+ this target
+ sdk_version: what to emit for LOCAL_SDK_VERSION in output
"""
gyp.common.EnsureDirExists(output_filename)
@@ -183,14 +161,23 @@ class AndroidMkWriter(object):
if self.android_stem != self.android_module:
self.WriteLn('LOCAL_MODULE_STEM := ' + self.android_stem)
self.WriteLn('LOCAL_MODULE_SUFFIX := ' + self.android_suffix)
- self.WriteLn('LOCAL_MODULE_TAGS := optional')
if self.toolset == 'host':
self.WriteLn('LOCAL_IS_HOST_MODULE := true')
+ self.WriteLn('LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)')
+ else:
+ self.WriteLn('LOCAL_MODULE_TARGET_ARCH := '
+ '$(TARGET_$(GYP_VAR_PREFIX)ARCH)')
+ self.WriteLn('LOCAL_SDK_VERSION := %s' % sdk_version)
# Grab output directories; needed for Actions and Rules.
- self.WriteLn('gyp_intermediate_dir := $(call local-intermediates-dir)')
+ if self.toolset == 'host':
+ self.WriteLn('gyp_intermediate_dir := '
+ '$(call local-intermediates-dir,,$(GYP_HOST_VAR_PREFIX))')
+ else:
+ self.WriteLn('gyp_intermediate_dir := '
+ '$(call local-intermediates-dir,,$(GYP_VAR_PREFIX))')
self.WriteLn('gyp_shared_intermediate_dir := '
- '$(call intermediates-dir-for,GYP,shared)')
+ '$(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))')
self.WriteLn()
# List files this target depends on so that actions/rules/copies/sources
@@ -226,7 +213,8 @@ class AndroidMkWriter(object):
if spec.get('sources', []) or extra_sources:
self.WriteSources(spec, configs, extra_sources)
- self.WriteTarget(spec, configs, deps, link_deps, part_of_all)
+ self.WriteTarget(spec, configs, deps, link_deps, part_of_all,
+ write_alias_target)
# Update global list of target outputs, used in dependency tracking.
target_outputs[qualified_target] = ('path', self.output_binary)
@@ -291,6 +279,7 @@ class AndroidMkWriter(object):
# writing duplicate dummy rules for those outputs.
main_output = make.QuoteSpaces(self.LocalPathify(outputs[0]))
self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output)
+ self.WriteLn('%s: gyp_var_prefix := $(GYP_VAR_PREFIX)' % main_output)
self.WriteLn('%s: gyp_intermediate_dir := '
'$(abspath $(gyp_intermediate_dir))' % main_output)
self.WriteLn('%s: gyp_shared_intermediate_dir := '
@@ -305,12 +294,19 @@ class AndroidMkWriter(object):
self.WriteLn('%s: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))'
% main_output)
+ # Don't allow spaces in input/output filenames, but make an exception for
+ # filenames which start with '$(' since it's okay for there to be spaces
+ # inside of make function/macro invocations.
for input in inputs:
- assert ' ' not in input, (
- "Spaces in action input filenames not supported (%s)" % input)
+ if not input.startswith('$(') and ' ' in input:
+ raise gyp.common.GypError(
+ 'Action input filename "%s" in target %s contains a space' %
+ (input, self.target))
for output in outputs:
- assert ' ' not in output, (
- "Spaces in action output filenames not supported (%s)" % output)
+ if not output.startswith('$(') and ' ' in output:
+ raise gyp.common.GypError(
+ 'Action output filename "%s" in target %s contains a space' %
+ (output, self.target))
self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES)' %
(main_output, ' '.join(map(self.LocalPathify, inputs))))
@@ -337,13 +333,10 @@ class AndroidMkWriter(object):
"""
if len(rules) == 0:
return
- rule_trigger = '%s_rule_trigger' % self.android_module
- did_write_rule = False
for rule in rules:
if len(rule.get('rule_sources', [])) == 0:
continue
- did_write_rule = True
name = make.StringToMakefileVariable('%s_%s' % (self.relative_target,
rule['rule_name']))
self.WriteLn('\n### Generated for rule "%s":' % name)
@@ -391,6 +384,7 @@ class AndroidMkWriter(object):
outputs = map(self.LocalPathify, outputs)
main_output = outputs[0]
self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output)
+ self.WriteLn('%s: gyp_var_prefix := $(GYP_VAR_PREFIX)' % main_output)
self.WriteLn('%s: gyp_intermediate_dir := '
'$(abspath $(gyp_intermediate_dir))' % main_output)
self.WriteLn('%s: gyp_shared_intermediate_dir := '
@@ -412,13 +406,9 @@ class AndroidMkWriter(object):
# Make each output depend on the main output, with an empty command
# to force make to notice that the mtime has changed.
self.WriteLn('%s: %s ;' % (output, main_output))
- self.WriteLn('.PHONY: %s' % (rule_trigger))
- self.WriteLn('%s: %s' % (rule_trigger, main_output))
- self.WriteLn('')
- if did_write_rule:
- extra_sources.append(rule_trigger) # Force all rules to run.
- self.WriteLn('### Finished generating for all rules')
- self.WriteLn('')
+ self.WriteLn()
+
+ self.WriteLn()
def WriteCopies(self, copies, extra_outputs):
@@ -501,6 +491,9 @@ class AndroidMkWriter(object):
self.WriteLn('LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) '
'$(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))')
self.WriteLn('LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))')
+ # Android uses separate flags for assembly file invocations, but gyp expects
+ # the same CFLAGS to be applied:
+ self.WriteLn('LOCAL_ASFLAGS := $(LOCAL_CFLAGS)')
def WriteSources(self, spec, configs, extra_sources):
@@ -609,16 +602,16 @@ class AndroidMkWriter(object):
prefix = ''
if spec['toolset'] == 'host':
- suffix = '_host_gyp'
+ suffix = '_$(TARGET_$(GYP_VAR_PREFIX)ARCH)_host_gyp'
else:
suffix = '_gyp'
if self.path:
- name = '%s%s_%s%s' % (prefix, self.path, self.target, suffix)
+ middle = make.StringToMakefileVariable('%s_%s' % (self.path, self.target))
else:
- name = '%s%s%s' % (prefix, self.target, suffix)
+ middle = make.StringToMakefileVariable(self.target)
- return make.StringToMakefileVariable(name)
+ return ''.join([prefix, middle, suffix])
def ComputeOutputParts(self, spec):
@@ -672,32 +665,31 @@ class AndroidMkWriter(object):
E.g., the loadable module 'foobar' in directory 'baz' will produce
'$(obj)/baz/libfoobar.so'
"""
- if self.type == 'executable' and self.toolset == 'host':
+ if self.type == 'executable':
# We install host executables into shared_intermediate_dir so they can be
# run by gyp rules that refer to PRODUCT_DIR.
path = '$(gyp_shared_intermediate_dir)'
elif self.type == 'shared_library':
if self.toolset == 'host':
- path = '$(HOST_OUT_INTERMEDIATE_LIBRARIES)'
+ path = '$($(GYP_HOST_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES)'
else:
- path = '$(TARGET_OUT_INTERMEDIATE_LIBRARIES)'
+ path = '$($(GYP_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)'
else:
# Other targets just get built into their intermediate dir.
if self.toolset == 'host':
- path = '$(call intermediates-dir-for,%s,%s,true)' % (self.android_class,
- self.android_module)
+ path = ('$(call intermediates-dir-for,%s,%s,true,,'
+ '$(GYP_HOST_VAR_PREFIX))' % (self.android_class,
+ self.android_module))
else:
- path = '$(call intermediates-dir-for,%s,%s)' % (self.android_class,
- self.android_module)
+ path = ('$(call intermediates-dir-for,%s,%s,,,$(GYP_VAR_PREFIX))'
+ % (self.android_class, self.android_module))
assert spec.get('product_dir') is None # TODO: not supported?
return os.path.join(path, self.ComputeOutputBasename(spec))
def NormalizeIncludePaths(self, include_paths):
""" Normalize include_paths.
- Convert absolute paths to relative to the Android top directory;
- filter out include paths that are already brought in by the Android build
- system.
+ Convert absolute paths to relative to the Android top directory.
Args:
include_paths: A list of unprocessed include paths.
@@ -708,10 +700,7 @@ class AndroidMkWriter(object):
for path in include_paths:
if path[0] == '/':
path = gyp.common.RelativePath(path, self.android_top_dir)
-
- # Filter out the Android standard search path.
- if path not in android_standard_include_paths:
- normalized.append(path)
+ normalized.append(path)
return normalized
def ExtractIncludesFromCFlags(self, cflags):
@@ -732,16 +721,20 @@ class AndroidMkWriter(object):
return (clean_cflags, include_paths)
- def ComputeAndroidLibraryModuleNames(self, libraries):
- """Compute the Android module names from libraries, ie spec.get('libraries')
+ def FilterLibraries(self, libraries):
+ """Filter the 'libraries' key to separate things that shouldn't be ldflags.
+
+ Library entries that look like filenames should be converted to android
+ module names instead of being passed to the linker as flags.
Args:
libraries: the value of spec.get('libraries')
Returns:
- A tuple (static_lib_modules, dynamic_lib_modules)
+ A tuple (static_lib_modules, dynamic_lib_modules, ldflags)
"""
static_lib_modules = []
dynamic_lib_modules = []
+ ldflags = []
for libs in libraries:
# Libs can have multiple words.
for lib in libs.split():
@@ -758,13 +751,9 @@ class AndroidMkWriter(object):
if match:
dynamic_lib_modules.append(match.group(1))
continue
- # "-lstlport" -> libstlport
if lib.startswith('-l'):
- if lib.endswith('_static'):
- static_lib_modules.append('lib' + lib[2:])
- else:
- dynamic_lib_modules.append('lib' + lib[2:])
- return (static_lib_modules, dynamic_lib_modules)
+ ldflags.append(lib)
+ return (static_lib_modules, dynamic_lib_modules, ldflags)
def ComputeDeps(self, spec):
@@ -792,47 +781,74 @@ class AndroidMkWriter(object):
spec, configs: input from gyp.
link_deps: link dependency list; see ComputeDeps()
"""
- for configname, config in sorted(configs.iteritems()):
- ldflags = list(config.get('ldflags', []))
- self.WriteLn('')
- self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname)
- self.WriteLn('\nLOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))')
-
# Libraries (i.e. -lfoo)
+ # These must be included even for static libraries as some of them provide
+ # implicit include paths through the build system.
libraries = gyp.common.uniquer(spec.get('libraries', []))
- static_libs, dynamic_libs = self.ComputeAndroidLibraryModuleNames(
- libraries)
-
- # Link dependencies (i.e. libfoo.a, libfoo.so)
- static_link_deps = [x[1] for x in link_deps if x[0] == 'static']
- shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared']
- self.WriteLn('')
- self.WriteList(static_libs + static_link_deps,
- 'LOCAL_STATIC_LIBRARIES')
- self.WriteLn('# Enable grouping to fix circular references')
- self.WriteLn('LOCAL_GROUP_STATIC_LIBRARIES := true')
- self.WriteLn('')
- self.WriteList(dynamic_libs + shared_link_deps,
- 'LOCAL_SHARED_LIBRARIES')
-
-
- def WriteTarget(self, spec, configs, deps, link_deps, part_of_all):
+ static_libs, dynamic_libs, ldflags_libs = self.FilterLibraries(libraries)
+
+ if self.type != 'static_library':
+ for configname, config in sorted(configs.iteritems()):
+ ldflags = list(config.get('ldflags', []))
+ self.WriteLn('')
+ self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname)
+ self.WriteList(ldflags_libs, 'LOCAL_GYP_LIBS')
+ self.WriteLn('LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION)) '
+ '$(LOCAL_GYP_LIBS)')
+
+ # Link dependencies (i.e. other gyp targets this target depends on)
+ # These need not be included for static libraries as within the gyp build
+ # we do not use the implicit include path mechanism.
+ if self.type != 'static_library':
+ static_link_deps = [x[1] for x in link_deps if x[0] == 'static']
+ shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared']
+ else:
+ static_link_deps = []
+ shared_link_deps = []
+
+ # Only write the lists if they are non-empty.
+ if static_libs or static_link_deps:
+ self.WriteLn('')
+ self.WriteList(static_libs + static_link_deps,
+ 'LOCAL_STATIC_LIBRARIES')
+ self.WriteLn('# Enable grouping to fix circular references')
+ self.WriteLn('LOCAL_GROUP_STATIC_LIBRARIES := true')
+ if dynamic_libs or shared_link_deps:
+ self.WriteLn('')
+ self.WriteList(dynamic_libs + shared_link_deps,
+ 'LOCAL_SHARED_LIBRARIES')
+
+
+ def WriteTarget(self, spec, configs, deps, link_deps, part_of_all,
+ write_alias_target):
"""Write Makefile code to produce the final target of the gyp spec.
spec, configs: input from gyp.
deps, link_deps: dependency lists; see ComputeDeps()
part_of_all: flag indicating this target is part of 'all'
+ write_alias_target: flag indicating whether to create short aliases for this
+ target
"""
self.WriteLn('### Rules for final target.')
if self.type != 'none':
self.WriteTargetFlags(spec, configs, link_deps)
+ settings = spec.get('aosp_build_settings', {})
+ if settings:
+ self.WriteLn('### Set directly by aosp_build_settings.')
+ for k, v in settings.iteritems():
+ if isinstance(v, list):
+ self.WriteList(v, k)
+ else:
+ self.WriteLn('%s := %s' % (k, make.QuoteIfNecessary(v)))
+ self.WriteLn('')
+
# Add to the set of targets which represent the gyp 'all' target. We use the
# name 'gyp_all_modules' as the Android build system doesn't allow the use
# of the Make target 'all' and because 'all_modules' is the equivalent of
# the Make target 'all' on Android.
- if part_of_all:
+ if part_of_all and write_alias_target:
self.WriteLn('# Add target alias to "gyp_all_modules" target.')
self.WriteLn('.PHONY: gyp_all_modules')
self.WriteLn('gyp_all_modules: %s' % self.android_module)
@@ -841,7 +857,7 @@ class AndroidMkWriter(object):
# Add an alias from the gyp target name to the Android module name. This
# simplifies manual builds of the target, and is required by the test
# framework.
- if self.target != self.android_module:
+ if self.target != self.android_module and write_alias_target:
self.WriteLn('# Alias gyp target name.')
self.WriteLn('.PHONY: %s' % self.target)
self.WriteLn('%s: %s' % (self.target, self.android_module))
@@ -859,17 +875,17 @@ class AndroidMkWriter(object):
self.WriteLn('LOCAL_PRELINK_MODULE := false')
self.WriteLn('include $(BUILD_%sSHARED_LIBRARY)' % modifier)
elif self.type == 'executable':
- if self.toolset == 'host':
- self.WriteLn('LOCAL_MODULE_PATH := $(gyp_shared_intermediate_dir)')
- else:
- # Don't install target executables for now, as it results in them being
- # included in ROM. This can be revisited if there's a reason to install
- # them later.
- self.WriteLn('LOCAL_UNINSTALLABLE_MODULE := true')
+ # Executables are for build and test purposes only, so they're installed
+ # to a directory that doesn't get included in the system image.
+ self.WriteLn('LOCAL_MODULE_PATH := $(gyp_shared_intermediate_dir)')
self.WriteLn('include $(BUILD_%sEXECUTABLE)' % modifier)
else:
self.WriteLn('LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp')
self.WriteLn('LOCAL_UNINSTALLABLE_MODULE := true')
+ if self.toolset == 'target':
+ self.WriteLn('LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)')
+ else:
+ self.WriteLn('LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_HOST_VAR_PREFIX)')
self.WriteLn()
self.WriteLn('include $(BUILD_SYSTEM)/base_rules.mk')
self.WriteLn()
@@ -877,6 +893,8 @@ class AndroidMkWriter(object):
self.WriteLn('\t$(hide) echo "Gyp timestamp: $@"')
self.WriteLn('\t$(hide) mkdir -p $(dir $@)')
self.WriteLn('\t$(hide) touch $@')
+ self.WriteLn()
+ self.WriteLn('LOCAL_2ND_ARCH_VAR_PREFIX :=')
def WriteList(self, value_list, variable=None, prefix='',
@@ -926,7 +944,7 @@ class AndroidMkWriter(object):
'INPUT_ROOT': expansion,
'INPUT_DIRNAME': dirname,
}
- return path
+ return os.path.normpath(path)
def PerformBuild(data, configurations, params):
@@ -946,6 +964,8 @@ def GenerateOutput(target_list, target_dicts, data, params):
generator_flags = params.get('generator_flags', {})
builddir_name = generator_flags.get('output_dir', 'out')
limit_to_target_all = generator_flags.get('limit_to_target_all', False)
+ write_alias_targets = generator_flags.get('write_alias_targets', True)
+ sdk_version = generator_flags.get('aosp_sdk_version', 19)
android_top_dir = os.environ.get('ANDROID_BUILD_TOP')
assert android_top_dir, '$ANDROID_BUILD_TOP not set; you need to run lunch.'
@@ -1031,8 +1051,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
spec = target_dicts[qualified_target]
configs = spec['configurations']
- part_of_all = (qualified_target in needed_targets and
- not int(spec.get('suppress_wildcard', False)))
+ part_of_all = qualified_target in needed_targets
if limit_to_target_all and not part_of_all:
continue
@@ -1041,7 +1060,9 @@ def GenerateOutput(target_list, target_dicts, data, params):
writer = AndroidMkWriter(android_top_dir)
android_module = writer.Write(qualified_target, relative_target, base_path,
output_file, spec, configs,
- part_of_all=part_of_all)
+ part_of_all=part_of_all,
+ write_alias_target=write_alias_targets,
+ sdk_version=sdk_version)
if android_module in android_modules:
print ('ERROR: Android module names must be unique. The following '
'targets both generate Android module name %s.\n %s\n %s' %
@@ -1057,6 +1078,9 @@ def GenerateOutput(target_list, target_dicts, data, params):
include_list.add(mkfile_rel_path)
root_makefile.write('GYP_CONFIGURATION ?= %s\n' % default_configuration)
+ root_makefile.write('GYP_VAR_PREFIX ?=\n')
+ root_makefile.write('GYP_HOST_VAR_PREFIX ?=\n')
+ root_makefile.write('GYP_HOST_MULTILIB ?=\n')
# Write out the sorted list of includes.
root_makefile.write('\n')
@@ -1064,6 +1088,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
root_makefile.write('include $(LOCAL_PATH)/' + include_file + '\n')
root_makefile.write('\n')
- root_makefile.write(SHARED_FOOTER)
+ if write_alias_targets:
+ root_makefile.write(ALL_MODULES_FOOTER)
root_makefile.close()
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py
index 10d015ee8..8f5feddee 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py
@@ -216,7 +216,7 @@ def WriteVariable(output, variable_name, prepend=None):
output.write('}')
-class CMakeTargetType:
+class CMakeTargetType(object):
def __init__(self, command, modifier, property_modifier):
self.command = command
self.modifier = modifier
@@ -464,7 +464,7 @@ def WriteCopies(target_name, copies, extra_deps, path_to_gyp, output):
extra_deps.append(copy_name)
return
- class Copy:
+ class Copy(object):
def __init__(self, ext, command):
self.cmake_inputs = []
self.cmake_outputs = []
@@ -743,7 +743,7 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use,
if target_output_directory is None:
if target_type in ('executable', 'loadable_module'):
target_output_directory = generator_default_variables['PRODUCT_DIR']
- elif target_type in ('shared_library'):
+ elif target_type == 'shared_library':
target_output_directory = '${builddir}/lib.${TOOLSET}'
elif spec.get('standalone_static_library', False):
target_output_directory = generator_default_variables['PRODUCT_DIR']
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py
index 84380b04d..3544347b3 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py
@@ -24,6 +24,7 @@ import gyp
import gyp.common
import gyp.msvs_emulation
import shlex
+import xml.etree.cElementTree as ET
generator_wants_static_library_dependencies_adjusted = False
@@ -31,8 +32,8 @@ generator_default_variables = {
}
for dirname in ['INTERMEDIATE_DIR', 'PRODUCT_DIR', 'LIB_DIR', 'SHARED_LIB_DIR']:
- # Some gyp steps fail if these are empty(!).
- generator_default_variables[dirname] = 'dir'
+ # Some gyp steps fail if these are empty(!), so we convert them to variables
+ generator_default_variables[dirname] = '$' + dirname
for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
@@ -77,7 +78,8 @@ def CalculateGeneratorInputInfo(params):
def GetAllIncludeDirectories(target_list, target_dicts,
- shared_intermediate_dirs, config_name, params):
+ shared_intermediate_dirs, config_name, params,
+ compiler_path):
"""Calculate the set of include directories to be used.
Returns:
@@ -88,6 +90,33 @@ def GetAllIncludeDirectories(target_list, target_dicts,
gyp_includes_set = set()
compiler_includes_list = []
+ # Find compiler's default include dirs.
+ if compiler_path:
+ command = shlex.split(compiler_path)
+ command.extend(['-E', '-xc++', '-v', '-'])
+ proc = subprocess.Popen(args=command, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ output = proc.communicate()[1]
+ # Extract the list of include dirs from the output, which has this format:
+ # ...
+ # #include "..." search starts here:
+ # #include <...> search starts here:
+ # /usr/include/c++/4.6
+ # /usr/local/include
+ # End of search list.
+ # ...
+ in_include_list = False
+ for line in output.splitlines():
+ if line.startswith('#include'):
+ in_include_list = True
+ continue
+ if line.startswith('End of search list.'):
+ break
+ if in_include_list:
+ include_dir = line.strip()
+ if include_dir not in compiler_includes_list:
+ compiler_includes_list.append(include_dir)
+
flavor = gyp.common.GetFlavor(params)
if flavor == 'win':
generator_flags = params.get('generator_flags', {})
@@ -106,11 +135,10 @@ def GetAllIncludeDirectories(target_list, target_dicts,
else:
cflags = config['cflags']
for cflag in cflags:
- include_dir = ''
if cflag.startswith('-I'):
include_dir = cflag[2:]
- if include_dir and not include_dir in compiler_includes_list:
- compiler_includes_list.append(include_dir)
+ if include_dir not in compiler_includes_list:
+ compiler_includes_list.append(include_dir)
# Find standard gyp include dirs.
if config.has_key('include_dirs'):
@@ -125,9 +153,7 @@ def GetAllIncludeDirectories(target_list, target_dicts,
include_dir = base_dir + '/' + include_dir
include_dir = os.path.abspath(include_dir)
- if not include_dir in gyp_includes_set:
- gyp_includes_set.add(include_dir)
-
+ gyp_includes_set.add(include_dir)
# Generate a list that has all the include dirs.
all_includes_list = list(gyp_includes_set)
@@ -140,7 +166,7 @@ def GetAllIncludeDirectories(target_list, target_dicts,
return all_includes_list
-def GetCompilerPath(target_list, target_dicts, data):
+def GetCompilerPath(target_list, data, options):
"""Determine a command that can be used to invoke the compiler.
Returns:
@@ -148,13 +174,12 @@ def GetCompilerPath(target_list, target_dicts, data):
the compiler from that. Otherwise, see if a compiler was specified via the
CC_target environment variable.
"""
-
# First, see if the compiler is configured in make's settings.
build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
make_global_settings_dict = data[build_file].get('make_global_settings', {})
for key, value in make_global_settings_dict:
if key in ['CC', 'CXX']:
- return value
+ return os.path.join(options.toplevel_dir, value)
# Check to see if the compiler was specified as an environment variable.
for key in ['CC_target', 'CC', 'CXX']:
@@ -165,7 +190,8 @@ def GetCompilerPath(target_list, target_dicts, data):
return 'gcc'
-def GetAllDefines(target_list, target_dicts, data, config_name, params):
+def GetAllDefines(target_list, target_dicts, data, config_name, params,
+ compiler_path):
"""Calculate the defines for a project.
Returns:
@@ -202,9 +228,8 @@ def GetAllDefines(target_list, target_dicts, data, config_name, params):
# Get default compiler defines (if possible).
if flavor == 'win':
return all_defines # Default defines already processed in the loop above.
- cc_target = GetCompilerPath(target_list, target_dicts, data)
- if cc_target:
- command = shlex.split(cc_target)
+ if compiler_path:
+ command = shlex.split(compiler_path)
command.extend(['-E', '-dM', '-'])
cpp_proc = subprocess.Popen(args=command, cwd='.',
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
@@ -270,31 +295,123 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
shared_intermediate_dirs = [os.path.join(toplevel_build, 'obj', 'gen'),
os.path.join(toplevel_build, 'gen')]
- out_name = os.path.join(toplevel_build, 'eclipse-cdt-settings.xml')
+ GenerateCdtSettingsFile(target_list,
+ target_dicts,
+ data,
+ params,
+ config_name,
+ os.path.join(toplevel_build,
+ 'eclipse-cdt-settings.xml'),
+ options,
+ shared_intermediate_dirs)
+ GenerateClasspathFile(target_list,
+ target_dicts,
+ options.toplevel_dir,
+ toplevel_build,
+ os.path.join(toplevel_build,
+ 'eclipse-classpath.xml'))
+
+
+def GenerateCdtSettingsFile(target_list, target_dicts, data, params,
+ config_name, out_name, options,
+ shared_intermediate_dirs):
gyp.common.EnsureDirExists(out_name)
- out = open(out_name, 'w')
+ with open(out_name, 'w') as out:
+ out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
+ out.write('<cdtprojectproperties>\n')
+
+ eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
+ 'GNU C++', 'GNU C', 'Assembly']
+ compiler_path = GetCompilerPath(target_list, data, options)
+ include_dirs = GetAllIncludeDirectories(target_list, target_dicts,
+ shared_intermediate_dirs,
+ config_name, params, compiler_path)
+ WriteIncludePaths(out, eclipse_langs, include_dirs)
+ defines = GetAllDefines(target_list, target_dicts, data, config_name,
+ params, compiler_path)
+ WriteMacros(out, eclipse_langs, defines)
+
+ out.write('</cdtprojectproperties>\n')
+
+
+def GenerateClasspathFile(target_list, target_dicts, toplevel_dir,
+ toplevel_build, out_name):
+ '''Generates a classpath file suitable for symbol navigation and code
+ completion of Java code (such as in Android projects) by finding all
+ .java and .jar files used as action inputs.'''
+ gyp.common.EnsureDirExists(out_name)
+ result = ET.Element('classpath')
+
+ def AddElements(kind, paths):
+ # First, we need to normalize the paths so they are all relative to the
+ # toplevel dir.
+ rel_paths = set()
+ for path in paths:
+ if os.path.isabs(path):
+ rel_paths.add(os.path.relpath(path, toplevel_dir))
+ else:
+ rel_paths.add(path)
- out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
- out.write('<cdtprojectproperties>\n')
+ for path in sorted(rel_paths):
+ entry_element = ET.SubElement(result, 'classpathentry')
+ entry_element.set('kind', kind)
+ entry_element.set('path', path)
- eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
- 'GNU C++', 'GNU C', 'Assembly']
- include_dirs = GetAllIncludeDirectories(target_list, target_dicts,
- shared_intermediate_dirs, config_name,
- params)
- WriteIncludePaths(out, eclipse_langs, include_dirs)
- defines = GetAllDefines(target_list, target_dicts, data, config_name, params)
- WriteMacros(out, eclipse_langs, defines)
+ AddElements('lib', GetJavaJars(target_list, target_dicts, toplevel_dir))
+ AddElements('src', GetJavaSourceDirs(target_list, target_dicts, toplevel_dir))
+ # Include the standard JRE container and a dummy out folder
+ AddElements('con', ['org.eclipse.jdt.launching.JRE_CONTAINER'])
+ # Include a dummy out folder so that Eclipse doesn't use the default /bin
+ # folder in the root of the project.
+ AddElements('output', [os.path.join(toplevel_build, '.eclipse-java-build')])
- out.write('</cdtprojectproperties>\n')
- out.close()
+ ET.ElementTree(result).write(out_name)
+
+
+def GetJavaJars(target_list, target_dicts, toplevel_dir):
+ '''Generates a sequence of all .jars used as inputs.'''
+ for target_name in target_list:
+ target = target_dicts[target_name]
+ for action in target.get('actions', []):
+ for input_ in action['inputs']:
+ if os.path.splitext(input_)[1] == '.jar' and not input_.startswith('$'):
+ if os.path.isabs(input_):
+ yield input_
+ else:
+ yield os.path.join(os.path.dirname(target_name), input_)
+
+
+def GetJavaSourceDirs(target_list, target_dicts, toplevel_dir):
+ '''Generates a sequence of all likely java package root directories.'''
+ for target_name in target_list:
+ target = target_dicts[target_name]
+ for action in target.get('actions', []):
+ for input_ in action['inputs']:
+ if (os.path.splitext(input_)[1] == '.java' and
+ not input_.startswith('$')):
+ dir_ = os.path.dirname(os.path.join(os.path.dirname(target_name),
+ input_))
+ # If there is a parent 'src' or 'java' folder, navigate up to it -
+ # these are canonical package root names in Chromium. This will
+ # break if 'src' or 'java' exists in the package structure. This
+ # could be further improved by inspecting the java file for the
+ # package name if this proves to be too fragile in practice.
+ parent_search = dir_
+ while os.path.basename(parent_search) not in ['src', 'java']:
+ parent_search, _ = os.path.split(parent_search)
+ if not parent_search or parent_search == toplevel_dir:
+ # Didn't find a known root, just return the original path
+ yield dir_
+ break
+ else:
+ yield parent_search
def GenerateOutput(target_list, target_dicts, data, params):
"""Generate an XML settings file that can be imported into a CDT project."""
if params['options'].generator_output:
- raise NotImplementedError, "--generator_output not implemented for eclipse"
+ raise NotImplementedError("--generator_output not implemented for eclipse")
user_config = params.get('generator_flags', {}).get('config', None)
if user_config:
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py
index 22ef57f84..3efdb9966 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py
@@ -39,9 +39,11 @@ import pprint
# These variables should just be spit back out as variable references.
_generator_identity_variables = [
+ 'CONFIGURATION_NAME',
'EXECUTABLE_PREFIX',
'EXECUTABLE_SUFFIX',
'INTERMEDIATE_DIR',
+ 'LIB_DIR',
'PRODUCT_DIR',
'RULE_INPUT_ROOT',
'RULE_INPUT_DIRNAME',
@@ -49,6 +51,11 @@ _generator_identity_variables = [
'RULE_INPUT_NAME',
'RULE_INPUT_PATH',
'SHARED_INTERMEDIATE_DIR',
+ 'SHARED_LIB_DIR',
+ 'SHARED_LIB_PREFIX',
+ 'SHARED_LIB_SUFFIX',
+ 'STATIC_LIB_PREFIX',
+ 'STATIC_LIB_SUFFIX',
]
# gypd doesn't define a default value for OS like many other generator
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py
index b3f8a2b77..06c7fdc2e 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py
@@ -29,6 +29,7 @@ import gyp
import gyp.common
import gyp.xcode_emulation
from gyp.common import GetEnvironFallback
+from gyp.common import GypError
generator_default_variables = {
'EXECUTABLE_PREFIX': '',
@@ -280,15 +281,7 @@ LDFLAGS.target ?= $(LDFLAGS)
AR.target ?= $(AR)
# C++ apps need to be linked with g++.
-#
-# Note: flock is used to seralize linking. Linking is a memory-intensive
-# process so running parallel links can often lead to thrashing. To disable
-# the serialization, override LINK via an envrionment variable as follows:
-#
-# export LINK=g++
-#
-# This will allow make to invoke N linker processes as specified in -jN.
-LINK ?= %(flock)s $(builddir)/linker.lock $(CXX.target)
+LINK ?= $(CXX.target)
# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
# to replicate this environment fallback in make as well.
@@ -631,6 +624,38 @@ def QuoteSpaces(s, quote=r'\ '):
return s.replace(' ', quote)
+# TODO: Avoid code duplication with _ValidateSourcesForMSVSProject in msvs.py.
+def _ValidateSourcesForOSX(spec, all_sources):
+ """Makes sure if duplicate basenames are not specified in the source list.
+
+ Arguments:
+ spec: The target dictionary containing the properties of the target.
+ """
+ if spec.get('type', None) != 'static_library':
+ return
+
+ basenames = {}
+ for source in all_sources:
+ name, ext = os.path.splitext(source)
+ is_compiled_file = ext in [
+ '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S']
+ if not is_compiled_file:
+ continue
+ basename = os.path.basename(name) # Don't include extension.
+ basenames.setdefault(basename, []).append(source)
+
+ error = ''
+ for basename, files in basenames.iteritems():
+ if len(files) > 1:
+ error += ' %s: %s\n' % (basename, ' '.join(files))
+
+ if error:
+ print('static library %s has several files with the same basename:\n' %
+ spec['target_name'] + error + 'libtool on OS X will generate' +
+ ' warnings for them.')
+ raise GypError('Duplicate basenames in sources section, see list above')
+
+
# Map from qualified target to path to output.
target_outputs = {}
# Map from qualified target to any linkable output. A subset
@@ -640,7 +665,7 @@ target_outputs = {}
target_link_deps = {}
-class MakefileWriter:
+class MakefileWriter(object):
"""MakefileWriter packages up the writing of one target-specific foobar.mk.
Its only real entry point is Write(), and is mostly used for namespacing.
@@ -758,6 +783,10 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# Sources.
all_sources = spec.get('sources', []) + extra_sources
if all_sources:
+ if self.flavor == 'mac':
+ # libtool on OS X generates warnings for duplicate basenames in the same
+ # target.
+ _ValidateSourcesForOSX(spec, all_sources)
self.WriteSources(
configs, deps, all_sources, extra_outputs,
extra_link_deps, part_of_all,
@@ -1101,9 +1130,12 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
for output, res in gyp.xcode_emulation.GetMacBundleResources(
generator_default_variables['PRODUCT_DIR'], self.xcode_settings,
map(Sourceify, map(self.Absolutify, resources))):
- self.WriteDoCmd([output], [res], 'mac_tool,,,copy-bundle-resource',
- part_of_all=True)
- bundle_deps.append(output)
+ _, ext = os.path.splitext(output)
+ if ext != '.xcassets':
+ # Make does not supports '.xcassets' emulation.
+ self.WriteDoCmd([output], [res], 'mac_tool,,,copy-bundle-resource',
+ part_of_all=True)
+ bundle_deps.append(output)
def WriteMacInfoPlist(self, bundle_deps):
@@ -2036,7 +2068,6 @@ def GenerateOutput(target_list, target_dicts, data, params):
build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
make_global_settings_array = data[build_file].get('make_global_settings', [])
wrappers = {}
- wrappers['LINK'] = '%s $(builddir)/linker.lock' % flock_command
for key, value in make_global_settings_array:
if key.endswith('_wrapper'):
wrappers[key[:-len('_wrapper')]] = '$(abspath %s)' % value
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py
index c59aea106..8e6bd7ba0 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py
@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import collections
import copy
import ntpath
import os
@@ -13,6 +12,7 @@ import sys
import gyp.common
import gyp.easy_xml as easy_xml
+import gyp.generator.ninja as ninja_generator
import gyp.MSVSNew as MSVSNew
import gyp.MSVSProject as MSVSProject
import gyp.MSVSSettings as MSVSSettings
@@ -21,6 +21,7 @@ import gyp.MSVSUserFile as MSVSUserFile
import gyp.MSVSUtil as MSVSUtil
import gyp.MSVSVersion as MSVSVersion
from gyp.common import GypError
+from gyp.common import OrderedSet
# TODO: Remove once bots are on 2.7, http://crbug.com/241769
def _import_OrderedDict():
@@ -41,7 +42,7 @@ OrderedDict = _import_OrderedDict()
# if IncrediBuild is executed from inside Visual Studio. This regex
# validates that the string looks like a GUID with all uppercase hex
# letters.
-VALID_MSVS_GUID_CHARS = re.compile('^[A-F0-9\-]+$')
+VALID_MSVS_GUID_CHARS = re.compile(r'^[A-F0-9\-]+$')
generator_default_variables = {
@@ -81,6 +82,10 @@ generator_additional_non_configuration_keys = [
'msvs_external_builder_out_dir',
'msvs_external_builder_build_cmd',
'msvs_external_builder_clean_cmd',
+ 'msvs_external_builder_clcompile_cmd',
+ 'msvs_enable_winrt',
+ 'msvs_requires_importlibrary',
+ 'msvs_enable_winphone',
]
@@ -97,46 +102,6 @@ cached_username = None
cached_domain = None
-# Based on http://code.activestate.com/recipes/576694/.
-class OrderedSet(collections.MutableSet):
- def __init__(self, iterable=None):
- self.end = end = []
- end += [None, end, end] # sentinel node for doubly linked list
- self.map = {} # key --> [key, prev, next]
- if iterable is not None:
- self |= iterable
-
- def __len__(self):
- return len(self.map)
-
- def discard(self, key):
- if key in self.map:
- key, prev, next = self.map.pop(key)
- prev[2] = next
- next[1] = prev
-
- def __contains__(self, key):
- return key in self.map
-
- def add(self, key):
- if key not in self.map:
- end = self.end
- curr = end[1]
- curr[2] = end[1] = self.map[key] = [key, curr, end]
-
- def update(self, iterable):
- for i in iterable:
- if i not in self:
- self.add(i)
-
- def __iter__(self):
- end = self.end
- curr = end[2]
- while curr is not end:
- yield curr[0]
- curr = curr[2]
-
-
# TODO(gspencer): Switch the os.environ calls to be
# win32api.GetDomainName() and win32api.GetUserName() once the
# python version in depot_tools has been updated to work on Vista
@@ -153,11 +118,11 @@ def _GetDomainAndUserName():
call = subprocess.Popen(['net', 'config', 'Workstation'],
stdout=subprocess.PIPE)
config = call.communicate()[0]
- username_re = re.compile('^User name\s+(\S+)', re.MULTILINE)
+ username_re = re.compile(r'^User name\s+(\S+)', re.MULTILINE)
username_match = username_re.search(config)
if username_match:
username = username_match.group(1)
- domain_re = re.compile('^Logon domain\s+(\S+)', re.MULTILINE)
+ domain_re = re.compile(r'^Logon domain\s+(\S+)', re.MULTILINE)
domain_match = domain_re.search(config)
if domain_match:
domain = domain_match.group(1)
@@ -266,7 +231,8 @@ def _ConvertSourcesToFilterHierarchy(sources, prefix=None, excluded=None,
for f in folders:
contents = _ConvertSourcesToFilterHierarchy(folders[f], prefix=prefix + [f],
excluded=excluded,
- list_excluded=list_excluded)
+ list_excluded=list_excluded,
+ msvs_version=msvs_version)
contents = MSVSProject.Filter(f, contents=contents)
result.append(contents)
return result
@@ -322,7 +288,7 @@ def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path,
if [x for x in cmd if '$(InputDir)' in x]:
input_dir_preamble = (
'set INPUTDIR=$(InputDir)\n'
- 'set INPUTDIR=%INPUTDIR:$(ProjectDir)=%\n'
+ 'if NOT DEFINED INPUTDIR set INPUTDIR=.\\\n'
'set INPUTDIR=%INPUTDIR:~0,-1%\n'
)
else:
@@ -851,23 +817,27 @@ def _GenerateRulesForMSVS(p, output_dir, options, spec,
if rules_external:
_GenerateExternalRules(rules_external, output_dir, spec,
sources, options, actions_to_add)
- _AdjustSourcesForRules(spec, rules, sources, excluded_sources)
+ _AdjustSourcesForRules(rules, sources, excluded_sources, False)
-def _AdjustSourcesForRules(spec, rules, sources, excluded_sources):
+def _AdjustSourcesForRules(rules, sources, excluded_sources, is_msbuild):
# Add outputs generated by each rule (if applicable).
for rule in rules:
- # Done if not processing outputs as sources.
- if int(rule.get('process_outputs_as_sources', False)):
- # Add in the outputs from this rule.
- trigger_files = _FindRuleTriggerFiles(rule, sources)
- for trigger_file in trigger_files:
+ # Add in the outputs from this rule.
+ trigger_files = _FindRuleTriggerFiles(rule, sources)
+ for trigger_file in trigger_files:
+ # Remove trigger_file from excluded_sources to let the rule be triggered
+ # (e.g. rule trigger ax_enums.idl is added to excluded_sources
+ # because it's also in an action's inputs in the same project)
+ excluded_sources.discard(_FixPath(trigger_file))
+ # Done if not processing outputs as sources.
+ if int(rule.get('process_outputs_as_sources', False)):
inputs, outputs = _RuleInputsAndOutputs(rule, trigger_file)
inputs = OrderedSet(_FixPaths(inputs))
outputs = OrderedSet(_FixPaths(outputs))
inputs.remove(_FixPath(trigger_file))
sources.update(inputs)
- if not spec.get('msvs_external_builder'):
+ if not is_msbuild:
excluded_sources.update(inputs)
sources.update(outputs)
@@ -954,6 +924,42 @@ def _GenerateProject(project, options, version, generator_flags):
return _GenerateMSVSProject(project, options, version, generator_flags)
+# TODO: Avoid code duplication with _ValidateSourcesForOSX in make.py.
+def _ValidateSourcesForMSVSProject(spec, version):
+ """Makes sure if duplicate basenames are not specified in the source list.
+
+ Arguments:
+ spec: The target dictionary containing the properties of the target.
+ version: The VisualStudioVersion object.
+ """
+ # This validation should not be applied to MSVC2010 and later.
+ assert not version.UsesVcxproj()
+
+ # TODO: Check if MSVC allows this for loadable_module targets.
+ if spec.get('type', None) not in ('static_library', 'shared_library'):
+ return
+ sources = spec.get('sources', [])
+ basenames = {}
+ for source in sources:
+ name, ext = os.path.splitext(source)
+ is_compiled_file = ext in [
+ '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S']
+ if not is_compiled_file:
+ continue
+ basename = os.path.basename(name) # Don't include extension.
+ basenames.setdefault(basename, []).append(source)
+
+ error = ''
+ for basename, files in basenames.iteritems():
+ if len(files) > 1:
+ error += ' %s: %s\n' % (basename, ' '.join(files))
+
+ if error:
+ print('static library %s has several files with the same basename:\n' %
+ spec['target_name'] + error + 'MSVC08 cannot handle that.')
+ raise GypError('Duplicate basenames in sources section, see list above')
+
+
def _GenerateMSVSProject(project, options, version, generator_flags):
"""Generates a .vcproj file. It may create .rules and .user files too.
@@ -979,6 +985,11 @@ def _GenerateMSVSProject(project, options, version, generator_flags):
for config_name, config in spec['configurations'].iteritems():
_AddConfigurationToMSVSProject(p, spec, config_type, config_name, config)
+ # MSVC08 and prior version cannot handle duplicate basenames in the same
+ # target.
+ # TODO: Take excluded sources into consideration if possible.
+ _ValidateSourcesForMSVSProject(spec, version)
+
# Prepare list of sources and excluded sources.
gyp_file = os.path.split(project.build_file)[1]
sources, excluded_sources = _PrepareListOfSources(spec, generator_flags,
@@ -1098,7 +1109,8 @@ def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config):
for this configuration.
"""
# Get the information for this configuration
- include_dirs, resource_include_dirs = _GetIncludeDirs(config)
+ include_dirs, midl_include_dirs, resource_include_dirs = \
+ _GetIncludeDirs(config)
libraries = _GetLibraries(spec)
library_dirs = _GetLibraryDirs(config)
out_file, vc_tool, _ = _GetOutputFilePathAndTool(spec, msbuild=False)
@@ -1126,6 +1138,8 @@ def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config):
# Add the information to the appropriate tool
_ToolAppend(tools, 'VCCLCompilerTool',
'AdditionalIncludeDirectories', include_dirs)
+ _ToolAppend(tools, 'VCMIDLTool',
+ 'AdditionalIncludeDirectories', midl_include_dirs)
_ToolAppend(tools, 'VCResourceCompilerTool',
'AdditionalIncludeDirectories', resource_include_dirs)
# Add in libraries.
@@ -1181,10 +1195,14 @@ def _GetIncludeDirs(config):
include_dirs = (
config.get('include_dirs', []) +
config.get('msvs_system_include_dirs', []))
+ midl_include_dirs = (
+ config.get('midl_include_dirs', []) +
+ config.get('msvs_system_include_dirs', []))
resource_include_dirs = config.get('resource_include_dirs', include_dirs)
include_dirs = _FixPaths(include_dirs)
+ midl_include_dirs = _FixPaths(midl_include_dirs)
resource_include_dirs = _FixPaths(resource_include_dirs)
- return include_dirs, resource_include_dirs
+ return include_dirs, midl_include_dirs, resource_include_dirs
def _GetLibraryDirs(config):
@@ -1218,7 +1236,7 @@ def _GetLibraries(spec):
found = OrderedSet()
unique_libraries_list = []
for entry in reversed(libraries):
- library = re.sub('^\-l', '', entry)
+ library = re.sub(r'^\-l', '', entry)
if not os.path.splitext(library)[1]:
library += '.lib'
if library not in found:
@@ -1478,8 +1496,14 @@ def _AdjustSourcesAndConvertToFilterHierarchy(
# Prune filters with a single child to flatten ugly directory structures
# such as ../../src/modules/module1 etc.
- while len(sources) == 1 and isinstance(sources[0], MSVSProject.Filter):
- sources = sources[0].contents
+ if version.UsesVcxproj():
+ while all([isinstance(s, MSVSProject.Filter) for s in sources]) \
+ and len(set([s.name for s in sources])) == 1:
+ assert all([len(s.contents) == 1 for s in sources])
+ sources = [s.contents[0] for s in sources]
+ else:
+ while len(sources) == 1 and isinstance(sources[0], MSVSProject.Filter):
+ sources = sources[0].contents
return sources, excluded_sources, excluded_idl
@@ -1815,7 +1839,7 @@ def _CreateProjectObjects(target_list, target_dicts, options, msvs_version):
return projects
-def _InitNinjaFlavor(options, target_list, target_dicts):
+def _InitNinjaFlavor(params, target_list, target_dicts):
"""Initialize targets for the ninja flavor.
This sets up the necessary variables in the targets to generate msvs projects
@@ -1823,7 +1847,7 @@ def _InitNinjaFlavor(options, target_list, target_dicts):
if they have not been set. This allows individual specs to override the
default values initialized here.
Arguments:
- options: Options provided to the generator.
+ params: Params provided to the generator.
target_list: List of target pairs: 'base/base.gyp:base'.
target_dicts: Dict of target properties keyed on target pair.
"""
@@ -1837,8 +1861,15 @@ def _InitNinjaFlavor(options, target_list, target_dicts):
spec['msvs_external_builder'] = 'ninja'
if not spec.get('msvs_external_builder_out_dir'):
- spec['msvs_external_builder_out_dir'] = \
- options.depth + '/out/$(Configuration)'
+ gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target)
+ gyp_dir = os.path.dirname(gyp_file)
+ configuration = '$(Configuration)'
+ if params.get('target_arch') == 'x64':
+ configuration += '_x64'
+ spec['msvs_external_builder_out_dir'] = os.path.join(
+ gyp.common.RelativePath(params['options'].toplevel_dir, gyp_dir),
+ ninja_generator.ComputeOutputDir(params),
+ configuration)
if not spec.get('msvs_external_builder_build_cmd'):
spec['msvs_external_builder_build_cmd'] = [
path_to_ninja,
@@ -1851,8 +1882,7 @@ def _InitNinjaFlavor(options, target_list, target_dicts):
path_to_ninja,
'-C',
'$(OutDir)',
- '-t',
- 'clean',
+ '-tclean',
'$(ProjectName)',
]
@@ -1933,7 +1963,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
# Optionally configure each spec to use ninja as the external builder.
if params.get('flavor') == 'ninja':
- _InitNinjaFlavor(options, target_list, target_dicts)
+ _InitNinjaFlavor(params, target_list, target_dicts)
# Prepare the set of configurations.
configs = set()
@@ -1986,7 +2016,7 @@ def GenerateOutput(target_list, target_dicts, data, params):
def _GenerateMSBuildFiltersFile(filters_path, source_files,
- extension_to_rule_name):
+ rule_dependencies, extension_to_rule_name):
"""Generate the filters file.
This file is used by Visual Studio to organize the presentation of source
@@ -1999,8 +2029,8 @@ def _GenerateMSBuildFiltersFile(filters_path, source_files,
"""
filter_group = []
source_group = []
- _AppendFiltersForMSBuild('', source_files, extension_to_rule_name,
- filter_group, source_group)
+ _AppendFiltersForMSBuild('', source_files, rule_dependencies,
+ extension_to_rule_name, filter_group, source_group)
if filter_group:
content = ['Project',
{'ToolsVersion': '4.0',
@@ -2015,7 +2045,7 @@ def _GenerateMSBuildFiltersFile(filters_path, source_files,
os.unlink(filters_path)
-def _AppendFiltersForMSBuild(parent_filter_name, sources,
+def _AppendFiltersForMSBuild(parent_filter_name, sources, rule_dependencies,
extension_to_rule_name,
filter_group, source_group):
"""Creates the list of filters and sources to be added in the filter file.
@@ -2041,11 +2071,12 @@ def _AppendFiltersForMSBuild(parent_filter_name, sources,
['UniqueIdentifier', MSVSNew.MakeGuid(source.name)]])
# Recurse and add its dependents.
_AppendFiltersForMSBuild(filter_name, source.contents,
- extension_to_rule_name,
+ rule_dependencies, extension_to_rule_name,
filter_group, source_group)
else:
# It's a source. Create a source entry.
- _, element = _MapFileToMsBuildSourceType(source, extension_to_rule_name)
+ _, element = _MapFileToMsBuildSourceType(source, rule_dependencies,
+ extension_to_rule_name)
source_entry = [element, {'Include': source}]
# Specify the filter it is part of, if any.
if parent_filter_name:
@@ -2053,7 +2084,8 @@ def _AppendFiltersForMSBuild(parent_filter_name, sources,
source_group.append(source_entry)
-def _MapFileToMsBuildSourceType(source, extension_to_rule_name):
+def _MapFileToMsBuildSourceType(source, rule_dependencies,
+ extension_to_rule_name):
"""Returns the group and element type of the source file.
Arguments:
@@ -2076,9 +2108,15 @@ def _MapFileToMsBuildSourceType(source, extension_to_rule_name):
elif ext == '.rc':
group = 'resource'
element = 'ResourceCompile'
+ elif ext == '.asm':
+ group = 'masm'
+ element = 'MASM'
elif ext == '.idl':
group = 'midl'
element = 'Midl'
+ elif source in rule_dependencies:
+ group = 'rule_dependency'
+ element = 'CustomBuild'
else:
group = 'none'
element = 'None'
@@ -2088,7 +2126,8 @@ def _MapFileToMsBuildSourceType(source, extension_to_rule_name):
def _GenerateRulesForMSBuild(output_dir, options, spec,
sources, excluded_sources,
props_files_of_rules, targets_files_of_rules,
- actions_to_add, extension_to_rule_name):
+ actions_to_add, rule_dependencies,
+ extension_to_rule_name):
# MSBuild rules are implemented using three files: an XML file, a .targets
# file and a .props file.
# See http://blogs.msdn.com/b/vcblog/archive/2010/04/21/quick-help-on-vs2010-custom-build-rule.aspx
@@ -2104,6 +2143,7 @@ def _GenerateRulesForMSBuild(output_dir, options, spec,
continue
msbuild_rule = MSBuildRule(rule, spec)
msbuild_rules.append(msbuild_rule)
+ rule_dependencies.update(msbuild_rule.additional_dependencies.split(';'))
extension_to_rule_name[msbuild_rule.extension] = msbuild_rule.rule_name
if msbuild_rules:
base = spec['target_name'] + options.suffix
@@ -2125,7 +2165,7 @@ def _GenerateRulesForMSBuild(output_dir, options, spec,
if rules_external:
_GenerateExternalRules(rules_external, output_dir, spec,
sources, options, actions_to_add)
- _AdjustSourcesForRules(spec, rules, sources, excluded_sources)
+ _AdjustSourcesForRules(rules, sources, excluded_sources, True)
class MSBuildRule(object):
@@ -2578,14 +2618,30 @@ def _GetMSBuildProjectConfigurations(configurations):
def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name):
namespace = os.path.splitext(gyp_file_name)[0]
- return [
+ properties = [
['PropertyGroup', {'Label': 'Globals'},
- ['ProjectGuid', guid],
- ['Keyword', 'Win32Proj'],
- ['RootNamespace', namespace],
+ ['ProjectGuid', guid],
+ ['Keyword', 'Win32Proj'],
+ ['RootNamespace', namespace],
+ ['IgnoreWarnCompileDuplicatedFilename', 'true'],
]
- ]
+ ]
+ if os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or \
+ os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64':
+ properties[0].append(['PreferredToolArchitecture', 'x64'])
+
+ if spec.get('msvs_enable_winrt'):
+ properties[0].append(['DefaultLanguage', 'en-US'])
+ properties[0].append(['AppContainerApplication', 'true'])
+ properties[0].append(['ApplicationTypeRevision', '8.1'])
+
+ if spec.get('msvs_enable_winphone'):
+ properties[0].append(['ApplicationType', 'Windows Phone'])
+ else:
+ properties[0].append(['ApplicationType', 'Windows Store'])
+
+ return properties
def _GetMSBuildConfigurationDetails(spec, build_file):
properties = {}
@@ -2596,8 +2652,9 @@ def _GetMSBuildConfigurationDetails(spec, build_file):
_AddConditionalProperty(properties, condition, 'ConfigurationType',
msbuild_attributes['ConfigurationType'])
if character_set:
- _AddConditionalProperty(properties, condition, 'CharacterSet',
- character_set)
+ if 'msvs_enable_winrt' not in spec :
+ _AddConditionalProperty(properties, condition, 'CharacterSet',
+ character_set)
return _GetMSBuildPropertyGroup(spec, 'Configuration', properties)
@@ -2818,7 +2875,7 @@ def _AddConditionalProperty(properties, condition, name, value):
# Regex for msvs variable references ( i.e. $(FOO) ).
-MSVS_VARIABLE_REFERENCE = re.compile('\$\(([a-zA-Z_][a-zA-Z0-9_]*)\)')
+MSVS_VARIABLE_REFERENCE = re.compile(r'\$\(([a-zA-Z_][a-zA-Z0-9_]*)\)')
def _GetMSBuildPropertyGroup(spec, label, properties):
@@ -2902,7 +2959,8 @@ def _FinalizeMSBuildSettings(spec, configuration):
converted = True
msvs_settings = configuration.get('msvs_settings', {})
msbuild_settings = MSVSSettings.ConvertToMSBuildSettings(msvs_settings)
- include_dirs, resource_include_dirs = _GetIncludeDirs(configuration)
+ include_dirs, midl_include_dirs, resource_include_dirs = \
+ _GetIncludeDirs(configuration)
libraries = _GetLibraries(spec)
library_dirs = _GetLibraryDirs(configuration)
out_file, _, msbuild_tool = _GetOutputFilePathAndTool(spec, msbuild=True)
@@ -2912,7 +2970,7 @@ def _FinalizeMSBuildSettings(spec, configuration):
# Visual Studio 2010 has TR1
defines = [d for d in defines if d != '_HAS_TR1=0']
# Warn of ignored settings
- ignored_settings = ['msvs_prebuild', 'msvs_postbuild', 'msvs_tool_files']
+ ignored_settings = ['msvs_tool_files']
for ignored_setting in ignored_settings:
value = configuration.get(ignored_setting)
if value:
@@ -2921,9 +2979,8 @@ def _FinalizeMSBuildSettings(spec, configuration):
defines = [_EscapeCppDefineForMSBuild(d) for d in defines]
disabled_warnings = _GetDisabledWarnings(configuration)
- # TODO(jeanluc) Validate & warn that we don't translate
- # prebuild = configuration.get('msvs_prebuild')
- # postbuild = configuration.get('msvs_postbuild')
+ prebuild = configuration.get('msvs_prebuild')
+ postbuild = configuration.get('msvs_postbuild')
def_file = _GetModuleDefinition(spec)
precompiled_header = configuration.get('msvs_precompiled_header')
@@ -2933,6 +2990,8 @@ def _FinalizeMSBuildSettings(spec, configuration):
# if you don't have any resources.
_ToolAppend(msbuild_settings, 'ClCompile',
'AdditionalIncludeDirectories', include_dirs)
+ _ToolAppend(msbuild_settings, 'Midl',
+ 'AdditionalIncludeDirectories', midl_include_dirs)
_ToolAppend(msbuild_settings, 'ResourceCompile',
'AdditionalIncludeDirectories', resource_include_dirs)
# Add in libraries, note that even for empty libraries, we want this
@@ -2963,6 +3022,13 @@ def _FinalizeMSBuildSettings(spec, configuration):
'PrecompiledHeaderFile', precompiled_header)
_ToolAppend(msbuild_settings, 'ClCompile',
'ForcedIncludeFiles', [precompiled_header])
+ else:
+ _ToolAppend(msbuild_settings, 'ClCompile', 'PrecompiledHeader', 'NotUsing')
+ # Turn off WinRT compilation
+ _ToolAppend(msbuild_settings, 'ClCompile', 'CompileAsWinRT', 'false')
+ # Turn on import libraries if appropriate
+ if spec.get('msvs_requires_importlibrary'):
+ _ToolAppend(msbuild_settings, '', 'IgnoreImportLibrary', 'false')
# Loadable modules don't generate import libraries;
# tell dependent projects to not expect one.
if spec['type'] == 'loadable_module':
@@ -2971,6 +3037,10 @@ def _FinalizeMSBuildSettings(spec, configuration):
if def_file:
_ToolAppend(msbuild_settings, 'Link', 'ModuleDefinitionFile', def_file)
configuration['finalized_msbuild_settings'] = msbuild_settings
+ if prebuild:
+ _ToolAppend(msbuild_settings, 'PreBuildEvent', 'Command', prebuild)
+ if postbuild:
+ _ToolAppend(msbuild_settings, 'PostBuildEvent', 'Command', postbuild)
def _GetValueFormattedForMSBuild(tool_name, name, value):
@@ -3026,15 +3096,18 @@ def _VerifySourcesExist(sources, root_dir):
return missing_sources
-def _GetMSBuildSources(spec, sources, exclusions, extension_to_rule_name,
- actions_spec, sources_handled_by_action, list_excluded):
- groups = ['none', 'midl', 'include', 'compile', 'resource', 'rule']
+def _GetMSBuildSources(spec, sources, exclusions, rule_dependencies,
+ extension_to_rule_name, actions_spec,
+ sources_handled_by_action, list_excluded):
+ groups = ['none', 'masm', 'midl', 'include', 'compile', 'resource', 'rule',
+ 'rule_dependency']
grouped_sources = {}
for g in groups:
grouped_sources[g] = []
_AddSources2(spec, sources, exclusions, grouped_sources,
- extension_to_rule_name, sources_handled_by_action, list_excluded)
+ rule_dependencies, extension_to_rule_name,
+ sources_handled_by_action, list_excluded)
sources = []
for g in groups:
if grouped_sources[g]:
@@ -3045,13 +3118,15 @@ def _GetMSBuildSources(spec, sources, exclusions, extension_to_rule_name,
def _AddSources2(spec, sources, exclusions, grouped_sources,
- extension_to_rule_name, sources_handled_by_action,
+ rule_dependencies, extension_to_rule_name,
+ sources_handled_by_action,
list_excluded):
extensions_excluded_from_precompile = []
for source in sources:
if isinstance(source, MSVSProject.Filter):
_AddSources2(spec, source.contents, exclusions, grouped_sources,
- extension_to_rule_name, sources_handled_by_action,
+ rule_dependencies, extension_to_rule_name,
+ sources_handled_by_action,
list_excluded)
else:
if not source in sources_handled_by_action:
@@ -3094,7 +3169,7 @@ def _AddSources2(spec, sources, exclusions, grouped_sources,
detail.append(['PrecompiledHeader', ''])
detail.append(['ForcedIncludeFiles', ''])
- group, element = _MapFileToMsBuildSourceType(source,
+ group, element = _MapFileToMsBuildSourceType(source, rule_dependencies,
extension_to_rule_name)
grouped_sources[group].append([element, {'Include': source}] + detail)
@@ -3138,6 +3213,7 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
actions_to_add = {}
props_files_of_rules = set()
targets_files_of_rules = set()
+ rule_dependencies = set()
extension_to_rule_name = {}
list_excluded = generator_flags.get('msvs_list_excluded_files', True)
@@ -3146,10 +3222,11 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
_GenerateRulesForMSBuild(project_dir, options, spec,
sources, excluded_sources,
props_files_of_rules, targets_files_of_rules,
- actions_to_add, extension_to_rule_name)
+ actions_to_add, rule_dependencies,
+ extension_to_rule_name)
else:
rules = spec.get('rules', [])
- _AdjustSourcesForRules(spec, rules, sources, excluded_sources)
+ _AdjustSourcesForRules(rules, sources, excluded_sources, True)
sources, excluded_sources, excluded_idl = (
_AdjustSourcesAndConvertToFilterHierarchy(spec, options,
@@ -3172,6 +3249,7 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
spec, actions_to_add)
_GenerateMSBuildFiltersFile(project.path + '.filters', sources,
+ rule_dependencies,
extension_to_rule_name)
missing_sources = _VerifySourcesExist(sources, project_dir)
@@ -3186,6 +3264,12 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
['Import', {'Project': r'$(VCTargetsPath)\Microsoft.Cpp.props'}]]
import_cpp_targets_section = [
['Import', {'Project': r'$(VCTargetsPath)\Microsoft.Cpp.targets'}]]
+ import_masm_props_section = [
+ ['Import',
+ {'Project': r'$(VCTargetsPath)\BuildCustomizations\masm.props'}]]
+ import_masm_targets_section = [
+ ['Import',
+ {'Project': r'$(VCTargetsPath)\BuildCustomizations\masm.targets'}]]
macro_section = [['PropertyGroup', {'Label': 'UserMacros'}]]
content = [
@@ -3199,8 +3283,12 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
content += _GetMSBuildGlobalProperties(spec, project.guid, project_file_name)
content += import_default_section
content += _GetMSBuildConfigurationDetails(spec, project.build_file)
- content += _GetMSBuildLocalProperties(project.msbuild_toolset)
+ if spec.get('msvs_enable_winphone'):
+ content += _GetMSBuildLocalProperties('v120_wp81')
+ else:
+ content += _GetMSBuildLocalProperties(project.msbuild_toolset)
content += import_cpp_props_section
+ content += import_masm_props_section
content += _GetMSBuildExtensions(props_files_of_rules)
content += _GetMSBuildPropertySheets(configurations)
content += macro_section
@@ -3208,10 +3296,11 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
project.build_file)
content += _GetMSBuildToolSettingsSections(spec, configurations)
content += _GetMSBuildSources(
- spec, sources, exclusions, extension_to_rule_name, actions_spec,
- sources_handled_by_action, list_excluded)
+ spec, sources, exclusions, rule_dependencies, extension_to_rule_name,
+ actions_spec, sources_handled_by_action, list_excluded)
content += _GetMSBuildProjectReferences(project)
content += import_cpp_targets_section
+ content += import_masm_targets_section
content += _GetMSBuildExtensionTargets(targets_files_of_rules)
if spec.get('msvs_external_builder'):
@@ -3228,7 +3317,9 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
def _GetMSBuildExternalBuilderTargets(spec):
"""Return a list of MSBuild targets for external builders.
- Right now, only "Build" and "Clean" targets are generated.
+ The "Build" and "Clean" targets are always generated. If the spec contains
+ 'msvs_external_builder_clcompile_cmd', then the "ClCompile" target will also
+ be generated, to support building selected C/C++ files.
Arguments:
spec: The gyp target spec.
@@ -3247,7 +3338,17 @@ def _GetMSBuildExternalBuilderTargets(spec):
clean_target = ['Target', {'Name': 'Clean'}]
clean_target.append(['Exec', {'Command': clean_cmd}])
- return [build_target, clean_target]
+ targets = [build_target, clean_target]
+
+ if spec.get('msvs_external_builder_clcompile_cmd'):
+ clcompile_cmd = _BuildCommandLineForRuleRaw(
+ spec, spec['msvs_external_builder_clcompile_cmd'],
+ False, False, False, False)
+ clcompile_target = ['Target', {'Name': 'ClCompile'}]
+ clcompile_target.append(['Exec', {'Command': clcompile_cmd}])
+ targets.append(clcompile_target)
+
+ return targets
def _GetMSBuildExtensions(props_files_of_rules):
@@ -3301,8 +3402,8 @@ def _GenerateActionsForMSBuild(spec, actions_to_add):
# get too long. See also _AddActions: cygwin's setup_env mustn't be called
# for every invocation or the command that sets the PATH will grow too
# long.
- command = (
- '\r\nif %errorlevel% neq 0 exit /b %errorlevel%\r\n'.join(commands))
+ command = '\r\n'.join([c + '\r\nif %errorlevel% neq 0 exit /b %errorlevel%'
+ for c in commands])
_AddMSBuildAction(spec,
primary_input,
inputs,
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py
index c2951a4c5..624c99ae8 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import collections
import copy
import hashlib
import json
@@ -13,6 +14,7 @@ import subprocess
import sys
import gyp
import gyp.common
+from gyp.common import OrderedSet
import gyp.msvs_emulation
import gyp.MSVSUtil as MSVSUtil
import gyp.xcode_emulation
@@ -60,17 +62,7 @@ generator_additional_path_sections = []
generator_extra_sources_for_rules = []
generator_filelist_paths = None
-# TODO: figure out how to not build extra host objects in the non-cross-compile
-# case when this is enabled, and enable unconditionally.
-generator_supports_multiple_toolsets = (
- os.environ.get('GYP_CROSSCOMPILE') or
- os.environ.get('AR_host') or
- os.environ.get('CC_host') or
- os.environ.get('CXX_host') or
- os.environ.get('AR_target') or
- os.environ.get('CC_target') or
- os.environ.get('CXX_target'))
-
+generator_supports_multiple_toolsets = gyp.common.CrossCompileRequested()
def StripPrefix(arg, prefix):
if arg.startswith(prefix):
@@ -106,7 +98,7 @@ def AddArch(output, arch):
return '%s.%s%s' % (output, arch, extension)
-class Target:
+class Target(object):
"""Target represents the paths used within a single gyp target.
Conceptually, building a single target A is a series of steps:
@@ -210,8 +202,8 @@ class Target:
# an output file; the result can be namespaced such that it is unique
# to the input file name as well as the output target name.
-class NinjaWriter:
- def __init__(self, qualified_target, target_outputs, base_dir, build_dir,
+class NinjaWriter(object):
+ def __init__(self, hash_for_rules, target_outputs, base_dir, build_dir,
output_file, toplevel_build, output_file_name, flavor,
toplevel_dir=None):
"""
@@ -221,7 +213,7 @@ class NinjaWriter:
toplevel_dir: path to the toplevel directory
"""
- self.qualified_target = qualified_target
+ self.hash_for_rules = hash_for_rules
self.target_outputs = target_outputs
self.base_dir = base_dir
self.build_dir = build_dir
@@ -338,12 +330,15 @@ class NinjaWriter:
obj += '.' + self.toolset
path_dir, path_basename = os.path.split(path)
+ assert not os.path.isabs(path_dir), (
+ "'%s' can not be absolute path (see crbug.com/462153)." % path_dir)
+
if qualified:
path_basename = self.name + '.' + path_basename
return os.path.normpath(os.path.join(obj, self.base_dir, path_dir,
path_basename))
- def WriteCollapsedDependencies(self, name, targets):
+ def WriteCollapsedDependencies(self, name, targets, order_only=None):
"""Given a list of targets, return a path for a single file
representing the result of building all the targets or None.
@@ -351,10 +346,11 @@ class NinjaWriter:
assert targets == filter(None, targets), targets
if len(targets) == 0:
+ assert not order_only
return None
- if len(targets) > 1:
+ if len(targets) > 1 or order_only:
stamp = self.GypPathToUniqueOutput(name + '.stamp')
- targets = self.ninja.build(stamp, 'stamp', targets)
+ targets = self.ninja.build(stamp, 'stamp', targets, order_only=order_only)
self.ninja.newline()
return targets[0]
@@ -391,6 +387,9 @@ class NinjaWriter:
self.ninja.variable('arch', self.win_env[arch])
self.ninja.variable('cc', '$cl_' + arch)
self.ninja.variable('cxx', '$cl_' + arch)
+ self.ninja.variable('cc_host', '$cl_' + arch)
+ self.ninja.variable('cxx_host', '$cl_' + arch)
+ self.ninja.variable('asm', '$ml_' + arch)
if self.flavor == 'mac':
self.archs = self.xcode_settings.GetActiveArchs(config_name)
@@ -472,6 +471,8 @@ class NinjaWriter:
else:
print "Warning: Actions/rules writing object files don't work with " \
"multiarch targets, dropping. (target %s)" % spec['target_name']
+ elif self.flavor == 'mac' and len(self.archs) > 1:
+ link_deps = collections.defaultdict(list)
if self.flavor == 'win' and self.target.type == 'static_library':
@@ -523,7 +524,7 @@ class NinjaWriter:
def WriteWinIdlFiles(self, spec, prebuild):
"""Writes rules to match MSVS's implicit idl handling."""
assert self.flavor == 'win'
- if self.msvs_settings.HasExplicitIdlRules(spec):
+ if self.msvs_settings.HasExplicitIdlRulesOrActions(spec):
return []
outputs = []
for source in filter(lambda x: x.endswith('.idl'), spec['sources']):
@@ -557,9 +558,10 @@ class NinjaWriter:
stamp = self.WriteCollapsedDependencies('actions_rules_copies', outputs)
if self.is_mac_bundle:
- self.WriteMacBundleResources(
+ xcassets = self.WriteMacBundleResources(
extra_mac_bundle_resources + mac_bundle_resources, mac_bundle_depends)
- self.WriteMacInfoPlist(mac_bundle_depends)
+ partial_info_plist = self.WriteMacXCassets(xcassets, mac_bundle_depends)
+ self.WriteMacInfoPlist(partial_info_plist, mac_bundle_depends)
return stamp
@@ -580,23 +582,24 @@ class NinjaWriter:
def WriteActions(self, actions, extra_sources, prebuild,
extra_mac_bundle_resources):
# Actions cd into the base directory.
- env = self.GetSortedXcodeEnv()
- if self.flavor == 'win':
- env = self.msvs_settings.GetVSMacroEnv(
- '$!PRODUCT_DIR', config=self.config_name)
+ env = self.GetToolchainEnv()
all_outputs = []
for action in actions:
# First write out a rule for the action.
- name = '%s_%s' % (action['action_name'],
- hashlib.md5(self.qualified_target).hexdigest())
+ name = '%s_%s' % (action['action_name'], self.hash_for_rules)
description = self.GenerateDescription('ACTION',
action.get('message', None),
name)
is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action)
if self.flavor == 'win' else False)
args = action['action']
+ depfile = action.get('depfile', None)
+ if depfile:
+ depfile = self.ExpandSpecial(depfile, self.base_to_build)
+ pool = 'console' if int(action.get('ninja_use_console', 0)) else None
rule_name, _ = self.WriteNewNinjaRule(name, args, description,
- is_cygwin, env=env)
+ is_cygwin, env, pool,
+ depfile=depfile)
inputs = [self.GypPathToNinja(i, env) for i in action['inputs']]
if int(action.get('process_outputs_as_sources', False)):
@@ -616,15 +619,16 @@ class NinjaWriter:
def WriteRules(self, rules, extra_sources, prebuild,
mac_bundle_resources, extra_mac_bundle_resources):
- env = self.GetSortedXcodeEnv()
+ env = self.GetToolchainEnv()
all_outputs = []
for rule in rules:
- # First write out a rule for the rule action.
- name = '%s_%s' % (rule['rule_name'],
- hashlib.md5(self.qualified_target).hexdigest())
# Skip a rule with no action and no inputs.
if 'action' not in rule and not rule.get('rule_sources', []):
continue
+
+ # First write out a rule for the rule action.
+ name = '%s_%s' % (rule['rule_name'], self.hash_for_rules)
+
args = rule['action']
description = self.GenerateDescription(
'RULE',
@@ -632,8 +636,9 @@ class NinjaWriter:
('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name)
is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule)
if self.flavor == 'win' else False)
+ pool = 'console' if int(rule.get('ninja_use_console', 0)) else None
rule_name, args = self.WriteNewNinjaRule(
- name, args, description, is_cygwin, env=env)
+ name, args, description, is_cygwin, env, pool)
# TODO: if the command references the outputs directly, we should
# simplify it to just use $out.
@@ -645,16 +650,31 @@ class NinjaWriter:
needed_variables = set(['source'])
for argument in args:
for var in special_locals:
- if ('${%s}' % var) in argument:
+ if '${%s}' % var in argument:
needed_variables.add(var)
def cygwin_munge(path):
+ # pylint: disable=cell-var-from-loop
if is_cygwin:
return path.replace('\\', '/')
return path
+ inputs = [self.GypPathToNinja(i, env) for i in rule.get('inputs', [])]
+
+ # If there are n source files matching the rule, and m additional rule
+ # inputs, then adding 'inputs' to each build edge written below will
+ # write m * n inputs. Collapsing reduces this to m + n.
+ sources = rule.get('rule_sources', [])
+ num_inputs = len(inputs)
+ if prebuild:
+ num_inputs += 1
+ if num_inputs > 2 and len(sources) > 2:
+ inputs = [self.WriteCollapsedDependencies(
+ rule['rule_name'], inputs, order_only=prebuild)]
+ prebuild = []
+
# For each source file, write an edge that generates all the outputs.
- for source in rule.get('rule_sources', []):
+ for source in sources:
source = os.path.normpath(source)
dirname, basename = os.path.split(source)
root, ext = os.path.splitext(basename)
@@ -663,9 +683,6 @@ class NinjaWriter:
outputs = [self.ExpandRuleVariables(o, root, dirname,
source, ext, basename)
for o in rule['outputs']]
- inputs = [self.ExpandRuleVariables(i, root, dirname,
- source, ext, basename)
- for i in rule.get('inputs', [])]
if int(rule.get('process_outputs_as_sources', False)):
extra_sources += outputs
@@ -703,10 +720,11 @@ class NinjaWriter:
else:
assert var == None, repr(var)
- inputs = [self.GypPathToNinja(i, env) for i in inputs]
outputs = [self.GypPathToNinja(o, env) for o in outputs]
- extra_bindings.append(('unique_name',
- hashlib.md5(outputs[0]).hexdigest()))
+ if self.flavor == 'win':
+ # WriteNewNinjaRule uses unique_name for creating an rsp file on win.
+ extra_bindings.append(('unique_name',
+ hashlib.md5(outputs[0]).hexdigest()))
self.ninja.build(outputs, rule_name, self.GypPathToNinja(source),
implicit=inputs,
order_only=prebuild,
@@ -718,7 +736,7 @@ class NinjaWriter:
def WriteCopies(self, copies, prebuild, mac_bundle_depends):
outputs = []
- env = self.GetSortedXcodeEnv()
+ env = self.GetToolchainEnv()
for copy in copies:
for path in copy['files']:
# Normalize the path so trailing slashes don't confuse us.
@@ -742,15 +760,68 @@ class NinjaWriter:
def WriteMacBundleResources(self, resources, bundle_depends):
"""Writes ninja edges for 'mac_bundle_resources'."""
+ xcassets = []
for output, res in gyp.xcode_emulation.GetMacBundleResources(
generator_default_variables['PRODUCT_DIR'],
self.xcode_settings, map(self.GypPathToNinja, resources)):
output = self.ExpandSpecial(output)
- self.ninja.build(output, 'mac_tool', res,
- variables=[('mactool_cmd', 'copy-bundle-resource')])
- bundle_depends.append(output)
+ if os.path.splitext(output)[-1] != '.xcassets':
+ isBinary = self.xcode_settings.IsBinaryOutputFormat(self.config_name)
+ self.ninja.build(output, 'mac_tool', res,
+ variables=[('mactool_cmd', 'copy-bundle-resource'), \
+ ('binary', isBinary)])
+ bundle_depends.append(output)
+ else:
+ xcassets.append(res)
+ return xcassets
+
+ def WriteMacXCassets(self, xcassets, bundle_depends):
+ """Writes ninja edges for 'mac_bundle_resources' .xcassets files.
+
+ This add an invocation of 'actool' via the 'mac_tool.py' helper script.
+ It assumes that the assets catalogs define at least one imageset and
+ thus an Assets.car file will be generated in the application resources
+ directory. If this is not the case, then the build will probably be done
+ at each invocation of ninja."""
+ if not xcassets:
+ return
+
+ extra_arguments = {}
+ settings_to_arg = {
+ 'XCASSETS_APP_ICON': 'app-icon',
+ 'XCASSETS_LAUNCH_IMAGE': 'launch-image',
+ }
+ settings = self.xcode_settings.xcode_settings[self.config_name]
+ for settings_key, arg_name in settings_to_arg.iteritems():
+ value = settings.get(settings_key)
+ if value:
+ extra_arguments[arg_name] = value
+
+ partial_info_plist = None
+ if extra_arguments:
+ partial_info_plist = self.GypPathToUniqueOutput(
+ 'assetcatalog_generated_info.plist')
+ extra_arguments['output-partial-info-plist'] = partial_info_plist
- def WriteMacInfoPlist(self, bundle_depends):
+ outputs = []
+ outputs.append(
+ os.path.join(
+ self.xcode_settings.GetBundleResourceFolder(),
+ 'Assets.car'))
+ if partial_info_plist:
+ outputs.append(partial_info_plist)
+
+ keys = QuoteShellArgument(json.dumps(extra_arguments), self.flavor)
+ extra_env = self.xcode_settings.GetPerTargetSettings()
+ env = self.GetSortedXcodeEnv(additional_settings=extra_env)
+ env = self.ComputeExportEnvString(env)
+
+ bundle_depends.extend(self.ninja.build(
+ outputs, 'compile_xcassets', xcassets,
+ variables=[('env', env), ('keys', keys)]))
+ return partial_info_plist
+
+ def WriteMacInfoPlist(self, partial_info_plist, bundle_depends):
"""Write build rules for bundle Info.plist files."""
info_plist, out, defines, extra_env = gyp.xcode_emulation.GetMacInfoPlist(
generator_default_variables['PRODUCT_DIR'],
@@ -770,10 +841,18 @@ class NinjaWriter:
env = self.GetSortedXcodeEnv(additional_settings=extra_env)
env = self.ComputeExportEnvString(env)
+ if partial_info_plist:
+ intermediate_plist = self.GypPathToUniqueOutput('merged_info.plist')
+ info_plist = self.ninja.build(
+ intermediate_plist, 'merge_infoplist',
+ [partial_info_plist, info_plist])
+
keys = self.xcode_settings.GetExtraPlistItems(self.config_name)
keys = QuoteShellArgument(json.dumps(keys), self.flavor)
+ isBinary = self.xcode_settings.IsBinaryOutputFormat(self.config_name)
self.ninja.build(out, 'copy_infoplist', info_plist,
- variables=[('env', env), ('keys', keys)])
+ variables=[('env', env), ('keys', keys),
+ ('binary', isBinary)])
bundle_depends.append(out)
def WriteSources(self, ninja_file, config_name, config, sources, predepends,
@@ -785,6 +864,8 @@ class NinjaWriter:
self.ninja.variable('cxx', '$cxx_host')
self.ninja.variable('ld', '$ld_host')
self.ninja.variable('ldxx', '$ldxx_host')
+ self.ninja.variable('nm', '$nm_host')
+ self.ninja.variable('readelf', '$readelf_host')
if self.flavor != 'mac' or len(self.archs) == 1:
return self.WriteSourcesForArch(
@@ -810,6 +891,7 @@ class NinjaWriter:
cflags_objcc = ['$cflags_cc'] + \
self.xcode_settings.GetCflagsObjCC(config_name)
elif self.flavor == 'win':
+ asmflags = self.msvs_settings.GetAsmflags(config_name)
cflags = self.msvs_settings.GetCflags(config_name)
cflags_c = self.msvs_settings.GetCflagsC(config_name)
cflags_cc = self.msvs_settings.GetCflagsCC(config_name)
@@ -844,22 +926,31 @@ class NinjaWriter:
self.WriteVariableList(ninja_file, 'defines',
[Define(d, self.flavor) for d in defines])
if self.flavor == 'win':
+ self.WriteVariableList(ninja_file, 'asmflags',
+ map(self.ExpandSpecial, asmflags))
self.WriteVariableList(ninja_file, 'rcflags',
[QuoteShellArgument(self.ExpandSpecial(f), self.flavor)
for f in self.msvs_settings.GetRcflags(config_name,
self.GypPathToNinja)])
include_dirs = config.get('include_dirs', [])
- env = self.GetSortedXcodeEnv()
+
+ env = self.GetToolchainEnv()
if self.flavor == 'win':
- env = self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR',
- config=config_name)
include_dirs = self.msvs_settings.AdjustIncludeDirs(include_dirs,
config_name)
self.WriteVariableList(ninja_file, 'includes',
[QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor)
for i in include_dirs])
+ if self.flavor == 'win':
+ midl_include_dirs = config.get('midl_include_dirs', [])
+ midl_include_dirs = self.msvs_settings.AdjustMidlIncludeDirs(
+ midl_include_dirs, config_name)
+ self.WriteVariableList(ninja_file, 'midl_includes',
+ [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor)
+ for i in midl_include_dirs])
+
pch_commands = precompiled_header.GetPchBuildCommands(arch)
if self.flavor == 'mac':
# Most targets use no precompiled headers, so only write these if needed.
@@ -868,6 +959,8 @@ class NinjaWriter:
include = precompiled_header.GetInclude(ext, arch)
if include: ninja_file.variable(var, include)
+ arflags = config.get('arflags', [])
+
self.WriteVariableList(ninja_file, 'cflags',
map(self.ExpandSpecial, cflags))
self.WriteVariableList(ninja_file, 'cflags_c',
@@ -879,6 +972,8 @@ class NinjaWriter:
map(self.ExpandSpecial, cflags_objc))
self.WriteVariableList(ninja_file, 'cflags_objcc',
map(self.ExpandSpecial, cflags_objcc))
+ self.WriteVariableList(ninja_file, 'arflags',
+ map(self.ExpandSpecial, arflags))
ninja_file.newline()
outputs = []
has_rc_source = False
@@ -894,9 +989,7 @@ class NinjaWriter:
elif ext == 's' and self.flavor != 'win': # Doesn't generate .o.d files.
command = 'cc_s'
elif (self.flavor == 'win' and ext == 'asm' and
- self.msvs_settings.GetArch(config_name) == 'x86' and
not self.msvs_settings.HasExplicitAsmRules(spec)):
- # Asm files only get auto assembled for x86 (not x64).
command = 'asm'
# Add the _asm suffix as msvs is capable of handling .cc and
# .asm files of the same name without collision.
@@ -968,9 +1061,19 @@ class NinjaWriter:
arch=arch)
for arch in self.archs]
extra_bindings = []
+ build_output = output
if not self.is_mac_bundle:
self.AppendPostbuildVariable(extra_bindings, spec, output, output)
- self.ninja.build(output, 'lipo', inputs, variables=extra_bindings)
+
+ # TODO(yyanagisawa): more work needed to fix:
+ # https://code.google.com/p/gyp/issues/detail?id=411
+ if (spec['type'] in ('shared_library', 'loadable_module') and
+ not self.is_mac_bundle):
+ extra_bindings.append(('lib', output))
+ self.ninja.build([output, output + '.TOC'], 'solipo', inputs,
+ variables=extra_bindings)
+ else:
+ self.ninja.build(build_output, 'lipo', inputs, variables=extra_bindings)
return output
def WriteLinkForArch(self, ninja_file, spec, config_name, config,
@@ -1063,7 +1166,7 @@ class NinjaWriter:
rpath = 'lib/'
if self.toolset != 'target':
rpath += self.toolset
- ldflags.append('-Wl,-rpath=\$$ORIGIN/%s' % rpath)
+ ldflags.append(r'-Wl,-rpath=\$$ORIGIN/%s' % rpath)
ldflags.append('-Wl,-rpath-link=%s' % rpath)
self.WriteVariableList(ninja_file, 'ldflags',
gyp.common.uniquer(map(self.ExpandSpecial, ldflags)))
@@ -1095,9 +1198,27 @@ class NinjaWriter:
extra_bindings.append(('soname', os.path.split(output)[1]))
extra_bindings.append(('lib',
gyp.common.EncodePOSIXShellArgument(output)))
+ if self.flavor != 'win':
+ link_file_list = output
+ if self.is_mac_bundle:
+ # 'Dependency Framework.framework/Versions/A/Dependency Framework' ->
+ # 'Dependency Framework.framework.rsp'
+ link_file_list = self.xcode_settings.GetWrapperName()
+ if arch:
+ link_file_list += '.' + arch
+ link_file_list += '.rsp'
+ # If an rspfile contains spaces, ninja surrounds the filename with
+ # quotes around it and then passes it to open(), creating a file with
+ # quotes in its name (and when looking for the rsp file, the name
+ # makes it through bash which strips the quotes) :-/
+ link_file_list = link_file_list.replace(' ', '_')
+ extra_bindings.append(
+ ('link_file_list',
+ gyp.common.EncodePOSIXShellArgument(link_file_list)))
if self.flavor == 'win':
extra_bindings.append(('binary', output))
- if '/NOENTRY' not in ldflags:
+ if ('/NOENTRY' not in ldflags and
+ not self.msvs_settings.GetNoImportLibrary(config_name)):
self.target.import_lib = output + '.lib'
extra_bindings.append(('implibflag',
'/IMPLIB:%s' % self.target.import_lib))
@@ -1196,6 +1317,19 @@ class NinjaWriter:
self.target.bundle = output
return output
+ def GetToolchainEnv(self, additional_settings=None):
+ """Returns the variables toolchain would set for build steps."""
+ env = self.GetSortedXcodeEnv(additional_settings=additional_settings)
+ if self.flavor == 'win':
+ env = self.GetMsvsToolchainEnv(
+ additional_settings=additional_settings)
+ return env
+
+ def GetMsvsToolchainEnv(self, additional_settings=None):
+ """Returns the variables Visual Studio would set for build steps."""
+ return self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR',
+ config=self.config_name)
+
def GetSortedXcodeEnv(self, additional_settings=None):
"""Returns the variables Xcode would set for build steps."""
assert self.abs_build_dir
@@ -1377,7 +1511,8 @@ class NinjaWriter:
values = []
ninja_file.variable(var, ' '.join(values))
- def WriteNewNinjaRule(self, name, args, description, is_cygwin, env):
+ def WriteNewNinjaRule(self, name, args, description, is_cygwin, env, pool,
+ depfile=None):
"""Write out a new ninja "rule" statement for a given command.
Returns the name of the new rule, and a copy of |args| with variables
@@ -1435,7 +1570,8 @@ class NinjaWriter:
# GYP rules/actions express being no-ops by not touching their outputs.
# Avoid executing downstream dependencies in this case by specifying
# restat=1 to ninja.
- self.ninja.rule(rule_name, command, description, restat=True,
+ self.ninja.rule(rule_name, command, description, depfile=depfile,
+ restat=True, pool=pool,
rspfile=rspfile, rspfile_content=rspfile_content)
self.ninja.newline()
@@ -1466,12 +1602,13 @@ def CalculateVariables(default_variables, params):
generator_extra_sources_for_rules = getattr(xcode_generator,
'generator_extra_sources_for_rules', [])
elif flavor == 'win':
+ exts = gyp.MSVSUtil.TARGET_TYPE_EXT
default_variables.setdefault('OS', 'win')
- default_variables['EXECUTABLE_SUFFIX'] = '.exe'
+ default_variables['EXECUTABLE_SUFFIX'] = '.' + exts['executable']
default_variables['STATIC_LIB_PREFIX'] = ''
- default_variables['STATIC_LIB_SUFFIX'] = '.lib'
+ default_variables['STATIC_LIB_SUFFIX'] = '.' + exts['static_library']
default_variables['SHARED_LIB_PREFIX'] = ''
- default_variables['SHARED_LIB_SUFFIX'] = '.dll'
+ default_variables['SHARED_LIB_SUFFIX'] = '.' + exts['shared_library']
# Copy additional generator configuration data from VS, which is shared
# by the Windows Ninja generator.
@@ -1535,6 +1672,10 @@ def CommandWithWrapper(cmd, wrappers, prog):
def GetDefaultConcurrentLinks():
"""Returns a best-guess for a number of concurrent links."""
+ pool_size = int(os.getenv('GYP_LINK_CONCURRENCY', 0))
+ if pool_size:
+ return pool_size
+
if sys.platform in ('win32', 'cygwin'):
import ctypes
@@ -1557,19 +1698,17 @@ def GetDefaultConcurrentLinks():
mem_limit = max(1, stat.ullTotalPhys / (4 * (2 ** 30))) # total / 4GB
hard_cap = max(1, int(os.getenv('GYP_LINK_CONCURRENCY_MAX', 2**32)))
- # return min(mem_limit, hard_cap)
- # TODO(scottmg): Temporary speculative fix for OOM on builders
- # See http://crbug.com/333000.
- return 2
+ return min(mem_limit, hard_cap)
elif sys.platform.startswith('linux'):
- with open("/proc/meminfo") as meminfo:
- memtotal_re = re.compile(r'^MemTotal:\s*(\d*)\s*kB')
- for line in meminfo:
- match = memtotal_re.match(line)
- if not match:
- continue
- # Allow 8Gb per link on Linux because Gold is quite memory hungry
- return max(1, int(match.group(1)) / (8 * (2 ** 20)))
+ if os.path.exists("/proc/meminfo"):
+ with open("/proc/meminfo") as meminfo:
+ memtotal_re = re.compile(r'^MemTotal:\s*(\d*)\s*kB')
+ for line in meminfo:
+ match = memtotal_re.match(line)
+ if not match:
+ continue
+ # Allow 8Gb per link on Linux because Gold is quite memory hungry
+ return max(1, int(match.group(1)) / (8 * (2 ** 20)))
return 1
elif sys.platform == 'darwin':
try:
@@ -1666,14 +1805,15 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
# 'CC_host'/'CXX_host' enviroment variable, cc_host/cxx_host should be set
# to cc/cxx.
if flavor == 'win':
- # Overridden by local arch choice in the use_deps case.
- # Chromium's ffmpeg c99conv.py currently looks for a 'cc =' line in
- # build.ninja so needs something valid here. http://crbug.com/233985
- cc = 'cl.exe'
- cxx = 'cl.exe'
+ ar = 'lib.exe'
+ # cc and cxx must be set to the correct architecture by overriding with one
+ # of cl_x86 or cl_x64 below.
+ cc = 'UNSET'
+ cxx = 'UNSET'
ld = 'link.exe'
ld_host = '$ld'
else:
+ ar = 'ar'
cc = 'cc'
cxx = 'c++'
ld = '$cc'
@@ -1681,10 +1821,16 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
ld_host = '$cc_host'
ldxx_host = '$cxx_host'
+ ar_host = 'ar'
cc_host = None
cxx_host = None
cc_host_global_setting = None
cxx_host_global_setting = None
+ clang_cl = None
+ nm = 'nm'
+ nm_host = 'nm'
+ readelf = 'readelf'
+ readelf_host = 'readelf'
build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
make_global_settings = data[build_file].get('make_global_settings', [])
@@ -1692,8 +1838,14 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
options.toplevel_dir)
wrappers = {}
for key, value in make_global_settings:
+ if key == 'AR':
+ ar = os.path.join(build_to_root, value)
+ if key == 'AR.host':
+ ar_host = os.path.join(build_to_root, value)
if key == 'CC':
cc = os.path.join(build_to_root, value)
+ if cc.endswith('clang-cl'):
+ clang_cl = cc
if key == 'CXX':
cxx = os.path.join(build_to_root, value)
if key == 'CC.host':
@@ -1702,6 +1854,18 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
if key == 'CXX.host':
cxx_host = os.path.join(build_to_root, value)
cxx_host_global_setting = value
+ if key == 'LD':
+ ld = os.path.join(build_to_root, value)
+ if key == 'LD.host':
+ ld_host = os.path.join(build_to_root, value)
+ if key == 'NM':
+ nm = os.path.join(build_to_root, value)
+ if key == 'NM.host':
+ nm_host = os.path.join(build_to_root, value)
+ if key == 'READELF':
+ readelf = os.path.join(build_to_root, value)
+ if key == 'READELF.host':
+ readelf_host = os.path.join(build_to_root, value)
if key.endswith('_wrapper'):
wrappers[key[:-len('_wrapper')]] = os.path.join(build_to_root, value)
@@ -1713,12 +1877,25 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
wrappers[key_prefix] = os.path.join(build_to_root, value)
if flavor == 'win':
+ configs = [target_dicts[qualified_target]['configurations'][config_name]
+ for qualified_target in target_list]
+ shared_system_includes = None
+ if not generator_flags.get('ninja_use_custom_environment_files', 0):
+ shared_system_includes = \
+ gyp.msvs_emulation.ExtractSharedMSVSSystemIncludes(
+ configs, generator_flags)
cl_paths = gyp.msvs_emulation.GenerateEnvironmentFiles(
- toplevel_build, generator_flags, OpenOutput)
+ toplevel_build, generator_flags, shared_system_includes, OpenOutput)
for arch, path in cl_paths.iteritems():
- master_ninja.variable(
- 'cl_' + arch, CommandWithWrapper('CC', wrappers,
- QuoteShellArgument(path, flavor)))
+ if clang_cl:
+ # If we have selected clang-cl, use that instead.
+ path = clang_cl
+ command = CommandWithWrapper('CC', wrappers,
+ QuoteShellArgument(path, 'win'))
+ if clang_cl:
+ # Use clang-cl to cross-compile for x86 or x86_64.
+ command += (' -m32' if arch == 'x86' else ' -m64')
+ master_ninja.variable('cl_' + arch, command)
cc = GetEnvironFallback(['CC_target', 'CC'], cc)
master_ninja.variable('cc', CommandWithWrapper('CC', wrappers, cc))
@@ -1728,14 +1905,22 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
if flavor == 'win':
master_ninja.variable('ld', ld)
master_ninja.variable('idl', 'midl.exe')
- master_ninja.variable('ar', 'lib.exe')
+ master_ninja.variable('ar', ar)
master_ninja.variable('rc', 'rc.exe')
- master_ninja.variable('asm', 'ml.exe')
+ master_ninja.variable('ml_x86', 'ml.exe')
+ master_ninja.variable('ml_x64', 'ml64.exe')
master_ninja.variable('mt', 'mt.exe')
else:
master_ninja.variable('ld', CommandWithWrapper('LINK', wrappers, ld))
master_ninja.variable('ldxx', CommandWithWrapper('LINK', wrappers, ldxx))
- master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], 'ar'))
+ master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], ar))
+ if flavor != 'mac':
+ # Mac does not use readelf/nm for .TOC generation, so avoiding polluting
+ # the master ninja with extra unused variables.
+ master_ninja.variable(
+ 'nm', GetEnvironFallback(['NM_target', 'NM'], nm))
+ master_ninja.variable(
+ 'readelf', GetEnvironFallback(['READELF_target', 'READELF'], readelf))
if generator_supports_multiple_toolsets:
if not cc_host:
@@ -1743,7 +1928,10 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
if not cxx_host:
cxx_host = cxx
- master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], 'ar'))
+ master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], ar_host))
+ master_ninja.variable('nm_host', GetEnvironFallback(['NM_host'], nm_host))
+ master_ninja.variable('readelf_host',
+ GetEnvironFallback(['READELF_host'], readelf_host))
cc_host = GetEnvironFallback(['CC_host'], cc_host)
cxx_host = GetEnvironFallback(['CXX_host'], cxx_host)
@@ -1826,7 +2014,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
description='IDL $in',
command=('%s gyp-win-tool midl-wrapper $arch $outdir '
'$tlb $h $dlldata $iid $proxy $in '
- '$idlflags' % sys.executable))
+ '$midl_includes $idlflags' % sys.executable))
master_ninja.rule(
'rc',
description='RC $in',
@@ -1836,20 +2024,20 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
sys.executable))
master_ninja.rule(
'asm',
- description='ASM $in',
+ description='ASM $out',
command=('%s gyp-win-tool asm-wrapper '
- '$arch $asm $defines $includes /c /Fo $out $in' %
+ '$arch $asm $defines $includes $asmflags /c /Fo $out $in' %
sys.executable))
if flavor != 'mac' and flavor != 'win':
master_ninja.rule(
'alink',
description='AR $out',
- command='rm -f $out && $ar rcs $out $in')
+ command='rm -f $out && $ar rcs $arflags $out $in')
master_ninja.rule(
'alink_thin',
description='AR $out',
- command='rm -f $out && $ar rcsT $out $in')
+ command='rm -f $out && $ar rcsT $arflags $out $in')
# This allows targets that only need to depend on $lib's API to declare an
# order-only dependency on $lib.TOC and avoid relinking such downstream
@@ -1857,38 +2045,39 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
# The resulting string leaves an uninterpolated %{suffix} which
# is used in the final substitution below.
mtime_preserving_solink_base = (
- 'if [ ! -e $lib -o ! -e ${lib}.TOC ]; then '
- '%(solink)s && %(extract_toc)s > ${lib}.TOC; else '
- '%(solink)s && %(extract_toc)s > ${lib}.tmp && '
- 'if ! cmp -s ${lib}.tmp ${lib}.TOC; then mv ${lib}.tmp ${lib}.TOC ; '
+ 'if [ ! -e $lib -o ! -e $lib.TOC ]; then '
+ '%(solink)s && %(extract_toc)s > $lib.TOC; else '
+ '%(solink)s && %(extract_toc)s > $lib.tmp && '
+ 'if ! cmp -s $lib.tmp $lib.TOC; then mv $lib.tmp $lib.TOC ; '
'fi; fi'
% { 'solink':
'$ld -shared $ldflags -o $lib -Wl,-soname=$soname %(suffix)s',
'extract_toc':
- ('{ readelf -d ${lib} | grep SONAME ; '
- 'nm -gD -f p ${lib} | cut -f1-2 -d\' \'; }')})
+ ('{ $readelf -d $lib | grep SONAME ; '
+ '$nm -gD -f p $lib | cut -f1-2 -d\' \'; }')})
master_ninja.rule(
'solink',
description='SOLINK $lib',
restat=True,
- command=(mtime_preserving_solink_base % {
- 'suffix': '-Wl,--whole-archive $in $solibs -Wl,--no-whole-archive '
- '$libs'}),
+ command=mtime_preserving_solink_base % {'suffix': '@$link_file_list'},
+ rspfile='$link_file_list',
+ rspfile_content=
+ '-Wl,--whole-archive $in $solibs -Wl,--no-whole-archive $libs',
pool='link_pool')
master_ninja.rule(
'solink_module',
description='SOLINK(module) $lib',
restat=True,
- command=(mtime_preserving_solink_base % {
- 'suffix': '-Wl,--start-group $in $solibs -Wl,--end-group '
- '$libs'}),
+ command=mtime_preserving_solink_base % {'suffix': '@$link_file_list'},
+ rspfile='$link_file_list',
+ rspfile_content='-Wl,--start-group $in -Wl,--end-group $solibs $libs',
pool='link_pool')
master_ninja.rule(
'link',
description='LINK $out',
command=('$ld $ldflags -o $out '
- '-Wl,--start-group $in $solibs -Wl,--end-group $libs'),
+ '-Wl,--start-group $in -Wl,--end-group $solibs $libs'),
pool='link_pool')
elif flavor == 'win':
master_ninja.rule(
@@ -1927,21 +2116,31 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
'lipo',
description='LIPO $out, POSTBUILDS',
command='rm -f $out && lipo -create $in -output $out$postbuilds')
+ master_ninja.rule(
+ 'solipo',
+ description='SOLIPO $out, POSTBUILDS',
+ command=(
+ 'rm -f $lib $lib.TOC && lipo -create $in -output $lib$postbuilds &&'
+ '%(extract_toc)s > $lib.TOC'
+ % { 'extract_toc':
+ '{ otool -l $lib | grep LC_ID_DYLIB -A 5; '
+ 'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'}))
+
# Record the public interface of $lib in $lib.TOC. See the corresponding
# comment in the posix section above for details.
solink_base = '$ld %(type)s $ldflags -o $lib %(suffix)s'
mtime_preserving_solink_base = (
- 'if [ ! -e $lib -o ! -e ${lib}.TOC ] || '
+ 'if [ ! -e $lib -o ! -e $lib.TOC ] || '
# Always force dependent targets to relink if this library
# reexports something. Handling this correctly would require
# recursive TOC dumping but this is rare in practice, so punt.
'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then '
- '%(solink)s && %(extract_toc)s > ${lib}.TOC; '
+ '%(solink)s && %(extract_toc)s > $lib.TOC; '
'else '
- '%(solink)s && %(extract_toc)s > ${lib}.tmp && '
- 'if ! cmp -s ${lib}.tmp ${lib}.TOC; then '
- 'mv ${lib}.tmp ${lib}.TOC ; '
+ '%(solink)s && %(extract_toc)s > $lib.tmp && '
+ 'if ! cmp -s $lib.tmp $lib.TOC; then '
+ 'mv $lib.tmp $lib.TOC ; '
'fi; '
'fi'
% { 'solink': solink_base,
@@ -1949,34 +2148,42 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
'{ otool -l $lib | grep LC_ID_DYLIB -A 5; '
'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'})
- solink_suffix = '$in $solibs $libs$postbuilds'
+
+ solink_suffix = '@$link_file_list$postbuilds'
master_ninja.rule(
'solink',
description='SOLINK $lib, POSTBUILDS',
restat=True,
command=mtime_preserving_solink_base % {'suffix': solink_suffix,
'type': '-shared'},
+ rspfile='$link_file_list',
+ rspfile_content='$in $solibs $libs',
pool='link_pool')
master_ninja.rule(
'solink_notoc',
description='SOLINK $lib, POSTBUILDS',
restat=True,
command=solink_base % {'suffix':solink_suffix, 'type': '-shared'},
+ rspfile='$link_file_list',
+ rspfile_content='$in $solibs $libs',
pool='link_pool')
- solink_module_suffix = '$in $solibs $libs$postbuilds'
master_ninja.rule(
'solink_module',
description='SOLINK(module) $lib, POSTBUILDS',
restat=True,
- command=mtime_preserving_solink_base % {'suffix': solink_module_suffix,
+ command=mtime_preserving_solink_base % {'suffix': solink_suffix,
'type': '-bundle'},
+ rspfile='$link_file_list',
+ rspfile_content='$in $solibs $libs',
pool='link_pool')
master_ninja.rule(
'solink_module_notoc',
description='SOLINK(module) $lib, POSTBUILDS',
restat=True,
- command=solink_base % {'suffix': solink_module_suffix, 'type': '-bundle'},
+ command=solink_base % {'suffix': solink_suffix, 'type': '-bundle'},
+ rspfile='$link_file_list',
+ rspfile_content='$in $solibs $libs',
pool='link_pool')
master_ninja.rule(
@@ -1993,11 +2200,19 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
master_ninja.rule(
'copy_infoplist',
description='COPY INFOPLIST $in',
- command='$env ./gyp-mac-tool copy-info-plist $in $out $keys')
+ command='$env ./gyp-mac-tool copy-info-plist $in $out $binary $keys')
+ master_ninja.rule(
+ 'merge_infoplist',
+ description='MERGE INFOPLISTS $in',
+ command='$env ./gyp-mac-tool merge-info-plist $out $in')
+ master_ninja.rule(
+ 'compile_xcassets',
+ description='COMPILE XCASSETS $in',
+ command='$env ./gyp-mac-tool compile-xcassets $keys $in')
master_ninja.rule(
'mac_tool',
description='MACTOOL $mactool_cmd $in',
- command='$env ./gyp-mac-tool $mactool_cmd $in $out')
+ command='$env ./gyp-mac-tool $mactool_cmd $in $out $binary')
master_ninja.rule(
'package_framework',
description='PACKAGE FRAMEWORK $out, POSTBUILDS',
@@ -2037,6 +2252,15 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
# objects.
target_short_names = {}
+ # short name of targets that were skipped because they didn't contain anything
+ # interesting.
+ # NOTE: there may be overlap between this an non_empty_target_names.
+ empty_target_names = set()
+
+ # Set of non-empty short target names.
+ # NOTE: there may be overlap between this an empty_target_names.
+ non_empty_target_names = set()
+
for qualified_target in target_list:
# qualified_target is like: third_party/icu/icu.gyp:icui18n#target
build_file, name, toolset = \
@@ -2053,6 +2277,10 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
build_file = gyp.common.RelativePath(build_file, options.toplevel_dir)
+ qualified_target_for_hash = gyp.common.QualifiedTarget(build_file, name,
+ toolset)
+ hash_for_rules = hashlib.md5(qualified_target_for_hash).hexdigest()
+
base_path = os.path.dirname(build_file)
obj = 'obj'
if toolset != 'target':
@@ -2060,7 +2288,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
output_file = os.path.join(obj, base_path, name + '.ninja')
ninja_output = StringIO()
- writer = NinjaWriter(qualified_target, target_outputs, base_path, build_dir,
+ writer = NinjaWriter(hash_for_rules, target_outputs, base_path, build_dir,
ninja_output,
toplevel_build, output_file,
flavor, toplevel_dir=options.toplevel_dir)
@@ -2080,6 +2308,9 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
target_outputs[qualified_target] = target
if qualified_target in all_targets:
all_outputs.add(target.FinalOutput())
+ non_empty_target_names.add(name)
+ else:
+ empty_target_names.add(name)
if target_short_names:
# Write a short name to build this target. This benefits both the
@@ -2091,6 +2322,16 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
master_ninja.build(short_name, 'phony', [x.FinalOutput() for x in
target_short_names[short_name]])
+ # Write phony targets for any empty targets that weren't written yet. As
+ # short names are not necessarily unique only do this for short names that
+ # haven't already been output for another target.
+ empty_target_names = empty_target_names - non_empty_target_names
+ if empty_target_names:
+ master_ninja.newline()
+ master_ninja.comment('Empty targets (output for completeness).')
+ for name in sorted(empty_target_names):
+ master_ninja.build(name, 'phony')
+
if all_outputs:
master_ninja.newline()
master_ninja.build('all', 'phony', list(all_outputs))
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py
index 52661bcdf..1767b2f45 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py
@@ -15,15 +15,18 @@ import TestCommon
class TestPrefixesAndSuffixes(unittest.TestCase):
def test_BinaryNamesWindows(self):
- writer = ninja.NinjaWriter('foo', 'wee', '.', '.', 'build.ninja', '.',
- 'build.ninja', 'win')
- spec = { 'target_name': 'wee' }
- self.assertTrue(writer.ComputeOutputFileName(spec, 'executable').
- endswith('.exe'))
- self.assertTrue(writer.ComputeOutputFileName(spec, 'shared_library').
- endswith('.dll'))
- self.assertTrue(writer.ComputeOutputFileName(spec, 'static_library').
- endswith('.lib'))
+ # These cannot run on non-Windows as they require a VS installation to
+ # correctly handle variable expansion.
+ if sys.platform.startswith('win'):
+ writer = ninja.NinjaWriter('foo', 'wee', '.', '.', 'build.ninja', '.',
+ 'build.ninja', 'win')
+ spec = { 'target_name': 'wee' }
+ self.assertTrue(writer.ComputeOutputFileName(spec, 'executable').
+ endswith('.exe'))
+ self.assertTrue(writer.ComputeOutputFileName(spec, 'shared_library').
+ endswith('.dll'))
+ self.assertTrue(writer.ComputeOutputFileName(spec, 'static_library').
+ endswith('.lib'))
def test_BinaryNamesLinux(self):
writer = ninja.NinjaWriter('foo', 'wee', '.', '.', 'build.ninja', '.',
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py
index 331e78baa..482b53ac8 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py
@@ -5,6 +5,7 @@
import filecmp
import gyp.common
import gyp.xcodeproj_file
+import gyp.xcode_ninja
import errno
import os
import sys
@@ -68,6 +69,9 @@ generator_additional_path_sections = [
# The Xcode-specific keys that exist on targets and aren't moved down to
# configurations.
generator_additional_non_configuration_keys = [
+ 'ios_app_extension',
+ 'ios_watch_app',
+ 'ios_watchkit_extension',
'mac_bundle',
'mac_bundle_resources',
'mac_framework_headers',
@@ -484,7 +488,7 @@ sys.exit(subprocess.call(sys.argv[1:]))" """
def AddSourceToTarget(source, type, pbxp, xct):
# TODO(mark): Perhaps source_extensions and library_extensions can be made a
# little bit fancier.
- source_extensions = ['c', 'cc', 'cpp', 'cxx', 'm', 'mm', 's']
+ source_extensions = ['c', 'cc', 'cpp', 'cxx', 'm', 'mm', 's', 'swift']
# .o is conceptually more of a "source" than a "library," but Xcode thinks
# of "sources" as things to compile and "libraries" (or "frameworks") as
@@ -520,7 +524,7 @@ def AddHeaderToTarget(header, pbxp, xct, is_public):
xct.HeadersPhase().AddFile(header, settings)
-_xcode_variable_re = re.compile('(\$\((.*?)\))')
+_xcode_variable_re = re.compile(r'(\$\((.*?)\))')
def ExpandXcodeVariables(string, expansions):
"""Expands Xcode-style $(VARIABLES) in string per the expansions dict.
@@ -575,12 +579,17 @@ def PerformBuild(data, configurations, params):
def GenerateOutput(target_list, target_dicts, data, params):
+ # Optionally configure each spec to use ninja as the external builder.
+ ninja_wrapper = params.get('flavor') == 'ninja'
+ if ninja_wrapper:
+ (target_list, target_dicts, data) = \
+ gyp.xcode_ninja.CreateWrapper(target_list, target_dicts, data, params)
+
options = params['options']
generator_flags = params.get('generator_flags', {})
parallel_builds = generator_flags.get('xcode_parallel_builds', True)
serialize_all_tests = \
generator_flags.get('xcode_serialize_all_test_runs', True)
- project_version = generator_flags.get('xcode_project_version', None)
skip_excluded_files = \
not generator_flags.get('xcode_list_excluded_files', True)
xcode_projects = {}
@@ -598,8 +607,6 @@ def GenerateOutput(target_list, target_dicts, data, params):
if parallel_builds:
pbxp.SetProperty('attributes',
{'BuildIndependentTargetsInParallel': 'YES'})
- if project_version:
- xcp.project_file.SetXcodeVersion(project_version)
# Add gyp/gypi files to project
if not generator_flags.get('standalone'):
@@ -637,14 +644,18 @@ def GenerateOutput(target_list, target_dicts, data, params):
# com.googlecode.gyp.xcode.bundle, a pseudo-type that xcode.py interprets
# to create a single-file mh_bundle.
_types = {
- 'executable': 'com.apple.product-type.tool',
- 'loadable_module': 'com.googlecode.gyp.xcode.bundle',
- 'shared_library': 'com.apple.product-type.library.dynamic',
- 'static_library': 'com.apple.product-type.library.static',
- 'executable+bundle': 'com.apple.product-type.application',
- 'loadable_module+bundle': 'com.apple.product-type.bundle',
- 'loadable_module+xctest': 'com.apple.product-type.bundle.unit-test',
- 'shared_library+bundle': 'com.apple.product-type.framework',
+ 'executable': 'com.apple.product-type.tool',
+ 'loadable_module': 'com.googlecode.gyp.xcode.bundle',
+ 'shared_library': 'com.apple.product-type.library.dynamic',
+ 'static_library': 'com.apple.product-type.library.static',
+ 'executable+bundle': 'com.apple.product-type.application',
+ 'loadable_module+bundle': 'com.apple.product-type.bundle',
+ 'loadable_module+xctest': 'com.apple.product-type.bundle.unit-test',
+ 'shared_library+bundle': 'com.apple.product-type.framework',
+ 'executable+extension+bundle': 'com.apple.product-type.app-extension',
+ 'executable+watch+extension+bundle':
+ 'com.apple.product-type.watchkit-extension',
+ 'executable+watch+bundle': 'com.apple.product-type.application.watchapp',
}
target_properties = {
@@ -655,6 +666,9 @@ def GenerateOutput(target_list, target_dicts, data, params):
type = spec['type']
is_xctest = int(spec.get('mac_xctest_bundle', 0))
is_bundle = int(spec.get('mac_bundle', 0)) or is_xctest
+ is_app_extension = int(spec.get('ios_app_extension', 0))
+ is_watchkit_extension = int(spec.get('ios_watchkit_extension', 0))
+ is_watch_app = int(spec.get('ios_watch_app', 0))
if type != 'none':
type_bundle_key = type
if is_xctest:
@@ -662,6 +676,18 @@ def GenerateOutput(target_list, target_dicts, data, params):
assert type == 'loadable_module', (
'mac_xctest_bundle targets must have type loadable_module '
'(target %s)' % target_name)
+ elif is_app_extension:
+ assert is_bundle, ('ios_app_extension flag requires mac_bundle '
+ '(target %s)' % target_name)
+ type_bundle_key += '+extension+bundle'
+ elif is_watchkit_extension:
+ assert is_bundle, ('ios_watchkit_extension flag requires mac_bundle '
+ '(target %s)' % target_name)
+ type_bundle_key += '+watch+extension+bundle'
+ elif is_watch_app:
+ assert is_bundle, ('ios_watch_app flag requires mac_bundle '
+ '(target %s)' % target_name)
+ type_bundle_key += '+watch+bundle'
elif is_bundle:
type_bundle_key += '+bundle'
@@ -703,11 +729,16 @@ def GenerateOutput(target_list, target_dicts, data, params):
# and is made a dependency of this target. This way the work is done
# before the dependency checks for what should be recompiled.
support_xct = None
- if type != 'none' and (spec_actions or spec_rules):
+ # The Xcode "issues" don't affect xcode-ninja builds, since the dependency
+ # logic all happens in ninja. Don't bother creating the extra targets in
+ # that case.
+ if type != 'none' and (spec_actions or spec_rules) and not ninja_wrapper:
support_xccl = CreateXCConfigurationList(configuration_names);
+ support_target_suffix = generator_flags.get(
+ 'support_target_suffix', ' Support')
support_target_properties = {
'buildConfigurationList': support_xccl,
- 'name': target_name + ' Support',
+ 'name': target_name + support_target_suffix,
}
if target_product_name:
support_target_properties['productName'] = \
@@ -1096,6 +1127,9 @@ exit 1
# Relative paths are relative to $(SRCROOT).
dest = '$(SRCROOT)/' + dest
+ code_sign = int(copy_group.get('xcode_code_sign', 0))
+ settings = (None, '{ATTRIBUTES = (CodeSignOnCopy, ); }')[code_sign];
+
# Coalesce multiple "copies" sections in the same target with the same
# "destination" property into the same PBXCopyFilesBuildPhase, otherwise
# they'll wind up with ID collisions.
@@ -1114,7 +1148,7 @@ exit 1
pbxcp_dict[dest] = pbxcp
for file in copy_group['files']:
- pbxcp.AddFile(file)
+ pbxcp.AddFile(file, settings)
# Excluded files can also go into the project file.
if not skip_excluded_files:
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/input.py b/node_modules/node-gyp/gyp/pylib/gyp/input.py
index 6472912db..34fbc5471 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/input.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/input.py
@@ -10,8 +10,8 @@ from compiler.ast import Module
from compiler.ast import Node
from compiler.ast import Stmt
import compiler
-import copy
import gyp.common
+import gyp.simple_copy
import multiprocessing
import optparse
import os.path
@@ -24,6 +24,7 @@ import threading
import time
import traceback
from gyp.common import GypError
+from gyp.common import OrderedSet
# A list of types that are treated as linkable.
@@ -45,18 +46,36 @@ base_path_sections = [
'outputs',
'sources',
]
-path_sections = []
+path_sections = set()
-is_path_section_charset = set('=+?!')
-is_path_section_match_re = re.compile('_(dir|file|path)s?$')
+# These per-process dictionaries are used to cache build file data when loading
+# in parallel mode.
+per_process_data = {}
+per_process_aux_data = {}
def IsPathSection(section):
- # If section ends in one of these characters, it's applied to a section
+ # If section ends in one of the '=+?!' characters, it's applied to a section
# without the trailing characters. '/' is notably absent from this list,
# because there's no way for a regular expression to be treated as a path.
- while section[-1:] in is_path_section_charset:
+ while section[-1:] in '=+?!':
section = section[:-1]
- return section in path_sections or is_path_section_match_re.search(section)
+
+ if section in path_sections:
+ return True
+
+ # Sections mathing the regexp '_(dir|file|path)s?$' are also
+ # considered PathSections. Using manual string matching since that
+ # is much faster than the regexp and this can be called hundreds of
+ # thousands of times so micro performance matters.
+ if "_" in section:
+ tail = section[-6:]
+ if tail[-1] == 's':
+ tail = tail[:-1]
+ if tail[-5:] in ('_file', '_path'):
+ return True
+ return tail[-4:] == '_dir'
+
+ return False
# base_non_configuration_keys is a list of key names that belong in the target
# itself and should not be propagated into its configurations. It is merged
@@ -196,11 +215,11 @@ def CheckNode(node, keypath):
elif isinstance(node, Const):
return node.getChildren()[0]
else:
- raise TypeError, "Unknown AST node at key path '" + '.'.join(keypath) + \
- "': " + repr(node)
+ raise TypeError("Unknown AST node at key path '" + '.'.join(keypath) +
+ "': " + repr(node))
-def LoadOneBuildFile(build_file_path, data, aux_data, variables, includes,
+def LoadOneBuildFile(build_file_path, data, aux_data, includes,
is_target, check):
if build_file_path in data:
return data[build_file_path]
@@ -224,7 +243,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, variables, includes,
gyp.common.ExceptionAppend(e, 'while reading ' + build_file_path)
raise
- if not isinstance(build_file_data, dict):
+ if type(build_file_data) is not dict:
raise GypError("%s does not evaluate to a dictionary." % build_file_path)
data[build_file_path] = build_file_data
@@ -236,10 +255,10 @@ def LoadOneBuildFile(build_file_path, data, aux_data, variables, includes,
try:
if is_target:
LoadBuildFileIncludesIntoDict(build_file_data, build_file_path, data,
- aux_data, variables, includes, check)
+ aux_data, includes, check)
else:
LoadBuildFileIncludesIntoDict(build_file_data, build_file_path, data,
- aux_data, variables, None, check)
+ aux_data, None, check)
except Exception, e:
gyp.common.ExceptionAppend(e,
'while reading includes of ' + build_file_path)
@@ -249,7 +268,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, variables, includes,
def LoadBuildFileIncludesIntoDict(subdict, subdict_path, data, aux_data,
- variables, includes, check):
+ includes, check):
includes_list = []
if includes != None:
includes_list.extend(includes)
@@ -273,30 +292,27 @@ def LoadBuildFileIncludesIntoDict(subdict, subdict_path, data, aux_data,
gyp.DebugOutput(gyp.DEBUG_INCLUDES, "Loading Included File: '%s'", include)
MergeDicts(subdict,
- LoadOneBuildFile(include, data, aux_data, variables, None,
- False, check),
+ LoadOneBuildFile(include, data, aux_data, None, False, check),
subdict_path, include)
# Recurse into subdictionaries.
for k, v in subdict.iteritems():
- if v.__class__ == dict:
- LoadBuildFileIncludesIntoDict(v, subdict_path, data, aux_data, variables,
+ if type(v) is dict:
+ LoadBuildFileIncludesIntoDict(v, subdict_path, data, aux_data,
None, check)
- elif v.__class__ == list:
- LoadBuildFileIncludesIntoList(v, subdict_path, data, aux_data, variables,
+ elif type(v) is list:
+ LoadBuildFileIncludesIntoList(v, subdict_path, data, aux_data,
check)
# This recurses into lists so that it can look for dicts.
-def LoadBuildFileIncludesIntoList(sublist, sublist_path, data, aux_data,
- variables, check):
+def LoadBuildFileIncludesIntoList(sublist, sublist_path, data, aux_data, check):
for item in sublist:
- if item.__class__ == dict:
+ if type(item) is dict:
LoadBuildFileIncludesIntoDict(item, sublist_path, data, aux_data,
- variables, None, check)
- elif item.__class__ == list:
- LoadBuildFileIncludesIntoList(item, sublist_path, data, aux_data,
- variables, check)
+ None, check)
+ elif type(item) is list:
+ LoadBuildFileIncludesIntoList(item, sublist_path, data, aux_data, check)
# Processes toolsets in all the targets. This recurses into condition entries
# since they can contain toolsets as well.
@@ -320,7 +336,7 @@ def ProcessToolsetsInDict(data):
if len(toolsets) > 0:
# Optimization: only do copies if more than one toolset is specified.
for build in toolsets[1:]:
- new_target = copy.deepcopy(target)
+ new_target = gyp.simple_copy.deepcopy(target)
new_target['toolset'] = build
new_target_list.append(new_target)
target['toolset'] = toolsets[0]
@@ -328,9 +344,10 @@ def ProcessToolsetsInDict(data):
data['targets'] = new_target_list
if 'conditions' in data:
for condition in data['conditions']:
- if isinstance(condition, list):
+ if type(condition) is list:
for condition_dict in condition[1:]:
- ProcessToolsetsInDict(condition_dict)
+ if type(condition_dict) is dict:
+ ProcessToolsetsInDict(condition_dict)
# TODO(mark): I don't love this name. It just means that it's going to load
@@ -350,15 +367,22 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
else:
variables['DEPTH'] = d.replace('\\', '/')
- if build_file_path in data['target_build_files']:
- # Already loaded.
- return False
- data['target_build_files'].add(build_file_path)
+ # The 'target_build_files' key is only set when loading target build files in
+ # the non-parallel code path, where LoadTargetBuildFile is called
+ # recursively. In the parallel code path, we don't need to check whether the
+ # |build_file_path| has already been loaded, because the 'scheduled' set in
+ # ParallelState guarantees that we never load the same |build_file_path|
+ # twice.
+ if 'target_build_files' in data:
+ if build_file_path in data['target_build_files']:
+ # Already loaded.
+ return False
+ data['target_build_files'].add(build_file_path)
gyp.DebugOutput(gyp.DEBUG_INCLUDES,
"Loading Target Build File '%s'", build_file_path)
- build_file_data = LoadOneBuildFile(build_file_path, data, aux_data, variables,
+ build_file_data = LoadOneBuildFile(build_file_path, data, aux_data,
includes, True, check)
# Store DEPTH for later use in generators.
@@ -408,7 +432,8 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
# copy with the target-specific data merged into it as the replacement
# target dict.
old_target_dict = build_file_data['targets'][index]
- new_target_dict = copy.deepcopy(build_file_data['target_defaults'])
+ new_target_dict = gyp.simple_copy.deepcopy(
+ build_file_data['target_defaults'])
MergeDicts(new_target_dict, old_target_dict,
build_file_path, build_file_path)
build_file_data['targets'][index] = new_target_dict
@@ -443,10 +468,8 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
else:
return (build_file_path, dependencies)
-
def CallLoadTargetBuildFile(global_flags,
- build_file_path, data,
- aux_data, variables,
+ build_file_path, variables,
includes, depth, check,
generator_input_info):
"""Wrapper around LoadTargetBuildFile for parallel processing.
@@ -462,35 +485,24 @@ def CallLoadTargetBuildFile(global_flags,
for key, value in global_flags.iteritems():
globals()[key] = value
- # Save the keys so we can return data that changed.
- data_keys = set(data)
- aux_data_keys = set(aux_data)
-
SetGeneratorGlobals(generator_input_info)
- result = LoadTargetBuildFile(build_file_path, data,
- aux_data, variables,
+ result = LoadTargetBuildFile(build_file_path, per_process_data,
+ per_process_aux_data, variables,
includes, depth, check, False)
if not result:
return result
(build_file_path, dependencies) = result
- data_out = {}
- for key in data:
- if key == 'target_build_files':
- continue
- if key not in data_keys:
- data_out[key] = data[key]
- aux_data_out = {}
- for key in aux_data:
- if key not in aux_data_keys:
- aux_data_out[key] = aux_data[key]
+ # We can safely pop the build_file_data from per_process_data because it
+ # will never be referenced by this process again, so we don't need to keep
+ # it in the cache.
+ build_file_data = per_process_data.pop(build_file_path)
# This gets serialized and sent back to the main process via a pipe.
# It's handled in LoadTargetBuildFileCallback.
return (build_file_path,
- data_out,
- aux_data_out,
+ build_file_data,
dependencies)
except GypError, e:
sys.stderr.write("gyp: %s\n" % e)
@@ -521,8 +533,6 @@ class ParallelState(object):
self.condition = None
# The "data" dict that was passed to LoadTargetBuildFileParallel
self.data = None
- # The "aux_data" dict that was passed to LoadTargetBuildFileParallel
- self.aux_data = None
# The number of parallel calls outstanding; decremented when a response
# was received.
self.pending = 0
@@ -543,12 +553,9 @@ class ParallelState(object):
self.condition.notify()
self.condition.release()
return
- (build_file_path0, data0, aux_data0, dependencies0) = result
+ (build_file_path0, build_file_data0, dependencies0) = result
+ self.data[build_file_path0] = build_file_data0
self.data['target_build_files'].add(build_file_path0)
- for key in data0:
- self.data[key] = data0[key]
- for key in aux_data0:
- self.aux_data[key] = aux_data0[key]
for new_dependency in dependencies0:
if new_dependency not in self.scheduled:
self.scheduled.add(new_dependency)
@@ -558,9 +565,8 @@ class ParallelState(object):
self.condition.release()
-def LoadTargetBuildFilesParallel(build_files, data, aux_data,
- variables, includes, depth, check,
- generator_input_info):
+def LoadTargetBuildFilesParallel(build_files, data, variables, includes, depth,
+ check, generator_input_info):
parallel_state = ParallelState()
parallel_state.condition = threading.Condition()
# Make copies of the build_files argument that we can modify while working.
@@ -568,7 +574,6 @@ def LoadTargetBuildFilesParallel(build_files, data, aux_data,
parallel_state.scheduled = set(build_files)
parallel_state.pending = 0
parallel_state.data = data
- parallel_state.aux_data = aux_data
try:
parallel_state.condition.acquire()
@@ -582,20 +587,16 @@ def LoadTargetBuildFilesParallel(build_files, data, aux_data,
dependency = parallel_state.dependencies.pop()
parallel_state.pending += 1
- data_in = {}
- data_in['target_build_files'] = data['target_build_files']
- aux_data_in = {}
global_flags = {
'path_sections': globals()['path_sections'],
'non_configuration_keys': globals()['non_configuration_keys'],
'multiple_toolsets': globals()['multiple_toolsets']}
if not parallel_state.pool:
- parallel_state.pool = multiprocessing.Pool(8)
+ parallel_state.pool = multiprocessing.Pool(multiprocessing.cpu_count())
parallel_state.pool.apply_async(
CallLoadTargetBuildFile,
args = (global_flags, dependency,
- data_in, aux_data_in,
variables, includes, depth, check, generator_input_info),
callback = parallel_state.LoadTargetBuildFileCallback)
except KeyboardInterrupt, e:
@@ -636,39 +637,50 @@ def FindEnclosingBracketGroup(input_str):
return (-1, -1)
-canonical_int_re = re.compile('(0|-?[1-9][0-9]*)$')
-
-
def IsStrCanonicalInt(string):
"""Returns True if |string| is in its canonical integer form.
The canonical form is such that str(int(string)) == string.
"""
- return isinstance(string, str) and canonical_int_re.match(string)
+ if type(string) is str:
+ # This function is called a lot so for maximum performance, avoid
+ # involving regexps which would otherwise make the code much
+ # shorter. Regexps would need twice the time of this function.
+ if string:
+ if string == "0":
+ return True
+ if string[0] == "-":
+ string = string[1:]
+ if not string:
+ return False
+ if '1' <= string[0] <= '9':
+ return string.isdigit()
+
+ return False
# This matches things like "<(asdf)", "<!(cmd)", "<!@(cmd)", "<|(list)",
# "<!interpreter(arguments)", "<([list])", and even "<([)" and "<(<())".
# In the last case, the inner "<()" is captured in match['content'].
early_variable_re = re.compile(
- '(?P<replace>(?P<type><(?:(?:!?@?)|\|)?)'
- '(?P<command_string>[-a-zA-Z0-9_.]+)?'
- '\((?P<is_array>\s*\[?)'
- '(?P<content>.*?)(\]?)\))')
+ r'(?P<replace>(?P<type><(?:(?:!?@?)|\|)?)'
+ r'(?P<command_string>[-a-zA-Z0-9_.]+)?'
+ r'\((?P<is_array>\s*\[?)'
+ r'(?P<content>.*?)(\]?)\))')
# This matches the same as early_variable_re, but with '>' instead of '<'.
late_variable_re = re.compile(
- '(?P<replace>(?P<type>>(?:(?:!?@?)|\|)?)'
- '(?P<command_string>[-a-zA-Z0-9_.]+)?'
- '\((?P<is_array>\s*\[?)'
- '(?P<content>.*?)(\]?)\))')
+ r'(?P<replace>(?P<type>>(?:(?:!?@?)|\|)?)'
+ r'(?P<command_string>[-a-zA-Z0-9_.]+)?'
+ r'\((?P<is_array>\s*\[?)'
+ r'(?P<content>.*?)(\]?)\))')
# This matches the same as early_variable_re, but with '^' instead of '<'.
latelate_variable_re = re.compile(
- '(?P<replace>(?P<type>[\^](?:(?:!?@?)|\|)?)'
- '(?P<command_string>[-a-zA-Z0-9_.]+)?'
- '\((?P<is_array>\s*\[?)'
- '(?P<content>.*?)(\]?)\))')
+ r'(?P<replace>(?P<type>[\^](?:(?:!?@?)|\|)?)'
+ r'(?P<command_string>[-a-zA-Z0-9_.]+)?'
+ r'\((?P<is_array>\s*\[?)'
+ r'(?P<content>.*?)(\]?)\))')
# Global cache of results from running commands so they don't have to be run
# more then once.
@@ -677,7 +689,7 @@ cached_command_results = {}
def FixupPlatformCommand(cmd):
if sys.platform == 'win32':
- if type(cmd) == list:
+ if type(cmd) is list:
cmd = [re.sub('^cat ', 'type ', cmd[0])] + cmd[1:]
else:
cmd = re.sub('^cat ', 'type ', cmd)
@@ -767,7 +779,7 @@ def ExpandVariables(input, phase, variables, build_file):
# contexts. However, since filtration has no chance to run on <|(),
# this seems like the only obvious way to give them access to filters.
if file_list:
- processed_variables = copy.deepcopy(variables)
+ processed_variables = gyp.simple_copy.deepcopy(variables)
ProcessListFiltersInDict(contents, processed_variables)
# Recurse to expand variables in the contents
contents = ExpandVariables(contents, phase,
@@ -804,7 +816,7 @@ def ExpandVariables(input, phase, variables, build_file):
# This works around actions/rules which have more inputs than will
# fit on the command line.
if file_list:
- if type(contents) == list:
+ if type(contents) is list:
contents_list = contents
else:
contents_list = contents.split(' ')
@@ -837,17 +849,15 @@ def ExpandVariables(input, phase, variables, build_file):
use_shell = False
# Check for a cached value to avoid executing commands, or generating
- # file lists more than once.
- # TODO(http://code.google.com/p/gyp/issues/detail?id=112): It is
- # possible that the command being invoked depends on the current
- # directory. For that case the syntax needs to be extended so that the
- # directory is also used in cache_key (it becomes a tuple).
+ # file lists more than once. The cache key contains the command to be
+ # run as well as the directory to run it from, to account for commands
+ # that depend on their current directory.
# TODO(http://code.google.com/p/gyp/issues/detail?id=111): In theory,
# someone could author a set of GYP files where each time the command
# is invoked it produces different output by design. When the need
# arises, the syntax should be extended to support no caching off a
# command's output so it is run every time.
- cache_key = str(contents)
+ cache_key = (str(contents), build_file_dir)
cached_value = cached_command_results.get(cache_key, None)
if cached_value is None:
gyp.DebugOutput(gyp.DEBUG_VARIABLES,
@@ -925,10 +935,9 @@ def ExpandVariables(input, phase, variables, build_file):
else:
replacement = variables[contents]
- if isinstance(replacement, list):
+ if type(replacement) is list:
for item in replacement:
- if (not contents[-1] == '/' and
- not isinstance(item, str) and not isinstance(item, int)):
+ if not contents[-1] == '/' and type(item) not in (str, int):
raise GypError('Variable ' + contents +
' must expand to a string or list of strings; ' +
'list contains a ' +
@@ -938,8 +947,7 @@ def ExpandVariables(input, phase, variables, build_file):
# with conditions sections.
ProcessVariablesAndConditionsInList(replacement, phase, variables,
build_file)
- elif not isinstance(replacement, str) and \
- not isinstance(replacement, int):
+ elif type(replacement) not in (str, int):
raise GypError('Variable ' + contents +
' must expand to a string or list of strings; ' +
'found a ' + replacement.__class__.__name__)
@@ -948,7 +956,7 @@ def ExpandVariables(input, phase, variables, build_file):
# Expanding in list context. It's guaranteed that there's only one
# replacement to do in |input_str| and that it's this replacement. See
# above.
- if isinstance(replacement, list):
+ if type(replacement) is list:
# If it's already a list, make a copy.
output = replacement[:]
else:
@@ -957,7 +965,7 @@ def ExpandVariables(input, phase, variables, build_file):
else:
# Expanding in string context.
encoded_replacement = ''
- if isinstance(replacement, list):
+ if type(replacement) is list:
# When expanding a list into string context, turn the list items
# into a string in a way that will work with a subprocess call.
#
@@ -975,26 +983,32 @@ def ExpandVariables(input, phase, variables, build_file):
# Prepare for the next match iteration.
input_str = output
- # Look for more matches now that we've replaced some, to deal with
- # expanding local variables (variables defined in the same
- # variables block as this one).
- gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output)
- if isinstance(output, list):
- if output and isinstance(output[0], list):
- # Leave output alone if it's a list of lists.
- # We don't want such lists to be stringified.
- pass
- else:
- new_output = []
- for item in output:
- new_output.append(
- ExpandVariables(item, phase, variables, build_file))
- output = new_output
+ if output == input:
+ gyp.DebugOutput(gyp.DEBUG_VARIABLES,
+ "Found only identity matches on %r, avoiding infinite "
+ "recursion.",
+ output)
else:
- output = ExpandVariables(output, phase, variables, build_file)
+ # Look for more matches now that we've replaced some, to deal with
+ # expanding local variables (variables defined in the same
+ # variables block as this one).
+ gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output)
+ if type(output) is list:
+ if output and type(output[0]) is list:
+ # Leave output alone if it's a list of lists.
+ # We don't want such lists to be stringified.
+ pass
+ else:
+ new_output = []
+ for item in output:
+ new_output.append(
+ ExpandVariables(item, phase, variables, build_file))
+ output = new_output
+ else:
+ output = ExpandVariables(output, phase, variables, build_file)
# Convert all strings that are canonically-represented integers into integers.
- if isinstance(output, list):
+ if type(output) is list:
for index in xrange(0, len(output)):
if IsStrCanonicalInt(output[index]):
output[index] = int(output[index])
@@ -1003,6 +1017,80 @@ def ExpandVariables(input, phase, variables, build_file):
return output
+# The same condition is often evaluated over and over again so it
+# makes sense to cache as much as possible between evaluations.
+cached_conditions_asts = {}
+
+def EvalCondition(condition, conditions_key, phase, variables, build_file):
+ """Returns the dict that should be used or None if the result was
+ that nothing should be used."""
+ if type(condition) is not list:
+ raise GypError(conditions_key + ' must be a list')
+ if len(condition) < 2:
+ # It's possible that condition[0] won't work in which case this
+ # attempt will raise its own IndexError. That's probably fine.
+ raise GypError(conditions_key + ' ' + condition[0] +
+ ' must be at least length 2, not ' + str(len(condition)))
+
+ i = 0
+ result = None
+ while i < len(condition):
+ cond_expr = condition[i]
+ true_dict = condition[i + 1]
+ if type(true_dict) is not dict:
+ raise GypError('{} {} must be followed by a dictionary, not {}'.format(
+ conditions_key, cond_expr, type(true_dict)))
+ if len(condition) > i + 2 and type(condition[i + 2]) is dict:
+ false_dict = condition[i + 2]
+ i = i + 3
+ if i != len(condition):
+ raise GypError('{} {} has {} unexpected trailing items'.format(
+ conditions_key, cond_expr, len(condition) - i))
+ else:
+ false_dict = None
+ i = i + 2
+ if result == None:
+ result = EvalSingleCondition(
+ cond_expr, true_dict, false_dict, phase, variables, build_file)
+
+ return result
+
+
+def EvalSingleCondition(
+ cond_expr, true_dict, false_dict, phase, variables, build_file):
+ """Returns true_dict if cond_expr evaluates to true, and false_dict
+ otherwise."""
+ # Do expansions on the condition itself. Since the conditon can naturally
+ # contain variable references without needing to resort to GYP expansion
+ # syntax, this is of dubious value for variables, but someone might want to
+ # use a command expansion directly inside a condition.
+ cond_expr_expanded = ExpandVariables(cond_expr, phase, variables,
+ build_file)
+ if type(cond_expr_expanded) not in (str, int):
+ raise ValueError(
+ 'Variable expansion in this context permits str and int ' + \
+ 'only, found ' + cond_expr_expanded.__class__.__name__)
+
+ try:
+ if cond_expr_expanded in cached_conditions_asts:
+ ast_code = cached_conditions_asts[cond_expr_expanded]
+ else:
+ ast_code = compile(cond_expr_expanded, '<string>', 'eval')
+ cached_conditions_asts[cond_expr_expanded] = ast_code
+ if eval(ast_code, {'__builtins__': None}, variables):
+ return true_dict
+ return false_dict
+ except SyntaxError, e:
+ syntax_error = SyntaxError('%s while evaluating condition \'%s\' in %s '
+ 'at character %d.' %
+ (str(e.args[0]), e.text, build_file, e.offset),
+ e.filename, e.lineno, e.offset, e.text)
+ raise syntax_error
+ except NameError, e:
+ gyp.common.ExceptionAppend(e, 'while evaluating condition \'%s\' in %s' %
+ (cond_expr_expanded, build_file))
+ raise GypError(e)
+
def ProcessConditionsInDict(the_dict, phase, variables, build_file):
# Process a 'conditions' or 'target_conditions' section in the_dict,
@@ -1038,48 +1126,8 @@ def ProcessConditionsInDict(the_dict, phase, variables, build_file):
del the_dict[conditions_key]
for condition in conditions_list:
- if not isinstance(condition, list):
- raise GypError(conditions_key + ' must be a list')
- if len(condition) != 2 and len(condition) != 3:
- # It's possible that condition[0] won't work in which case this
- # attempt will raise its own IndexError. That's probably fine.
- raise GypError(conditions_key + ' ' + condition[0] +
- ' must be length 2 or 3, not ' + str(len(condition)))
-
- [cond_expr, true_dict] = condition[0:2]
- false_dict = None
- if len(condition) == 3:
- false_dict = condition[2]
-
- # Do expansions on the condition itself. Since the conditon can naturally
- # contain variable references without needing to resort to GYP expansion
- # syntax, this is of dubious value for variables, but someone might want to
- # use a command expansion directly inside a condition.
- cond_expr_expanded = ExpandVariables(cond_expr, phase, variables,
- build_file)
- if not isinstance(cond_expr_expanded, str) and \
- not isinstance(cond_expr_expanded, int):
- raise ValueError, \
- 'Variable expansion in this context permits str and int ' + \
- 'only, found ' + expanded.__class__.__name__
-
- try:
- ast_code = compile(cond_expr_expanded, '<string>', 'eval')
-
- if eval(ast_code, {'__builtins__': None}, variables):
- merge_dict = true_dict
- else:
- merge_dict = false_dict
- except SyntaxError, e:
- syntax_error = SyntaxError('%s while evaluating condition \'%s\' in %s '
- 'at character %d.' %
- (str(e.args[0]), e.text, build_file, e.offset),
- e.filename, e.lineno, e.offset, e.text)
- raise syntax_error
- except NameError, e:
- gyp.common.ExceptionAppend(e, 'while evaluating condition \'%s\' in %s' %
- (cond_expr_expanded, build_file))
- raise GypError(e)
+ merge_dict = EvalCondition(condition, conditions_key, phase, variables,
+ build_file)
if merge_dict != None:
# Expand variables and nested conditinals in the merge_dict before
@@ -1094,8 +1142,7 @@ def LoadAutomaticVariablesFromDict(variables, the_dict):
# Any keys with plain string values in the_dict become automatic variables.
# The variable name is the key name with a "_" character prepended.
for key, value in the_dict.iteritems():
- if isinstance(value, str) or isinstance(value, int) or \
- isinstance(value, list):
+ if type(value) in (str, int, list):
variables['_' + key] = value
@@ -1108,8 +1155,7 @@ def LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key):
# (it could be a list or it could be parentless because it is a root dict),
# the_dict_key will be None.
for key, value in the_dict.get('variables', {}).iteritems():
- if not isinstance(value, str) and not isinstance(value, int) and \
- not isinstance(value, list):
+ if type(value) not in (str, int, list):
continue
if key.endswith('%'):
@@ -1162,12 +1208,12 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in,
for key, value in the_dict.iteritems():
# Skip "variables", which was already processed if present.
- if key != 'variables' and isinstance(value, str):
+ if key != 'variables' and type(value) is str:
expanded = ExpandVariables(value, phase, variables, build_file)
- if not isinstance(expanded, str) and not isinstance(expanded, int):
- raise ValueError, \
+ if type(expanded) not in (str, int):
+ raise ValueError(
'Variable expansion in this context permits str and int ' + \
- 'only, found ' + expanded.__class__.__name__ + ' for ' + key
+ 'only, found ' + expanded.__class__.__name__ + ' for ' + key)
the_dict[key] = expanded
# Variable expansion may have resulted in changes to automatics. Reload.
@@ -1221,23 +1267,23 @@ def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in,
for key, value in the_dict.iteritems():
# Skip "variables" and string values, which were already processed if
# present.
- if key == 'variables' or isinstance(value, str):
+ if key == 'variables' or type(value) is str:
continue
- if isinstance(value, dict):
+ if type(value) is dict:
# Pass a copy of the variables dict so that subdicts can't influence
# parents.
ProcessVariablesAndConditionsInDict(value, phase, variables,
build_file, key)
- elif isinstance(value, list):
+ elif type(value) is list:
# The list itself can't influence the variables dict, and
# ProcessVariablesAndConditionsInList will make copies of the variables
# dict if it needs to pass it to something that can influence it. No
# copy is necessary here.
ProcessVariablesAndConditionsInList(value, phase, variables,
build_file)
- elif not isinstance(value, int):
- raise TypeError, 'Unknown type ' + value.__class__.__name__ + \
- ' for ' + key
+ elif type(value) is not int:
+ raise TypeError('Unknown type ' + value.__class__.__name__ + \
+ ' for ' + key)
def ProcessVariablesAndConditionsInList(the_list, phase, variables,
@@ -1246,17 +1292,17 @@ def ProcessVariablesAndConditionsInList(the_list, phase, variables,
index = 0
while index < len(the_list):
item = the_list[index]
- if isinstance(item, dict):
+ if type(item) is dict:
# Make a copy of the variables dict so that it won't influence anything
# outside of its own scope.
ProcessVariablesAndConditionsInDict(item, phase, variables, build_file)
- elif isinstance(item, list):
+ elif type(item) is list:
ProcessVariablesAndConditionsInList(item, phase, variables, build_file)
- elif isinstance(item, str):
+ elif type(item) is str:
expanded = ExpandVariables(item, phase, variables, build_file)
- if isinstance(expanded, str) or isinstance(expanded, int):
+ if type(expanded) in (str, int):
the_list[index] = expanded
- elif isinstance(expanded, list):
+ elif type(expanded) is list:
the_list[index:index+1] = expanded
index += len(expanded)
@@ -1264,13 +1310,13 @@ def ProcessVariablesAndConditionsInList(the_list, phase, variables,
# without falling into the index increment below.
continue
else:
- raise ValueError, \
+ raise ValueError(
'Variable expansion in this context permits strings and ' + \
'lists only, found ' + expanded.__class__.__name__ + ' at ' + \
- index
- elif not isinstance(item, int):
- raise TypeError, 'Unknown type ' + item.__class__.__name__ + \
- ' at index ' + index
+ index)
+ elif type(item) is not int:
+ raise TypeError('Unknown type ' + item.__class__.__name__ + \
+ ' at index ' + index)
index = index + 1
@@ -1443,6 +1489,20 @@ def RemoveSelfDependencies(targets):
target_dict[dependency_key] = Filter(dependencies, target_name)
+def RemoveLinkDependenciesFromNoneTargets(targets):
+ """Remove dependencies having the 'link_dependency' attribute from the 'none'
+ targets."""
+ for target_name, target_dict in targets.iteritems():
+ for dependency_key in dependency_sections:
+ dependencies = target_dict.get(dependency_key, [])
+ if dependencies:
+ for t in dependencies:
+ if target_dict.get('type', None) == 'none':
+ if targets[t].get('variables', {}).get('link_dependency', 0):
+ target_dict[dependency_key] = \
+ Filter(target_dict[dependency_key], t)
+
+
class DependencyGraphNode(object):
"""
@@ -1468,7 +1528,7 @@ class DependencyGraphNode(object):
# are the "ref" attributes of DependencyGraphNodes. Every target will
# appear in flat_list after all of its dependencies, and before all of its
# dependents.
- flat_list = []
+ flat_list = OrderedSet()
# in_degree_zeros is the list of DependencyGraphNodes that have no
# dependencies not in flat_list. Initially, it is a copy of the children
@@ -1482,12 +1542,15 @@ class DependencyGraphNode(object):
# as work progresses, so that the next node to process from the list can
# always be accessed at a consistent position.
node = in_degree_zeros.pop()
- flat_list.append(node.ref)
+ flat_list.add(node.ref)
# Look at dependents of the node just added to flat_list. Some of them
# may now belong in in_degree_zeros.
for node_dependent in node.dependents:
is_in_degree_zero = True
+ # TODO: We want to check through the
+ # node_dependent.dependencies list but if it's long and we
+ # always start at the beginning, then we get O(n^2) behaviour.
for node_dependent_dependency in node_dependent.dependencies:
if not node_dependent_dependency.ref in flat_list:
# The dependent one or more dependencies not in flat_list. There
@@ -1503,28 +1566,27 @@ class DependencyGraphNode(object):
# iteration of the outer loop.
in_degree_zeros.add(node_dependent)
- return flat_list
+ return list(flat_list)
- def FindCycles(self, path=None):
+ def FindCycles(self):
"""
Returns a list of cycles in the graph, where each cycle is its own list.
"""
- if path is None:
- path = [self]
-
results = []
- for node in self.dependents:
- if node in path:
- cycle = [node]
- for part in path:
- cycle.append(part)
- if part == node:
- break
- results.append(tuple(cycle))
- else:
- results.extend(node.FindCycles([node] + path))
+ visited = set()
+
+ def Visit(node, path):
+ for child in node.dependents:
+ if child in path:
+ results.append([child] + path[:path.index(child) + 1])
+ elif not child in visited:
+ visited.add(child)
+ Visit(child, [child] + path)
+
+ visited.add(self)
+ Visit(self, [self])
- return list(set(results))
+ return results
def DirectDependencies(self, dependencies=None):
"""Returns a list of just direct dependencies."""
@@ -1589,21 +1651,26 @@ class DependencyGraphNode(object):
return self._AddImportedDependencies(targets, dependencies)
def DeepDependencies(self, dependencies=None):
- """Returns a list of all of a target's dependencies, recursively."""
- if dependencies == None:
- dependencies = []
+ """Returns an OrderedSet of all of a target's dependencies, recursively."""
+ if dependencies is None:
+ # Using a list to get ordered output and a set to do fast "is it
+ # already added" checks.
+ dependencies = OrderedSet()
for dependency in self.dependencies:
# Check for None, corresponding to the root node.
- if dependency.ref != None and dependency.ref not in dependencies:
- dependencies.append(dependency.ref)
+ if dependency.ref is None:
+ continue
+ if dependency.ref not in dependencies:
+ dependencies.add(dependency.ref)
dependency.DeepDependencies(dependencies)
return dependencies
def _LinkDependenciesInternal(self, targets, include_shared_libraries,
dependencies=None, initial=True):
- """Returns a list of dependency targets that are linked into this target.
+ """Returns an OrderedSet of dependency targets that are linked
+ into this target.
This function has a split personality, depending on the setting of
|initial|. Outside callers should always leave |initial| at its default
@@ -1616,11 +1683,13 @@ class DependencyGraphNode(object):
If |include_shared_libraries| is False, the resulting dependencies will not
include shared_library targets that are linked into this target.
"""
- if dependencies == None:
- dependencies = []
+ if dependencies is None:
+ # Using a list to get ordered output and a set to do fast "is it
+ # already added" checks.
+ dependencies = OrderedSet()
# Check for None, corresponding to the root node.
- if self.ref == None:
+ if self.ref is None:
return dependencies
# It's kind of sucky that |targets| has to be passed into this function,
@@ -1648,8 +1717,7 @@ class DependencyGraphNode(object):
# Don't traverse 'none' targets if explicitly excluded.
if (target_type == 'none' and
not targets[self.ref].get('dependencies_traverse', True)):
- if self.ref not in dependencies:
- dependencies.append(self.ref)
+ dependencies.add(self.ref)
return dependencies
# Executables and loadable modules are already fully and finally linked.
@@ -1671,7 +1739,7 @@ class DependencyGraphNode(object):
# The target is linkable, add it to the list of link dependencies.
if self.ref not in dependencies:
- dependencies.append(self.ref)
+ dependencies.add(self.ref)
if initial or not is_linkable:
# If this is a subsequent target and it's linkable, don't look any
# further for linkable dependencies, as they'll already be linked into
@@ -1735,12 +1803,22 @@ def BuildDependencyList(targets):
flat_list = root_node.FlattenToList()
# If there's anything left unvisited, there must be a circular dependency
- # (cycle). If you need to figure out what's wrong, look for elements of
- # targets that are not in flat_list.
+ # (cycle).
if len(flat_list) != len(targets):
+ if not root_node.dependents:
+ # If all targets have dependencies, add the first target as a dependent
+ # of root_node so that the cycle can be discovered from root_node.
+ target = targets.keys()[0]
+ target_node = dependency_nodes[target]
+ target_node.dependencies.append(root_node)
+ root_node.dependents.append(target_node)
+
+ cycles = []
+ for cycle in root_node.FindCycles():
+ paths = [node.ref for node in cycle]
+ cycles.append('Cycle: %s' % ' -> '.join(paths))
raise DependencyGraphNode.CircularException(
- 'Some targets not reachable, cycle in dependency graph detected: ' +
- ' '.join(set(flat_list) ^ set(targets)))
+ 'Cycles in dependency graph detected:\n' + '\n'.join(cycles))
return [dependency_nodes, flat_list]
@@ -1790,20 +1868,18 @@ def VerifyNoGYPFileCircularDependencies(targets):
# If there's anything left unvisited, there must be a circular dependency
# (cycle).
if len(flat_list) != len(dependency_nodes):
- bad_files = []
- for file in dependency_nodes.iterkeys():
- if not file in flat_list:
- bad_files.append(file)
- common_path_prefix = os.path.commonprefix(dependency_nodes)
+ if not root_node.dependents:
+ # If all files have dependencies, add the first file as a dependent
+ # of root_node so that the cycle can be discovered from root_node.
+ file_node = dependency_nodes.values()[0]
+ file_node.dependencies.append(root_node)
+ root_node.dependents.append(file_node)
cycles = []
for cycle in root_node.FindCycles():
- simplified_paths = []
- for node in cycle:
- assert(node.ref.startswith(common_path_prefix))
- simplified_paths.append(node.ref[len(common_path_prefix):])
- cycles.append('Cycle: %s' % ' -> '.join(simplified_paths))
- raise DependencyGraphNode.CircularException, \
- 'Cycles in .gyp file dependency graph detected:\n' + '\n'.join(cycles)
+ paths = [node.ref for node in cycle]
+ cycles.append('Cycle: %s' % ' -> '.join(paths))
+ raise DependencyGraphNode.CircularException(
+ 'Cycles in .gyp file dependency graph detected:\n' + '\n'.join(cycles))
def DoDependentSettings(key, flat_list, targets, dependency_nodes):
@@ -1966,25 +2042,25 @@ def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True):
hashable_to_set = set(x for x in to if is_hashable(x))
for item in fro:
singleton = False
- if isinstance(item, str) or isinstance(item, int):
+ if type(item) in (str, int):
# The cheap and easy case.
if is_paths:
to_item = MakePathRelative(to_file, fro_file, item)
else:
to_item = item
- if not isinstance(item, str) or not item.startswith('-'):
+ if not (type(item) is str and item.startswith('-')):
# Any string that doesn't begin with a "-" is a singleton - it can
# only appear once in a list, to be enforced by the list merge append
# or prepend.
singleton = True
- elif isinstance(item, dict):
+ elif type(item) is dict:
# Make a copy of the dictionary, continuing to look for paths to fix.
# The other intelligent aspects of merge processing won't apply because
# item is being merged into an empty dict.
to_item = {}
MergeDicts(to_item, item, to_file, fro_file)
- elif isinstance(item, list):
+ elif type(item) is list:
# Recurse, making a copy of the list. If the list contains any
# descendant dicts, path fixing will occur. Note that here, custom
# values for is_paths and append are dropped; those are only to be
@@ -1993,9 +2069,9 @@ def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True):
to_item = []
MergeLists(to_item, item, to_file, fro_file)
else:
- raise TypeError, \
+ raise TypeError(
'Attempt to merge list item of unsupported type ' + \
- item.__class__.__name__
+ item.__class__.__name__)
if append:
# If appending a singleton that's already in the list, don't append.
@@ -2030,30 +2106,30 @@ def MergeDicts(to, fro, to_file, fro_file):
# modified.
if k in to:
bad_merge = False
- if isinstance(v, str) or isinstance(v, int):
- if not (isinstance(to[k], str) or isinstance(to[k], int)):
+ if type(v) in (str, int):
+ if type(to[k]) not in (str, int):
bad_merge = True
- elif v.__class__ != to[k].__class__:
+ elif type(v) is not type(to[k]):
bad_merge = True
if bad_merge:
- raise TypeError, \
+ raise TypeError(
'Attempt to merge dict value of type ' + v.__class__.__name__ + \
' into incompatible type ' + to[k].__class__.__name__ + \
- ' for key ' + k
- if isinstance(v, str) or isinstance(v, int):
+ ' for key ' + k)
+ if type(v) in (str, int):
# Overwrite the existing value, if any. Cheap and easy.
is_path = IsPathSection(k)
if is_path:
to[k] = MakePathRelative(to_file, fro_file, v)
else:
to[k] = v
- elif isinstance(v, dict):
+ elif type(v) is dict:
# Recurse, guaranteeing copies will be made of objects that require it.
if not k in to:
to[k] = {}
MergeDicts(to[k], v, to_file, fro_file)
- elif isinstance(v, list):
+ elif type(v) is list:
# Lists in dicts can be merged with different policies, depending on
# how the key in the "from" dict (k, the from-key) is written.
#
@@ -2096,13 +2172,13 @@ def MergeDicts(to, fro, to_file, fro_file):
# If the key ends in "?", the list will only be merged if it doesn't
# already exist.
continue
- if not isinstance(to[list_base], list):
+ elif type(to[list_base]) is not list:
# This may not have been checked above if merging in a list with an
# extension character.
- raise TypeError, \
+ raise TypeError(
'Attempt to merge dict value of type ' + v.__class__.__name__ + \
' into incompatible type ' + to[list_base].__class__.__name__ + \
- ' for key ' + list_base + '(' + k + ')'
+ ' for key ' + list_base + '(' + k + ')')
else:
to[list_base] = []
@@ -2114,9 +2190,9 @@ def MergeDicts(to, fro, to_file, fro_file):
is_paths = IsPathSection(list_base)
MergeLists(to[list_base], v, to_file, fro_file, is_paths, append)
else:
- raise TypeError, \
+ raise TypeError(
'Attempt to merge dict value of unsupported type ' + \
- v.__class__.__name__ + ' for key ' + k
+ v.__class__.__name__ + ' for key ' + k)
def MergeConfigWithInheritance(new_configuration_dict, build_file,
@@ -2157,43 +2233,39 @@ def SetUpConfigurations(target, target_dict):
if not 'configurations' in target_dict:
target_dict['configurations'] = {'Default': {}}
if not 'default_configuration' in target_dict:
- concrete = [i for i in target_dict['configurations'].iterkeys()
- if not target_dict['configurations'][i].get('abstract')]
+ concrete = [i for (i, config) in target_dict['configurations'].iteritems()
+ if not config.get('abstract')]
target_dict['default_configuration'] = sorted(concrete)[0]
- for configuration in target_dict['configurations'].keys():
- old_configuration_dict = target_dict['configurations'][configuration]
+ merged_configurations = {}
+ configs = target_dict['configurations']
+ for (configuration, old_configuration_dict) in configs.iteritems():
# Skip abstract configurations (saves work only).
if old_configuration_dict.get('abstract'):
continue
# Configurations inherit (most) settings from the enclosing target scope.
# Get the inheritance relationship right by making a copy of the target
# dict.
- new_configuration_dict = copy.deepcopy(target_dict)
-
- # Take out the bits that don't belong in a "configurations" section.
- # Since configuration setup is done before conditional, exclude, and rules
- # processing, be careful with handling of the suffix characters used in
- # those phases.
- delete_keys = []
- for key in new_configuration_dict:
+ new_configuration_dict = {}
+ for (key, target_val) in target_dict.iteritems():
key_ext = key[-1:]
if key_ext in key_suffixes:
key_base = key[:-1]
else:
key_base = key
- if key_base in non_configuration_keys:
- delete_keys.append(key)
-
- for key in delete_keys:
- del new_configuration_dict[key]
+ if not key_base in non_configuration_keys:
+ new_configuration_dict[key] = gyp.simple_copy.deepcopy(target_val)
# Merge in configuration (with all its parents first).
MergeConfigWithInheritance(new_configuration_dict, build_file,
target_dict, configuration, [])
- # Put the new result back into the target dict as a configuration.
- target_dict['configurations'][configuration] = new_configuration_dict
+ merged_configurations[configuration] = new_configuration_dict
+
+ # Put the new configurations back into the target dict as a configuration.
+ for configuration in merged_configurations.keys():
+ target_dict['configurations'][configuration] = (
+ merged_configurations[configuration])
# Now drop all the abstract ones.
for configuration in target_dict['configurations'].keys():
@@ -2264,9 +2336,9 @@ def ProcessListFiltersInDict(name, the_dict):
if operation != '!' and operation != '/':
continue
- if not isinstance(value, list):
- raise ValueError, name + ' key ' + key + ' must be list, not ' + \
- value.__class__.__name__
+ if type(value) is not list:
+ raise ValueError(name + ' key ' + key + ' must be list, not ' + \
+ value.__class__.__name__)
list_key = key[:-1]
if list_key not in the_dict:
@@ -2276,12 +2348,12 @@ def ProcessListFiltersInDict(name, the_dict):
del_lists.append(key)
continue
- if not isinstance(the_dict[list_key], list):
+ if type(the_dict[list_key]) is not list:
value = the_dict[list_key]
- raise ValueError, name + ' key ' + list_key + \
- ' must be list, not ' + \
- value.__class__.__name__ + ' when applying ' + \
- {'!': 'exclusion', '/': 'regex'}[operation]
+ raise ValueError(name + ' key ' + list_key + \
+ ' must be list, not ' + \
+ value.__class__.__name__ + ' when applying ' + \
+ {'!': 'exclusion', '/': 'regex'}[operation])
if not list_key in lists:
lists.append(list_key)
@@ -2330,8 +2402,8 @@ def ProcessListFiltersInDict(name, the_dict):
action_value = 1
else:
# This is an action that doesn't make any sense.
- raise ValueError, 'Unrecognized action ' + action + ' in ' + name + \
- ' key ' + regex_key
+ raise ValueError('Unrecognized action ' + action + ' in ' + name + \
+ ' key ' + regex_key)
for index in xrange(0, len(the_list)):
list_item = the_list[index]
@@ -2378,17 +2450,17 @@ def ProcessListFiltersInDict(name, the_dict):
# Now recurse into subdicts and lists that may contain dicts.
for key, value in the_dict.iteritems():
- if isinstance(value, dict):
+ if type(value) is dict:
ProcessListFiltersInDict(key, value)
- elif isinstance(value, list):
+ elif type(value) is list:
ProcessListFiltersInList(key, value)
def ProcessListFiltersInList(name, the_list):
for item in the_list:
- if isinstance(item, dict):
+ if type(item) is dict:
ProcessListFiltersInDict(name, item)
- elif isinstance(item, list):
+ elif type(item) is list:
ProcessListFiltersInList(name, item)
@@ -2416,33 +2488,6 @@ def ValidateTargetType(target, target_dict):
target_type))
-def ValidateSourcesInTarget(target, target_dict, build_file):
- # TODO: Check if MSVC allows this for loadable_module targets.
- if target_dict.get('type', None) not in ('static_library', 'shared_library'):
- return
- sources = target_dict.get('sources', [])
- basenames = {}
- for source in sources:
- name, ext = os.path.splitext(source)
- is_compiled_file = ext in [
- '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S']
- if not is_compiled_file:
- continue
- basename = os.path.basename(name) # Don't include extension.
- basenames.setdefault(basename, []).append(source)
-
- error = ''
- for basename, files in basenames.iteritems():
- if len(files) > 1:
- error += ' %s: %s\n' % (basename, ' '.join(files))
-
- if error:
- print('static library %s has several files with the same basename:\n' %
- target + error + 'Some build systems, e.g. MSVC08, '
- 'cannot handle that.')
- raise GypError('Duplicate basenames in sources section, see list above')
-
-
def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules):
"""Ensures that the rules sections in target_dict are valid and consistent,
and determines which sources they apply to.
@@ -2506,7 +2551,7 @@ def ValidateRunAsInTarget(target, target_dict, build_file):
run_as = target_dict.get('run_as')
if not run_as:
return
- if not isinstance(run_as, dict):
+ if type(run_as) is not dict:
raise GypError("The 'run_as' in target %s from file %s should be a "
"dictionary." %
(target_name, build_file))
@@ -2515,17 +2560,17 @@ def ValidateRunAsInTarget(target, target_dict, build_file):
raise GypError("The 'run_as' in target %s from file %s must have an "
"'action' section." %
(target_name, build_file))
- if not isinstance(action, list):
+ if type(action) is not list:
raise GypError("The 'action' for 'run_as' in target %s from file %s "
"must be a list." %
(target_name, build_file))
working_directory = run_as.get('working_directory')
- if working_directory and not isinstance(working_directory, str):
+ if working_directory and type(working_directory) is not str:
raise GypError("The 'working_directory' for 'run_as' in target %s "
"in file %s should be a string." %
(target_name, build_file))
environment = run_as.get('environment')
- if environment and not isinstance(environment, dict):
+ if environment and type(environment) is not dict:
raise GypError("The 'environment' for 'run_as' in target %s "
"in file %s should be a dictionary." %
(target_name, build_file))
@@ -2555,17 +2600,17 @@ def TurnIntIntoStrInDict(the_dict):
# Use items instead of iteritems because there's no need to try to look at
# reinserted keys and their associated values.
for k, v in the_dict.items():
- if isinstance(v, int):
+ if type(v) is int:
v = str(v)
the_dict[k] = v
- elif isinstance(v, dict):
+ elif type(v) is dict:
TurnIntIntoStrInDict(v)
- elif isinstance(v, list):
+ elif type(v) is list:
TurnIntIntoStrInList(v)
- if isinstance(k, int):
- the_dict[str(k)] = v
+ if type(k) is int:
del the_dict[k]
+ the_dict[str(k)] = v
def TurnIntIntoStrInList(the_list):
@@ -2573,11 +2618,11 @@ def TurnIntIntoStrInList(the_list):
"""
for index in xrange(0, len(the_list)):
item = the_list[index]
- if isinstance(item, int):
+ if type(item) is int:
the_list[index] = str(item)
- elif isinstance(item, dict):
+ elif type(item) is dict:
TurnIntIntoStrInDict(item)
- elif isinstance(item, list):
+ elif type(item) is list:
TurnIntIntoStrInList(item)
@@ -2647,8 +2692,8 @@ def SetGeneratorGlobals(generator_input_info):
# Set up path_sections and non_configuration_keys with the default data plus
# the generator-specific data.
global path_sections
- path_sections = base_path_sections[:]
- path_sections.extend(generator_input_info['path_sections'])
+ path_sections = set(base_path_sections)
+ path_sections.update(generator_input_info['path_sections'])
global non_configuration_keys
non_configuration_keys = base_non_configuration_keys[:]
@@ -2677,15 +2722,14 @@ def Load(build_files, variables, includes, depth, generator_input_info, check,
# well as meta-data (e.g. 'included_files' key). 'target_build_files' keeps
# track of the keys corresponding to "target" files.
data = {'target_build_files': set()}
- aux_data = {}
# Normalize paths everywhere. This is important because paths will be
# used as keys to the data dict and for references between input files.
build_files = set(map(os.path.normpath, build_files))
if parallel:
- LoadTargetBuildFilesParallel(build_files, data, aux_data,
- variables, includes, depth, check,
- generator_input_info)
+ LoadTargetBuildFilesParallel(build_files, data, variables, includes, depth,
+ check, generator_input_info)
else:
+ aux_data = {}
for build_file in build_files:
try:
LoadTargetBuildFile(build_file, data, aux_data,
@@ -2707,6 +2751,10 @@ def Load(build_files, variables, includes, depth, generator_input_info, check,
# Expand dependencies specified as build_file:*.
ExpandWildcardDependencies(targets, data)
+ # Remove all dependencies marked as 'link_dependency' from the targets of
+ # type 'none'.
+ RemoveLinkDependenciesFromNoneTargets(targets)
+
# Apply exclude (!) and regex (/) list filters only for dependency_sections.
for target_name, target_dict in targets.iteritems():
tmp_dict = {}
@@ -2792,10 +2840,6 @@ def Load(build_files, variables, includes, depth, generator_input_info, check,
target_dict = targets[target]
build_file = gyp.common.BuildFile(target)
ValidateTargetType(target, target_dict)
- # TODO(thakis): Get vpx_scale/arm/scalesystemdependent.c to be renamed to
- # scalesystemdependent_arm_additions.c or similar.
- if 'arm' not in variables.get('target_arch', ''):
- ValidateSourcesInTarget(target, target_dict, build_file)
ValidateRulesInTarget(target, target_dict, extra_sources_for_rules)
ValidateRunAsInTarget(target, target_dict, build_file)
ValidateActionsInTarget(target, target_dict, build_file)
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/input_test.py b/node_modules/node-gyp/gyp/pylib/gyp/input_test.py
index cdbf6b2fa..4234fbb83 100755
--- a/node_modules/node-gyp/gyp/pylib/gyp/input_test.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/input_test.py
@@ -44,16 +44,16 @@ class TestFindCycles(unittest.TestCase):
def test_cycle_self_reference(self):
self._create_dependency(self.nodes['a'], self.nodes['a'])
- self.assertEquals([(self.nodes['a'], self.nodes['a'])],
+ self.assertEquals([[self.nodes['a'], self.nodes['a']]],
self.nodes['a'].FindCycles())
def test_cycle_two_nodes(self):
self._create_dependency(self.nodes['a'], self.nodes['b'])
self._create_dependency(self.nodes['b'], self.nodes['a'])
- self.assertEquals([(self.nodes['a'], self.nodes['b'], self.nodes['a'])],
+ self.assertEquals([[self.nodes['a'], self.nodes['b'], self.nodes['a']]],
self.nodes['a'].FindCycles())
- self.assertEquals([(self.nodes['b'], self.nodes['a'], self.nodes['b'])],
+ self.assertEquals([[self.nodes['b'], self.nodes['a'], self.nodes['b']]],
self.nodes['b'].FindCycles())
def test_two_cycles(self):
@@ -65,9 +65,9 @@ class TestFindCycles(unittest.TestCase):
cycles = self.nodes['a'].FindCycles()
self.assertTrue(
- (self.nodes['a'], self.nodes['b'], self.nodes['a']) in cycles)
+ [self.nodes['a'], self.nodes['b'], self.nodes['a']] in cycles)
self.assertTrue(
- (self.nodes['b'], self.nodes['c'], self.nodes['b']) in cycles)
+ [self.nodes['b'], self.nodes['c'], self.nodes['b']] in cycles)
self.assertEquals(2, len(cycles))
def test_big_cycle(self):
@@ -77,12 +77,12 @@ class TestFindCycles(unittest.TestCase):
self._create_dependency(self.nodes['d'], self.nodes['e'])
self._create_dependency(self.nodes['e'], self.nodes['a'])
- self.assertEquals([(self.nodes['a'],
+ self.assertEquals([[self.nodes['a'],
self.nodes['b'],
self.nodes['c'],
self.nodes['d'],
self.nodes['e'],
- self.nodes['a'])],
+ self.nodes['a']]],
self.nodes['a'].FindCycles())
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py
index ac19b6dc8..366439a06 100755
--- a/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py
@@ -45,7 +45,7 @@ class MacTool(object):
"""Transforms a tool name like copy-info-plist to CopyInfoPlist"""
return name_string.title().replace('-', '')
- def ExecCopyBundleResource(self, source, dest):
+ def ExecCopyBundleResource(self, source, dest, convert_to_binary):
"""Copies a resource file to the bundle/Resources directory, performing any
necessary compilation on each resource."""
extension = os.path.splitext(source)[1].lower()
@@ -62,7 +62,7 @@ class MacTool(object):
elif extension == '.storyboard':
return self._CopyXIBFile(source, dest)
elif extension == '.strings':
- self._CopyStringsFile(source, dest)
+ self._CopyStringsFile(source, dest, convert_to_binary)
else:
shutil.copy(source, dest)
@@ -92,7 +92,11 @@ class MacTool(object):
sys.stdout.write(line)
return ibtoolout.returncode
- def _CopyStringsFile(self, source, dest):
+ def _ConvertToBinary(self, dest):
+ subprocess.check_call([
+ 'xcrun', 'plutil', '-convert', 'binary1', '-o', dest, dest])
+
+ def _CopyStringsFile(self, source, dest, convert_to_binary):
"""Copies a .strings file using iconv to reconvert the input into UTF-16."""
input_code = self._DetectInputEncoding(source) or "UTF-8"
@@ -112,6 +116,9 @@ class MacTool(object):
fp.write(s.decode(input_code).encode('UTF-16'))
fp.close()
+ if convert_to_binary == 'True':
+ self._ConvertToBinary(dest)
+
def _DetectInputEncoding(self, file_name):
"""Reads the first few bytes from file_name and tries to guess the text
encoding. Returns None as a guess if it can't detect it."""
@@ -131,7 +138,7 @@ class MacTool(object):
else:
return None
- def ExecCopyInfoPlist(self, source, dest, *keys):
+ def ExecCopyInfoPlist(self, source, dest, convert_to_binary, *keys):
"""Copies the |source| Info.plist to the destination directory |dest|."""
# Read the source Info.plist into memory.
fd = open(source, 'r')
@@ -146,7 +153,7 @@ class MacTool(object):
# Go through all the environment variables and replace them as variables in
# the file.
- IDENT_RE = re.compile('[/\s]')
+ IDENT_RE = re.compile(r'[/\s]')
for key in os.environ:
if key.startswith('_'):
continue
@@ -185,6 +192,9 @@ class MacTool(object):
# "compiled".
self._WritePkgInfo(dest)
+ if convert_to_binary == 'True':
+ self._ConvertToBinary(dest)
+
def _WritePkgInfo(self, info_plist):
"""This writes the PkgInfo file from the data stored in Info.plist."""
plist = plistlib.readPlist(info_plist)
@@ -219,11 +229,28 @@ class MacTool(object):
"""Calls libtool and filters out '/path/to/libtool: file: foo.o has no
symbols'."""
libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$')
- libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE)
+ libtool_re5 = re.compile(
+ r'^.*libtool: warning for library: ' +
+ r'.* the table of contents is empty ' +
+ r'\(no object file members in the library define global symbols\)$')
+ env = os.environ.copy()
+ # Ref:
+ # http://www.opensource.apple.com/source/cctools/cctools-809/misc/libtool.c
+ # The problem with this flag is that it resets the file mtime on the file to
+ # epoch=0, e.g. 1970-1-1 or 1969-12-31 depending on timezone.
+ env['ZERO_AR_DATE'] = '1'
+ libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, env=env)
_, err = libtoolout.communicate()
for line in err.splitlines():
- if not libtool_re.match(line):
+ if not libtool_re.match(line) and not libtool_re5.match(line):
print >>sys.stderr, line
+ # Unconditionally touch the output .a file on the command line if present
+ # and the command succeeded. A bit hacky.
+ if not libtoolout.returncode:
+ for i in range(len(cmd_list) - 1):
+ if cmd_list[i] == "-o" and cmd_list[i+1].endswith('.a'):
+ os.utime(cmd_list[i+1], None)
+ break
return libtoolout.returncode
def ExecPackageFramework(self, framework, version):
@@ -262,6 +289,66 @@ class MacTool(object):
os.remove(link)
os.symlink(dest, link)
+ def ExecCompileXcassets(self, keys, *inputs):
+ """Compiles multiple .xcassets files into a single .car file.
+
+ This invokes 'actool' to compile all the inputs .xcassets files. The
+ |keys| arguments is a json-encoded dictionary of extra arguments to
+ pass to 'actool' when the asset catalogs contains an application icon
+ or a launch image.
+
+ Note that 'actool' does not create the Assets.car file if the asset
+ catalogs does not contains imageset.
+ """
+ command_line = [
+ 'xcrun', 'actool', '--output-format', 'human-readable-text',
+ '--compress-pngs', '--notices', '--warnings', '--errors',
+ ]
+ is_iphone_target = 'IPHONEOS_DEPLOYMENT_TARGET' in os.environ
+ if is_iphone_target:
+ platform = os.environ['CONFIGURATION'].split('-')[-1]
+ if platform not in ('iphoneos', 'iphonesimulator'):
+ platform = 'iphonesimulator'
+ command_line.extend([
+ '--platform', platform, '--target-device', 'iphone',
+ '--target-device', 'ipad', '--minimum-deployment-target',
+ os.environ['IPHONEOS_DEPLOYMENT_TARGET'], '--compile',
+ os.path.abspath(os.environ['CONTENTS_FOLDER_PATH']),
+ ])
+ else:
+ command_line.extend([
+ '--platform', 'macosx', '--target-device', 'mac',
+ '--minimum-deployment-target', os.environ['MACOSX_DEPLOYMENT_TARGET'],
+ '--compile',
+ os.path.abspath(os.environ['UNLOCALIZED_RESOURCES_FOLDER_PATH']),
+ ])
+ if keys:
+ keys = json.loads(keys)
+ for key, value in keys.iteritems():
+ arg_name = '--' + key
+ if isinstance(value, bool):
+ if value:
+ command_line.append(arg_name)
+ elif isinstance(value, list):
+ for v in value:
+ command_line.append(arg_name)
+ command_line.append(str(v))
+ else:
+ command_line.append(arg_name)
+ command_line.append(str(value))
+ # Note: actool crashes if inputs path are relative, so use os.path.abspath
+ # to get absolute path name for inputs.
+ command_line.extend(map(os.path.abspath, inputs))
+ subprocess.check_call(command_line)
+
+ def ExecMergeInfoPlist(self, output, *inputs):
+ """Merge multiple .plist files into a single .plist file."""
+ merged_plist = {}
+ for path in inputs:
+ plist = self._LoadPlistMaybeBinary(path)
+ self._MergePlist(merged_plist, plist)
+ plistlib.writePlist(merged_plist, output)
+
def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning):
"""Code sign a bundle.
@@ -398,6 +485,19 @@ class MacTool(object):
'security', 'cms', '-D', '-i', profile_path, '-o', temp.name])
return self._LoadPlistMaybeBinary(temp.name)
+ def _MergePlist(self, merged_plist, plist):
+ """Merge |plist| into |merged_plist|."""
+ for key, value in plist.iteritems():
+ if isinstance(value, dict):
+ merged_value = merged_plist.get(key, {})
+ if isinstance(merged_value, dict):
+ self._MergePlist(merged_value, value)
+ merged_plist[key] = merged_value
+ else:
+ merged_plist[key] = value
+ else:
+ merged_plist[key] = value
+
def _LoadPlistMaybeBinary(self, plist_path):
"""Loads into a memory a plist possibly encoded in binary format.
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py b/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py
index 6428fced0..ce5c46ea5 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py
@@ -12,10 +12,14 @@ import re
import subprocess
import sys
+from gyp.common import OrderedSet
+import gyp.MSVSUtil
import gyp.MSVSVersion
+
windows_quoter_regex = re.compile(r'(\\*)"')
+
def QuoteForRspFile(arg):
"""Quote a command line argument so that it appears as one argument when
processed via cmd.exe and parsed by CommandLineToArgvW (as is typical for
@@ -131,6 +135,54 @@ def _FindDirectXInstallation():
return dxsdk_dir
+def GetGlobalVSMacroEnv(vs_version):
+ """Get a dict of variables mapping internal VS macro names to their gyp
+ equivalents. Returns all variables that are independent of the target."""
+ env = {}
+ # '$(VSInstallDir)' and '$(VCInstallDir)' are available when and only when
+ # Visual Studio is actually installed.
+ if vs_version.Path():
+ env['$(VSInstallDir)'] = vs_version.Path()
+ env['$(VCInstallDir)'] = os.path.join(vs_version.Path(), 'VC') + '\\'
+ # Chromium uses DXSDK_DIR in include/lib paths, but it may or may not be
+ # set. This happens when the SDK is sync'd via src-internal, rather than
+ # by typical end-user installation of the SDK. If it's not set, we don't
+ # want to leave the unexpanded variable in the path, so simply strip it.
+ dxsdk_dir = _FindDirectXInstallation()
+ env['$(DXSDK_DIR)'] = dxsdk_dir if dxsdk_dir else ''
+ # Try to find an installation location for the Windows DDK by checking
+ # the WDK_DIR environment variable, may be None.
+ env['$(WDK_DIR)'] = os.environ.get('WDK_DIR', '')
+ return env
+
+def ExtractSharedMSVSSystemIncludes(configs, generator_flags):
+ """Finds msvs_system_include_dirs that are common to all targets, removes
+ them from all targets, and returns an OrderedSet containing them."""
+ all_system_includes = OrderedSet(
+ configs[0].get('msvs_system_include_dirs', []))
+ for config in configs[1:]:
+ system_includes = config.get('msvs_system_include_dirs', [])
+ all_system_includes = all_system_includes & OrderedSet(system_includes)
+ if not all_system_includes:
+ return None
+ # Expand macros in all_system_includes.
+ env = GetGlobalVSMacroEnv(GetVSVersion(generator_flags))
+ expanded_system_includes = OrderedSet([ExpandMacros(include, env)
+ for include in all_system_includes])
+ if any(['$' in include for include in expanded_system_includes]):
+ # Some path relies on target-specific variables, bail.
+ return None
+
+ # Remove system includes shared by all targets from the targets.
+ for config in configs:
+ includes = config.get('msvs_system_include_dirs', [])
+ if includes: # Don't insert a msvs_system_include_dirs key if not needed.
+ # This must check the unexpanded includes list:
+ new_includes = [i for i in includes if i not in all_system_includes]
+ config['msvs_system_include_dirs'] = new_includes
+ return expanded_system_includes
+
+
class MsvsSettings(object):
"""A class that understands the gyp 'msvs_...' values (especially the
msvs_settings field). They largely correpond to the VS2008 IDE DOM. This
@@ -139,11 +191,6 @@ class MsvsSettings(object):
def __init__(self, spec, generator_flags):
self.spec = spec
self.vs_version = GetVSVersion(generator_flags)
- self.dxsdk_dir = _FindDirectXInstallation()
-
- # Try to find an installation location for the Windows DDK by checking
- # the WDK_DIR environment variable, may be None.
- self.wdk_dir = os.environ.get('WDK_DIR')
supported_fields = [
('msvs_configuration_attributes', dict),
@@ -163,6 +210,30 @@ class MsvsSettings(object):
self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.'])
+ unsupported_fields = [
+ 'msvs_prebuild',
+ 'msvs_postbuild',
+ ]
+ unsupported = []
+ for field in unsupported_fields:
+ for config in configs.values():
+ if field in config:
+ unsupported += ["%s not supported (target %s)." %
+ (field, spec['target_name'])]
+ if unsupported:
+ raise Exception('\n'.join(unsupported))
+
+ def GetExtension(self):
+ """Returns the extension for the target, with no leading dot.
+
+ Uses 'product_extension' if specified, otherwise uses MSVS defaults based on
+ the target type.
+ """
+ ext = self.spec.get('product_extension', None)
+ if ext:
+ return ext
+ return gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec['type'], '')
+
def GetVSMacroEnv(self, base_to_build=None, config=None):
"""Get a dict of variables mapping internal VS macro names to their gyp
equivalents."""
@@ -170,29 +241,24 @@ class MsvsSettings(object):
target_name = self.spec.get('product_prefix', '') + \
self.spec.get('product_name', self.spec['target_name'])
target_dir = base_to_build + '\\' if base_to_build else ''
+ target_ext = '.' + self.GetExtension()
+ target_file_name = target_name + target_ext
+
replacements = {
- '$(OutDir)\\': target_dir,
- '$(TargetDir)\\': target_dir,
- '$(IntDir)': '$!INTERMEDIATE_DIR',
- '$(InputPath)': '${source}',
'$(InputName)': '${root}',
- '$(ProjectName)': self.spec['target_name'],
- '$(TargetName)': target_name,
+ '$(InputPath)': '${source}',
+ '$(IntDir)': '$!INTERMEDIATE_DIR',
+ '$(OutDir)\\': target_dir,
'$(PlatformName)': target_platform,
'$(ProjectDir)\\': '',
+ '$(ProjectName)': self.spec['target_name'],
+ '$(TargetDir)\\': target_dir,
+ '$(TargetExt)': target_ext,
+ '$(TargetFileName)': target_file_name,
+ '$(TargetName)': target_name,
+ '$(TargetPath)': os.path.join(target_dir, target_file_name),
}
- # '$(VSInstallDir)' and '$(VCInstallDir)' are available when and only when
- # Visual Studio is actually installed.
- if self.vs_version.Path():
- replacements['$(VSInstallDir)'] = self.vs_version.Path()
- replacements['$(VCInstallDir)'] = os.path.join(self.vs_version.Path(),
- 'VC') + '\\'
- # Chromium uses DXSDK_DIR in include/lib paths, but it may or may not be
- # set. This happens when the SDK is sync'd via src-internal, rather than
- # by typical end-user installation of the SDK. If it's not set, we don't
- # want to leave the unexpanded variable in the path, so simply strip it.
- replacements['$(DXSDK_DIR)'] = self.dxsdk_dir if self.dxsdk_dir else ''
- replacements['$(WDK_DIR)'] = self.wdk_dir if self.wdk_dir else ''
+ replacements.update(GetGlobalVSMacroEnv(self.vs_version))
return replacements
def ConvertVSMacros(self, s, base_to_build=None, config=None):
@@ -272,6 +338,15 @@ class MsvsSettings(object):
('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[]))
return [self.ConvertVSMacros(p, config=config) for p in includes]
+ def AdjustMidlIncludeDirs(self, midl_include_dirs, config):
+ """Updates midl_include_dirs to expand VS specific paths, and adds the
+ system include dirs used for platform SDK and similar."""
+ config = self._TargetConfig(config)
+ includes = midl_include_dirs + self.msvs_system_include_dirs[config]
+ includes.extend(self._Setting(
+ ('VCMIDLTool', 'AdditionalIncludeDirectories'), config, default=[]))
+ return [self.ConvertVSMacros(p, config=config) for p in includes]
+
def GetComputedDefines(self, config):
"""Returns the set of defines that are injected to the defines list based
on other VS settings."""
@@ -324,7 +399,7 @@ class MsvsSettings(object):
output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config)
generate_debug_info = self._Setting(
('VCLinkerTool', 'GenerateDebugInformation'), config)
- if generate_debug_info:
+ if generate_debug_info == 'true':
if output_file:
return expand_special(self.ConvertVSMacros(output_file, config=config))
else:
@@ -332,6 +407,22 @@ class MsvsSettings(object):
else:
return None
+ def GetNoImportLibrary(self, config):
+ """If NoImportLibrary: true, ninja will not expect the output to include
+ an import library."""
+ config = self._TargetConfig(config)
+ noimplib = self._Setting(('NoImportLibrary',), config)
+ return noimplib == 'true'
+
+ def GetAsmflags(self, config):
+ """Returns the flags that need to be added to ml invocations."""
+ config = self._TargetConfig(config)
+ asmflags = []
+ safeseh = self._Setting(('MASM', 'UseSafeExceptionHandlers'), config)
+ if safeseh == 'true':
+ asmflags.append('/safeseh')
+ return asmflags
+
def GetCflags(self, config):
"""Returns the flags that need to be added to .c and .cc compilations."""
config = self._TargetConfig(config)
@@ -348,9 +439,14 @@ class MsvsSettings(object):
cl('OmitFramePointers', map={'false': '-', 'true': ''}, prefix='/Oy')
cl('EnableIntrinsicFunctions', map={'false': '-', 'true': ''}, prefix='/Oi')
cl('FavorSizeOrSpeed', map={'1': 't', '2': 's'}, prefix='/O')
+ cl('FloatingPointModel',
+ map={'0': 'precise', '1': 'strict', '2': 'fast'}, prefix='/fp:',
+ default='0')
cl('WholeProgramOptimization', map={'true': '/GL'})
cl('WarningLevel', prefix='/W')
cl('WarnAsError', map={'true': '/WX'})
+ cl('CallingConvention',
+ map={'0': 'd', '1': 'r', '2': 'z', '3': 'v'}, prefix='/G')
cl('DebugInformationFormat',
map={'1': '7', '3': 'i', '4': 'I'}, prefix='/Z')
cl('RuntimeTypeInfo', map={'true': '/GR', 'false': '/GR-'})
@@ -366,21 +462,18 @@ class MsvsSettings(object):
map={'false': '-', 'true': ''}, prefix='/Zc:wchar_t')
cl('EnablePREfast', map={'true': '/analyze'})
cl('AdditionalOptions', prefix='')
+ cl('EnableEnhancedInstructionSet',
+ map={'1': 'SSE', '2': 'SSE2', '3': 'AVX', '4': 'IA32', '5': 'AVX2'},
+ prefix='/arch:')
cflags.extend(['/FI' + f for f in self._Setting(
('VCCLCompilerTool', 'ForcedIncludeFiles'), config, default=[])])
- if self.vs_version.short_name in ('2013', '2013e'):
+ if self.vs_version.short_name in ('2013', '2013e', '2015'):
# New flag required in 2013 to maintain previous PDB behavior.
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)
return cflags
- def GetPrecompiledHeader(self, config, gyp_to_build_path):
- """Returns an object that handles the generation of precompiled header
- build steps."""
- config = self._TargetConfig(config)
- return _PchHelper(self, config, gyp_to_build_path)
-
def _GetPchFlags(self, config, extension):
"""Get the flags to be added to the cflags for precompiled header support.
"""
@@ -425,7 +518,8 @@ class MsvsSettings(object):
libflags.extend(self._GetAdditionalLibraryDirectories(
'VCLibrarianTool', config, gyp_to_build_path))
lib('LinkTimeCodeGeneration', map={'true': '/LTCG'})
- lib('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:')
+ lib('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'},
+ prefix='/MACHINE:')
lib('AdditionalOptions')
return libflags
@@ -468,7 +562,8 @@ class MsvsSettings(object):
'VCLinkerTool', append=ldflags)
self._GetDefFileAsLdflags(ldflags, gyp_to_build_path)
ld('GenerateDebugInformation', map={'true': '/DEBUG'})
- ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:')
+ ld('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'},
+ prefix='/MACHINE:')
ldflags.extend(self._GetAdditionalLibraryDirectories(
'VCLinkerTool', config, gyp_to_build_path))
ld('DelayLoadDLLs', prefix='/DELAYLOAD:')
@@ -522,6 +617,14 @@ class MsvsSettings(object):
# TODO(scottmg): This should sort of be somewhere else (not really a flag).
ld('AdditionalDependencies', prefix='')
+ if self.GetArch(config) == 'x86':
+ safeseh_default = 'true'
+ else:
+ safeseh_default = None
+ ld('ImageHasSafeExceptionHandlers',
+ map={'false': ':NO', 'true': ''}, prefix='/SAFESEH',
+ default=safeseh_default)
+
# If the base address is not specifically controlled, DYNAMICBASE should
# be on by default.
base_flags = filter(lambda x: 'DYNAMICBASE' in x or x == '/FIXED',
@@ -708,10 +811,16 @@ class MsvsSettings(object):
return True
return False
- def HasExplicitIdlRules(self, spec):
- """Determine if there's an explicit rule for idl files. When there isn't we
- need to generate implicit rules to build MIDL .idl files."""
- return self._HasExplicitRuleForExtension(spec, 'idl')
+ def _HasExplicitIdlActions(self, spec):
+ """Determine if an action should not run midl for .idl files."""
+ return any([action.get('explicit_idl_action', 0)
+ for action in spec.get('actions', [])])
+
+ def HasExplicitIdlRulesOrActions(self, spec):
+ """Determine if there's an explicit rule or action for idl files. When
+ there isn't we need to generate implicit rules to build MIDL .idl files."""
+ return (self._HasExplicitRuleForExtension(spec, 'idl') or
+ self._HasExplicitIdlActions(spec))
def HasExplicitAsmRules(self, spec):
"""Determine if there's an explicit rule for asm files. When there isn't we
@@ -774,7 +883,7 @@ class PrecompiledHeader(object):
def GetObjDependencies(self, sources, objs, arch):
"""Given a list of sources files and the corresponding object files,
returns a list of the pch files that should be depended upon. The
- additional wrapping in the return value is for interface compatability
+ additional wrapping in the return value is for interface compatibility
with make.py on Mac, and xcode_emulation.py."""
assert arch is None
if not self._PchHeader():
@@ -810,7 +919,8 @@ def GetVSVersion(generator_flags):
global vs_version
if not vs_version:
vs_version = gyp.MSVSVersion.SelectVisualStudioVersion(
- generator_flags.get('msvs_version', 'auto'))
+ generator_flags.get('msvs_version', 'auto'),
+ allow_fallback=False)
return vs_version
def _GetVsvarsSetupArgs(generator_flags, arch):
@@ -878,7 +988,8 @@ def _ExtractCLPath(output_of_where):
if line.startswith('LOC:'):
return line[len('LOC:'):].strip()
-def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags, open_out):
+def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags,
+ system_includes, open_out):
"""It's not sufficient to have the absolute path to the compiler, linker,
etc. on Windows, as those tools rely on .dlls being in the PATH. We also
need to support both x86 and x64 compilers within the same build (to support
@@ -909,6 +1020,13 @@ def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags, open_out):
args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
variables, _ = popen.communicate()
env = _ExtractImportantEnvironment(variables)
+
+ # Inject system includes from gyp files into INCLUDE.
+ if system_includes:
+ system_includes = system_includes | OrderedSet(
+ env.get('INCLUDE', '').split(';'))
+ env['INCLUDE'] = ';'.join(system_includes)
+
env_block = _FormatAsEnvironmentBlock(env)
f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb')
f.write(env_block)
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py b/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py
new file mode 100644
index 000000000..74c98c5a7
--- /dev/null
+++ b/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py
@@ -0,0 +1,46 @@
+# Copyright 2014 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.
+
+"""A clone of the default copy.deepcopy that doesn't handle cyclic
+structures or complex types except for dicts and lists. This is
+because gyp copies so large structure that small copy overhead ends up
+taking seconds in a project the size of Chromium."""
+
+class Error(Exception):
+ pass
+
+__all__ = ["Error", "deepcopy"]
+
+def deepcopy(x):
+ """Deep copy operation on gyp objects such as strings, ints, dicts
+ and lists. More than twice as fast as copy.deepcopy but much less
+ generic."""
+
+ try:
+ return _deepcopy_dispatch[type(x)](x)
+ except KeyError:
+ raise Error('Unsupported type %s for deepcopy. Use copy.deepcopy ' +
+ 'or expand simple_copy support.' % type(x))
+
+_deepcopy_dispatch = d = {}
+
+def _deepcopy_atomic(x):
+ return x
+
+for x in (type(None), int, long, float,
+ bool, str, unicode, type):
+ d[x] = _deepcopy_atomic
+
+def _deepcopy_list(x):
+ return [deepcopy(a) for a in x]
+d[list] = _deepcopy_list
+
+def _deepcopy_dict(x):
+ y = {}
+ for key, value in x.iteritems():
+ y[deepcopy(key)] = deepcopy(value)
+ return y
+d[dict] = _deepcopy_dict
+
+del d
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py
index e9d7df0bb..417e465f7 100755
--- a/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py
@@ -13,6 +13,7 @@ import os
import re
import shutil
import subprocess
+import stat
import string
import sys
@@ -48,7 +49,8 @@ class WinTool(object):
for arg in args:
m = _LINK_EXE_OUT_ARG.match(arg)
if m:
- endpoint_name = '%s_%d' % (m.group('out'), os.getpid())
+ endpoint_name = re.sub(r'\W+', '',
+ '%s_%d' % (m.group('out'), os.getpid()))
break
if endpoint_name is None:
@@ -88,9 +90,19 @@ class WinTool(object):
"""Emulation of rm -rf out && cp -af in out."""
if os.path.exists(dest):
if os.path.isdir(dest):
- shutil.rmtree(dest)
+ def _on_error(fn, path, excinfo):
+ # The operation failed, possibly because the file is set to
+ # read-only. If that's why, make it writable and try the op again.
+ if not os.access(path, os.W_OK):
+ os.chmod(path, stat.S_IWRITE)
+ fn(path)
+ shutil.rmtree(dest, onerror=_on_error)
else:
+ if not os.access(dest, os.W_OK):
+ # Attempt to make the file writable before deleting it.
+ os.chmod(dest, stat.S_IWRITE)
os.unlink(dest)
+
if os.path.isdir(source):
shutil.copytree(source, dest)
else:
@@ -104,7 +116,7 @@ class WinTool(object):
env = self._GetEnv(arch)
if use_separate_mspdbsrv == 'True':
self._UseSeparateMspdbsrv(env, args)
- link = subprocess.Popen(args,
+ link = subprocess.Popen([args[0].replace('/', '\\')] + list(args[1:]),
shell=True,
env=env,
stdout=subprocess.PIPE,
@@ -236,19 +248,17 @@ class WinTool(object):
# Processing C:\Program Files (x86)\Microsoft SDKs\...\include\objidl.idl
# objidl.idl
lines = out.splitlines()
- prefix = 'Processing '
- processing = set(os.path.basename(x) for x in lines if x.startswith(prefix))
+ prefixes = ('Processing ', '64 bit Processing ')
+ processing = set(os.path.basename(x)
+ for x in lines if x.startswith(prefixes))
for line in lines:
- if not line.startswith(prefix) and line not in processing:
+ if not line.startswith(prefixes) and line not in processing:
print line
return popen.returncode
def ExecAsmWrapper(self, arch, *args):
"""Filter logo banner from invocations of asm.exe."""
env = self._GetEnv(arch)
- # MSVS doesn't assemble x64 asm files.
- if arch == 'environment.x64':
- return 0
popen = subprocess.Popen(args, shell=True, env=env,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = popen.communicate()
@@ -287,5 +297,16 @@ class WinTool(object):
dir = dir[0] if dir else None
return subprocess.call(args, shell=True, env=env, cwd=dir)
+ def ExecClCompile(self, project_dir, selected_files):
+ """Executed by msvs-ninja projects when the 'ClCompile' target is used to
+ build selected C/C++ files."""
+ project_dir = os.path.relpath(project_dir, BASE_DIR)
+ selected_files = selected_files.split(';')
+ ninja_targets = [os.path.join(project_dir, filename) + '^^'
+ for filename in selected_files]
+ cmd = ['ninja.exe']
+ cmd.extend(ninja_targets)
+ return subprocess.call(cmd, shell=True, cwd=BASE_DIR)
+
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
index 30f27d583..f1a839a2f 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
@@ -18,6 +18,129 @@ import sys
import tempfile
from gyp.common import GypError
+# Populated lazily by XcodeVersion, for efficiency, and to fix an issue when
+# "xcodebuild" is called too quickly (it has been found to return incorrect
+# version number).
+XCODE_VERSION_CACHE = None
+
+# Populated lazily by GetXcodeArchsDefault, to an |XcodeArchsDefault| instance
+# corresponding to the installed version of Xcode.
+XCODE_ARCHS_DEFAULT_CACHE = None
+
+
+def XcodeArchsVariableMapping(archs, archs_including_64_bit=None):
+ """Constructs a dictionary with expansion for $(ARCHS_STANDARD) variable,
+ and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT)."""
+ mapping = {'$(ARCHS_STANDARD)': archs}
+ if archs_including_64_bit:
+ mapping['$(ARCHS_STANDARD_INCLUDING_64_BIT)'] = archs_including_64_bit
+ return mapping
+
+class XcodeArchsDefault(object):
+ """A class to resolve ARCHS variable from xcode_settings, resolving Xcode
+ macros and implementing filtering by VALID_ARCHS. The expansion of macros
+ depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and
+ on the version of Xcode.
+ """
+
+ # Match variable like $(ARCHS_STANDARD).
+ variable_pattern = re.compile(r'\$\([a-zA-Z_][a-zA-Z0-9_]*\)$')
+
+ def __init__(self, default, mac, iphonesimulator, iphoneos):
+ self._default = (default,)
+ self._archs = {'mac': mac, 'ios': iphoneos, 'iossim': iphonesimulator}
+
+ def _VariableMapping(self, sdkroot):
+ """Returns the dictionary of variable mapping depending on the SDKROOT."""
+ sdkroot = sdkroot.lower()
+ if 'iphoneos' in sdkroot:
+ return self._archs['ios']
+ elif 'iphonesimulator' in sdkroot:
+ return self._archs['iossim']
+ else:
+ return self._archs['mac']
+
+ def _ExpandArchs(self, archs, sdkroot):
+ """Expands variables references in ARCHS, and remove duplicates."""
+ variable_mapping = self._VariableMapping(sdkroot)
+ expanded_archs = []
+ for arch in archs:
+ if self.variable_pattern.match(arch):
+ variable = arch
+ try:
+ variable_expansion = variable_mapping[variable]
+ for arch in variable_expansion:
+ if arch not in expanded_archs:
+ expanded_archs.append(arch)
+ except KeyError as e:
+ print 'Warning: Ignoring unsupported variable "%s".' % variable
+ elif arch not in expanded_archs:
+ expanded_archs.append(arch)
+ return expanded_archs
+
+ def ActiveArchs(self, archs, valid_archs, sdkroot):
+ """Expands variables references in ARCHS, and filter by VALID_ARCHS if it
+ is defined (if not set, Xcode accept any value in ARCHS, otherwise, only
+ values present in VALID_ARCHS are kept)."""
+ expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or '')
+ if valid_archs:
+ filtered_archs = []
+ for arch in expanded_archs:
+ if arch in valid_archs:
+ filtered_archs.append(arch)
+ expanded_archs = filtered_archs
+ return expanded_archs
+
+
+def GetXcodeArchsDefault():
+ """Returns the |XcodeArchsDefault| object to use to expand ARCHS for the
+ installed version of Xcode. The default values used by Xcode for ARCHS
+ and the expansion of the variables depends on the version of Xcode used.
+
+ For all version anterior to Xcode 5.0 or posterior to Xcode 5.1 included
+ uses $(ARCHS_STANDARD) if ARCHS is unset, while Xcode 5.0 to 5.0.2 uses
+ $(ARCHS_STANDARD_INCLUDING_64_BIT). This variable was added to Xcode 5.0
+ and deprecated with Xcode 5.1.
+
+ For "macosx" SDKROOT, all version starting with Xcode 5.0 includes 64-bit
+ architecture as part of $(ARCHS_STANDARD) and default to only building it.
+
+ For "iphoneos" and "iphonesimulator" SDKROOT, 64-bit architectures are part
+ of $(ARCHS_STANDARD_INCLUDING_64_BIT) from Xcode 5.0. From Xcode 5.1, they
+ are also part of $(ARCHS_STANDARD).
+
+ All thoses rules are coded in the construction of the |XcodeArchsDefault|
+ object to use depending on the version of Xcode detected. The object is
+ for performance reason."""
+ global XCODE_ARCHS_DEFAULT_CACHE
+ if XCODE_ARCHS_DEFAULT_CACHE:
+ return XCODE_ARCHS_DEFAULT_CACHE
+ xcode_version, _ = XcodeVersion()
+ if xcode_version < '0500':
+ XCODE_ARCHS_DEFAULT_CACHE = XcodeArchsDefault(
+ '$(ARCHS_STANDARD)',
+ XcodeArchsVariableMapping(['i386']),
+ XcodeArchsVariableMapping(['i386']),
+ XcodeArchsVariableMapping(['armv7']))
+ elif xcode_version < '0510':
+ XCODE_ARCHS_DEFAULT_CACHE = XcodeArchsDefault(
+ '$(ARCHS_STANDARD_INCLUDING_64_BIT)',
+ XcodeArchsVariableMapping(['x86_64'], ['x86_64']),
+ XcodeArchsVariableMapping(['i386'], ['i386', 'x86_64']),
+ XcodeArchsVariableMapping(
+ ['armv7', 'armv7s'],
+ ['armv7', 'armv7s', 'arm64']))
+ else:
+ XCODE_ARCHS_DEFAULT_CACHE = XcodeArchsDefault(
+ '$(ARCHS_STANDARD)',
+ XcodeArchsVariableMapping(['x86_64'], ['x86_64']),
+ XcodeArchsVariableMapping(['i386', 'x86_64'], ['i386', 'x86_64']),
+ XcodeArchsVariableMapping(
+ ['armv7', 'armv7s', 'arm64'],
+ ['armv7', 'armv7s', 'arm64']))
+ return XCODE_ARCHS_DEFAULT_CACHE
+
+
class XcodeSettings(object):
"""A class that understands the gyp 'xcode_settings' object."""
@@ -34,10 +157,6 @@ class XcodeSettings(object):
# cached at class-level for efficiency.
_codesigning_key_cache = {}
- # Populated lazily by _XcodeVersion. Shared by all XcodeSettings, so cached
- # at class-level for efficiency.
- _xcode_version_cache = ()
-
def __init__(self, spec):
self.spec = spec
@@ -96,9 +215,24 @@ class XcodeSettings(object):
if test_key in self._Settings():
print 'Warning: Ignoring not yet implemented key "%s".' % test_key
+ def IsBinaryOutputFormat(self, configname):
+ default = "binary" if self.isIOS else "xml"
+ format = self.xcode_settings[configname].get('INFOPLIST_OUTPUT_FORMAT',
+ default)
+ return format == "binary"
+
def _IsBundle(self):
return int(self.spec.get('mac_bundle', 0)) != 0
+ def _IsIosAppExtension(self):
+ return int(self.spec.get('ios_app_extension', 0)) != 0
+
+ def _IsIosWatchKitExtension(self):
+ return int(self.spec.get('ios_watchkit_extension', 0)) != 0
+
+ def _IsIosWatchApp(self):
+ return int(self.spec.get('ios_watch_app', 0)) != 0
+
def GetFrameworkVersion(self):
"""Returns the framework version of the current target. Only valid for
bundles."""
@@ -118,7 +252,10 @@ class XcodeSettings(object):
'WRAPPER_EXTENSION', default=default_wrapper_extension)
return '.' + self.spec.get('product_extension', wrapper_extension)
elif self.spec['type'] == 'executable':
- return '.' + self.spec.get('product_extension', 'app')
+ if self._IsIosAppExtension() or self._IsIosWatchKitExtension():
+ return '.' + self.spec.get('product_extension', 'appex')
+ else:
+ return '.' + self.spec.get('product_extension', 'app')
else:
assert False, "Don't know extension for '%s', target '%s'" % (
self.spec['type'], self.spec['target_name'])
@@ -173,6 +310,18 @@ class XcodeSettings(object):
def GetProductType(self):
"""Returns the PRODUCT_TYPE of this target."""
+ if self._IsIosAppExtension():
+ assert self._IsBundle(), ('ios_app_extension flag requires mac_bundle '
+ '(target %s)' % self.spec['target_name'])
+ return 'com.apple.product-type.app-extension'
+ if self._IsIosWatchKitExtension():
+ assert self._IsBundle(), ('ios_watchkit_extension flag requires '
+ 'mac_bundle (target %s)' % self.spec['target_name'])
+ return 'com.apple.product-type.watchkit-extension'
+ if self._IsIosWatchApp():
+ assert self._IsBundle(), ('ios_watch_app flag requires mac_bundle '
+ '(target %s)' % self.spec['target_name'])
+ return 'com.apple.product-type.application.watchapp'
if self._IsBundle():
return {
'executable': 'com.apple.product-type.application',
@@ -267,17 +416,12 @@ class XcodeSettings(object):
def GetActiveArchs(self, configname):
"""Returns the architectures this target should be built for."""
- # TODO: Look at VALID_ARCHS, ONLY_ACTIVE_ARCH; possibly set
- # CURRENT_ARCH / NATIVE_ARCH env vars?
- return self.xcode_settings[configname].get('ARCHS', [self._DefaultArch()])
-
- def _GetStdout(self, cmdlist):
- job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE)
- out = job.communicate()[0]
- if job.returncode != 0:
- sys.stderr.write(out + '\n')
- raise GypError('Error %d running %s' % (job.returncode, cmdlist[0]))
- return out.rstrip('\n')
+ config_settings = self.xcode_settings[configname]
+ xcode_archs_default = GetXcodeArchsDefault()
+ return xcode_archs_default.ActiveArchs(
+ config_settings.get('ARCHS'),
+ config_settings.get('VALID_ARCHS'),
+ config_settings.get('SDKROOT'))
def _GetSdkVersionInfoItem(self, sdk, infoitem):
# xcodebuild requires Xcode and can't run on Command Line Tools-only
@@ -285,7 +429,7 @@ class XcodeSettings(object):
# Since the CLT has no SDK paths anyway, returning None is the
# most sensible route and should still do the right thing.
try:
- return self._GetStdout(['xcodebuild', '-version', '-sdk', sdk, infoitem])
+ return GetStdout(['xcodebuild', '-version', '-sdk', sdk, infoitem])
except:
pass
@@ -396,7 +540,8 @@ class XcodeSettings(object):
if arch is not None:
archs = [arch]
else:
- archs = self._Settings().get('ARCHS', [self._DefaultArch()])
+ assert self.configname
+ archs = self.GetActiveArchs(self.configname)
if len(archs) != 1:
# TODO: Supporting fat binaries will be annoying.
self._WarnUnimplemented('ARCHS')
@@ -588,8 +733,8 @@ class XcodeSettings(object):
# -exported_symbols_list file
# -Wl,exported_symbols_list file
# -Wl,exported_symbols_list,file
- LINKER_FILE = '(\S+)'
- WORD = '\S+'
+ LINKER_FILE = r'(\S+)'
+ WORD = r'\S+'
linker_flags = [
['-exported_symbols_list', LINKER_FILE], # Needed for NaCl.
['-unexported_symbols_list', LINKER_FILE],
@@ -653,7 +798,8 @@ class XcodeSettings(object):
if arch is not None:
archs = [arch]
else:
- archs = self._Settings().get('ARCHS', [self._DefaultArch()])
+ assert self.configname
+ archs = self.GetActiveArchs(self.configname)
if len(archs) != 1:
# TODO: Supporting fat binaries will be annoying.
self._WarnUnimplemented('ARCHS')
@@ -678,6 +824,21 @@ class XcodeSettings(object):
for directory in framework_dirs:
ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root))
+ is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension()
+ if sdk_root and is_extension:
+ # Adds the link flags for extensions. These flags are common for all
+ # extensions and provide loader and main function.
+ # These flags reflect the compilation options used by xcode to compile
+ # extensions.
+ ldflags.append('-lpkstart')
+ ldflags.append(sdk_root +
+ '/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit')
+ ldflags.append('-fapplication-extension')
+ ldflags.append('-Xlinker -rpath '
+ '-Xlinker @executable_path/../../Frameworks')
+
+ self._Appendf(ldflags, 'CLANG_CXX_LIBRARY', '-stdlib=%s')
+
self.configname = None
return ldflags
@@ -803,7 +964,7 @@ class XcodeSettings(object):
"""Return a shell command to codesign the iOS output binary so it can
be deployed to a device. This should be run as the very last step of the
build."""
- if not (self.isIOS and self.spec['type'] == "executable"):
+ if not (self.isIOS and self.spec['type'] == 'executable'):
return []
settings = self.xcode_settings[configname]
@@ -874,65 +1035,7 @@ class XcodeSettings(object):
return libraries
def _BuildMachineOSBuild(self):
- return self._GetStdout(['sw_vers', '-buildVersion'])
-
- # This method ported from the logic in Homebrew's CLT version check
- def _CLTVersion(self):
- # pkgutil output looks like
- # package-id: com.apple.pkg.CLTools_Executables
- # version: 5.0.1.0.1.1382131676
- # volume: /
- # location: /
- # install-time: 1382544035
- # groups: com.apple.FindSystemFiles.pkg-group com.apple.DevToolsBoth.pkg-group com.apple.DevToolsNonRelocatableShared.pkg-group
- STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo"
- FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
- MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables"
-
- regex = re.compile('version: (?P<version>.+)')
- for key in [MAVERICKS_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID]:
- try:
- output = self._GetStdout(['/usr/sbin/pkgutil', '--pkg-info', key])
- return re.search(regex, output).groupdict()['version']
- except:
- continue
-
- def _XcodeVersion(self):
- # `xcodebuild -version` output looks like
- # Xcode 4.6.3
- # Build version 4H1503
- # or like
- # Xcode 3.2.6
- # Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0
- # BuildVersion: 10M2518
- # Convert that to '0463', '4H1503'.
- if len(XcodeSettings._xcode_version_cache) == 0:
- try:
- version_list = self._GetStdout(['xcodebuild', '-version']).splitlines()
- # In some circumstances xcodebuild exits 0 but doesn't return
- # the right results; for example, a user on 10.7 or 10.8 with
- # a bogus path set via xcode-select
- # In that case this may be a CLT-only install so fall back to
- # checking that version.
- if len(version_list) < 2:
- raise GypError, "xcodebuild returned unexpected results"
- except:
- version = self._CLTVersion()
- if version:
- version = re.match('(\d\.\d\.?\d*)', version).groups()[0]
- else:
- raise GypError, "No Xcode or CLT version detected!"
- # The CLT has no build information, so we return an empty string.
- version_list = [version, '']
- version = version_list[0]
- build = version_list[-1]
- # Be careful to convert "4.2" to "0420":
- version = version.split()[-1].replace('.', '')
- version = (version + '0' * (3 - len(version))).zfill(4)
- if build:
- build = build.split()[-1]
- XcodeSettings._xcode_version_cache = (version, build)
- return XcodeSettings._xcode_version_cache
+ return GetStdout(['sw_vers', '-buildVersion'])
def _XcodeIOSDeviceFamily(self, configname):
family = self.xcode_settings[configname].get('TARGETED_DEVICE_FAMILY', '1')
@@ -944,7 +1047,7 @@ class XcodeSettings(object):
cache = {}
cache['BuildMachineOSBuild'] = self._BuildMachineOSBuild()
- xcode, xcode_build = self._XcodeVersion()
+ xcode, xcode_build = XcodeVersion()
cache['DTXcode'] = xcode
cache['DTXcodeBuild'] = xcode_build
@@ -982,14 +1085,15 @@ class XcodeSettings(object):
project, then the environment variable was empty. Starting with this
version, Xcode uses the name of the newest SDK installed.
"""
- if self._XcodeVersion() < '0500':
+ xcode_version, xcode_build = XcodeVersion()
+ if xcode_version < '0500':
return ''
default_sdk_path = self._XcodeSdkPath('')
default_sdk_root = XcodeSettings._sdk_root_cache.get(default_sdk_path)
if default_sdk_root:
return default_sdk_root
try:
- all_sdks = self._GetStdout(['xcodebuild', '-showsdks'])
+ all_sdks = GetStdout(['xcodebuild', '-showsdks'])
except:
# If xcodebuild fails, there will be no valid SDKs
return ''
@@ -1002,28 +1106,6 @@ class XcodeSettings(object):
return sdk_root
return ''
- def _DefaultArch(self):
- # For Mac projects, Xcode changed the default value used when ARCHS is not
- # set from "i386" to "x86_64".
- #
- # For iOS projects, if ARCHS is unset, it defaults to "armv7 armv7s" when
- # building for a device, and the simulator binaries are always build for
- # "i386".
- #
- # For new projects, ARCHS is set to $(ARCHS_STANDARD_INCLUDING_64_BIT),
- # which correspond to "armv7 armv7s arm64", and when building the simulator
- # the architecture is either "i386" or "x86_64" depending on the simulated
- # device (respectively 32-bit or 64-bit device).
- #
- # Since the value returned by this function is only used when ARCHS is not
- # set, then on iOS we return "i386", as the default xcode project generator
- # does not set ARCHS if it is not set in the .gyp file.
- if self.isIOS:
- return 'i386'
- version, build = self._XcodeVersion()
- if version >= '0500':
- return 'x86_64'
- return 'i386'
class MacPrefixHeader(object):
"""A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature.
@@ -1131,6 +1213,81 @@ class MacPrefixHeader(object):
]
+def XcodeVersion():
+ """Returns a tuple of version and build version of installed Xcode."""
+ # `xcodebuild -version` output looks like
+ # Xcode 4.6.3
+ # Build version 4H1503
+ # or like
+ # Xcode 3.2.6
+ # Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0
+ # BuildVersion: 10M2518
+ # Convert that to '0463', '4H1503'.
+ global XCODE_VERSION_CACHE
+ if XCODE_VERSION_CACHE:
+ return XCODE_VERSION_CACHE
+ try:
+ version_list = GetStdout(['xcodebuild', '-version']).splitlines()
+ # In some circumstances xcodebuild exits 0 but doesn't return
+ # the right results; for example, a user on 10.7 or 10.8 with
+ # a bogus path set via xcode-select
+ # In that case this may be a CLT-only install so fall back to
+ # checking that version.
+ if len(version_list) < 2:
+ raise GypError("xcodebuild returned unexpected results")
+ except:
+ version = CLTVersion()
+ if version:
+ version = re.match(r'(\d\.\d\.?\d*)', version).groups()[0]
+ else:
+ raise GypError("No Xcode or CLT version detected!")
+ # The CLT has no build information, so we return an empty string.
+ version_list = [version, '']
+ version = version_list[0]
+ build = version_list[-1]
+ # Be careful to convert "4.2" to "0420":
+ version = version.split()[-1].replace('.', '')
+ version = (version + '0' * (3 - len(version))).zfill(4)
+ if build:
+ build = build.split()[-1]
+ XCODE_VERSION_CACHE = (version, build)
+ return XCODE_VERSION_CACHE
+
+
+# This function ported from the logic in Homebrew's CLT version check
+def CLTVersion():
+ """Returns the version of command-line tools from pkgutil."""
+ # pkgutil output looks like
+ # package-id: com.apple.pkg.CLTools_Executables
+ # version: 5.0.1.0.1.1382131676
+ # volume: /
+ # location: /
+ # install-time: 1382544035
+ # groups: com.apple.FindSystemFiles.pkg-group com.apple.DevToolsBoth.pkg-group com.apple.DevToolsNonRelocatableShared.pkg-group
+ STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo"
+ FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
+ MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables"
+
+ regex = re.compile('version: (?P<version>.+)')
+ for key in [MAVERICKS_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID]:
+ try:
+ output = GetStdout(['/usr/sbin/pkgutil', '--pkg-info', key])
+ return re.search(regex, output).groupdict()['version']
+ except:
+ continue
+
+
+def GetStdout(cmdlist):
+ """Returns the content of standard output returned by invoking |cmdlist|.
+ Raises |GypError| if the command return with a non-zero return code."""
+ job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE)
+ out = job.communicate()[0]
+ if job.returncode != 0:
+ sys.stderr.write(out + '\n')
+ raise GypError('Error %d running %s' % (job.returncode, cmdlist[0]))
+ return out.rstrip('\n')
+
+
def MergeGlobalXcodeSettingsToSpec(global_dict, spec):
"""Merges the global xcode_settings dictionary into each configuration of the
target represented by spec. For keys that are both in the global and the local
@@ -1310,6 +1467,13 @@ def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
install_name_base = xcode_settings.GetInstallNameBase()
if install_name_base:
env['DYLIB_INSTALL_NAME_BASE'] = install_name_base
+ if XcodeVersion() >= '0500' and not env.get('SDKROOT'):
+ sdk_root = xcode_settings._SdkRoot(configuration)
+ if not sdk_root:
+ sdk_root = xcode_settings._XcodeSdkPath('')
+ if sdk_root is None:
+ sdk_root = ''
+ env['SDKROOT'] = sdk_root
if not additional_settings:
additional_settings = {}
@@ -1420,16 +1584,16 @@ def _HasIOSTarget(targets):
def _AddIOSDeviceConfigurations(targets):
"""Clone all targets and append -iphoneos to the name. Configure these targets
- to build for iOS devices."""
- for target_dict in targets.values():
- for config_name in target_dict['configurations'].keys():
- config = target_dict['configurations'][config_name]
- new_config_name = config_name + '-iphoneos'
- new_config_dict = copy.deepcopy(config)
- if target_dict['toolset'] == 'target':
- new_config_dict['xcode_settings']['ARCHS'] = ['armv7']
- new_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos'
- target_dict['configurations'][new_config_name] = new_config_dict
+ to build for iOS devices and use correct architectures for those builds."""
+ for target_dict in targets.itervalues():
+ toolset = target_dict['toolset']
+ configs = target_dict['configurations']
+ for config_name, config_dict in dict(configs).iteritems():
+ iphoneos_config_dict = copy.deepcopy(config_dict)
+ configs[config_name + '-iphoneos'] = iphoneos_config_dict
+ configs[config_name + '-iphonesimulator'] = config_dict
+ if toolset == 'target':
+ iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos'
return targets
def CloneConfigurationForDeviceAndEmulator(target_dicts):
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py b/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py
new file mode 100644
index 000000000..3820d6bf0
--- /dev/null
+++ b/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py
@@ -0,0 +1,270 @@
+# Copyright (c) 2014 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.
+
+"""Xcode-ninja wrapper project file generator.
+
+This updates the data structures passed to the Xcode gyp generator to build
+with ninja instead. The Xcode project itself is transformed into a list of
+executable targets, each with a build step to build with ninja, and a target
+with every source and resource file. This appears to sidestep some of the
+major performance headaches experienced using complex projects and large number
+of targets within Xcode.
+"""
+
+import errno
+import gyp.generator.ninja
+import os
+import re
+import xml.sax.saxutils
+
+
+def _WriteWorkspace(main_gyp, sources_gyp, params):
+ """ Create a workspace to wrap main and sources gyp paths. """
+ (build_file_root, build_file_ext) = os.path.splitext(main_gyp)
+ workspace_path = build_file_root + '.xcworkspace'
+ options = params['options']
+ if options.generator_output:
+ workspace_path = os.path.join(options.generator_output, workspace_path)
+ try:
+ os.makedirs(workspace_path)
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
+ output_string = '<?xml version="1.0" encoding="UTF-8"?>\n' + \
+ '<Workspace version = "1.0">\n'
+ for gyp_name in [main_gyp, sources_gyp]:
+ name = os.path.splitext(os.path.basename(gyp_name))[0] + '.xcodeproj'
+ name = xml.sax.saxutils.quoteattr("group:" + name)
+ output_string += ' <FileRef location = %s></FileRef>\n' % name
+ output_string += '</Workspace>\n'
+
+ workspace_file = os.path.join(workspace_path, "contents.xcworkspacedata")
+
+ try:
+ with open(workspace_file, 'r') as input_file:
+ input_string = input_file.read()
+ if input_string == output_string:
+ return
+ except IOError:
+ # Ignore errors if the file doesn't exist.
+ pass
+
+ with open(workspace_file, 'w') as output_file:
+ output_file.write(output_string)
+
+def _TargetFromSpec(old_spec, params):
+ """ Create fake target for xcode-ninja wrapper. """
+ # Determine ninja top level build dir (e.g. /path/to/out).
+ ninja_toplevel = None
+ jobs = 0
+ if params:
+ options = params['options']
+ ninja_toplevel = \
+ os.path.join(options.toplevel_dir,
+ gyp.generator.ninja.ComputeOutputDir(params))
+ jobs = params.get('generator_flags', {}).get('xcode_ninja_jobs', 0)
+
+ target_name = old_spec.get('target_name')
+ product_name = old_spec.get('product_name', target_name)
+ product_extension = old_spec.get('product_extension')
+
+ ninja_target = {}
+ ninja_target['target_name'] = target_name
+ ninja_target['product_name'] = product_name
+ if product_extension:
+ ninja_target['product_extension'] = product_extension
+ ninja_target['toolset'] = old_spec.get('toolset')
+ ninja_target['default_configuration'] = old_spec.get('default_configuration')
+ ninja_target['configurations'] = {}
+
+ # Tell Xcode to look in |ninja_toplevel| for build products.
+ new_xcode_settings = {}
+ if ninja_toplevel:
+ new_xcode_settings['CONFIGURATION_BUILD_DIR'] = \
+ "%s/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" % ninja_toplevel
+
+ if 'configurations' in old_spec:
+ for config in old_spec['configurations'].iterkeys():
+ old_xcode_settings = \
+ old_spec['configurations'][config].get('xcode_settings', {})
+ if 'IPHONEOS_DEPLOYMENT_TARGET' in old_xcode_settings:
+ new_xcode_settings['CODE_SIGNING_REQUIRED'] = "NO"
+ new_xcode_settings['IPHONEOS_DEPLOYMENT_TARGET'] = \
+ old_xcode_settings['IPHONEOS_DEPLOYMENT_TARGET']
+ ninja_target['configurations'][config] = {}
+ ninja_target['configurations'][config]['xcode_settings'] = \
+ new_xcode_settings
+
+ ninja_target['mac_bundle'] = old_spec.get('mac_bundle', 0)
+ ninja_target['ios_app_extension'] = old_spec.get('ios_app_extension', 0)
+ ninja_target['ios_watchkit_extension'] = \
+ old_spec.get('ios_watchkit_extension', 0)
+ ninja_target['ios_watchkit_app'] = old_spec.get('ios_watchkit_app', 0)
+ ninja_target['type'] = old_spec['type']
+ if ninja_toplevel:
+ ninja_target['actions'] = [
+ {
+ 'action_name': 'Compile and copy %s via ninja' % target_name,
+ 'inputs': [],
+ 'outputs': [],
+ 'action': [
+ 'env',
+ 'PATH=%s' % os.environ['PATH'],
+ 'ninja',
+ '-C',
+ new_xcode_settings['CONFIGURATION_BUILD_DIR'],
+ target_name,
+ ],
+ 'message': 'Compile and copy %s via ninja' % target_name,
+ },
+ ]
+ if jobs > 0:
+ ninja_target['actions'][0]['action'].extend(('-j', jobs))
+ return ninja_target
+
+def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec):
+ """Limit targets for Xcode wrapper.
+
+ Xcode sometimes performs poorly with too many targets, so only include
+ proper executable targets, with filters to customize.
+ Arguments:
+ target_extras: Regular expression to always add, matching any target.
+ executable_target_pattern: Regular expression limiting executable targets.
+ spec: Specifications for target.
+ """
+ target_name = spec.get('target_name')
+ # Always include targets matching target_extras.
+ if target_extras is not None and re.search(target_extras, target_name):
+ return True
+
+ # Otherwise just show executable targets.
+ if spec.get('type', '') == 'executable' and \
+ spec.get('product_extension', '') != 'bundle':
+
+ # If there is a filter and the target does not match, exclude the target.
+ if executable_target_pattern is not None:
+ if not re.search(executable_target_pattern, target_name):
+ return False
+ return True
+ return False
+
+def CreateWrapper(target_list, target_dicts, data, params):
+ """Initialize targets for the ninja wrapper.
+
+ This sets up the necessary variables in the targets to generate Xcode projects
+ that use ninja as an external builder.
+ Arguments:
+ target_list: List of target pairs: 'base/base.gyp:base'.
+ target_dicts: Dict of target properties keyed on target pair.
+ data: Dict of flattened build files keyed on gyp path.
+ params: Dict of global options for gyp.
+ """
+ orig_gyp = params['build_files'][0]
+ for gyp_name, gyp_dict in data.iteritems():
+ if gyp_name == orig_gyp:
+ depth = gyp_dict['_DEPTH']
+
+ # Check for custom main gyp name, otherwise use the default CHROMIUM_GYP_FILE
+ # and prepend .ninja before the .gyp extension.
+ generator_flags = params.get('generator_flags', {})
+ main_gyp = generator_flags.get('xcode_ninja_main_gyp', None)
+ if main_gyp is None:
+ (build_file_root, build_file_ext) = os.path.splitext(orig_gyp)
+ main_gyp = build_file_root + ".ninja" + build_file_ext
+
+ # Create new |target_list|, |target_dicts| and |data| data structures.
+ new_target_list = []
+ new_target_dicts = {}
+ new_data = {}
+
+ # Set base keys needed for |data|.
+ new_data[main_gyp] = {}
+ new_data[main_gyp]['included_files'] = []
+ new_data[main_gyp]['targets'] = []
+ new_data[main_gyp]['xcode_settings'] = \
+ data[orig_gyp].get('xcode_settings', {})
+
+ # Normally the xcode-ninja generator includes only valid executable targets.
+ # If |xcode_ninja_executable_target_pattern| is set, that list is reduced to
+ # executable targets that match the pattern. (Default all)
+ executable_target_pattern = \
+ generator_flags.get('xcode_ninja_executable_target_pattern', None)
+
+ # For including other non-executable targets, add the matching target name
+ # to the |xcode_ninja_target_pattern| regular expression. (Default none)
+ target_extras = generator_flags.get('xcode_ninja_target_pattern', None)
+
+ for old_qualified_target in target_list:
+ spec = target_dicts[old_qualified_target]
+ if IsValidTargetForWrapper(target_extras, executable_target_pattern, spec):
+ # Add to new_target_list.
+ target_name = spec.get('target_name')
+ new_target_name = '%s:%s#target' % (main_gyp, target_name)
+ new_target_list.append(new_target_name)
+
+ # Add to new_target_dicts.
+ new_target_dicts[new_target_name] = _TargetFromSpec(spec, params)
+
+ # Add to new_data.
+ for old_target in data[old_qualified_target.split(':')[0]]['targets']:
+ if old_target['target_name'] == target_name:
+ new_data_target = {}
+ new_data_target['target_name'] = old_target['target_name']
+ new_data_target['toolset'] = old_target['toolset']
+ new_data[main_gyp]['targets'].append(new_data_target)
+
+ # Create sources target.
+ sources_target_name = 'sources_for_indexing'
+ sources_target = _TargetFromSpec(
+ { 'target_name' : sources_target_name,
+ 'toolset': 'target',
+ 'default_configuration': 'Default',
+ 'mac_bundle': '0',
+ 'type': 'executable'
+ }, None)
+
+ # Tell Xcode to look everywhere for headers.
+ sources_target['configurations'] = {'Default': { 'include_dirs': [ depth ] } }
+
+ sources = []
+ for target, target_dict in target_dicts.iteritems():
+ base = os.path.dirname(target)
+ files = target_dict.get('sources', []) + \
+ target_dict.get('mac_bundle_resources', [])
+ for action in target_dict.get('actions', []):
+ files.extend(action.get('inputs', []))
+ # Remove files starting with $. These are mostly intermediate files for the
+ # build system.
+ files = [ file for file in files if not file.startswith('$')]
+
+ # Make sources relative to root build file.
+ relative_path = os.path.dirname(main_gyp)
+ sources += [ os.path.relpath(os.path.join(base, file), relative_path)
+ for file in files ]
+
+ sources_target['sources'] = sorted(set(sources))
+
+ # Put sources_to_index in it's own gyp.
+ sources_gyp = \
+ os.path.join(os.path.dirname(main_gyp), sources_target_name + ".gyp")
+ fully_qualified_target_name = \
+ '%s:%s#target' % (sources_gyp, sources_target_name)
+
+ # Add to new_target_list, new_target_dicts and new_data.
+ new_target_list.append(fully_qualified_target_name)
+ new_target_dicts[fully_qualified_target_name] = sources_target
+ new_data_target = {}
+ new_data_target['target_name'] = sources_target['target_name']
+ new_data_target['_DEPTH'] = depth
+ new_data_target['toolset'] = "target"
+ new_data[sources_gyp] = {}
+ new_data[sources_gyp]['targets'] = []
+ new_data[sources_gyp]['included_files'] = []
+ new_data[sources_gyp]['xcode_settings'] = \
+ data[orig_gyp].get('xcode_settings', {})
+ new_data[sources_gyp]['targets'].append(new_data_target)
+
+ # Write workspace to file.
+ _WriteWorkspace(main_gyp, sources_gyp, params)
+ return (new_target_list, new_target_dicts, new_data)
diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py b/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py
index 6e4a1dc69..034a0d2d4 100644
--- a/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py
+++ b/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py
@@ -173,7 +173,7 @@ _escaped = re.compile('[\\\\"]|[\x00-\x1f]')
# Used by SourceTreeAndPathFromPath
-_path_leading_variable = re.compile('^\$\((.*?)\)(/(.*))?$')
+_path_leading_variable = re.compile(r'^\$\((.*?)\)(/(.*))?$')
def SourceTreeAndPathFromPath(input_path):
"""Given input_path, returns a tuple with sourceTree and path values.
@@ -196,7 +196,7 @@ def SourceTreeAndPathFromPath(input_path):
return (source_tree, output_path)
def ConvertVariablesToShellSyntax(input_string):
- return re.sub('\$\((.*?)\)', '${\\1}', input_string)
+ return re.sub(r'\$\((.*?)\)', '${\\1}', input_string)
class XCObject(object):
"""The abstract base of all class types used in Xcode project files.
@@ -341,13 +341,13 @@ class XCObject(object):
elif isinstance(value, dict):
# dicts are never strong.
if is_strong:
- raise TypeError, 'Strong dict for key ' + key + ' in ' + \
- self.__class__.__name__
+ raise TypeError('Strong dict for key ' + key + ' in ' + \
+ self.__class__.__name__)
else:
that._properties[key] = value.copy()
else:
- raise TypeError, 'Unexpected type ' + value.__class__.__name__ + \
- ' for key ' + key + ' in ' + self.__class__.__name__
+ raise TypeError('Unexpected type ' + value.__class__.__name__ + \
+ ' for key ' + key + ' in ' + self.__class__.__name__)
return that
@@ -366,8 +366,7 @@ class XCObject(object):
('name' in self._schema and self._schema['name'][3]):
return self._properties['name']
- raise NotImplementedError, \
- self.__class__.__name__ + ' must implement Name'
+ raise NotImplementedError(self.__class__.__name__ + ' must implement Name')
def Comment(self):
"""Return a comment string for the object.
@@ -466,10 +465,10 @@ class XCObject(object):
for descendant in descendants:
if descendant.id in ids:
other = ids[descendant.id]
- raise KeyError, \
+ raise KeyError(
'Duplicate ID %s, objects "%s" and "%s" in "%s"' % \
(descendant.id, str(descendant._properties),
- str(other._properties), self._properties['rootObject'].Name())
+ str(other._properties), self._properties['rootObject'].Name()))
ids[descendant.id] = descendant
def Children(self):
@@ -630,7 +629,7 @@ class XCObject(object):
sep
printable += end_tabs + '}'
else:
- raise TypeError, "Can't make " + value.__class__.__name__ + ' printable'
+ raise TypeError("Can't make " + value.__class__.__name__ + ' printable')
if comment != None:
printable += ' ' + self._EncodeComment(comment)
@@ -756,31 +755,31 @@ class XCObject(object):
for property, value in properties.iteritems():
# Make sure the property is in the schema.
if not property in self._schema:
- raise KeyError, property + ' not in ' + self.__class__.__name__
+ raise KeyError(property + ' not in ' + self.__class__.__name__)
# Make sure the property conforms to the schema.
(is_list, property_type, is_strong) = self._schema[property][0:3]
if is_list:
if value.__class__ != list:
- raise TypeError, \
+ raise TypeError(
property + ' of ' + self.__class__.__name__ + \
- ' must be list, not ' + value.__class__.__name__
+ ' must be list, not ' + value.__class__.__name__)
for item in value:
if not isinstance(item, property_type) and \
not (item.__class__ == unicode and property_type == str):
# Accept unicode where str is specified. str is treated as
# UTF-8-encoded.
- raise TypeError, \
+ raise TypeError(
'item of ' + property + ' of ' + self.__class__.__name__ + \
' must be ' + property_type.__name__ + ', not ' + \
- item.__class__.__name__
+ item.__class__.__name__)
elif not isinstance(value, property_type) and \
not (value.__class__ == unicode and property_type == str):
# Accept unicode where str is specified. str is treated as
# UTF-8-encoded.
- raise TypeError, \
+ raise TypeError(
property + ' of ' + self.__class__.__name__ + ' must be ' + \
- property_type.__name__ + ', not ' + value.__class__.__name__
+ property_type.__name__ + ', not ' + value.__class__.__name__)
# Checks passed, perform the assignment.
if do_copy:
@@ -804,9 +803,9 @@ class XCObject(object):
elif isinstance(value, dict):
self._properties[property] = value.copy()
else:
- raise TypeError, "Don't know how to copy a " + \
- value.__class__.__name__ + ' object for ' + \
- property + ' in ' + self.__class__.__name__
+ raise TypeError("Don't know how to copy a " + \
+ value.__class__.__name__ + ' object for ' + \
+ property + ' in ' + self.__class__.__name__)
else:
self._properties[property] = value
@@ -837,15 +836,15 @@ class XCObject(object):
# Schema validation.
if not key in self._schema:
- raise KeyError, key + ' not in ' + self.__class__.__name__
+ raise KeyError(key + ' not in ' + self.__class__.__name__)
(is_list, property_type, is_strong) = self._schema[key][0:3]
if not is_list:
- raise TypeError, key + ' of ' + self.__class__.__name__ + ' must be list'
+ raise TypeError(key + ' of ' + self.__class__.__name__ + ' must be list')
if not isinstance(value, property_type):
- raise TypeError, 'item of ' + key + ' of ' + self.__class__.__name__ + \
- ' must be ' + property_type.__name__ + ', not ' + \
- value.__class__.__name__
+ raise TypeError('item of ' + key + ' of ' + self.__class__.__name__ + \
+ ' must be ' + property_type.__name__ + ', not ' + \
+ value.__class__.__name__)
# If the property doesn't exist yet, create a new empty list to receive the
# item.
@@ -869,7 +868,7 @@ class XCObject(object):
for property, attributes in self._schema.iteritems():
(is_list, property_type, is_strong, is_required) = attributes[0:4]
if is_required and not property in self._properties:
- raise KeyError, self.__class__.__name__ + ' requires ' + property
+ raise KeyError(self.__class__.__name__ + ' requires ' + property)
def _SetDefaultsFromSchema(self):
"""Assign object default values according to the schema. This will not
@@ -1143,16 +1142,16 @@ class PBXGroup(XCHierarchicalElement):
child_path = child.PathFromSourceTreeAndPath()
if child_path:
if child_path in self._children_by_path:
- raise ValueError, 'Found multiple children with path ' + child_path
+ raise ValueError('Found multiple children with path ' + child_path)
self._children_by_path[child_path] = child
if isinstance(child, PBXVariantGroup):
child_name = child._properties.get('name', None)
key = (child_name, child_path)
if key in self._variant_children_by_name_and_path:
- raise ValueError, 'Found multiple PBXVariantGroup children with ' + \
- 'name ' + str(child_name) + ' and path ' + \
- str(child_path)
+ raise ValueError('Found multiple PBXVariantGroup children with ' + \
+ 'name ' + str(child_name) + ' and path ' + \
+ str(child_path))
self._variant_children_by_name_and_path[key] = child
def AppendChild(self, child):
@@ -1508,9 +1507,12 @@ class PBXFileReference(XCFileLikeElement, XCContainerPortal, XCRemoteObject):
's': 'sourcecode.asm',
'storyboard': 'file.storyboard',
'strings': 'text.plist.strings',
+ 'swift': 'sourcecode.swift',
'ttf': 'file',
+ 'xcassets': 'folder.assetcatalog',
'xcconfig': 'text.xcconfig',
'xcdatamodel': 'wrapper.xcdatamodel',
+ 'xcdatamodeld':'wrapper.xcdatamodeld',
'xib': 'file.xib',
'y': 'sourcecode.yacc',
}
@@ -1605,7 +1607,7 @@ class XCConfigurationList(XCObject):
if configuration._properties['name'] == name:
return configuration
- raise KeyError, name
+ raise KeyError(name)
def DefaultConfiguration(self):
"""Convenience accessor to obtain the default XCBuildConfiguration."""
@@ -1662,7 +1664,7 @@ class XCConfigurationList(XCObject):
value = configuration_value
else:
if value != configuration_value:
- raise ValueError, 'Variant values for ' + key
+ raise ValueError('Variant values for ' + key)
return value
@@ -1769,8 +1771,8 @@ class XCBuildPhase(XCObject):
# added, either as a child or deeper descendant. The second item should
# be a boolean indicating whether files should be added into hierarchical
# groups or one single flat group.
- raise NotImplementedError, \
- self.__class__.__name__ + ' must implement FileGroup'
+ raise NotImplementedError(
+ self.__class__.__name__ + ' must implement FileGroup')
def _AddPathToDict(self, pbxbuildfile, path):
"""Adds path to the dict tracking paths belonging to this build phase.
@@ -1779,7 +1781,7 @@ class XCBuildPhase(XCObject):
"""
if path in self._files_by_path:
- raise ValueError, 'Found multiple build files with path ' + path
+ raise ValueError('Found multiple build files with path ' + path)
self._files_by_path[path] = pbxbuildfile
def _AddBuildFileToDicts(self, pbxbuildfile, path=None):
@@ -1834,8 +1836,8 @@ class XCBuildPhase(XCObject):
# problem.
if xcfilelikeelement in self._files_by_xcfilelikeelement and \
self._files_by_xcfilelikeelement[xcfilelikeelement] != pbxbuildfile:
- raise ValueError, 'Found multiple build files for ' + \
- xcfilelikeelement.Name()
+ raise ValueError('Found multiple build files for ' + \
+ xcfilelikeelement.Name())
self._files_by_xcfilelikeelement[xcfilelikeelement] = pbxbuildfile
def AppendBuildFile(self, pbxbuildfile, path=None):
@@ -1999,8 +2001,8 @@ class PBXCopyFilesBuildPhase(XCBuildPhase):
subfolder = 0
relative_path = path[1:]
else:
- raise ValueError, 'Can\'t use path %s in a %s' % \
- (path, self.__class__.__name__)
+ raise ValueError('Can\'t use path %s in a %s' % \
+ (path, self.__class__.__name__))
self._properties['dstPath'] = relative_path
self._properties['dstSubfolderSpec'] = subfolder
@@ -2236,10 +2238,16 @@ class PBXNativeTarget(XCTarget):
# Mapping from Xcode product-types to settings. The settings are:
# filetype : used for explicitFileType in the project file
# prefix : the prefix for the file name
- # suffix : the suffix for the filen ame
+ # suffix : the suffix for the file name
_product_filetypes = {
- 'com.apple.product-type.application': ['wrapper.application',
- '', '.app'],
+ 'com.apple.product-type.application': ['wrapper.application',
+ '', '.app'],
+ 'com.apple.product-type.application.watchapp': ['wrapper.application',
+ '', '.app'],
+ 'com.apple.product-type.watchkit-extension': ['wrapper.app-extension',
+ '', '.appex'],
+ 'com.apple.product-type.app-extension': ['wrapper.app-extension',
+ '', '.appex'],
'com.apple.product-type.bundle': ['wrapper.cfbundle',
'', '.bundle'],
'com.apple.product-type.framework': ['wrapper.framework',
@@ -2312,11 +2320,11 @@ class PBXNativeTarget(XCTarget):
if force_extension is not None:
# If it's a wrapper (bundle), set WRAPPER_EXTENSION.
+ # Extension override.
+ suffix = '.' + force_extension
if filetype.startswith('wrapper.'):
self.SetBuildSetting('WRAPPER_EXTENSION', force_extension)
else:
- # Extension override.
- suffix = '.' + force_extension
self.SetBuildSetting('EXECUTABLE_EXTENSION', force_extension)
if filetype.startswith('compiled.mach-o.executable'):
@@ -2732,8 +2740,53 @@ class PBXProject(XCContainerPortal):
self._SetUpProductReferences(other_pbxproject, product_group, project_ref)
+ inherit_unique_symroot = self._AllSymrootsUnique(other_pbxproject, False)
+ targets = other_pbxproject.GetProperty('targets')
+ if all(self._AllSymrootsUnique(t, inherit_unique_symroot) for t in targets):
+ dir_path = project_ref._properties['path']
+ product_group._hashables.extend(dir_path)
+
return [product_group, project_ref]
+ def _AllSymrootsUnique(self, target, inherit_unique_symroot):
+ # Returns True if all configurations have a unique 'SYMROOT' attribute.
+ # The value of inherit_unique_symroot decides, if a configuration is assumed
+ # to inherit a unique 'SYMROOT' attribute from its parent, if it doesn't
+ # define an explicit value for 'SYMROOT'.
+ symroots = self._DefinedSymroots(target)
+ for s in self._DefinedSymroots(target):
+ if (s is not None and not self._IsUniqueSymrootForTarget(s) or
+ s is None and not inherit_unique_symroot):
+ return False
+ return True if symroots else inherit_unique_symroot
+
+ def _DefinedSymroots(self, target):
+ # Returns all values for the 'SYMROOT' attribute defined in all
+ # configurations for this target. If any configuration doesn't define the
+ # 'SYMROOT' attribute, None is added to the returned set. If all
+ # configurations don't define the 'SYMROOT' attribute, an empty set is
+ # returned.
+ config_list = target.GetProperty('buildConfigurationList')
+ symroots = set()
+ for config in config_list.GetProperty('buildConfigurations'):
+ setting = config.GetProperty('buildSettings')
+ if 'SYMROOT' in setting:
+ symroots.add(setting['SYMROOT'])
+ else:
+ symroots.add(None)
+ if len(symroots) == 1 and None in symroots:
+ return set()
+ return symroots
+
+ def _IsUniqueSymrootForTarget(self, symroot):
+ # This method returns True if all configurations in target contain a
+ # 'SYMROOT' attribute that is unique for the given target. A value is
+ # unique, if the Xcode macro '$SRCROOT' appears in it in any form.
+ uniquifier = ['$SRCROOT', '$(SRCROOT)']
+ if any(x in symroot for x in uniquifier):
+ return True
+ return False
+
def _SetUpProductReferences(self, other_pbxproject, product_group,
project_ref):
# TODO(mark): This only adds references to products in other_pbxproject
@@ -2802,7 +2855,7 @@ class PBXProject(XCContainerPortal):
product_group = ref_dict['ProductGroup']
product_group._properties['children'] = sorted(
product_group._properties['children'],
- cmp=lambda x, y: CompareProducts(x, y, remote_products))
+ cmp=lambda x, y, rp=remote_products: CompareProducts(x, y, rp))
class XCProjectFile(XCObject):
@@ -2810,27 +2863,10 @@ class XCProjectFile(XCObject):
_schema.update({
'archiveVersion': [0, int, 0, 1, 1],
'classes': [0, dict, 0, 1, {}],
- 'objectVersion': [0, int, 0, 1, 45],
+ 'objectVersion': [0, int, 0, 1, 46],
'rootObject': [0, PBXProject, 1, 1],
})
- def SetXcodeVersion(self, version):
- version_to_object_version = {
- '2.4': 45,
- '3.0': 45,
- '3.1': 45,
- '3.2': 46,
- }
- if not version in version_to_object_version:
- supported_str = ', '.join(sorted(version_to_object_version.keys()))
- raise Exception(
- 'Unsupported Xcode version %s (supported: %s)' %
- ( version, supported_str ) )
- compatibility_version = 'Xcode %s' % version
- self._properties['rootObject'].SetProperty('compatibilityVersion',
- compatibility_version)
- self.SetProperty('objectVersion', version_to_object_version[version]);
-
def ComputeIDs(self, recursive=True, overwrite=True, hash=None):
# Although XCProjectFile is implemented here as an XCObject, it's not a
# proper object in the Xcode sense, and it certainly doesn't have its own
diff --git a/node_modules/node-gyp/gyp/pylintrc b/node_modules/node-gyp/gyp/pylintrc
deleted file mode 100644
index d7c23d2a2..000000000
--- a/node_modules/node-gyp/gyp/pylintrc
+++ /dev/null
@@ -1,307 +0,0 @@
-[MASTER]
-
-# Specify a configuration file.
-#rcfile=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Profiled execution.
-profile=no
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-
-[MESSAGES CONTROL]
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time.
-#enable=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once).
-# C0103: Invalid name "NN" (should match [a-z_][a-z0-9_]{2,30}$)
-# C0111: Missing docstring
-# C0302: Too many lines in module (NN)
-# R0902: Too many instance attributes (N/7)
-# R0903: Too few public methods (N/2)
-# R0904: Too many public methods (NN/20)
-# R0912: Too many branches (NN/12)
-# R0913: Too many arguments (N/5)
-# R0914: Too many local variables (NN/15)
-# R0915: Too many statements (NN/50)
-# W0141: Used builtin function 'map'
-# W0142: Used * or ** magic
-# W0232: Class has no __init__ method
-# W0511: TODO
-# W0603: Using the global statement
-#
-# These should be enabled eventually:
-# C0112: Empty docstring
-# C0301: Line too long (NN/80)
-# C0321: More than one statement on single line
-# C0322: Operator not preceded by a space
-# C0323: Operator not followed by a space
-# C0324: Comma not followed by a space
-# E0101: Explicit return in __init__
-# E0102: function already defined line NN
-# E1002: Use of super on an old style class
-# E1101: Instance of 'XX' has no 'YY' member
-# E1103: Instance of 'XX' has no 'XX' member (but some types could not be inferred)
-# E0602: Undefined variable 'XX'
-# F0401: Unable to import 'XX'
-# R0201: Method could be a function
-# R0801: Similar lines in N files
-# W0102: Dangerous default value {} as argument
-# W0104: Statement seems to have no effect
-# W0105: String statement has no effect
-# W0108: Lambda may not be necessary
-# W0201: Attribute 'XX' defined outside __init__
-# W0212: Access to a protected member XX of a client class
-# W0221: Arguments number differs from overridden method
-# W0223: Method 'XX' is abstract in class 'YY' but is not overridden
-# W0231: __init__ method from base class 'XX' is not called
-# W0301: Unnecessary semicolon
-# W0311: Bad indentation. Found NN spaces, expected NN
-# W0401: Wildcard import XX
-# W0402: Uses of a deprecated module 'string'
-# W0403: Relative import 'XX', should be 'YY.XX'
-# W0404: Reimport 'XX' (imported line NN)
-# W0601: Global variable 'XX' undefined at the module level
-# W0602: Using global for 'XX' but no assignment is done
-# W0611: Unused import pprint
-# W0612: Unused variable 'XX'
-# W0613: Unused argument 'XX'
-# W0614: Unused import XX from wildcard import
-# W0621: Redefining name 'XX' from outer scope (line NN)
-# W0622: Redefining built-in 'NN'
-# W0631: Using possibly undefined loop variable 'XX'
-# W0701: Raising a string exception
-# W0702: No exception type(s) specified
-disable=C0103,C0111,C0302,R0902,R0903,R0904,R0912,R0913,R0914,R0915,W0141,W0142,W0232,W0511,W0603,C0112,C0301,C0321,C0322,C0323,C0324,E0101,E0102,E1002,E1101,E1103,E0602,F0401,R0201,R0801,W0102,W0104,W0105,W0108,W0201,W0212,W0221,W0223,W0231,W0301,W0311,W0401,W0402,W0403,W0404,W0601,W0602,W0611,W0612,W0613,W0614,W0621,W0622,W0631,W0701,W0702
-
-
-[REPORTS]
-
-# Set the output format. Available formats are text, parseable, colorized, msvs
-# (visual studio) and html
-output-format=text
-
-# Include message's id in output
-include-ids=yes
-
-# Put messages in a separate file for each module / package specified on the
-# command line instead of printing them on stdout. Reports (if any) will be
-# written in a file name "pylint_global.[txt|html]".
-files-output=no
-
-# Tells whether to display a full report or only the messages
-reports=no
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Add a comment according to your evaluation note. This is used by the global
-# evaluation report (RP0004).
-comment=no
-
-
-[VARIABLES]
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# A regular expression matching the beginning of the name of dummy variables
-# (i.e. not used).
-dummy-variables-rgx=_|dummy
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-
-[TYPECHECK]
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# List of classes names for which member attributes should not be checked
-# (useful for classes with attributes dynamically set).
-ignored-classes=SQLObject
-
-# When zope mode is activated, add a predefined set of Zope acquired attributes
-# to generated-members.
-zope=no
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E0201 when accessed. Python regular
-# expressions are accepted.
-generated-members=REQUEST,acl_users,aq_parent
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,XXX,TODO
-
-
-[SIMILARITIES]
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-
-[FORMAT]
-
-# Maximum number of characters on a single line.
-max-line-length=80
-
-# Maximum number of lines in a module
-max-module-lines=1000
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-indent-string=' '
-
-
-[BASIC]
-
-# Required attributes for module, separated by a comma
-required-attributes=
-
-# List of builtins function names that should not be used, separated by a comma
-bad-functions=map,filter,apply,input
-
-# Regular expression which should only match correct module names
-module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-
-# Regular expression which should only match correct module level names
-const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
-
-# Regular expression which should only match correct class names
-class-rgx=[A-Z_][a-zA-Z0-9]+$
-
-# Regular expression which should only match correct function names
-function-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct method names
-method-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct instance attribute names
-attr-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct argument names
-argument-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct variable names
-variable-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct list comprehension /
-# generator expression variable names
-inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
-
-# Good variable names which should always be accepted, separated by a comma
-good-names=i,j,k,ex,Run,_
-
-# Bad variable names which should always be refused, separated by a comma
-bad-names=foo,bar,baz,toto,tutu,tata
-
-# Regular expression which should only match functions or classes name which do
-# not require a docstring
-no-docstring-rgx=__.*__
-
-
-[DESIGN]
-
-# Maximum number of arguments for function / method
-max-args=5
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore
-ignored-argument-names=_.*
-
-# Maximum number of locals for function / method body
-max-locals=15
-
-# Maximum number of return / yield for function / method body
-max-returns=6
-
-# Maximum number of branch for function / method body
-max-branchs=12
-
-# Maximum number of statements in function / method body
-max-statements=50
-
-# Maximum number of parents for a class (see R0901).
-max-parents=7
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=7
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=2
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=20
-
-
-[CLASSES]
-
-# List of interface methods to ignore, separated by a comma. This is used for
-# instance to not check methods defines in Zope's Interface base class.
-ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,__new__,setUp
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-
-[IMPORTS]
-
-# Deprecated modules which should not be used, separated by a comma
-deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled)
-import-graph=
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled)
-ext-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled)
-int-import-graph=
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=Exception
diff --git a/node_modules/node-gyp/gyp/tools/emacs/gyp.el b/node_modules/node-gyp/gyp/tools/emacs/gyp.el
index 3db9f6459..b98b155ce 100644
--- a/node_modules/node-gyp/gyp/tools/emacs/gyp.el
+++ b/node_modules/node-gyp/gyp/tools/emacs/gyp.el
@@ -15,14 +15,36 @@
"recent emacsen), not from the older and less maintained "
"python-mode.el")))
-(defadvice python-calculate-indentation (after ami-outdent-closing-parens
- activate)
+(defadvice python-indent-calculate-levels (after gyp-outdent-closing-parens
+ activate)
"De-indent closing parens, braces, and brackets in gyp-mode."
- (if (and (eq major-mode 'gyp-mode)
- (string-match "^ *[])}][],)}]* *$"
- (buffer-substring-no-properties
- (line-beginning-position) (line-end-position))))
- (setq ad-return-value (- ad-return-value 2))))
+ (when (and (eq major-mode 'gyp-mode)
+ (string-match "^ *[])}][],)}]* *$"
+ (buffer-substring-no-properties
+ (line-beginning-position) (line-end-position))))
+ (setf (first python-indent-levels)
+ (- (first python-indent-levels) python-continuation-offset))))
+
+(defadvice python-indent-guess-indent-offset (around
+ gyp-indent-guess-indent-offset
+ activate)
+ "Guess correct indent offset in gyp-mode."
+ (or (and (not (eq major-mode 'gyp-mode))
+ ad-do-it)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ ;; Find first line ending with an opening brace that is not a comment.
+ (or (and (re-search-forward "\\(^[[{]$\\|^.*[^#].*[[{]$\\)")
+ (forward-line)
+ (/= (current-indentation) 0)
+ (set (make-local-variable 'python-indent-offset)
+ (current-indentation))
+ (set (make-local-variable 'python-continuation-offset)
+ (current-indentation)))
+ (message "Can't guess gyp indent offset, using default: %s"
+ python-continuation-offset))))))
(define-derived-mode gyp-mode python-mode "Gyp"
"Major mode for editing .gyp files. See http://code.google.com/p/gyp/"
@@ -35,9 +57,10 @@
(defun gyp-set-indentation ()
"Hook function to configure python indentation to suit gyp mode."
- (setq python-continuation-offset 2
- python-indent 2
- python-guess-indent nil))
+ (set (make-local-variable 'python-indent-offset) 2)
+ (set (make-local-variable 'python-continuation-offset) 2)
+ (set (make-local-variable 'python-indent-guess-indent-offset) t)
+ (python-indent-guess-indent-offset))
(add-hook 'gyp-mode-hook 'gyp-set-indentation)
@@ -218,11 +241,11 @@
;; Top-level keywords
(list (concat "['\"]\\("
(regexp-opt (list "action" "action_name" "actions" "cflags"
- "conditions" "configurations" "copies" "defines"
- "dependencies" "destination"
+ "cflags_cc" "conditions" "configurations"
+ "copies" "defines" "dependencies" "destination"
"direct_dependent_settings"
"export_dependent_settings" "extension" "files"
- "include_dirs" "includes" "inputs" "libraries"
+ "include_dirs" "includes" "inputs" "ldflags" "libraries"
"link_settings" "mac_bundle" "message"
"msvs_external_rule" "outputs" "product_name"
"process_outputs_as_sources" "rules" "rule_name"
diff --git a/node_modules/node-gyp/gyp/tools/pretty_sln.py b/node_modules/node-gyp/gyp/tools/pretty_sln.py
index 3195d8581..ca8cf4ad3 100755
--- a/node_modules/node-gyp/gyp/tools/pretty_sln.py
+++ b/node_modules/node-gyp/gyp/tools/pretty_sln.py
@@ -38,12 +38,13 @@ def ParseSolution(solution_file):
# Regular expressions that matches the SLN format.
# The first line of a project definition.
- begin_project = re.compile(('^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942'
- '}"\) = "(.*)", "(.*)", "(.*)"$'))
+ begin_project = re.compile(r'^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942'
+ r'}"\) = "(.*)", "(.*)", "(.*)"$')
# The last line of a project definition.
end_project = re.compile('^EndProject$')
# The first line of a dependency list.
- begin_dep = re.compile('ProjectSection\(ProjectDependencies\) = postProject$')
+ begin_dep = re.compile(
+ r'ProjectSection\(ProjectDependencies\) = postProject$')
# The last line of a dependency list.
end_dep = re.compile('EndProjectSection$')
# A line describing a dependency.
diff --git a/node_modules/node-gyp/lib/build.js b/node_modules/node-gyp/lib/build.js
index df24aaf45..eeeb60266 100644
--- a/node_modules/node-gyp/lib/build.js
+++ b/node_modules/node-gyp/lib/build.js
@@ -150,7 +150,7 @@ function build (gyp, argv, callback) {
return (x.version < y.version ? -1 : 1)
})
;(function verifyMsbuild () {
- if (!msbuilds.length) return callback(notfoundErr);
+ if (!msbuilds.length) return callback(notfoundErr)
msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe')
fs.stat(msbuildPath, function (err, stat) {
if (err) {
diff --git a/node_modules/node-gyp/lib/configure.js b/node_modules/node-gyp/lib/configure.js
index 68f26d6e1..e1118d324 100644
--- a/node_modules/node-gyp/lib/configure.js
+++ b/node_modules/node-gyp/lib/configure.js
@@ -13,6 +13,7 @@ var fs = require('graceful-fs')
, semver = require('semver')
, mkdirp = require('mkdirp')
, cp = require('child_process')
+ , PathArray = require('path-array')
, extend = require('util')._extend
, spawn = cp.spawn
, execFile = cp.execFile
@@ -22,7 +23,7 @@ exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' f
function configure (gyp, argv, callback) {
- var python = gyp.opts.python || process.env.PYTHON || 'python'
+ var python = gyp.opts.python || process.env.PYTHON || 'python2'
, buildDir = path.resolve('build')
, configNames = [ 'config.gypi', 'common.gypi' ]
, configs = []
@@ -36,6 +37,10 @@ function configure (gyp, argv, callback) {
which(python, function (err, execPath) {
if (err) {
log.verbose('`which` failed', python, err)
+ if (python === 'python2') {
+ python = 'python'
+ return checkPython()
+ }
if (win) {
guessPython()
} else {
@@ -73,8 +78,8 @@ function configure (gyp, argv, callback) {
}
function checkPythonVersion () {
- var env = extend({}, process.env);
- env.TERM = 'dumb';
+ var env = extend({}, process.env)
+ env.TERM = 'dumb'
execFile(python, ['-c', 'import platform; print(platform.python_version());'], { env: env }, function (err, stdout) {
if (err) {
@@ -328,7 +333,8 @@ function configure (gyp, argv, callback) {
argv.unshift(gyp_script)
// make sure python uses files that came with this particular node package
- process.env.PYTHONPATH = path.resolve(__dirname, '..', 'gyp', 'pylib')
+ var pypath = new PathArray(process.env, 'PYTHONPATH')
+ pypath.unshift(path.join(__dirname, '..', 'gyp', 'pylib'))
var cp = gyp.spawn(python, argv)
cp.on('exit', onCpExit)
diff --git a/node_modules/node-gyp/lib/install.js b/node_modules/node-gyp/lib/install.js
index 6f72e6a93..89e4956a8 100644
--- a/node_modules/node-gyp/lib/install.js
+++ b/node_modules/node-gyp/lib/install.js
@@ -230,6 +230,11 @@ function install (gyp, argv, callback) {
// something went wrong downloading the tarball?
req.on('error', function (err) {
+ if (err.code === 'ENOTFOUND') {
+ return cb(new Error('This is most likely not a problem with node-gyp or the package itself and\n' +
+ 'is related to network connectivity. In most cases you are behind a proxy or have bad \n' +
+ 'network settings.'))
+ }
badDownload = true
cb(err)
})
@@ -243,7 +248,7 @@ function install (gyp, argv, callback) {
req.on('response', function (res) {
if (res.statusCode !== 200) {
badDownload = true
- cb(new Error(res.statusCode + ' status code downloading tarball'))
+ cb(new Error(res.statusCode + ' response dowloading ' + tarballUrl))
return
}
// content checksum
@@ -277,9 +282,12 @@ function install (gyp, argv, callback) {
var installVersionPath = path.resolve(devDir, 'installVersion')
fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref)
- // download SHASUMS.txt
- async++
- downloadShasums(deref)
+ // Only download SHASUMS.txt if not using tarPath override
+ if (!tarPath) {
+ // download SHASUMS.txt
+ async++
+ downloadShasums(deref)
+ }
if (async === 0) {
// no async tasks required
diff --git a/node_modules/node-gyp/lib/rebuild.js b/node_modules/node-gyp/lib/rebuild.js
index 497ffbd96..4c6f472aa 100644
--- a/node_modules/node-gyp/lib/rebuild.js
+++ b/node_modules/node-gyp/lib/rebuild.js
@@ -3,8 +3,6 @@ module.exports = exports = rebuild
exports.usage = 'Runs "clean", "configure" and "build" all at once'
-var log = require('npmlog')
-
function rebuild (gyp, argv, callback) {
gyp.todo.push(
diff --git a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/LICENSE b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/LICENSE
index 05a401094..19129e315 100644
--- a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/LICENSE
+++ b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/LICENSE
@@ -1,23 +1,15 @@
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-All rights reserved.
+The ISC License
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
+Copyright (c) Isaac Z. Schlueter and Contributors
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/browser.js b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/browser.js
index cf58a3f60..967b45c0d 100644
--- a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/browser.js
+++ b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/browser.js
@@ -2,35 +2,36 @@
module.exports = minimatch
minimatch.Minimatch = Minimatch
-var isWindows = false
-if (typeof process !== 'undefined' && process.platform === 'win32')
- isWindows = true
+var path = { sep: '/' }
+try {
+ path = require('path')
+} catch (er) {}
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
- , expand = require("brace-expansion")
+var expand = require('brace-expansion')
- // any single thing other than /
- // don't need to escape / when using new RegExp()
- , qmark = "[^/]"
+// any single thing other than /
+// don't need to escape / when using new RegExp()
+var qmark = '[^/]'
- // * => any number of characters
- , star = qmark + "*?"
+// * => any number of characters
+var star = qmark + '*?'
- // ** when dots are allowed. Anything goes, except .. and .
- // not (^ or / followed by one or two dots followed by $ or /),
- // followed by anything, any number of times.
- , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
+// ** when dots are allowed. Anything goes, except .. and .
+// not (^ or / followed by one or two dots followed by $ or /),
+// followed by anything, any number of times.
+var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
- // not a ^ or / followed by a dot,
- // followed by anything, any number of times.
- , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
+// not a ^ or / followed by a dot,
+// followed by anything, any number of times.
+var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
- // characters that need to be escaped in RegExp.
- , reSpecials = charSet("().*{}+?[]^$\\!")
+// characters that need to be escaped in RegExp.
+var reSpecials = charSet('().*{}+?[]^$\\!')
// "abc" -> { a:true, b:true, c:true }
function charSet (s) {
- return s.split("").reduce(function (set, c) {
+ return s.split('').reduce(function (set, c) {
set[c] = true
return set
}, {})
@@ -81,21 +82,20 @@ Minimatch.defaults = function (def) {
return minimatch.defaults(def).Minimatch
}
-
function minimatch (p, pattern, options) {
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
+ if (typeof pattern !== 'string') {
+ throw new TypeError('glob pattern string required')
}
if (!options) options = {}
// shortcut: comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
+ if (!options.nocomment && pattern.charAt(0) === '#') {
return false
}
// "" only matches ""
- if (pattern.trim() === "") return p === ""
+ if (pattern.trim() === '') return p === ''
return new Minimatch(pattern, options).match(p)
}
@@ -105,16 +105,17 @@ function Minimatch (pattern, options) {
return new Minimatch(pattern, options)
}
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
+ if (typeof pattern !== 'string') {
+ throw new TypeError('glob pattern string required')
}
if (!options) options = {}
pattern = pattern.trim()
// windows support: need to use /, not \
- if (isWindows)
- pattern = pattern.split("\\").join("/")
+ if (path.sep !== '/') {
+ pattern = pattern.split(path.sep).join('/')
+ }
this.options = options
this.set = []
@@ -128,7 +129,7 @@ function Minimatch (pattern, options) {
this.make()
}
-Minimatch.prototype.debug = function() {}
+Minimatch.prototype.debug = function () {}
Minimatch.prototype.make = make
function make () {
@@ -139,7 +140,7 @@ function make () {
var options = this.options
// empty patterns and comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
+ if (!options.nocomment && pattern.charAt(0) === '#') {
this.comment = true
return
}
@@ -178,7 +179,7 @@ function make () {
// filter out everything that didn't compile properly.
set = set.filter(function (s) {
- return -1 === s.indexOf(false)
+ return s.indexOf(false) === -1
})
this.debug(this.pattern, set)
@@ -189,17 +190,17 @@ function make () {
Minimatch.prototype.parseNegate = parseNegate
function parseNegate () {
var pattern = this.pattern
- , negate = false
- , options = this.options
- , negateOffset = 0
+ var negate = false
+ var options = this.options
+ var negateOffset = 0
if (options.nonegate) return
- for ( var i = 0, l = pattern.length
- ; i < l && pattern.charAt(i) === "!"
- ; i ++) {
+ for (var i = 0, l = pattern.length
+ ; i < l && pattern.charAt(i) === '!'
+ ; i++) {
negate = !negate
- negateOffset ++
+ negateOffset++
}
if (negateOffset) this.pattern = pattern.substr(negateOffset)
@@ -224,21 +225,22 @@ Minimatch.prototype.braceExpand = braceExpand
function braceExpand (pattern, options) {
if (!options) {
- if (this instanceof Minimatch)
+ if (this instanceof Minimatch) {
options = this.options
- else
+ } else {
options = {}
+ }
}
- pattern = typeof pattern === "undefined"
+ pattern = typeof pattern === 'undefined'
? this.pattern : pattern
- if (typeof pattern === "undefined") {
- throw new Error("undefined pattern")
+ if (typeof pattern === 'undefined') {
+ throw new Error('undefined pattern')
}
if (options.nobrace ||
- !pattern.match(/\{.*\}/)) {
+ !pattern.match(/\{.*\}/)) {
// shortcut. no need to expand.
return [pattern]
}
@@ -263,87 +265,86 @@ function parse (pattern, isSub) {
var options = this.options
// shortcuts
- if (!options.noglobstar && pattern === "**") return GLOBSTAR
- if (pattern === "") return ""
-
- var re = ""
- , hasMagic = !!options.nocase
- , escaping = false
- // ? => one single character
- , patternListStack = []
- , plType
- , stateChar
- , inClass = false
- , reClassStart = -1
- , classStart = -1
- // . and .. never match anything that doesn't start with .,
- // even when options.dot is set.
- , patternStart = pattern.charAt(0) === "." ? "" // anything
- // not (start or / followed by . or .. followed by / or end)
- : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
- : "(?!\\.)"
- , self = this
+ if (!options.noglobstar && pattern === '**') return GLOBSTAR
+ if (pattern === '') return ''
+
+ var re = ''
+ var hasMagic = !!options.nocase
+ var escaping = false
+ // ? => one single character
+ var patternListStack = []
+ var plType
+ var stateChar
+ var inClass = false
+ var reClassStart = -1
+ var classStart = -1
+ // . and .. never match anything that doesn't start with .,
+ // even when options.dot is set.
+ var patternStart = pattern.charAt(0) === '.' ? '' // anything
+ // not (start or / followed by . or .. followed by / or end)
+ : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
+ : '(?!\\.)'
+ var self = this
function clearStateChar () {
if (stateChar) {
// we had some state-tracking character
// that wasn't consumed by this pass.
switch (stateChar) {
- case "*":
+ case '*':
re += star
hasMagic = true
- break
- case "?":
+ break
+ case '?':
re += qmark
hasMagic = true
- break
+ break
default:
- re += "\\"+stateChar
- break
+ re += '\\' + stateChar
+ break
}
self.debug('clearStateChar %j %j', stateChar, re)
stateChar = false
}
}
- for ( var i = 0, len = pattern.length, c
- ; (i < len) && (c = pattern.charAt(i))
- ; i ++ ) {
-
- this.debug("%s\t%s %s %j", pattern, i, re, c)
+ for (var i = 0, len = pattern.length, c
+ ; (i < len) && (c = pattern.charAt(i))
+ ; i++) {
+ this.debug('%s\t%s %s %j', pattern, i, re, c)
// skip over any that are escaped.
if (escaping && reSpecials[c]) {
- re += "\\" + c
+ re += '\\' + c
escaping = false
continue
}
- SWITCH: switch (c) {
- case "/":
+ switch (c) {
+ case '/':
// completely not allowed, even escaped.
// Should already be path-split by now.
return false
- case "\\":
+ case '\\':
clearStateChar()
escaping = true
- continue
+ continue
// the various stateChar values
// for the "extglob" stuff.
- case "?":
- case "*":
- case "+":
- case "@":
- case "!":
- this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
+ case '?':
+ case '*':
+ case '+':
+ case '@':
+ case '!':
+ this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
// all of those are literals inside a class, except that
// the glob [!a] means [^a] in regexp
if (inClass) {
this.debug(' in class')
- if (c === "!" && i === classStart + 1) c = "^"
+ if (c === '!' && i === classStart + 1) c = '^'
re += c
continue
}
@@ -358,70 +359,70 @@ function parse (pattern, isSub) {
// just clear the statechar *now*, rather than even diving into
// the patternList stuff.
if (options.noext) clearStateChar()
- continue
+ continue
- case "(":
+ case '(':
if (inClass) {
- re += "("
+ re += '('
continue
}
if (!stateChar) {
- re += "\\("
+ re += '\\('
continue
}
plType = stateChar
- patternListStack.push({ type: plType
- , start: i - 1
- , reStart: re.length })
+ patternListStack.push({ type: plType, start: i - 1, reStart: re.length })
// negation is (?:(?!js)[^/]*)
- re += stateChar === "!" ? "(?:(?!" : "(?:"
+ re += stateChar === '!' ? '(?:(?!' : '(?:'
this.debug('plType %j %j', stateChar, re)
stateChar = false
- continue
+ continue
- case ")":
+ case ')':
if (inClass || !patternListStack.length) {
- re += "\\)"
+ re += '\\)'
continue
}
clearStateChar()
hasMagic = true
- re += ")"
+ re += ')'
plType = patternListStack.pop().type
// negation is (?:(?!js)[^/]*)
// The others are (?:<pattern>)<type>
switch (plType) {
- case "!":
- re += "[^/]*?)"
+ case '!':
+ re += '[^/]*?)'
break
- case "?":
- case "+":
- case "*": re += plType
- case "@": break // the default anyway
+ case '?':
+ case '+':
+ case '*':
+ re += plType
+ break
+ case '@': break // the default anyway
}
- continue
+ continue
- case "|":
+ case '|':
if (inClass || !patternListStack.length || escaping) {
- re += "\\|"
+ re += '\\|'
escaping = false
continue
}
clearStateChar()
- re += "|"
- continue
+ re += '|'
+ continue
// these are mostly the same in regexp and glob
- case "[":
+ case '[':
// swallow any state-tracking char before the [
clearStateChar()
if (inClass) {
- re += "\\" + c
+ re += '\\' + c
continue
}
@@ -429,15 +430,15 @@ function parse (pattern, isSub) {
classStart = i
reClassStart = re.length
re += c
- continue
+ continue
- case "]":
+ case ']':
// a right bracket shall lose its special
// meaning and represent itself in
// a bracket expression if it occurs
// first in the list. -- POSIX.2 2.8.3.2
if (i === classStart + 1 || !inClass) {
- re += "\\" + c
+ re += '\\' + c
escaping = false
continue
}
@@ -454,11 +455,11 @@ function parse (pattern, isSub) {
// to do safely. For now, this is safe and works.
var cs = pattern.substring(classStart + 1, i)
try {
- new RegExp('[' + cs + ']')
+ RegExp('[' + cs + ']')
} catch (er) {
// not a valid class!
var sp = this.parse(cs, SUBPARSE)
- re = re.substr(0, reClassStart) + "\\[" + sp[0] + '\\]'
+ re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
hasMagic = hasMagic || sp[1]
inClass = false
continue
@@ -469,7 +470,7 @@ function parse (pattern, isSub) {
hasMagic = true
inClass = false
re += c
- continue
+ continue
default:
// swallow any state char that wasn't consumed
@@ -479,8 +480,8 @@ function parse (pattern, isSub) {
// no need
escaping = false
} else if (reSpecials[c]
- && !(c === "^" && inClass)) {
- re += "\\"
+ && !(c === '^' && inClass)) {
+ re += '\\'
}
re += c
@@ -488,7 +489,6 @@ function parse (pattern, isSub) {
} // switch
} // for
-
// handle the case where we left a class open.
// "[abc" is valid, equivalent to "\[abc"
if (inClass) {
@@ -496,9 +496,9 @@ function parse (pattern, isSub) {
// this is a huge pita. We now have to re-walk
// the contents of the would-be class to re-translate
// any characters that were passed through as-is
- var cs = pattern.substr(classStart + 1)
- , sp = this.parse(cs, SUBPARSE)
- re = re.substr(0, reClassStart) + "\\[" + sp[0]
+ cs = pattern.substr(classStart + 1)
+ sp = this.parse(cs, SUBPARSE)
+ re = re.substr(0, reClassStart) + '\\[' + sp[0]
hasMagic = hasMagic || sp[1]
}
@@ -508,14 +508,13 @@ function parse (pattern, isSub) {
// and escape any | chars that were passed through as-is for the regexp.
// Go through and escape them, taking care not to double-escape any
// | chars that were already escaped.
- var pl
- while (pl = patternListStack.pop()) {
+ for (var pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
var tail = re.slice(pl.reStart + 3)
// maybe some even number of \, then maybe 1 \, followed by a |
tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
if (!$2) {
// the | isn't already escaped, so escape it.
- $2 = "\\"
+ $2 = '\\'
}
// need to escape all those slashes *again*, without escaping the
@@ -524,46 +523,44 @@ function parse (pattern, isSub) {
// it exactly after itself. That's why this trick works.
//
// I am sorry that you have to see this.
- return $1 + $1 + $2 + "|"
+ return $1 + $1 + $2 + '|'
})
- this.debug("tail=%j\n %s", tail, tail)
- var t = pl.type === "*" ? star
- : pl.type === "?" ? qmark
- : "\\" + pl.type
+ this.debug('tail=%j\n %s', tail, tail)
+ var t = pl.type === '*' ? star
+ : pl.type === '?' ? qmark
+ : '\\' + pl.type
hasMagic = true
- re = re.slice(0, pl.reStart)
- + t + "\\("
- + tail
+ re = re.slice(0, pl.reStart) + t + '\\(' + tail
}
// handle trailing things that only matter at the very end.
clearStateChar()
if (escaping) {
// trailing \\
- re += "\\\\"
+ re += '\\\\'
}
// only need to apply the nodot start if the re starts with
// something that could conceivably capture a dot
var addPatternStart = false
switch (re.charAt(0)) {
- case ".":
- case "[":
- case "(": addPatternStart = true
+ case '.':
+ case '[':
+ case '(': addPatternStart = true
}
// if the re is not "" at this point, then we need to make sure
// it doesn't match against an empty path part.
// Otherwise a/* will match a/, which it should not.
- if (re !== "" && hasMagic) re = "(?=.)" + re
+ if (re !== '' && hasMagic) re = '(?=.)' + re
if (addPatternStart) re = patternStart + re
// parsing just a piece of a larger pattern.
if (isSub === SUBPARSE) {
- return [ re, hasMagic ]
+ return [re, hasMagic]
}
// skip the regexp for non-magical patterns
@@ -573,8 +570,8 @@ function parse (pattern, isSub) {
return globUnescape(pattern)
}
- var flags = options.nocase ? "i" : ""
- , regExp = new RegExp("^" + re + "$", flags)
+ var flags = options.nocase ? 'i' : ''
+ var regExp = new RegExp('^' + re + '$', flags)
regExp._glob = pattern
regExp._src = re
@@ -598,34 +595,38 @@ function makeRe () {
// when you just want to work with a regex.
var set = this.set
- if (!set.length) return this.regexp = false
+ if (!set.length) {
+ this.regexp = false
+ return this.regexp
+ }
var options = this.options
var twoStar = options.noglobstar ? star
- : options.dot ? twoStarDot
- : twoStarNoDot
- , flags = options.nocase ? "i" : ""
+ : options.dot ? twoStarDot
+ : twoStarNoDot
+ var flags = options.nocase ? 'i' : ''
var re = set.map(function (pattern) {
return pattern.map(function (p) {
return (p === GLOBSTAR) ? twoStar
- : (typeof p === "string") ? regExpEscape(p)
- : p._src
- }).join("\\\/")
- }).join("|")
+ : (typeof p === 'string') ? regExpEscape(p)
+ : p._src
+ }).join('\\\/')
+ }).join('|')
// must match entire pattern
// ending in a * or ** will make it less strict.
- re = "^(?:" + re + ")$"
+ re = '^(?:' + re + ')$'
// can match anything, as long as it's not this.
- if (this.negate) re = "^(?!" + re + ").*$"
+ if (this.negate) re = '^(?!' + re + ').*$'
try {
- return this.regexp = new RegExp(re, flags)
+ this.regexp = new RegExp(re, flags)
} catch (ex) {
- return this.regexp = false
+ this.regexp = false
}
+ return this.regexp
}
minimatch.match = function (list, pattern, options) {
@@ -642,23 +643,24 @@ minimatch.match = function (list, pattern, options) {
Minimatch.prototype.match = match
function match (f, partial) {
- this.debug("match", f, this.pattern)
+ this.debug('match', f, this.pattern)
// short-circuit in the case of busted things.
// comments, etc.
if (this.comment) return false
- if (this.empty) return f === ""
+ if (this.empty) return f === ''
- if (f === "/" && partial) return true
+ if (f === '/' && partial) return true
var options = this.options
// windows: need to use /, not \
- if (isWindows)
- f = f.split("\\").join("/")
+ if (path.sep !== '/') {
+ f = f.split(path.sep).join('/')
+ }
// treat the test path as a set of pathparts.
f = f.split(slashSplit)
- this.debug(this.pattern, "split", f)
+ this.debug(this.pattern, 'split', f)
// just ONE of the pattern sets in this.set needs to match
// in order for it to be valid. If negating, then just one
@@ -666,17 +668,19 @@ function match (f, partial) {
// Either way, return on the first hit.
var set = this.set
- this.debug(this.pattern, "set", set)
+ this.debug(this.pattern, 'set', set)
// Find the basename of the path by looking for the last non-empty segment
- var filename;
- for (var i = f.length - 1; i >= 0; i--) {
+ var filename
+ var i
+ for (i = f.length - 1; i >= 0; i--) {
filename = f[i]
if (filename) break
}
- for (var i = 0, l = set.length; i < l; i ++) {
- var pattern = set[i], file = f
+ for (i = 0; i < set.length; i++) {
+ var pattern = set[i]
+ var file = f
if (options.matchBase && pattern.length === 1) {
file = [filename]
}
@@ -701,23 +705,20 @@ function match (f, partial) {
Minimatch.prototype.matchOne = function (file, pattern, partial) {
var options = this.options
- this.debug("matchOne",
- { "this": this
- , file: file
- , pattern: pattern })
+ this.debug('matchOne',
+ { 'this': this, file: file, pattern: pattern })
- this.debug("matchOne", file.length, pattern.length)
+ this.debug('matchOne', file.length, pattern.length)
- for ( var fi = 0
- , pi = 0
- , fl = file.length
- , pl = pattern.length
+ for (var fi = 0,
+ pi = 0,
+ fl = file.length,
+ pl = pattern.length
; (fi < fl) && (pi < pl)
- ; fi ++, pi ++ ) {
-
- this.debug("matchOne loop")
+ ; fi++, pi++) {
+ this.debug('matchOne loop')
var p = pattern[pi]
- , f = file[fi]
+ var f = file[fi]
this.debug(pattern, p, f)
@@ -751,7 +752,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi
- , pr = pi + 1
+ var pr = pi + 1
if (pr === pl) {
this.debug('** at the end')
// a ** at the end will just swallow the rest.
@@ -760,19 +761,18 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
- for ( ; fi < fl; fi ++) {
- if (file[fi] === "." || file[fi] === ".." ||
- (!options.dot && file[fi].charAt(0) === ".")) return false
+ for (; fi < fl; fi++) {
+ if (file[fi] === '.' || file[fi] === '..' ||
+ (!options.dot && file[fi].charAt(0) === '.')) return false
}
return true
}
// ok, let's see if we can swallow whatever we can.
- WHILE: while (fr < fl) {
+ while (fr < fl) {
var swallowee = file[fr]
- this.debug('\nglobstar while',
- file, fr, pattern, pr, swallowee)
+ this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
// XXX remove this slice. Just pass the start index.
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
@@ -782,23 +782,24 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
} else {
// can't swallow "." or ".." ever.
// can only swallow ".foo" when explicitly asked.
- if (swallowee === "." || swallowee === ".." ||
- (!options.dot && swallowee.charAt(0) === ".")) {
- this.debug("dot detected!", file, fr, pattern, pr)
- break WHILE
+ if (swallowee === '.' || swallowee === '..' ||
+ (!options.dot && swallowee.charAt(0) === '.')) {
+ this.debug('dot detected!', file, fr, pattern, pr)
+ break
}
// ** swallows a segment, and continue.
this.debug('globstar swallow a segment, and continue')
- fr ++
+ fr++
}
}
+
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
// If there's more *pattern* left, then
if (partial) {
// ran out of file
- this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
+ this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
if (fr === fl) return true
}
return false
@@ -808,16 +809,16 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// non-magic patterns just have to match exactly
// patterns with magic have been turned into regexps.
var hit
- if (typeof p === "string") {
+ if (typeof p === 'string') {
if (options.nocase) {
hit = f.toLowerCase() === p.toLowerCase()
} else {
hit = f === p
}
- this.debug("string match", p, f, hit)
+ this.debug('string match', p, f, hit)
} else {
hit = f.match(p)
- this.debug("pattern match", p, f, hit)
+ this.debug('pattern match', p, f, hit)
}
if (!hit) return false
@@ -849,26 +850,24 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// this is only acceptable if we're on the very last
// empty segment of a file with a trailing slash.
// a/* should match a/b/
- var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
+ var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
return emptyFileEnd
}
// should be unreachable.
- throw new Error("wtf?")
+ throw new Error('wtf?')
}
-
// replace stuff like \* with *
function globUnescape (s) {
- return s.replace(/\\(.)/g, "$1")
+ return s.replace(/\\(.)/g, '$1')
}
-
function regExpEscape (s) {
- return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
+ return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}
-},{"brace-expansion":2}],2:[function(require,module,exports){
+},{"brace-expansion":2,"path":undefined}],2:[function(require,module,exports){
var concatMap = require('concat-map');
var balanced = require('balanced-match');
diff --git a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/minimatch.js b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/minimatch.js
index 2bfdf62b7..5e13d6d5b 100644
--- a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/minimatch.js
+++ b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/minimatch.js
@@ -1,35 +1,36 @@
module.exports = minimatch
minimatch.Minimatch = Minimatch
-var isWindows = false
-if (typeof process !== 'undefined' && process.platform === 'win32')
- isWindows = true
+var path = { sep: '/' }
+try {
+ path = require('path')
+} catch (er) {}
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
- , expand = require("brace-expansion")
+var expand = require('brace-expansion')
- // any single thing other than /
- // don't need to escape / when using new RegExp()
- , qmark = "[^/]"
+// any single thing other than /
+// don't need to escape / when using new RegExp()
+var qmark = '[^/]'
- // * => any number of characters
- , star = qmark + "*?"
+// * => any number of characters
+var star = qmark + '*?'
- // ** when dots are allowed. Anything goes, except .. and .
- // not (^ or / followed by one or two dots followed by $ or /),
- // followed by anything, any number of times.
- , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
+// ** when dots are allowed. Anything goes, except .. and .
+// not (^ or / followed by one or two dots followed by $ or /),
+// followed by anything, any number of times.
+var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
- // not a ^ or / followed by a dot,
- // followed by anything, any number of times.
- , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
+// not a ^ or / followed by a dot,
+// followed by anything, any number of times.
+var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
- // characters that need to be escaped in RegExp.
- , reSpecials = charSet("().*{}+?[]^$\\!")
+// characters that need to be escaped in RegExp.
+var reSpecials = charSet('().*{}+?[]^$\\!')
// "abc" -> { a:true, b:true, c:true }
function charSet (s) {
- return s.split("").reduce(function (set, c) {
+ return s.split('').reduce(function (set, c) {
set[c] = true
return set
}, {})
@@ -80,21 +81,20 @@ Minimatch.defaults = function (def) {
return minimatch.defaults(def).Minimatch
}
-
function minimatch (p, pattern, options) {
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
+ if (typeof pattern !== 'string') {
+ throw new TypeError('glob pattern string required')
}
if (!options) options = {}
// shortcut: comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
+ if (!options.nocomment && pattern.charAt(0) === '#') {
return false
}
// "" only matches ""
- if (pattern.trim() === "") return p === ""
+ if (pattern.trim() === '') return p === ''
return new Minimatch(pattern, options).match(p)
}
@@ -104,16 +104,17 @@ function Minimatch (pattern, options) {
return new Minimatch(pattern, options)
}
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
+ if (typeof pattern !== 'string') {
+ throw new TypeError('glob pattern string required')
}
if (!options) options = {}
pattern = pattern.trim()
// windows support: need to use /, not \
- if (isWindows)
- pattern = pattern.split("\\").join("/")
+ if (path.sep !== '/') {
+ pattern = pattern.split(path.sep).join('/')
+ }
this.options = options
this.set = []
@@ -127,7 +128,7 @@ function Minimatch (pattern, options) {
this.make()
}
-Minimatch.prototype.debug = function() {}
+Minimatch.prototype.debug = function () {}
Minimatch.prototype.make = make
function make () {
@@ -138,7 +139,7 @@ function make () {
var options = this.options
// empty patterns and comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
+ if (!options.nocomment && pattern.charAt(0) === '#') {
this.comment = true
return
}
@@ -177,7 +178,7 @@ function make () {
// filter out everything that didn't compile properly.
set = set.filter(function (s) {
- return -1 === s.indexOf(false)
+ return s.indexOf(false) === -1
})
this.debug(this.pattern, set)
@@ -188,17 +189,17 @@ function make () {
Minimatch.prototype.parseNegate = parseNegate
function parseNegate () {
var pattern = this.pattern
- , negate = false
- , options = this.options
- , negateOffset = 0
+ var negate = false
+ var options = this.options
+ var negateOffset = 0
if (options.nonegate) return
- for ( var i = 0, l = pattern.length
- ; i < l && pattern.charAt(i) === "!"
- ; i ++) {
+ for (var i = 0, l = pattern.length
+ ; i < l && pattern.charAt(i) === '!'
+ ; i++) {
negate = !negate
- negateOffset ++
+ negateOffset++
}
if (negateOffset) this.pattern = pattern.substr(negateOffset)
@@ -223,21 +224,22 @@ Minimatch.prototype.braceExpand = braceExpand
function braceExpand (pattern, options) {
if (!options) {
- if (this instanceof Minimatch)
+ if (this instanceof Minimatch) {
options = this.options
- else
+ } else {
options = {}
+ }
}
- pattern = typeof pattern === "undefined"
+ pattern = typeof pattern === 'undefined'
? this.pattern : pattern
- if (typeof pattern === "undefined") {
- throw new Error("undefined pattern")
+ if (typeof pattern === 'undefined') {
+ throw new Error('undefined pattern')
}
if (options.nobrace ||
- !pattern.match(/\{.*\}/)) {
+ !pattern.match(/\{.*\}/)) {
// shortcut. no need to expand.
return [pattern]
}
@@ -262,87 +264,86 @@ function parse (pattern, isSub) {
var options = this.options
// shortcuts
- if (!options.noglobstar && pattern === "**") return GLOBSTAR
- if (pattern === "") return ""
-
- var re = ""
- , hasMagic = !!options.nocase
- , escaping = false
- // ? => one single character
- , patternListStack = []
- , plType
- , stateChar
- , inClass = false
- , reClassStart = -1
- , classStart = -1
- // . and .. never match anything that doesn't start with .,
- // even when options.dot is set.
- , patternStart = pattern.charAt(0) === "." ? "" // anything
- // not (start or / followed by . or .. followed by / or end)
- : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
- : "(?!\\.)"
- , self = this
+ if (!options.noglobstar && pattern === '**') return GLOBSTAR
+ if (pattern === '') return ''
+
+ var re = ''
+ var hasMagic = !!options.nocase
+ var escaping = false
+ // ? => one single character
+ var patternListStack = []
+ var plType
+ var stateChar
+ var inClass = false
+ var reClassStart = -1
+ var classStart = -1
+ // . and .. never match anything that doesn't start with .,
+ // even when options.dot is set.
+ var patternStart = pattern.charAt(0) === '.' ? '' // anything
+ // not (start or / followed by . or .. followed by / or end)
+ : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
+ : '(?!\\.)'
+ var self = this
function clearStateChar () {
if (stateChar) {
// we had some state-tracking character
// that wasn't consumed by this pass.
switch (stateChar) {
- case "*":
+ case '*':
re += star
hasMagic = true
- break
- case "?":
+ break
+ case '?':
re += qmark
hasMagic = true
- break
+ break
default:
- re += "\\"+stateChar
- break
+ re += '\\' + stateChar
+ break
}
self.debug('clearStateChar %j %j', stateChar, re)
stateChar = false
}
}
- for ( var i = 0, len = pattern.length, c
- ; (i < len) && (c = pattern.charAt(i))
- ; i ++ ) {
-
- this.debug("%s\t%s %s %j", pattern, i, re, c)
+ for (var i = 0, len = pattern.length, c
+ ; (i < len) && (c = pattern.charAt(i))
+ ; i++) {
+ this.debug('%s\t%s %s %j', pattern, i, re, c)
// skip over any that are escaped.
if (escaping && reSpecials[c]) {
- re += "\\" + c
+ re += '\\' + c
escaping = false
continue
}
- SWITCH: switch (c) {
- case "/":
+ switch (c) {
+ case '/':
// completely not allowed, even escaped.
// Should already be path-split by now.
return false
- case "\\":
+ case '\\':
clearStateChar()
escaping = true
- continue
+ continue
// the various stateChar values
// for the "extglob" stuff.
- case "?":
- case "*":
- case "+":
- case "@":
- case "!":
- this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
+ case '?':
+ case '*':
+ case '+':
+ case '@':
+ case '!':
+ this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
// all of those are literals inside a class, except that
// the glob [!a] means [^a] in regexp
if (inClass) {
this.debug(' in class')
- if (c === "!" && i === classStart + 1) c = "^"
+ if (c === '!' && i === classStart + 1) c = '^'
re += c
continue
}
@@ -357,70 +358,70 @@ function parse (pattern, isSub) {
// just clear the statechar *now*, rather than even diving into
// the patternList stuff.
if (options.noext) clearStateChar()
- continue
+ continue
- case "(":
+ case '(':
if (inClass) {
- re += "("
+ re += '('
continue
}
if (!stateChar) {
- re += "\\("
+ re += '\\('
continue
}
plType = stateChar
- patternListStack.push({ type: plType
- , start: i - 1
- , reStart: re.length })
+ patternListStack.push({ type: plType, start: i - 1, reStart: re.length })
// negation is (?:(?!js)[^/]*)
- re += stateChar === "!" ? "(?:(?!" : "(?:"
+ re += stateChar === '!' ? '(?:(?!' : '(?:'
this.debug('plType %j %j', stateChar, re)
stateChar = false
- continue
+ continue
- case ")":
+ case ')':
if (inClass || !patternListStack.length) {
- re += "\\)"
+ re += '\\)'
continue
}
clearStateChar()
hasMagic = true
- re += ")"
+ re += ')'
plType = patternListStack.pop().type
// negation is (?:(?!js)[^/]*)
// The others are (?:<pattern>)<type>
switch (plType) {
- case "!":
- re += "[^/]*?)"
+ case '!':
+ re += '[^/]*?)'
break
- case "?":
- case "+":
- case "*": re += plType
- case "@": break // the default anyway
+ case '?':
+ case '+':
+ case '*':
+ re += plType
+ break
+ case '@': break // the default anyway
}
- continue
+ continue
- case "|":
+ case '|':
if (inClass || !patternListStack.length || escaping) {
- re += "\\|"
+ re += '\\|'
escaping = false
continue
}
clearStateChar()
- re += "|"
- continue
+ re += '|'
+ continue
// these are mostly the same in regexp and glob
- case "[":
+ case '[':
// swallow any state-tracking char before the [
clearStateChar()
if (inClass) {
- re += "\\" + c
+ re += '\\' + c
continue
}
@@ -428,15 +429,15 @@ function parse (pattern, isSub) {
classStart = i
reClassStart = re.length
re += c
- continue
+ continue
- case "]":
+ case ']':
// a right bracket shall lose its special
// meaning and represent itself in
// a bracket expression if it occurs
// first in the list. -- POSIX.2 2.8.3.2
if (i === classStart + 1 || !inClass) {
- re += "\\" + c
+ re += '\\' + c
escaping = false
continue
}
@@ -453,11 +454,11 @@ function parse (pattern, isSub) {
// to do safely. For now, this is safe and works.
var cs = pattern.substring(classStart + 1, i)
try {
- new RegExp('[' + cs + ']')
+ RegExp('[' + cs + ']')
} catch (er) {
// not a valid class!
var sp = this.parse(cs, SUBPARSE)
- re = re.substr(0, reClassStart) + "\\[" + sp[0] + '\\]'
+ re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
hasMagic = hasMagic || sp[1]
inClass = false
continue
@@ -468,7 +469,7 @@ function parse (pattern, isSub) {
hasMagic = true
inClass = false
re += c
- continue
+ continue
default:
// swallow any state char that wasn't consumed
@@ -478,8 +479,8 @@ function parse (pattern, isSub) {
// no need
escaping = false
} else if (reSpecials[c]
- && !(c === "^" && inClass)) {
- re += "\\"
+ && !(c === '^' && inClass)) {
+ re += '\\'
}
re += c
@@ -487,7 +488,6 @@ function parse (pattern, isSub) {
} // switch
} // for
-
// handle the case where we left a class open.
// "[abc" is valid, equivalent to "\[abc"
if (inClass) {
@@ -495,9 +495,9 @@ function parse (pattern, isSub) {
// this is a huge pita. We now have to re-walk
// the contents of the would-be class to re-translate
// any characters that were passed through as-is
- var cs = pattern.substr(classStart + 1)
- , sp = this.parse(cs, SUBPARSE)
- re = re.substr(0, reClassStart) + "\\[" + sp[0]
+ cs = pattern.substr(classStart + 1)
+ sp = this.parse(cs, SUBPARSE)
+ re = re.substr(0, reClassStart) + '\\[' + sp[0]
hasMagic = hasMagic || sp[1]
}
@@ -507,14 +507,13 @@ function parse (pattern, isSub) {
// and escape any | chars that were passed through as-is for the regexp.
// Go through and escape them, taking care not to double-escape any
// | chars that were already escaped.
- var pl
- while (pl = patternListStack.pop()) {
+ for (var pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
var tail = re.slice(pl.reStart + 3)
// maybe some even number of \, then maybe 1 \, followed by a |
tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
if (!$2) {
// the | isn't already escaped, so escape it.
- $2 = "\\"
+ $2 = '\\'
}
// need to escape all those slashes *again*, without escaping the
@@ -523,46 +522,44 @@ function parse (pattern, isSub) {
// it exactly after itself. That's why this trick works.
//
// I am sorry that you have to see this.
- return $1 + $1 + $2 + "|"
+ return $1 + $1 + $2 + '|'
})
- this.debug("tail=%j\n %s", tail, tail)
- var t = pl.type === "*" ? star
- : pl.type === "?" ? qmark
- : "\\" + pl.type
+ this.debug('tail=%j\n %s', tail, tail)
+ var t = pl.type === '*' ? star
+ : pl.type === '?' ? qmark
+ : '\\' + pl.type
hasMagic = true
- re = re.slice(0, pl.reStart)
- + t + "\\("
- + tail
+ re = re.slice(0, pl.reStart) + t + '\\(' + tail
}
// handle trailing things that only matter at the very end.
clearStateChar()
if (escaping) {
// trailing \\
- re += "\\\\"
+ re += '\\\\'
}
// only need to apply the nodot start if the re starts with
// something that could conceivably capture a dot
var addPatternStart = false
switch (re.charAt(0)) {
- case ".":
- case "[":
- case "(": addPatternStart = true
+ case '.':
+ case '[':
+ case '(': addPatternStart = true
}
// if the re is not "" at this point, then we need to make sure
// it doesn't match against an empty path part.
// Otherwise a/* will match a/, which it should not.
- if (re !== "" && hasMagic) re = "(?=.)" + re
+ if (re !== '' && hasMagic) re = '(?=.)' + re
if (addPatternStart) re = patternStart + re
// parsing just a piece of a larger pattern.
if (isSub === SUBPARSE) {
- return [ re, hasMagic ]
+ return [re, hasMagic]
}
// skip the regexp for non-magical patterns
@@ -572,8 +569,8 @@ function parse (pattern, isSub) {
return globUnescape(pattern)
}
- var flags = options.nocase ? "i" : ""
- , regExp = new RegExp("^" + re + "$", flags)
+ var flags = options.nocase ? 'i' : ''
+ var regExp = new RegExp('^' + re + '$', flags)
regExp._glob = pattern
regExp._src = re
@@ -597,34 +594,38 @@ function makeRe () {
// when you just want to work with a regex.
var set = this.set
- if (!set.length) return this.regexp = false
+ if (!set.length) {
+ this.regexp = false
+ return this.regexp
+ }
var options = this.options
var twoStar = options.noglobstar ? star
- : options.dot ? twoStarDot
- : twoStarNoDot
- , flags = options.nocase ? "i" : ""
+ : options.dot ? twoStarDot
+ : twoStarNoDot
+ var flags = options.nocase ? 'i' : ''
var re = set.map(function (pattern) {
return pattern.map(function (p) {
return (p === GLOBSTAR) ? twoStar
- : (typeof p === "string") ? regExpEscape(p)
- : p._src
- }).join("\\\/")
- }).join("|")
+ : (typeof p === 'string') ? regExpEscape(p)
+ : p._src
+ }).join('\\\/')
+ }).join('|')
// must match entire pattern
// ending in a * or ** will make it less strict.
- re = "^(?:" + re + ")$"
+ re = '^(?:' + re + ')$'
// can match anything, as long as it's not this.
- if (this.negate) re = "^(?!" + re + ").*$"
+ if (this.negate) re = '^(?!' + re + ').*$'
try {
- return this.regexp = new RegExp(re, flags)
+ this.regexp = new RegExp(re, flags)
} catch (ex) {
- return this.regexp = false
+ this.regexp = false
}
+ return this.regexp
}
minimatch.match = function (list, pattern, options) {
@@ -641,23 +642,24 @@ minimatch.match = function (list, pattern, options) {
Minimatch.prototype.match = match
function match (f, partial) {
- this.debug("match", f, this.pattern)
+ this.debug('match', f, this.pattern)
// short-circuit in the case of busted things.
// comments, etc.
if (this.comment) return false
- if (this.empty) return f === ""
+ if (this.empty) return f === ''
- if (f === "/" && partial) return true
+ if (f === '/' && partial) return true
var options = this.options
// windows: need to use /, not \
- if (isWindows)
- f = f.split("\\").join("/")
+ if (path.sep !== '/') {
+ f = f.split(path.sep).join('/')
+ }
// treat the test path as a set of pathparts.
f = f.split(slashSplit)
- this.debug(this.pattern, "split", f)
+ this.debug(this.pattern, 'split', f)
// just ONE of the pattern sets in this.set needs to match
// in order for it to be valid. If negating, then just one
@@ -665,17 +667,19 @@ function match (f, partial) {
// Either way, return on the first hit.
var set = this.set
- this.debug(this.pattern, "set", set)
+ this.debug(this.pattern, 'set', set)
// Find the basename of the path by looking for the last non-empty segment
- var filename;
- for (var i = f.length - 1; i >= 0; i--) {
+ var filename
+ var i
+ for (i = f.length - 1; i >= 0; i--) {
filename = f[i]
if (filename) break
}
- for (var i = 0, l = set.length; i < l; i ++) {
- var pattern = set[i], file = f
+ for (i = 0; i < set.length; i++) {
+ var pattern = set[i]
+ var file = f
if (options.matchBase && pattern.length === 1) {
file = [filename]
}
@@ -700,23 +704,20 @@ function match (f, partial) {
Minimatch.prototype.matchOne = function (file, pattern, partial) {
var options = this.options
- this.debug("matchOne",
- { "this": this
- , file: file
- , pattern: pattern })
+ this.debug('matchOne',
+ { 'this': this, file: file, pattern: pattern })
- this.debug("matchOne", file.length, pattern.length)
+ this.debug('matchOne', file.length, pattern.length)
- for ( var fi = 0
- , pi = 0
- , fl = file.length
- , pl = pattern.length
+ for (var fi = 0,
+ pi = 0,
+ fl = file.length,
+ pl = pattern.length
; (fi < fl) && (pi < pl)
- ; fi ++, pi ++ ) {
-
- this.debug("matchOne loop")
+ ; fi++, pi++) {
+ this.debug('matchOne loop')
var p = pattern[pi]
- , f = file[fi]
+ var f = file[fi]
this.debug(pattern, p, f)
@@ -750,7 +751,7 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi
- , pr = pi + 1
+ var pr = pi + 1
if (pr === pl) {
this.debug('** at the end')
// a ** at the end will just swallow the rest.
@@ -759,19 +760,18 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
- for ( ; fi < fl; fi ++) {
- if (file[fi] === "." || file[fi] === ".." ||
- (!options.dot && file[fi].charAt(0) === ".")) return false
+ for (; fi < fl; fi++) {
+ if (file[fi] === '.' || file[fi] === '..' ||
+ (!options.dot && file[fi].charAt(0) === '.')) return false
}
return true
}
// ok, let's see if we can swallow whatever we can.
- WHILE: while (fr < fl) {
+ while (fr < fl) {
var swallowee = file[fr]
- this.debug('\nglobstar while',
- file, fr, pattern, pr, swallowee)
+ this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
// XXX remove this slice. Just pass the start index.
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
@@ -781,23 +781,24 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
} else {
// can't swallow "." or ".." ever.
// can only swallow ".foo" when explicitly asked.
- if (swallowee === "." || swallowee === ".." ||
- (!options.dot && swallowee.charAt(0) === ".")) {
- this.debug("dot detected!", file, fr, pattern, pr)
- break WHILE
+ if (swallowee === '.' || swallowee === '..' ||
+ (!options.dot && swallowee.charAt(0) === '.')) {
+ this.debug('dot detected!', file, fr, pattern, pr)
+ break
}
// ** swallows a segment, and continue.
this.debug('globstar swallow a segment, and continue')
- fr ++
+ fr++
}
}
+
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
// If there's more *pattern* left, then
if (partial) {
// ran out of file
- this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
+ this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
if (fr === fl) return true
}
return false
@@ -807,16 +808,16 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// non-magic patterns just have to match exactly
// patterns with magic have been turned into regexps.
var hit
- if (typeof p === "string") {
+ if (typeof p === 'string') {
if (options.nocase) {
hit = f.toLowerCase() === p.toLowerCase()
} else {
hit = f === p
}
- this.debug("string match", p, f, hit)
+ this.debug('string match', p, f, hit)
} else {
hit = f.match(p)
- this.debug("pattern match", p, f, hit)
+ this.debug('pattern match', p, f, hit)
}
if (!hit) return false
@@ -848,21 +849,19 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
// this is only acceptable if we're on the very last
// empty segment of a file with a trailing slash.
// a/* should match a/b/
- var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
+ var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
return emptyFileEnd
}
// should be unreachable.
- throw new Error("wtf?")
+ throw new Error('wtf?')
}
-
// replace stuff like \* with *
function globUnescape (s) {
- return s.replace(/\\(.)/g, "$1")
+ return s.replace(/\\(.)/g, '$1')
}
-
function regExpEscape (s) {
- return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
+ return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}
diff --git a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/package.json b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/package.json
index ed83501e9..986de9389 100644
--- a/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/package.json
+++ b/node_modules/node-gyp/node_modules/glob/node_modules/minimatch/package.json
@@ -6,13 +6,14 @@
},
"name": "minimatch",
"description": "a glob matcher in javascript",
- "version": "2.0.4",
+ "version": "2.0.8",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/minimatch.git"
},
"main": "minimatch.js",
"scripts": {
+ "pretest": "standard minimatch.js test/*.js",
"test": "tap test/*.js",
"prepublish": "browserify -o browser.js -e minimatch.js --bare"
},
@@ -24,29 +25,31 @@
},
"devDependencies": {
"browserify": "^9.0.3",
+ "standard": "^3.7.2",
"tap": ""
},
- "license": {
- "type": "MIT",
- "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
- },
+ "license": "ISC",
"files": [
"minimatch.js",
"browser.js"
],
- "gitHead": "c75d17c23df3b6050338ee654a58490255b36ebc",
+ "gitHead": "0bc7d9c4b2bc816502184862b45bd090de3406a3",
"bugs": {
"url": "https://github.com/isaacs/minimatch/issues"
},
- "homepage": "https://github.com/isaacs/minimatch",
- "_id": "minimatch@2.0.4",
- "_shasum": "83bea115803e7a097a78022427287edb762fafed",
+ "homepage": "https://github.com/isaacs/minimatch#readme",
+ "_id": "minimatch@2.0.8",
+ "_shasum": "0bc20f6bf3570a698ef0ddff902063c6cabda6bf",
"_from": "minimatch@>=2.0.1 <3.0.0",
- "_npmVersion": "2.7.1",
- "_nodeVersion": "1.4.2",
+ "_npmVersion": "2.10.0",
+ "_nodeVersion": "2.0.1",
"_npmUser": {
"name": "isaacs",
- "email": "i@izs.me"
+ "email": "isaacs@npmjs.com"
+ },
+ "dist": {
+ "shasum": "0bc20f6bf3570a698ef0ddff902063c6cabda6bf",
+ "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-2.0.8.tgz"
},
"maintainers": [
{
@@ -54,11 +57,7 @@
"email": "i@izs.me"
}
],
- "dist": {
- "shasum": "83bea115803e7a097a78022427287edb762fafed",
- "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-2.0.4.tgz"
- },
"directories": {},
- "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.4.tgz",
+ "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.8.tgz",
"readme": "ERROR: No README data found!"
}
diff --git a/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/LICENSE b/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/LICENSE
index 0c44ae716..19129e315 100644
--- a/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/LICENSE
+++ b/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/LICENSE
@@ -1,27 +1,15 @@
-Copyright (c) Isaac Z. Schlueter ("Author")
-All rights reserved.
+The ISC License
-The BSD License
+Copyright (c) Isaac Z. Schlueter and Contributors
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/README.md b/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/README.md
index 7e365129e..25a38a53f 100644
--- a/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/README.md
+++ b/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/README.md
@@ -11,7 +11,7 @@ string key suitable for caches and the like.
function doSomething (someObj) {
var key = sigmund(someObj, maxDepth) // max depth defaults to 10
var cached = cache.get(key)
- if (cached) return cached)
+ if (cached) return cached
var result = expensiveCalculation(someObj)
cache.set(key, result)
@@ -26,11 +26,11 @@ For example, the object `{0:'foo'}` will be treated identically to the
array `['foo']`.
Also, just as there is no way to summon the soul from the scribblings
-of a cocain-addled psychoanalyst, there is no way to revive the object
+of a cocaine-addled psychoanalyst, there is no way to revive the object
from the signature string that sigmund gives you. In fact, it's
barely even readable.
-As with `sys.inspect` and `JSON.stringify`, larger objects will
+As with `util.inspect` and `JSON.stringify`, larger objects will
produce larger signature strings.
Because sigmund is a bit less strict than the more thorough
diff --git a/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/package.json b/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/package.json
index 86b783a1d..4255e77a9 100644
--- a/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/package.json
+++ b/node_modules/node-gyp/node_modules/minimatch/node_modules/sigmund/package.json
@@ -1,6 +1,6 @@
{
"name": "sigmund",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "Quick and dirty signatures for Objects.",
"main": "sigmund.js",
"directories": {
@@ -16,7 +16,7 @@
},
"repository": {
"type": "git",
- "url": "git://github.com/isaacs/sigmund"
+ "url": "git://github.com/isaacs/sigmund.git"
},
"keywords": [
"object",
@@ -30,17 +30,24 @@
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
- "license": "BSD",
- "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n var cached = cache.get(key)\n if (cached) return cached)\n\n var result = expensiveCalculation(someObj)\n cache.set(key, result)\n return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you. In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions. For example, these objects\nhave the same signature:\n\n var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for. It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n",
- "_id": "sigmund@1.0.0",
- "dist": {
- "shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296",
- "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz"
+ "license": "ISC",
+ "gitHead": "527f97aa5bb253d927348698c0cd3bb267d098c6",
+ "bugs": {
+ "url": "https://github.com/isaacs/sigmund/issues"
},
- "_npmVersion": "1.1.48",
+ "homepage": "https://github.com/isaacs/sigmund#readme",
+ "_id": "sigmund@1.0.1",
+ "_shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
+ "_from": "sigmund@>=1.0.0 <1.1.0",
+ "_npmVersion": "2.10.0",
+ "_nodeVersion": "2.0.1",
"_npmUser": {
"name": "isaacs",
- "email": "i@izs.me"
+ "email": "isaacs@npmjs.com"
+ },
+ "dist": {
+ "shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
+ "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
},
"maintainers": [
{
@@ -48,7 +55,6 @@
"email": "i@izs.me"
}
],
- "_shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296",
- "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz",
- "_from": "sigmund@>=1.0.0 <1.1.0"
+ "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "readme": "ERROR: No README data found!"
}
diff --git a/node_modules/node-gyp/node_modules/minimatch/package.json b/node_modules/node-gyp/node_modules/minimatch/package.json
index ed21c5137..8bf46ccae 100644
--- a/node_modules/node-gyp/node_modules/minimatch/package.json
+++ b/node_modules/node-gyp/node_modules/minimatch/package.json
@@ -53,5 +53,6 @@
"tarball": "http://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz"
},
"directories": {},
- "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz"
+ "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz",
+ "readme": "ERROR: No README data found!"
}
diff --git a/node_modules/node-gyp/node_modules/path-array/.npmignore b/node_modules/node-gyp/node_modules/path-array/.npmignore
new file mode 100644
index 000000000..07e6e472c
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/.npmignore
@@ -0,0 +1 @@
+/node_modules
diff --git a/node_modules/node-gyp/node_modules/path-array/.travis.yml b/node_modules/node-gyp/node_modules/path-array/.travis.yml
new file mode 100644
index 000000000..c7d8e3d83
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/.travis.yml
@@ -0,0 +1,6 @@
+language: node_js
+node_js:
+ - 0.8
+ - 0.9
+ - 0.10
+ - 0.11
diff --git a/node_modules/node-gyp/node_modules/path-array/History.md b/node_modules/node-gyp/node_modules/path-array/History.md
new file mode 100644
index 000000000..ff93a2a28
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/History.md
@@ -0,0 +1,22 @@
+
+1.0.0 / 2014-11-11
+==================
+
+ * index: add support for a configrable `property` name to use
+ * README: fix Travis badge
+
+0.0.2 / 2013-12-22
+==================
+
+ * README++
+ * test: add unshift() test
+ * test: add more tests
+ * index: ensure that the indexed getters/setters are set up in the constructor
+ * add .travis.yml file
+ * add initial tests
+
+0.0.1 / 2013-12-21
+==================
+
+ * add README.md
+ * initial commit
diff --git a/node_modules/node-gyp/node_modules/path-array/README.md b/node_modules/node-gyp/node_modules/path-array/README.md
new file mode 100644
index 000000000..2595316a1
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/README.md
@@ -0,0 +1,92 @@
+path-array
+==========
+### Treat your `$PATH` like a JavaScript Array
+[![Build Status](https://travis-ci.org/TooTallNate/path-array.svg?branch=master)](https://travis-ci.org/TooTallNate/path-array)
+
+This module provides a JavaScript `Array` implementation that is backed by your
+`$PATH` env variable. That is, you can use regular Array functions like `shift()`,
+`pop()`, `push()`, `unshift()`, etc. to mutate your `$PATH`.
+
+Also works for preparing an `env` object for passing to
+[`child_process.spawn()`][cp.spawn].
+
+
+Installation
+------------
+
+Install with `npm`:
+
+``` bash
+$ npm install path-array
+```
+
+
+Example
+-------
+
+Interacting with your own `$PATH` env variable:
+
+``` js
+var PathArray = require('path-array');
+
+// no args uses `process.env` by default
+var p = new PathArray();
+
+console.log(p);
+// [ './node_modules/.bin',
+// '/opt/local/bin',
+// '/opt/local/sbin',
+// '/usr/local/bin',
+// '/usr/local/sbin',
+// '/usr/bin',
+// '/bin',
+// '/usr/sbin',
+// '/sbin',
+// '/usr/local/bin',
+// '/opt/X11/bin' ]
+
+// push another path entry. this function mutates the `process.env.PATH`
+p.unshift('/foo');
+
+console.log(process.env.PATH);
+// '/foo:./node_modules/.bin:/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin'
+```
+
+
+API
+---
+
+### new PathArray([env]) → PathArray
+
+Creates and returns a new `PathArray` instance with the given `env` object. If no
+`env` is specified, then [`process.env`][process.env] is used by default.
+
+
+License
+-------
+
+(The MIT License)
+
+Copyright (c) 2013 Nathan Rajlich &lt;nathan@tootallnate.net&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+[process.env]: http://nodejs.org/docs/latest/api/process.html#process_process_env
+[cp.spawn]: http://nodejs.org/docs/latest/api/child_process.html#child_process_child_process_spawn_command_args_options
diff --git a/node_modules/node-gyp/node_modules/path-array/index.js b/node_modules/node-gyp/node_modules/path-array/index.js
new file mode 100644
index 000000000..40b982d2f
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/index.js
@@ -0,0 +1,137 @@
+
+/**
+ * Module dependencies.
+ */
+
+var inherits = require('util').inherits;
+var delimiter = require('path').delimiter || ':';
+var ArrayIndex = require('array-index');
+
+/**
+ * Module exports.
+ */
+
+module.exports = PathArray;
+
+/**
+ * `PathArray` constructor. Treat your `$PATH` like a mutable JavaScript Array!
+ *
+ * @param {Env} env - `process.env` object to use.
+ * @param {String} [property] - optional property name to use (`PATH` by default).
+ * @public
+ */
+
+function PathArray (env, property) {
+ if (!(this instanceof PathArray)) return new PathArray(env);
+ ArrayIndex.call(this);
+
+ this.property = property || 'PATH';
+
+ // overwrite only the `get` operator of the ".length" property
+ Object.defineProperty(this, 'length', {
+ get: this._getLength
+ });
+
+ // store the `process.env` object as a non-enumerable `_env`
+ Object.defineProperty(this, '_env', {
+ value: env || process.env,
+ writable: true,
+ enumerable: false,
+ configurable: true
+ });
+
+ // need to invoke the `length` getter to ensure that the
+ // indexed getters/setters are set up at this point
+ void(this.length);
+}
+
+// inherit from ArrayIndex
+inherits(PathArray, ArrayIndex);
+
+/**
+ * Returns the current $PATH representation as an Array.
+ *
+ * @api private
+ */
+
+PathArray.prototype._array = function () {
+ var path = this._env[this.property];
+ if (!path) return [];
+ return path.split(delimiter);
+};
+
+/**
+ * Sets the `env` object's `PATH` string to the values in the passed in Array
+ * instance.
+ *
+ * @api private
+ */
+
+PathArray.prototype._setArray = function (arr) {
+ // mutate the $PATH
+ this._env[this.property] = arr.join(delimiter);
+};
+
+/**
+ * `.length` getter operation implementation.
+ *
+ * @api private
+ */
+
+PathArray.prototype._getLength = function () {
+ var length = this._array().length;
+
+ // invoke the ArrayIndex internal `set` operator to ensure that
+ // there's getters/setters defined for the determined length so far...
+ this.length = length;
+
+ return length;
+};
+
+/**
+ * ArrayIndex [0] getter operator implementation.
+ *
+ * @api private
+ */
+
+PathArray.prototype.__get__ = function get (index) {
+ return this._array()[index];
+};
+
+/**
+ * ArrayIndex [0]= setter operator implementation.
+ *
+ * @api private
+ */
+
+PathArray.prototype.__set__ = function set (index, value) {
+ var arr = this._array();
+ arr[index] = value;
+ this._setArray(arr);
+ return value;
+};
+
+/**
+ * `toString()` returns the current $PATH string.
+ *
+ * @api public
+ */
+
+PathArray.prototype.toString = function toString () {
+ return this._env[this.property] || '';
+};
+
+// proxy the JavaScript Array functions, and mutate the $PATH
+Object.getOwnPropertyNames(Array.prototype).forEach(function (name) {
+ if ('constructor' == name) return;
+ if ('function' != typeof Array.prototype[name]) return;
+ if (/to(Locale)?String/.test(name)) return;
+ //console.log('proxy %s', name);
+
+ PathArray.prototype[name] = function () {
+ var arr = this._array();
+ var rtn = arr[name].apply(arr, arguments);
+ this._setArray(arr);
+ return rtn;
+ };
+});
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.npmignore b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.npmignore
new file mode 100644
index 000000000..3c3629e64
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.npmignore
@@ -0,0 +1 @@
+node_modules
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.travis.yml b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.travis.yml
new file mode 100644
index 000000000..99cdc7439
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
+ - "0.11"
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/History.md b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/History.md
new file mode 100644
index 000000000..20b03e9a8
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/History.md
@@ -0,0 +1,39 @@
+
+0.1.1 / 2014-11-03
+==================
+
+ * index: use `%o` debug formatters
+ * .travis: don't test node v0.9.x
+ * README: use svg for Travis badge
+ * add .jshintrc file
+
+0.1.0 / 2013-12-01
+==================
+
+ * add `History.md` file
+ * .travis.yml: test node v0.8-v0.11
+ * add component.json
+ * package: update "main" field
+ * package: beautify
+
+0.0.4 / 2013-09-27
+==================
+
+ * ensure that the `length` property has the same maximum as regular Arrays
+
+0.0.3 / 2013-09-15
+==================
+
+ * add `toArray()`, `toJSON()`, and `toString()` functions
+ * add an `inspect()` function
+
+0.0.2 / 2013-09-15
+==================
+
+ * use "configurable: true"
+ * add `travis.yml` file
+
+0.0.1 / 2013-06-14
+==================
+
+ * Initial release
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/Makefile b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/Makefile
new file mode 100644
index 000000000..0f14dac30
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/Makefile
@@ -0,0 +1,11 @@
+
+build: components index.js
+ @component build --dev
+
+components: component.json
+ @component install --dev
+
+clean:
+ rm -fr build components template.js
+
+.PHONY: clean
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/README.md b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/README.md
new file mode 100644
index 000000000..ecd3498dd
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/README.md
@@ -0,0 +1,156 @@
+array-index
+===========
+### Invoke getter/setter functions on array-like objects
+[![Build Status](https://secure.travis-ci.org/TooTallNate/array-index.svg)](http://travis-ci.org/TooTallNate/array-index)
+
+
+This little module provides an `ArrayIndex` constructor function that you can
+inherit from with your own objects. When a numbered property gets read, then the
+`__get__` function on the object will be invoked. When a numbered property gets
+set, then the `__set__` function on the object will be invoked.
+
+
+Installation
+------------
+
+Install with `npm`:
+
+``` bash
+$ npm install array-index
+```
+
+
+Examples
+--------
+
+A quick silly example, using `Math.sqrt()` for the "getter":
+
+``` js
+var ArrayIndex = require('array-index')
+
+// let's just create a singleton instance.
+var a = new ArrayIndex()
+
+// the "__get__" function is invoked for each "a[n]" access.
+// it is given a single argument, the "index" currently being accessed.
+// so here, we're passing in the `Math.sqrt()` function, so accessing
+// "a[9]" will return `Math.sqrt(9)`.
+a.__get__ = Math.sqrt
+
+// the "__get__" and "__set__" functions are only invoked up
+// to "a.length", so we must set that manually.
+a.length = 10
+
+console.log(a)
+// [ 0,
+// 1,
+// 1.4142135623730951,
+// 1.7320508075688772,
+// 2,
+// 2.23606797749979,
+// 2.449489742783178,
+// 2.6457513110645907,
+// 2.8284271247461903,
+// 3,
+// __get__: [Function: sqrt] ]
+```
+
+Here's an example of creating a subclass of `ArrayIndex` using `util.inherits()`:
+
+``` js
+var ArrayIndex = require('array-index')
+var inherits = require('util').inherits
+
+function MyArray (length) {
+ // be sure to call the ArrayIndex constructor in your own constructor
+ ArrayIndex.call(this, length)
+
+ // the "set" object will contain values at indexes previously set,
+ // so that they can be returned in the "getter" function. This is just a
+ // silly example, your subclass will have more meaningful logic.
+ Object.defineProperty(this, 'set', {
+ value: Object.create(null),
+ enumerable: false
+ })
+}
+
+// inherit from the ArrayIndex's prototype
+inherits(MyArray, ArrayIndex)
+
+MyArray.prototype.__get__ = function (index) {
+ if (index in this.set) return this.set[index]
+ return index * 2
+}
+
+MyArray.prototype.__set__ = function (index, v) {
+ this.set[index] = v
+}
+
+
+// and now you can create some instances
+var a = new MyArray(15)
+a[9] = a[10] = a[14] = '_'
+a[0] = 'nate'
+
+console.log(a)
+// [ 'nate', 2, 4, 6, 8, 10, 12, 14, 16, '_', '_', 22, 24, 26, '_' ]
+```
+
+API
+---
+
+The `ArrayIndex` base class is meant to be subclassed, but it also has a few
+convenient functions built-in.
+
+### "length" -> Number
+
+The length of the ArrayIndex instance. The `__get__` and `__set__` functions will
+only be invoked on the object up to this "length". You may set this length at any
+time to adjust the amount range where the getters/setters will be invoked.
+
+### "toArray()" -> Array
+
+Returns a new regular Array instance with the same values that this ArrayIndex
+class would have. This function calls the `__get__` function repeatedly from
+`0...length-1` and returns the "flattened" array instance.
+
+### "toJSON()" -> Array
+
+All `ArrayIndex` instances get basic support for `JSON.stringify()`, which is
+the same as a "flattened" Array being stringified.
+
+### "toString()" -> String
+
+The `toString()` override is basically just `array.toArray().toString()`.
+
+### "format()" -> String
+
+The `inspect()` implementation for the REPL attempts to mimic what a regular
+Array looks like in the REPL.
+
+
+License
+-------
+
+(The MIT License)
+
+Copyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/component.json b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/component.json
new file mode 100644
index 000000000..390d7a7fe
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/component.json
@@ -0,0 +1,22 @@
+{
+ "name": "array-index",
+ "repo": "TooTallNate/array-index",
+ "description": "Invoke getter/setter functions on array-like objects",
+ "keywords": [
+ "index",
+ "array",
+ "getter",
+ "setter",
+ "proxy"
+ ],
+ "version": "0.1.1",
+ "dependencies": {
+ "visionmedia/debug": "*"
+ },
+ "development": {},
+ "license": "MIT",
+ "main": "index.js",
+ "scripts": [
+ "index.js"
+ ]
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/index.js b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/index.js
new file mode 100644
index 000000000..18069c6bc
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/index.js
@@ -0,0 +1,180 @@
+
+/**
+ * Module dependencies.
+ */
+
+var util = require('util')
+var debug = require('debug')('array-index')
+
+/**
+ * JavaScript Array "length" is bound to an unsigned 32-bit int.
+ * See: http://stackoverflow.com/a/6155063/376773
+ */
+
+var MAX_LENGTH = Math.pow(2, 32)
+
+/**
+ * Module exports.
+ */
+
+module.exports = ArrayIndex
+
+/**
+ * Subclass this.
+ */
+
+function ArrayIndex (length) {
+ Object.defineProperty(this, 'length', {
+ get: getLength,
+ set: setLength,
+ enumerable: false,
+ configurable: true
+ })
+
+ Object.defineProperty(this, '__length', {
+ value: 0,
+ writable: true,
+ enumerable: false,
+ configurable: true
+ })
+
+ if (arguments.length > 0) {
+ this.length = length
+ }
+}
+
+/**
+ * You overwrite the "__get__" function in your subclass.
+ */
+
+ArrayIndex.prototype.__get__ = function () {
+ throw new Error('you must implement the __get__ function')
+}
+
+/**
+ * You overwrite the "__set__" function in your subclass.
+ */
+
+ArrayIndex.prototype.__set__ = function () {
+ throw new Error('you must implement the __set__ function')
+}
+
+/**
+ * Converts this array class into a real JavaScript Array. Note that this
+ * is a "flattened" array and your defined getters and setters won't be invoked
+ * when you interact with the returned Array. This function will call the
+ * getter on every array index of the object.
+ *
+ * @return {Array} The flattened array
+ * @api public
+ */
+
+ArrayIndex.prototype.toArray = function toArray () {
+ var i = 0, l = this.length, array = new Array(l)
+ for (; i < l; i++) {
+ array[i] = this[i]
+ }
+ return array
+}
+
+/**
+ * Basic support for `JSON.stringify()`.
+ */
+
+ArrayIndex.prototype.toJSON = function toJSON () {
+ return this.toArray()
+}
+
+/**
+ * toString() override. Use Array.prototype.toString().
+ */
+
+ArrayIndex.prototype.toString = function toString () {
+ var a = this.toArray()
+ return a.toString.apply(a, arguments)
+}
+
+/**
+ * inspect() override. For the REPL.
+ */
+
+ArrayIndex.prototype.inspect = function inspect () {
+ var a = this.toArray()
+ Object.keys(this).forEach(function (k) {
+ a[k] = this[k]
+ }, this)
+ return util.inspect(a)
+}
+
+/**
+ * Getter for the "length" property.
+ * Returns the value of the "__length" property.
+ */
+
+function getLength () {
+ debug('getting "length": %o', this.__length)
+ return this.__length
+}
+
+/**
+ * Setter for the "length" property.
+ * Calls "ensureLength()", then sets the "__length" property.
+ */
+
+function setLength (v) {
+ debug('setting "length": %o', v)
+ return this.__length = ensureLength(v)
+}
+
+/**
+ * Ensures that getters/setters from 0 up to "_length" have been defined
+ * on `ArrayIndex.prototype`.
+ *
+ * @api private
+ */
+
+function ensureLength (_length) {
+ var length
+ if (_length > MAX_LENGTH) {
+ length = MAX_LENGTH
+ } else {
+ length = _length | 0
+ }
+ var cur = ArrayIndex.prototype.__length__ | 0
+ var num = length - cur
+ if (num > 0) {
+ var desc = {}
+ debug('creating a descriptor object with %o entries', num)
+ for (var i = cur; i < length; i++) {
+ desc[i] = setup(i)
+ }
+ debug('done creating descriptor object')
+ debug('calling `Object.defineProperties()` with %o entries', num)
+ Object.defineProperties(ArrayIndex.prototype, desc)
+ debug('finished `Object.defineProperties()`')
+ ArrayIndex.prototype.__length__ = length
+ }
+ return length
+}
+
+/**
+ * Returns a property descriptor for the given "index", with "get" and "set"
+ * functions created within the closure.
+ *
+ * @api private
+ */
+
+function setup (index) {
+ function get () {
+ return this.__get__(index)
+ }
+ function set (v) {
+ return this.__set__(index, v)
+ }
+ return {
+ enumerable: true
+ , configurable: true
+ , get: get
+ , set: set
+ }
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/.npmignore b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/.npmignore
new file mode 100644
index 000000000..7e6163db0
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/.npmignore
@@ -0,0 +1,6 @@
+support
+test
+examples
+example
+*.sock
+dist
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/History.md b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/History.md
new file mode 100644
index 000000000..854c9711c
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/History.md
@@ -0,0 +1,195 @@
+
+2.2.0 / 2015-05-09
+==================
+
+ * package: update "ms" to v0.7.1 (#202, @dougwilson)
+ * README: add logging to file example (#193, @DanielOchoa)
+ * README: fixed a typo (#191, @amir-s)
+ * browser: expose `storage` (#190, @stephenmathieson)
+ * Makefile: add a `distclean` target (#189, @stephenmathieson)
+
+2.1.3 / 2015-03-13
+==================
+
+ * Updated stdout/stderr example (#186)
+ * Updated example/stdout.js to match debug current behaviour
+ * Renamed example/stderr.js to stdout.js
+ * Update Readme.md (#184)
+ * replace high intensity foreground color for bold (#182, #183)
+
+2.1.2 / 2015-03-01
+==================
+
+ * dist: recompile
+ * update "ms" to v0.7.0
+ * package: update "browserify" to v9.0.3
+ * component: fix "ms.js" repo location
+ * changed bower package name
+ * updated documentation about using debug in a browser
+ * fix: security error on safari (#167, #168, @yields)
+
+2.1.1 / 2014-12-29
+==================
+
+ * browser: use `typeof` to check for `console` existence
+ * browser: check for `console.log` truthiness (fix IE 8/9)
+ * browser: add support for Chrome apps
+ * Readme: added Windows usage remarks
+ * Add `bower.json` to properly support bower install
+
+2.1.0 / 2014-10-15
+==================
+
+ * node: implement `DEBUG_FD` env variable support
+ * package: update "browserify" to v6.1.0
+ * package: add "license" field to package.json (#135, @panuhorsmalahti)
+
+2.0.0 / 2014-09-01
+==================
+
+ * package: update "browserify" to v5.11.0
+ * node: use stderr rather than stdout for logging (#29, @stephenmathieson)
+
+1.0.4 / 2014-07-15
+==================
+
+ * dist: recompile
+ * example: remove `console.info()` log usage
+ * example: add "Content-Type" UTF-8 header to browser example
+ * browser: place %c marker after the space character
+ * browser: reset the "content" color via `color: inherit`
+ * browser: add colors support for Firefox >= v31
+ * debug: prefer an instance `log()` function over the global one (#119)
+ * Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
+
+1.0.3 / 2014-07-09
+==================
+
+ * Add support for multiple wildcards in namespaces (#122, @seegno)
+ * browser: fix lint
+
+1.0.2 / 2014-06-10
+==================
+
+ * browser: update color palette (#113, @gscottolson)
+ * common: make console logging function configurable (#108, @timoxley)
+ * node: fix %o colors on old node <= 0.8.x
+ * Makefile: find node path using shell/which (#109, @timoxley)
+
+1.0.1 / 2014-06-06
+==================
+
+ * browser: use `removeItem()` to clear localStorage
+ * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
+ * package: add "contributors" section
+ * node: fix comment typo
+ * README: list authors
+
+1.0.0 / 2014-06-04
+==================
+
+ * make ms diff be global, not be scope
+ * debug: ignore empty strings in enable()
+ * node: make DEBUG_COLORS able to disable coloring
+ * *: export the `colors` array
+ * npmignore: don't publish the `dist` dir
+ * Makefile: refactor to use browserify
+ * package: add "browserify" as a dev dependency
+ * Readme: add Web Inspector Colors section
+ * node: reset terminal color for the debug content
+ * node: map "%o" to `util.inspect()`
+ * browser: map "%j" to `JSON.stringify()`
+ * debug: add custom "formatters"
+ * debug: use "ms" module for humanizing the diff
+ * Readme: add "bash" syntax highlighting
+ * browser: add Firebug color support
+ * browser: add colors for WebKit browsers
+ * node: apply log to `console`
+ * rewrite: abstract common logic for Node & browsers
+ * add .jshintrc file
+
+0.8.1 / 2014-04-14
+==================
+
+ * package: re-add the "component" section
+
+0.8.0 / 2014-03-30
+==================
+
+ * add `enable()` method for nodejs. Closes #27
+ * change from stderr to stdout
+ * remove unnecessary index.js file
+
+0.7.4 / 2013-11-13
+==================
+
+ * remove "browserify" key from package.json (fixes something in browserify)
+
+0.7.3 / 2013-10-30
+==================
+
+ * fix: catch localStorage security error when cookies are blocked (Chrome)
+ * add debug(err) support. Closes #46
+ * add .browser prop to package.json. Closes #42
+
+0.7.2 / 2013-02-06
+==================
+
+ * fix package.json
+ * fix: Mobile Safari (private mode) is broken with debug
+ * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
+
+0.7.1 / 2013-02-05
+==================
+
+ * add repository URL to package.json
+ * add DEBUG_COLORED to force colored output
+ * add browserify support
+ * fix component. Closes #24
+
+0.7.0 / 2012-05-04
+==================
+
+ * Added .component to package.json
+ * Added debug.component.js build
+
+0.6.0 / 2012-03-16
+==================
+
+ * Added support for "-" prefix in DEBUG [Vinay Pulim]
+ * Added `.enabled` flag to the node version [TooTallNate]
+
+0.5.0 / 2012-02-02
+==================
+
+ * Added: humanize diffs. Closes #8
+ * Added `debug.disable()` to the CS variant
+ * Removed padding. Closes #10
+ * Fixed: persist client-side variant again. Closes #9
+
+0.4.0 / 2012-02-01
+==================
+
+ * Added browser variant support for older browsers [TooTallNate]
+ * Added `debug.enable('project:*')` to browser variant [TooTallNate]
+ * Added padding to diff (moved it to the right)
+
+0.3.0 / 2012-01-26
+==================
+
+ * Added millisecond diff when isatty, otherwise UTC string
+
+0.2.0 / 2012-01-22
+==================
+
+ * Added wildcard support
+
+0.1.0 / 2011-12-02
+==================
+
+ * Added: remove colors unless stderr isatty [TooTallNate]
+
+0.0.1 / 2010-01-03
+==================
+
+ * Initial release
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Makefile b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Makefile
new file mode 100644
index 000000000..5cf4a5962
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Makefile
@@ -0,0 +1,36 @@
+
+# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
+THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
+
+# BIN directory
+BIN := $(THIS_DIR)/node_modules/.bin
+
+# applications
+NODE ?= $(shell which node)
+NPM ?= $(NODE) $(shell which npm)
+BROWSERIFY ?= $(NODE) $(BIN)/browserify
+
+all: dist/debug.js
+
+install: node_modules
+
+clean:
+ @rm -rf dist
+
+dist:
+ @mkdir -p $@
+
+dist/debug.js: node_modules browser.js debug.js dist
+ @$(BROWSERIFY) \
+ --standalone debug \
+ . > $@
+
+distclean: clean
+ @rm -rf node_modules
+
+node_modules: package.json
+ @NODE_ENV= $(NPM) install
+ @touch node_modules
+
+.PHONY: all install clean distclean
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Readme.md b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Readme.md
new file mode 100644
index 000000000..b4f45e3cc
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/Readme.md
@@ -0,0 +1,188 @@
+# debug
+
+ tiny node.js debugging utility modelled after node core's debugging technique.
+
+## Installation
+
+```bash
+$ npm install debug
+```
+
+## Usage
+
+ With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
+
+Example _app.js_:
+
+```js
+var debug = require('debug')('http')
+ , http = require('http')
+ , name = 'My App';
+
+// fake app
+
+debug('booting %s', name);
+
+http.createServer(function(req, res){
+ debug(req.method + ' ' + req.url);
+ res.end('hello\n');
+}).listen(3000, function(){
+ debug('listening');
+});
+
+// fake worker of some kind
+
+require('./worker');
+```
+
+Example _worker.js_:
+
+```js
+var debug = require('debug')('worker');
+
+setInterval(function(){
+ debug('doing some work');
+}, 1000);
+```
+
+ The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
+
+ ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
+
+ ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
+
+#### Windows note
+
+ On Windows the environment variable is set using the `set` command.
+
+ ```cmd
+ set DEBUG=*,-not_this
+ ```
+
+Then, run the program to be debugged as usual.
+
+## Millisecond diff
+
+ When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
+
+ ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
+
+ When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
+
+ ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
+
+## Conventions
+
+ If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
+
+## Wildcards
+
+ The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
+
+ You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
+
+## Browser support
+
+ Debug works in the browser as well, currently persisted by `localStorage`. Consider the situation shown below where you have `worker:a` and `worker:b`, and wish to debug both. Somewhere in the code on your page, include:
+
+```js
+window.myDebug = require("debug");
+```
+
+ ("debug" is a global object in the browser so we give this object a different name.) When your page is open in the browser, type the following in the console:
+
+```js
+myDebug.enable("worker:*")
+```
+
+ Refresh the page. Debug output will continue to be sent to the console until it is disabled by typing `myDebug.disable()` in the console.
+
+```js
+a = debug('worker:a');
+b = debug('worker:b');
+
+setInterval(function(){
+ a('doing some work');
+}, 1000);
+
+setInterval(function(){
+ b('doing some work');
+}, 1200);
+```
+
+#### Web Inspector Colors
+
+ Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
+ option. These are WebKit web inspectors, Firefox ([since version
+ 31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
+ and the Firebug plugin for Firefox (any version).
+
+ Colored output looks something like:
+
+ ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
+
+### stderr vs stdout
+
+You can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:
+
+Example _stdout.js_:
+
+```js
+var debug = require('debug');
+var error = debug('app:error');
+
+// by default stderr is used
+error('goes to stderr!');
+
+var log = debug('app:log');
+// set this namespace to log via console.log
+log.log = console.log.bind(console); // don't forget to bind to console!
+log('goes to stdout');
+error('still goes to stderr!');
+
+// set all output to go via console.info
+// overrides all per-namespace log settings
+debug.log = console.info.bind(console);
+error('now goes to stdout via console.info');
+log('still goes to stdout, but via console.info now');
+```
+
+### Save debug output to a file
+
+You can save all debug statements to a file by piping them.
+
+Example:
+
+```bash
+$ DEBUG_FD=3 node your-app.js 3> whatever.log
+```
+
+## Authors
+
+ - TJ Holowaychuk
+ - Nathan Rajlich
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2014 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/bower.json b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/bower.json
new file mode 100644
index 000000000..6af573ff5
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/bower.json
@@ -0,0 +1,28 @@
+{
+ "name": "visionmedia-debug",
+ "main": "dist/debug.js",
+ "version": "2.2.0",
+ "homepage": "https://github.com/visionmedia/debug",
+ "authors": [
+ "TJ Holowaychuk <tj@vision-media.ca>"
+ ],
+ "description": "visionmedia-debug",
+ "moduleType": [
+ "amd",
+ "es6",
+ "globals",
+ "node"
+ ],
+ "keywords": [
+ "visionmedia",
+ "debug"
+ ],
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ]
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/browser.js b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/browser.js
new file mode 100644
index 000000000..7c7645221
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/browser.js
@@ -0,0 +1,168 @@
+
+/**
+ * This is the web browser implementation of `debug()`.
+ *
+ * Expose `debug()` as the module.
+ */
+
+exports = module.exports = require('./debug');
+exports.log = log;
+exports.formatArgs = formatArgs;
+exports.save = save;
+exports.load = load;
+exports.useColors = useColors;
+exports.storage = 'undefined' != typeof chrome
+ && 'undefined' != typeof chrome.storage
+ ? chrome.storage.local
+ : localstorage();
+
+/**
+ * Colors.
+ */
+
+exports.colors = [
+ 'lightseagreen',
+ 'forestgreen',
+ 'goldenrod',
+ 'dodgerblue',
+ 'darkorchid',
+ 'crimson'
+];
+
+/**
+ * Currently only WebKit-based Web Inspectors, Firefox >= v31,
+ * and the Firebug extension (any Firefox version) are known
+ * to support "%c" CSS customizations.
+ *
+ * TODO: add a `localStorage` variable to explicitly enable/disable colors
+ */
+
+function useColors() {
+ // is webkit? http://stackoverflow.com/a/16459606/376773
+ return ('WebkitAppearance' in document.documentElement.style) ||
+ // is firebug? http://stackoverflow.com/a/398120/376773
+ (window.console && (console.firebug || (console.exception && console.table))) ||
+ // is firefox >= v31?
+ // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
+ (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
+}
+
+/**
+ * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
+ */
+
+exports.formatters.j = function(v) {
+ return JSON.stringify(v);
+};
+
+
+/**
+ * Colorize log arguments if enabled.
+ *
+ * @api public
+ */
+
+function formatArgs() {
+ var args = arguments;
+ var useColors = this.useColors;
+
+ args[0] = (useColors ? '%c' : '')
+ + this.namespace
+ + (useColors ? ' %c' : ' ')
+ + args[0]
+ + (useColors ? '%c ' : ' ')
+ + '+' + exports.humanize(this.diff);
+
+ if (!useColors) return args;
+
+ var c = 'color: ' + this.color;
+ args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
+
+ // the final "%c" is somewhat tricky, because there could be other
+ // arguments passed either before or after the %c, so we need to
+ // figure out the correct index to insert the CSS into
+ var index = 0;
+ var lastC = 0;
+ args[0].replace(/%[a-z%]/g, function(match) {
+ if ('%%' === match) return;
+ index++;
+ if ('%c' === match) {
+ // we only are interested in the *last* %c
+ // (the user may have provided their own)
+ lastC = index;
+ }
+ });
+
+ args.splice(lastC, 0, c);
+ return args;
+}
+
+/**
+ * Invokes `console.log()` when available.
+ * No-op when `console.log` is not a "function".
+ *
+ * @api public
+ */
+
+function log() {
+ // this hackery is required for IE8/9, where
+ // the `console.log` function doesn't have 'apply'
+ return 'object' === typeof console
+ && console.log
+ && Function.prototype.apply.call(console.log, console, arguments);
+}
+
+/**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+
+function save(namespaces) {
+ try {
+ if (null == namespaces) {
+ exports.storage.removeItem('debug');
+ } else {
+ exports.storage.debug = namespaces;
+ }
+ } catch(e) {}
+}
+
+/**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+
+function load() {
+ var r;
+ try {
+ r = exports.storage.debug;
+ } catch(e) {}
+ return r;
+}
+
+/**
+ * Enable namespaces listed in `localStorage.debug` initially.
+ */
+
+exports.enable(load());
+
+/**
+ * Localstorage attempts to return the localstorage.
+ *
+ * This is necessary because safari throws
+ * when a user disables cookies/localstorage
+ * and you attempt to access it.
+ *
+ * @return {LocalStorage}
+ * @api private
+ */
+
+function localstorage(){
+ try {
+ return window.localStorage;
+ } catch (e) {}
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/component.json b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/component.json
new file mode 100644
index 000000000..ca1063724
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/component.json
@@ -0,0 +1,19 @@
+{
+ "name": "debug",
+ "repo": "visionmedia/debug",
+ "description": "small debugging utility",
+ "version": "2.2.0",
+ "keywords": [
+ "debug",
+ "log",
+ "debugger"
+ ],
+ "main": "browser.js",
+ "scripts": [
+ "browser.js",
+ "debug.js"
+ ],
+ "dependencies": {
+ "rauchg/ms.js": "0.7.1"
+ }
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/debug.js b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/debug.js
new file mode 100644
index 000000000..7571a8605
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/debug.js
@@ -0,0 +1,197 @@
+
+/**
+ * This is the common logic for both the Node.js and web browser
+ * implementations of `debug()`.
+ *
+ * Expose `debug()` as the module.
+ */
+
+exports = module.exports = debug;
+exports.coerce = coerce;
+exports.disable = disable;
+exports.enable = enable;
+exports.enabled = enabled;
+exports.humanize = require('ms');
+
+/**
+ * The currently active debug mode names, and names to skip.
+ */
+
+exports.names = [];
+exports.skips = [];
+
+/**
+ * Map of special "%n" handling functions, for the debug "format" argument.
+ *
+ * Valid key names are a single, lowercased letter, i.e. "n".
+ */
+
+exports.formatters = {};
+
+/**
+ * Previously assigned color.
+ */
+
+var prevColor = 0;
+
+/**
+ * Previous log timestamp.
+ */
+
+var prevTime;
+
+/**
+ * Select a color.
+ *
+ * @return {Number}
+ * @api private
+ */
+
+function selectColor() {
+ return exports.colors[prevColor++ % exports.colors.length];
+}
+
+/**
+ * Create a debugger with the given `namespace`.
+ *
+ * @param {String} namespace
+ * @return {Function}
+ * @api public
+ */
+
+function debug(namespace) {
+
+ // define the `disabled` version
+ function disabled() {
+ }
+ disabled.enabled = false;
+
+ // define the `enabled` version
+ function enabled() {
+
+ var self = enabled;
+
+ // set `diff` timestamp
+ var curr = +new Date();
+ var ms = curr - (prevTime || curr);
+ self.diff = ms;
+ self.prev = prevTime;
+ self.curr = curr;
+ prevTime = curr;
+
+ // add the `color` if not set
+ if (null == self.useColors) self.useColors = exports.useColors();
+ if (null == self.color && self.useColors) self.color = selectColor();
+
+ var args = Array.prototype.slice.call(arguments);
+
+ args[0] = exports.coerce(args[0]);
+
+ if ('string' !== typeof args[0]) {
+ // anything else let's inspect with %o
+ args = ['%o'].concat(args);
+ }
+
+ // apply any `formatters` transformations
+ var index = 0;
+ args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
+ // if we encounter an escaped % then don't increase the array index
+ if (match === '%%') return match;
+ index++;
+ var formatter = exports.formatters[format];
+ if ('function' === typeof formatter) {
+ var val = args[index];
+ match = formatter.call(self, val);
+
+ // now we need to remove `args[index]` since it's inlined in the `format`
+ args.splice(index, 1);
+ index--;
+ }
+ return match;
+ });
+
+ if ('function' === typeof exports.formatArgs) {
+ args = exports.formatArgs.apply(self, args);
+ }
+ var logFn = enabled.log || exports.log || console.log.bind(console);
+ logFn.apply(self, args);
+ }
+ enabled.enabled = true;
+
+ var fn = exports.enabled(namespace) ? enabled : disabled;
+
+ fn.namespace = namespace;
+
+ return fn;
+}
+
+/**
+ * Enables a debug mode by namespaces. This can include modes
+ * separated by a colon and wildcards.
+ *
+ * @param {String} namespaces
+ * @api public
+ */
+
+function enable(namespaces) {
+ exports.save(namespaces);
+
+ var split = (namespaces || '').split(/[\s,]+/);
+ var len = split.length;
+
+ for (var i = 0; i < len; i++) {
+ if (!split[i]) continue; // ignore empty strings
+ namespaces = split[i].replace(/\*/g, '.*?');
+ if (namespaces[0] === '-') {
+ exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
+ } else {
+ exports.names.push(new RegExp('^' + namespaces + '$'));
+ }
+ }
+}
+
+/**
+ * Disable debug output.
+ *
+ * @api public
+ */
+
+function disable() {
+ exports.enable('');
+}
+
+/**
+ * Returns true if the given mode name is enabled, false otherwise.
+ *
+ * @param {String} name
+ * @return {Boolean}
+ * @api public
+ */
+
+function enabled(name) {
+ var i, len;
+ for (i = 0, len = exports.skips.length; i < len; i++) {
+ if (exports.skips[i].test(name)) {
+ return false;
+ }
+ }
+ for (i = 0, len = exports.names.length; i < len; i++) {
+ if (exports.names[i].test(name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Coerce `val`.
+ *
+ * @param {Mixed} val
+ * @return {Mixed}
+ * @api private
+ */
+
+function coerce(val) {
+ if (val instanceof Error) return val.stack || val.message;
+ return val;
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node.js b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node.js
new file mode 100644
index 000000000..1d392a81d
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node.js
@@ -0,0 +1,209 @@
+
+/**
+ * Module dependencies.
+ */
+
+var tty = require('tty');
+var util = require('util');
+
+/**
+ * This is the Node.js implementation of `debug()`.
+ *
+ * Expose `debug()` as the module.
+ */
+
+exports = module.exports = require('./debug');
+exports.log = log;
+exports.formatArgs = formatArgs;
+exports.save = save;
+exports.load = load;
+exports.useColors = useColors;
+
+/**
+ * Colors.
+ */
+
+exports.colors = [6, 2, 3, 4, 5, 1];
+
+/**
+ * The file descriptor to write the `debug()` calls to.
+ * Set the `DEBUG_FD` env variable to override with another value. i.e.:
+ *
+ * $ DEBUG_FD=3 node script.js 3>debug.log
+ */
+
+var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
+var stream = 1 === fd ? process.stdout :
+ 2 === fd ? process.stderr :
+ createWritableStdioStream(fd);
+
+/**
+ * Is stdout a TTY? Colored output is enabled when `true`.
+ */
+
+function useColors() {
+ var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase();
+ if (0 === debugColors.length) {
+ return tty.isatty(fd);
+ } else {
+ return '0' !== debugColors
+ && 'no' !== debugColors
+ && 'false' !== debugColors
+ && 'disabled' !== debugColors;
+ }
+}
+
+/**
+ * Map %o to `util.inspect()`, since Node doesn't do that out of the box.
+ */
+
+var inspect = (4 === util.inspect.length ?
+ // node <= 0.8.x
+ function (v, colors) {
+ return util.inspect(v, void 0, void 0, colors);
+ } :
+ // node > 0.8.x
+ function (v, colors) {
+ return util.inspect(v, { colors: colors });
+ }
+);
+
+exports.formatters.o = function(v) {
+ return inspect(v, this.useColors)
+ .replace(/\s*\n\s*/g, ' ');
+};
+
+/**
+ * Adds ANSI color escape codes if enabled.
+ *
+ * @api public
+ */
+
+function formatArgs() {
+ var args = arguments;
+ var useColors = this.useColors;
+ var name = this.namespace;
+
+ if (useColors) {
+ var c = this.color;
+
+ args[0] = ' \u001b[3' + c + ';1m' + name + ' '
+ + '\u001b[0m'
+ + args[0] + '\u001b[3' + c + 'm'
+ + ' +' + exports.humanize(this.diff) + '\u001b[0m';
+ } else {
+ args[0] = new Date().toUTCString()
+ + ' ' + name + ' ' + args[0];
+ }
+ return args;
+}
+
+/**
+ * Invokes `console.error()` with the specified arguments.
+ */
+
+function log() {
+ return stream.write(util.format.apply(this, arguments) + '\n');
+}
+
+/**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+
+function save(namespaces) {
+ if (null == namespaces) {
+ // If you set a process.env field to null or undefined, it gets cast to the
+ // string 'null' or 'undefined'. Just delete instead.
+ delete process.env.DEBUG;
+ } else {
+ process.env.DEBUG = namespaces;
+ }
+}
+
+/**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+
+function load() {
+ return process.env.DEBUG;
+}
+
+/**
+ * Copied from `node/src/node.js`.
+ *
+ * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
+ * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
+ */
+
+function createWritableStdioStream (fd) {
+ var stream;
+ var tty_wrap = process.binding('tty_wrap');
+
+ // Note stream._type is used for test-module-load-list.js
+
+ switch (tty_wrap.guessHandleType(fd)) {
+ case 'TTY':
+ stream = new tty.WriteStream(fd);
+ stream._type = 'tty';
+
+ // Hack to have stream not keep the event loop alive.
+ // See https://github.com/joyent/node/issues/1726
+ if (stream._handle && stream._handle.unref) {
+ stream._handle.unref();
+ }
+ break;
+
+ case 'FILE':
+ var fs = require('fs');
+ stream = new fs.SyncWriteStream(fd, { autoClose: false });
+ stream._type = 'fs';
+ break;
+
+ case 'PIPE':
+ case 'TCP':
+ var net = require('net');
+ stream = new net.Socket({
+ fd: fd,
+ readable: false,
+ writable: true
+ });
+
+ // FIXME Should probably have an option in net.Socket to create a
+ // stream from an existing fd which is writable only. But for now
+ // we'll just add this hack and set the `readable` member to false.
+ // Test: ./node test/fixtures/echo.js < /etc/passwd
+ stream.readable = false;
+ stream.read = null;
+ stream._type = 'pipe';
+
+ // FIXME Hack to have stream not keep the event loop alive.
+ // See https://github.com/joyent/node/issues/1726
+ if (stream._handle && stream._handle.unref) {
+ stream._handle.unref();
+ }
+ break;
+
+ default:
+ // Probably an error on in uv_guess_handle()
+ throw new Error('Implement me. Unknown stream file type!');
+ }
+
+ // For supporting legacy API we put the FD here.
+ stream.fd = fd;
+
+ stream._isStdio = true;
+
+ return stream;
+}
+
+/**
+ * Enable namespaces listed in `process.env.DEBUG` initially.
+ */
+
+exports.enable(load());
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/.npmignore b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/.npmignore
new file mode 100644
index 000000000..d1aa0ce42
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/.npmignore
@@ -0,0 +1,5 @@
+node_modules
+test
+History.md
+Makefile
+component.json
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/History.md b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/History.md
new file mode 100644
index 000000000..32fdfc176
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/History.md
@@ -0,0 +1,66 @@
+
+0.7.1 / 2015-04-20
+==================
+
+ * prevent extraordinary long inputs (@evilpacket)
+ * Fixed broken readme link
+
+0.7.0 / 2014-11-24
+==================
+
+ * add time abbreviations, updated tests and readme for the new units
+ * fix example in the readme.
+ * add LICENSE file
+
+0.6.2 / 2013-12-05
+==================
+
+ * Adding repository section to package.json to suppress warning from NPM.
+
+0.6.1 / 2013-05-10
+==================
+
+ * fix singularization [visionmedia]
+
+0.6.0 / 2013-03-15
+==================
+
+ * fix minutes
+
+0.5.1 / 2013-02-24
+==================
+
+ * add component namespace
+
+0.5.0 / 2012-11-09
+==================
+
+ * add short formatting as default and .long option
+ * add .license property to component.json
+ * add version to component.json
+
+0.4.0 / 2012-10-22
+==================
+
+ * add rounding to fix crazy decimals
+
+0.3.0 / 2012-09-07
+==================
+
+ * fix `ms(<String>)` [visionmedia]
+
+0.2.0 / 2012-09-03
+==================
+
+ * add component.json [visionmedia]
+ * add days support [visionmedia]
+ * add hours support [visionmedia]
+ * add minutes support [visionmedia]
+ * add seconds support [visionmedia]
+ * add ms string support [visionmedia]
+ * refactor tests to facilitate ms(number) [visionmedia]
+
+0.1.0 / 2012-03-07
+==================
+
+ * Initial release
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/LICENSE b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/LICENSE
new file mode 100644
index 000000000..6c07561b6
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/LICENSE
@@ -0,0 +1,20 @@
+(The MIT License)
+
+Copyright (c) 2014 Guillermo Rauch <rauchg@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/README.md b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/README.md
new file mode 100644
index 000000000..9b4fd0358
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/README.md
@@ -0,0 +1,35 @@
+# ms.js: miliseconds conversion utility
+
+```js
+ms('2 days') // 172800000
+ms('1d') // 86400000
+ms('10h') // 36000000
+ms('2.5 hrs') // 9000000
+ms('2h') // 7200000
+ms('1m') // 60000
+ms('5s') // 5000
+ms('100') // 100
+```
+
+```js
+ms(60000) // "1m"
+ms(2 * 60000) // "2m"
+ms(ms('10 hours')) // "10h"
+```
+
+```js
+ms(60000, { long: true }) // "1 minute"
+ms(2 * 60000, { long: true }) // "2 minutes"
+ms(ms('10 hours'), { long: true }) // "10 hours"
+```
+
+- Node/Browser compatible. Published as [`ms`](https://www.npmjs.org/package/ms) in [NPM](http://nodejs.org/download).
+- If a number is supplied to `ms`, a string with a unit is returned.
+- If a string that contains the number is supplied, it returns it as
+a number (e.g: it returns `100` for `'100'`).
+- If you pass a string with a number and a valid unit, the number of
+equivalent ms is returned.
+
+## License
+
+MIT
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/index.js b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/index.js
new file mode 100644
index 000000000..4f9277169
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/index.js
@@ -0,0 +1,125 @@
+/**
+ * Helpers.
+ */
+
+var s = 1000;
+var m = s * 60;
+var h = m * 60;
+var d = h * 24;
+var y = d * 365.25;
+
+/**
+ * Parse or format the given `val`.
+ *
+ * Options:
+ *
+ * - `long` verbose formatting [false]
+ *
+ * @param {String|Number} val
+ * @param {Object} options
+ * @return {String|Number}
+ * @api public
+ */
+
+module.exports = function(val, options){
+ options = options || {};
+ if ('string' == typeof val) return parse(val);
+ return options.long
+ ? long(val)
+ : short(val);
+};
+
+/**
+ * Parse the given `str` and return milliseconds.
+ *
+ * @param {String} str
+ * @return {Number}
+ * @api private
+ */
+
+function parse(str) {
+ str = '' + str;
+ if (str.length > 10000) return;
+ var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
+ if (!match) return;
+ var n = parseFloat(match[1]);
+ var type = (match[2] || 'ms').toLowerCase();
+ switch (type) {
+ case 'years':
+ case 'year':
+ case 'yrs':
+ case 'yr':
+ case 'y':
+ return n * y;
+ case 'days':
+ case 'day':
+ case 'd':
+ return n * d;
+ case 'hours':
+ case 'hour':
+ case 'hrs':
+ case 'hr':
+ case 'h':
+ return n * h;
+ case 'minutes':
+ case 'minute':
+ case 'mins':
+ case 'min':
+ case 'm':
+ return n * m;
+ case 'seconds':
+ case 'second':
+ case 'secs':
+ case 'sec':
+ case 's':
+ return n * s;
+ case 'milliseconds':
+ case 'millisecond':
+ case 'msecs':
+ case 'msec':
+ case 'ms':
+ return n;
+ }
+}
+
+/**
+ * Short format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function short(ms) {
+ if (ms >= d) return Math.round(ms / d) + 'd';
+ if (ms >= h) return Math.round(ms / h) + 'h';
+ if (ms >= m) return Math.round(ms / m) + 'm';
+ if (ms >= s) return Math.round(ms / s) + 's';
+ return ms + 'ms';
+}
+
+/**
+ * Long format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function long(ms) {
+ return plural(ms, d, 'day')
+ || plural(ms, h, 'hour')
+ || plural(ms, m, 'minute')
+ || plural(ms, s, 'second')
+ || ms + ' ms';
+}
+
+/**
+ * Pluralization helper.
+ */
+
+function plural(ms, n, name) {
+ if (ms < n) return;
+ if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
+ return Math.ceil(ms / n) + ' ' + name + 's';
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/package.json b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/package.json
new file mode 100644
index 000000000..253335e62
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/node_modules/ms/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "ms",
+ "version": "0.7.1",
+ "description": "Tiny ms conversion utility",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/guille/ms.js.git"
+ },
+ "main": "./index",
+ "devDependencies": {
+ "mocha": "*",
+ "expect.js": "*",
+ "serve": "*"
+ },
+ "component": {
+ "scripts": {
+ "ms/index.js": "index.js"
+ }
+ },
+ "gitHead": "713dcf26d9e6fd9dbc95affe7eff9783b7f1b909",
+ "bugs": {
+ "url": "https://github.com/guille/ms.js/issues"
+ },
+ "homepage": "https://github.com/guille/ms.js",
+ "_id": "ms@0.7.1",
+ "scripts": {},
+ "_shasum": "9cd13c03adbff25b65effde7ce864ee952017098",
+ "_from": "ms@0.7.1",
+ "_npmVersion": "2.7.5",
+ "_nodeVersion": "0.12.2",
+ "_npmUser": {
+ "name": "rauchg",
+ "email": "rauchg@gmail.com"
+ },
+ "maintainers": [
+ {
+ "name": "rauchg",
+ "email": "rauchg@gmail.com"
+ }
+ ],
+ "dist": {
+ "shasum": "9cd13c03adbff25b65effde7ce864ee952017098",
+ "tarball": "http://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ },
+ "directories": {},
+ "_resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "readme": "ERROR: No README data found!"
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/package.json b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/package.json
new file mode 100644
index 000000000..7e6d9fc59
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/node_modules/debug/package.json
@@ -0,0 +1,73 @@
+{
+ "name": "debug",
+ "version": "2.2.0",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/visionmedia/debug.git"
+ },
+ "description": "small debugging utility",
+ "keywords": [
+ "debug",
+ "log",
+ "debugger"
+ ],
+ "author": {
+ "name": "TJ Holowaychuk",
+ "email": "tj@vision-media.ca"
+ },
+ "contributors": [
+ {
+ "name": "Nathan Rajlich",
+ "email": "nathan@tootallnate.net",
+ "url": "http://n8.io"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "ms": "0.7.1"
+ },
+ "devDependencies": {
+ "browserify": "9.0.3",
+ "mocha": "*"
+ },
+ "main": "./node.js",
+ "browser": "./browser.js",
+ "component": {
+ "scripts": {
+ "debug/index.js": "browser.js",
+ "debug/debug.js": "debug.js"
+ }
+ },
+ "gitHead": "b38458422b5aa8aa6d286b10dfe427e8a67e2b35",
+ "bugs": {
+ "url": "https://github.com/visionmedia/debug/issues"
+ },
+ "homepage": "https://github.com/visionmedia/debug",
+ "_id": "debug@2.2.0",
+ "scripts": {},
+ "_shasum": "f87057e995b1a1f6ae6a4960664137bc56f039da",
+ "_from": "debug@*",
+ "_npmVersion": "2.7.4",
+ "_nodeVersion": "0.12.2",
+ "_npmUser": {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ },
+ "maintainers": [
+ {
+ "name": "tjholowaychuk",
+ "email": "tj@vision-media.ca"
+ },
+ {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ }
+ ],
+ "dist": {
+ "shasum": "f87057e995b1a1f6ae6a4960664137bc56f039da",
+ "tarball": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz"
+ },
+ "directories": {},
+ "_resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "readme": "ERROR: No README data found!"
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/package.json b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/package.json
new file mode 100644
index 000000000..8ed83ab24
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/package.json
@@ -0,0 +1,57 @@
+{
+ "name": "array-index",
+ "description": "Invoke getter/setter functions on array-like objects",
+ "keywords": [
+ "index",
+ "array",
+ "getter",
+ "setter",
+ "proxy"
+ ],
+ "version": "0.1.1",
+ "author": {
+ "name": "Nathan Rajlich",
+ "email": "nathan@tootallnate.net",
+ "url": "http://tootallnate.net"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/TooTallNate/array-index.git"
+ },
+ "main": "index.js",
+ "scripts": {
+ "test": "node test"
+ },
+ "dependencies": {
+ "debug": "*"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "gitHead": "65a5d884f25b4b7a1608e367d715d713dbd3b3d6",
+ "bugs": {
+ "url": "https://github.com/TooTallNate/array-index/issues"
+ },
+ "homepage": "https://github.com/TooTallNate/array-index",
+ "_id": "array-index@0.1.1",
+ "_shasum": "4d5eaf06cc3d925847cd73d1535c217ba306d3e1",
+ "_from": "array-index@>=0.1.0 <0.2.0",
+ "_npmVersion": "2.1.3",
+ "_nodeVersion": "0.10.32",
+ "_npmUser": {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ },
+ "maintainers": [
+ {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ }
+ ],
+ "dist": {
+ "shasum": "4d5eaf06cc3d925847cd73d1535c217ba306d3e1",
+ "tarball": "http://registry.npmjs.org/array-index/-/array-index-0.1.1.tgz"
+ },
+ "directories": {},
+ "_resolved": "https://registry.npmjs.org/array-index/-/array-index-0.1.1.tgz"
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/test.js b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/test.js
new file mode 100644
index 000000000..d9e9c1828
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/node_modules/array-index/test.js
@@ -0,0 +1,76 @@
+
+var ArrayIndex = require('./')
+var inherits = require('util').inherits
+var assert = require('assert')
+
+
+/**
+ * Create a "subclass".
+ */
+
+function Arrayish (length) {
+ ArrayIndex.call(this, length)
+ this.sets = Object.create(null)
+}
+
+// inherit from `ArrayIndex`
+inherits(Arrayish, ArrayIndex)
+
+
+// create an instance and run some tests
+var a = new Arrayish(11)
+
+assert.throws(function () {
+ a[0]
+}, /__get__/)
+
+assert.throws(function () {
+ a[0] = 0
+}, /__set__/)
+
+
+/**
+ * This "getter" function checks if the index has previosly been "set", and if so
+ * returns the index * the value previously set. If the index hasn't been set,
+ * return the index as-is.
+ */
+
+Arrayish.prototype.__get__ = function get (index) {
+ if (index in this.sets) {
+ return +this.sets[index] * index
+ } else {
+ return index
+ }
+}
+
+/**
+ * Store the last value set for this index.
+ */
+
+Arrayish.prototype.__set__ = function set (index, value) {
+ this.sets[index] = value
+}
+
+
+// test getters without being "set"
+assert.equal(0, a[0])
+assert.equal(1, a[1])
+assert.equal(2, a[2])
+assert.equal(3, a[3])
+assert.equal(4, a[4])
+
+// test setters, followed by getters
+a[10] = 1
+assert.equal(10, a[10])
+a[10] = 2
+assert.equal(20, a[10])
+a[10] = 3
+assert.equal(30, a[10])
+
+// test "length"
+assert.equal(11, a.length)
+
+a[4] = 20
+a[6] = 5.55432
+var b = [0, 1, 2, 3, 80, 5, 33.325919999999996, 7, 8, 9, 30]
+assert.equal(JSON.stringify(b), JSON.stringify(a))
diff --git a/node_modules/node-gyp/node_modules/path-array/package.json b/node_modules/node-gyp/node_modules/path-array/package.json
new file mode 100644
index 000000000..ad8edc9f8
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/package.json
@@ -0,0 +1,55 @@
+{
+ "name": "path-array",
+ "version": "1.0.0",
+ "description": "Treat your $PATH like a JavaScript Array",
+ "main": "index.js",
+ "scripts": {
+ "test": "mocha --reporter spec"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/TooTallNate/node-path-array.git"
+ },
+ "keywords": [
+ "PATH",
+ "env",
+ "array"
+ ],
+ "author": {
+ "name": "Nathan Rajlich",
+ "email": "nathan@tootallnate.net",
+ "url": "http://n8.io/"
+ },
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/TooTallNate/node-path-array/issues"
+ },
+ "homepage": "https://github.com/TooTallNate/node-path-array",
+ "dependencies": {
+ "array-index": "~0.1.0"
+ },
+ "devDependencies": {
+ "mocha": "~1.16.1"
+ },
+ "gitHead": "5d1fedd54e4413459f67e4a4babb024144cd00d0",
+ "_id": "path-array@1.0.0",
+ "_shasum": "6c14130c33084f0150553c657b38397ab67aaa4e",
+ "_from": "path-array@>=1.0.0 <2.0.0",
+ "_npmVersion": "1.4.28",
+ "_npmUser": {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ },
+ "maintainers": [
+ {
+ "name": "tootallnate",
+ "email": "nathan@tootallnate.net"
+ }
+ ],
+ "dist": {
+ "shasum": "6c14130c33084f0150553c657b38397ab67aaa4e",
+ "tarball": "http://registry.npmjs.org/path-array/-/path-array-1.0.0.tgz"
+ },
+ "directories": {},
+ "_resolved": "https://registry.npmjs.org/path-array/-/path-array-1.0.0.tgz"
+}
diff --git a/node_modules/node-gyp/node_modules/path-array/test/test.js b/node_modules/node-gyp/node_modules/path-array/test/test.js
new file mode 100644
index 000000000..fc1f3736f
--- /dev/null
+++ b/node_modules/node-gyp/node_modules/path-array/test/test.js
@@ -0,0 +1,68 @@
+
+/**
+ * Module dependencies.
+ */
+
+var assert = require('assert');
+var PathArray = require('../');
+var delimiter = require('path').delimiter || ':';
+
+describe('PathArray', function () {
+ it('should use `process.env` by default', function () {
+ var p = new PathArray();
+ assert.equal(p._env, process.env);
+ });
+ it('should return the $PATH string for .toString()', function () {
+ var p = new PathArray();
+ assert.equal(p.toString(), process.env.PATH);
+ });
+ it('should accept an arbitrary `env` object', function () {
+ var env = { PATH: '/foo' + delimiter + '/bar' };
+ var p = new PathArray(env);
+ assert.equal(p.toString(), env.PATH);
+ });
+ it('should work for [n] getter syntax', function () {
+ var env = { PATH: '/foo' + delimiter + '/bar' };
+ var p = new PathArray(env);
+ assert.equal('/foo', p[0]);
+ assert.equal('/bar', p[1]);
+ });
+ it('should work for [n]= setter syntax', function () {
+ var env = { PATH: '/foo' + delimiter + '/bar' };
+ var p = new PathArray(env);
+ p[0] = '/baz';
+ assert.equal('/baz' + delimiter + '/bar', env.PATH);
+ });
+ it('should work with .push()', function () {
+ var env = { PATH: '/foo' + delimiter + '/bar' };
+ var p = new PathArray(env);
+ p.push('/baz');
+ assert.equal('/foo' + delimiter + '/bar' + delimiter + '/baz', env.PATH);
+ });
+ it('should work with .shift()', function () {
+ var env = { PATH: '/foo' + delimiter + '/bar' };
+ var p = new PathArray(env);
+ assert.equal('/foo', p.shift());
+ assert.equal('/bar', env.PATH);
+ });
+ it('should work with .pop()', function () {
+ var env = { PATH: '/foo' + delimiter + '/bar' };
+ var p = new PathArray(env);
+ assert.equal('/bar', p.pop());
+ assert.equal('/foo', env.PATH);
+ });
+ it('should work with .unshift()', function () {
+ var env = { PATH: '/foo' + delimiter + '/bar' };
+ var p = new PathArray(env);
+ p.unshift('/baz');
+ assert.equal('/baz' + delimiter + '/foo' + delimiter + '/bar', env.PATH);
+ });
+ it('should be able to specify property name to use with second argument', function () {
+ var env = { PYTHONPATH: '/foo' };
+ var p = new PathArray(env, 'PYTHONPATH');
+ assert.equal(1, p.length);
+ p.push('/baz');
+ assert.equal(2, p.length);
+ assert.equal('/foo' + delimiter + '/baz', env.PYTHONPATH);
+ });
+});
diff --git a/node_modules/node-gyp/node_modules/tar/package.json b/node_modules/node-gyp/node_modules/tar/package.json
index 5aa78aec3..7fab5394c 100644
--- a/node_modules/node-gyp/node_modules/tar/package.json
+++ b/node_modules/node-gyp/node_modules/tar/package.json
@@ -56,5 +56,6 @@
"tarball": "http://registry.npmjs.org/tar/-/tar-1.0.3.tgz"
},
"directories": {},
- "_resolved": "https://registry.npmjs.org/tar/-/tar-1.0.3.tgz"
+ "_resolved": "https://registry.npmjs.org/tar/-/tar-1.0.3.tgz",
+ "readme": "ERROR: No README data found!"
}
diff --git a/node_modules/node-gyp/package.json b/node_modules/node-gyp/package.json
index 6015fe750..fc0ba266c 100644
--- a/node_modules/node-gyp/package.json
+++ b/node_modules/node-gyp/package.json
@@ -1,6 +1,7 @@
{
"name": "node-gyp",
"description": "Node.js native addon build tool",
+ "license": "MIT",
"keywords": [
"native",
"addon",
@@ -10,7 +11,7 @@
"bindings",
"gyp"
],
- "version": "1.0.3",
+ "version": "2.0.0",
"installVersion": 9,
"author": {
"name": "Nathan Rajlich",
@@ -35,6 +36,7 @@
"nopt": "2 || 3",
"npmlog": "0 || 1",
"osenv": "0",
+ "path-array": "^1.0.0",
"request": "2",
"rimraf": "2",
"semver": "2.x || 3.x || 4",
@@ -44,16 +46,17 @@
"engines": {
"node": ">= 0.8.0"
},
- "gitHead": "abad2b58c03de713eb1805f7a681b1084c08b316",
+ "gitHead": "4587ae35ae0079b18f8e7ed2129c31c7e623644a",
"bugs": {
"url": "https://github.com/TooTallNate/node-gyp/issues"
},
- "homepage": "https://github.com/TooTallNate/node-gyp",
- "_id": "node-gyp@1.0.3",
+ "homepage": "https://github.com/TooTallNate/node-gyp#readme",
+ "_id": "node-gyp@2.0.0",
"scripts": {},
- "_shasum": "a2f63f2df0b1f6cc69fa54bce3cc298aa769cbd8",
- "_from": "node-gyp@>=1.0.3 <1.1.0",
- "_npmVersion": "1.4.28",
+ "_shasum": "0063644d2c9c8452489d5922cdf7b0085081b66b",
+ "_from": "node-gyp@>=2.0.0 <2.1.0",
+ "_npmVersion": "2.9.1",
+ "_nodeVersion": "0.12.3",
"_npmUser": {
"name": "tootallnate",
"email": "nathan@tootallnate.net"
@@ -73,9 +76,9 @@
}
],
"dist": {
- "shasum": "a2f63f2df0b1f6cc69fa54bce3cc298aa769cbd8",
- "tarball": "http://registry.npmjs.org/node-gyp/-/node-gyp-1.0.3.tgz"
+ "shasum": "0063644d2c9c8452489d5922cdf7b0085081b66b",
+ "tarball": "http://registry.npmjs.org/node-gyp/-/node-gyp-2.0.0.tgz"
},
"directories": {},
- "_resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-1.0.3.tgz"
+ "_resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-2.0.0.tgz"
}
diff --git a/node_modules/node-gyp/src/win_delay_load_hook.c b/node_modules/node-gyp/src/win_delay_load_hook.c
new file mode 100644
index 000000000..f397cfa19
--- /dev/null
+++ b/node_modules/node-gyp/src/win_delay_load_hook.c
@@ -0,0 +1,33 @@
+/*
+ * When this file is linked to a DLL, it sets up a delay-load hook that
+ * intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe'
+ * dynamically. Instead of trying to locate the .exe file it'll just return
+ * a handle to the process image.
+ *
+ * This allows compiled addons to work when node.exe or iojs.exe is renamed.
+ */
+
+#ifdef _MSC_VER
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <delayimp.h>
+#include <string.h>
+
+static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) {
+ HMODULE m;
+ if (event != dliNotePreLoadLibrary)
+ return NULL;
+
+ if (_stricmp(info->szDll, "iojs.exe") != 0 &&
+ _stricmp(info->szDll, "node.exe") != 0)
+ return NULL;
+
+ m = GetModuleHandle(NULL);
+ return (FARPROC) m;
+}
+
+PfnDliHook __pfnDliNotifyHook2 = load_exe_hook;
+
+#endif