Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Address issues encountered while building on Windows+Cygwin environments #1817

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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():
cclauss marked this conversation as resolved.
Show resolved Hide resolved
rvagg marked this conversation as resolved.
Show resolved Hide resolved
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
20 changes: 19 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])
rvagg marked this conversation as resolved.
Show resolved Hide resolved
dir=base_temp_dir)
try:
self.tmp_file = os.fdopen(tmp_fd, 'wb')
except Exception:
Expand Down Expand Up @@ -611,3 +617,15 @@ 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