Skip to content

Commit

Permalink
gyp: improve Windows+Cygwin compatibility
Browse files Browse the repository at this point in the history
Fixes: #1782
PR-URL: #1817
Reviewed-By: Christian Clauss <cclauss@me.com>
Reviewed-By: Rod Vagg <r@va.gg>
  • Loading branch information
Jose Quijada authored and rvagg committed Sep 26, 2019
1 parent 8bcb1fb commit 5553cd9
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 4 deletions.
32 changes: 30 additions & 2 deletions gyp/gyp_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,38 @@

import os
import sys
import subprocess

# Below IsCygwin() function copied from pylib/gyp/common.py
def IsCygwin():
try:
out = subprocess.Popen("uname",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout,stderr = out.communicate()
return "CYGWIN" in str(stdout)
except Exception:
return False


def UnixifyPath(path):
try:
if not IsCygwin():
return path
out = subprocess.Popen(["cygpath", "-u", path],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout,stderr = out.communicate()
return str(stdout)
except Exception:
return path


# Make sure we're using the version of pylib in this repo, not one installed
# elsewhere on the system.
sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), 'pylib'))
# elsewhere on the system. Also convert to Unix style path on Cygwin systems,
# else the 'gyp' library will not be found
path = UnixifyPath(sys.argv[0])
sys.path.insert(0, os.path.join(os.path.dirname(path), 'pylib'))
import gyp

if __name__ == '__main__':
Expand Down
19 changes: 18 additions & 1 deletion gyp/pylib/gyp/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import re
import tempfile
import sys
import subprocess


# A minimal memoizing decorator. It'll blow up if the args aren't immutable,
Expand Down Expand Up @@ -337,11 +338,16 @@ def WriteOnDiff(filename):
class Writer(object):
"""Wrapper around file which only covers the target if it differs."""
def __init__(self):
# On Cygwin remove the "dir" argument because `C:` prefixed paths are treated as relative,
# consequently ending up with current dir "/cygdrive/c/..." being prefixed to those, which was
# obviously a non-existent path, for example: "/cygdrive/c/<some folder>/C:\<my win style abs path>".
# See https://docs.python.org/2/library/tempfile.html#tempfile.mkstemp for more details
base_temp_dir = "" if IsCygwin() else os.path.dirname(filename)
# Pick temporary file.
tmp_fd, self.tmp_path = tempfile.mkstemp(
suffix='.tmp',
prefix=os.path.split(filename)[1] + '.gyp.',
dir=os.path.split(filename)[0])
dir=base_temp_dir)
try:
self.tmp_file = os.fdopen(tmp_fd, 'wb')
except Exception:
Expand Down Expand Up @@ -611,3 +617,14 @@ def CrossCompileRequested():
os.environ.get('AR_target') or
os.environ.get('CC_target') or
os.environ.get('CXX_target'))

def IsCygwin():
try:
out = subprocess.Popen("uname",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout,stderr = out.communicate()
return "CYGWIN" in str(stdout)
except Exception:
return False

12 changes: 11 additions & 1 deletion gyp/pylib/gyp/generator/msvs.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def _FixPath(path):
Returns:
The path with all slashes made into backslashes.
"""
if fixpath_prefix and path and not os.path.isabs(path) and not path[0] == '$':
if fixpath_prefix and path and not os.path.isabs(path) and not path[0] == '$' and not _IsWindowsAbsPath(path):
path = os.path.join(fixpath_prefix, path)
path = path.replace('/', '\\')
path = _NormalizedSource(path)
Expand All @@ -174,6 +174,16 @@ def _FixPath(path):
return path


def _IsWindowsAbsPath(path):
"""
On Cygwin systems Python needs a little help determining if a path is an absolute Windows path or not, so that
it does not treat those as relative, which results in bad paths like:
'..\C:\<some path>\some_source_code_file.cc'
"""
return path.startswith('c:') or path.startswith('C:')


def _FixPaths(paths):
"""Fix each of the paths of the list."""
return [_FixPath(i) for i in paths]
Expand Down
7 changes: 7 additions & 0 deletions lib/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ function configure (gyp, argv, callback) {
outputDir = buildDir
}
var nodeGypDir = path.resolve(__dirname, '..')

var nodeLibFile = path.join(nodeDir,
!gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)',
release.name + '.lib')
Expand All @@ -308,6 +309,12 @@ function configure (gyp, argv, callback) {
argv.push('-Dnode_exp_file=' + nodeExpFile)
}
argv.push('-Dnode_gyp_dir=' + nodeGypDir)

// Do this to keep Cygwin environments happy, else the unescaped '\' gets eaten up,
// resulting in bad paths, Ex c:parentFolderfolderanotherFolder instead of c:\parentFolder\folder\anotherFolder
if (win) {
nodeLibFile = nodeLibFile.replace(/\\/g, '\\\\')
}
argv.push('-Dnode_lib_file=' + nodeLibFile)
argv.push('-Dmodule_root_dir=' + process.cwd())
argv.push('-Dnode_engine=' +
Expand Down

0 comments on commit 5553cd9

Please sign in to comment.