Skip to content
Merged
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
33 changes: 25 additions & 8 deletions pylib/gyp/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,9 @@ def EnsureDirExists(path):
except OSError:
pass

def GetCrossCompilerPredefines(): # -> dict
def GetCompilerPredefines(): # -> dict
cmd = []
defines = {}

# shlex.split() will eat '\' in posix mode, but
# setting posix=False will preserve extra '"' cause CreateProcess fail on Windows
Expand All @@ -439,7 +440,7 @@ def replace_sep(s):
if CXXFLAGS := os.environ.get("CXXFLAGS"):
cmd += shlex.split(replace_sep(CXXFLAGS))
else:
return {}
return defines

if sys.platform == "win32":
fd, input = tempfile.mkstemp(suffix=".c")
Expand All @@ -450,17 +451,33 @@ def replace_sep(s):
real_cmd, shell=True,
capture_output=True, check=True
).stdout
except subprocess.CalledProcessError as e:
print(
"Warning: failed to get compiler predefines\n"
"cmd: %s\n"
"status: %d" % (e.cmd, e.returncode),
file=sys.stderr
)
return defines
finally:
os.unlink(input)
else:
input = "/dev/null"
real_cmd = [*cmd, "-dM", "-E", "-x", "c", input]
stdout = subprocess.run(
real_cmd, shell=False,
capture_output=True, check=True
).stdout
try:
stdout = subprocess.run(
real_cmd, shell=False,
capture_output=True, check=True
).stdout
except subprocess.CalledProcessError as e:
print(
"Warning: failed to get compiler predefines\n"
"cmd: %s\n"
"status: %d" % (e.cmd, e.returncode),
file=sys.stderr
)
return defines

defines = {}
lines = stdout.decode("utf-8").replace("\r\n", "\n").split("\n")
for line in lines:
if (line or "").startswith("#define "):
Expand Down Expand Up @@ -499,7 +516,7 @@ def GetFlavor(params):
if "flavor" in params:
return params["flavor"]

defines = GetCrossCompilerPredefines()
defines = GetCompilerPredefines()
if "__EMSCRIPTEN__" in defines:
return "emscripten"
if "__wasm__" in defines:
Expand Down
32 changes: 24 additions & 8 deletions pylib/gyp/common_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""Unit tests for the common.py file."""

import os
import subprocess
import sys
import unittest
from unittest.mock import MagicMock, patch
Expand Down Expand Up @@ -85,22 +86,34 @@ def decode(self, encoding):
@patch("os.close")
@patch("os.unlink")
@patch("tempfile.mkstemp")
def test_GetCrossCompilerPredefines(self, mock_mkstemp, mock_unlink, mock_close):
def test_GetCompilerPredefines(self, mock_mkstemp, mock_unlink, mock_close):
mock_close.return_value = None
mock_unlink.return_value = None
mock_mkstemp.return_value = (0, "temp.c")

def mock_run(env, defines_stdout, expected_cmd):
def mock_run(env, defines_stdout, expected_cmd, throws=False):
with patch("subprocess.run") as mock_run:
mock_process = MagicMock()
mock_process.returncode = 0
mock_process.stdout = TestGetFlavor.MockCommunicate(defines_stdout)
mock_run.return_value = mock_process
expected_input = "temp.c" if sys.platform == "win32" else "/dev/null"
if throws:
mock_run.side_effect = subprocess.CalledProcessError(
returncode=1,
cmd=[
*expected_cmd,
"-dM", "-E", "-x", "c", expected_input
]
)
else:
mock_process = MagicMock()
mock_process.returncode = 0
mock_process.stdout = TestGetFlavor.MockCommunicate(defines_stdout)
mock_run.return_value = mock_process
with patch.dict(os.environ, env):
defines = gyp.common.GetCrossCompilerPredefines()
try:
defines = gyp.common.GetCompilerPredefines()
except Exception as e:
self.fail(f"GetCompilerPredefines raised an exception: {e}")
flavor = gyp.common.GetFlavor({})
if env.get("CC_target"):
if env.get("CC_target") or env.get("CC"):
mock_run.assert_called_with(
[
*expected_cmd,
Expand All @@ -110,6 +123,9 @@ def mock_run(env, defines_stdout, expected_cmd):
capture_output=True, check=True)
return [defines, flavor]

[defines0, _] = mock_run({ "CC": "cl.exe" }, "", ["cl.exe"], True)
assert defines0 == {}

[defines1, _] = mock_run({}, "", [])
assert defines1 == {}

Expand Down
Loading