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

github.com/SCons/scons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Brill <48932340+jcbrill@users.noreply.github.com>2023-10-15 13:31:45 +0300
committerJoseph Brill <48932340+jcbrill@users.noreply.github.com>2023-10-15 13:31:45 +0300
commit8365968e78d7e463aaca2ce1c36652ec6eae3fa6 (patch)
tree5a87d8f98e4a252b732b8c1833daf5b2f07f8cf7
parentbcb02dc61812f159aee7b0327e92fabc5d79214d (diff)
parent83f8e5fcca75439fa62ee6e6aa92198eb7283a0b (diff)
Merge branch 'master' into jbrill-msvc-normalize
-rw-r--r--CHANGES.txt7
-rw-r--r--RELEASE.txt5
-rw-r--r--SCons/Action.py228
-rw-r--r--SCons/ActionTests.py54
-rw-r--r--SCons/Tool/midl.py2
-rw-r--r--SCons/Tool/mslib.py5
-rw-r--r--SCons/Tool/mslink.py7
-rw-r--r--SCons/Tool/mssdk.py6
-rw-r--r--SCons/Tool/msvc.py9
-rw-r--r--SCons/Tool/msvs.py5
-rw-r--r--test/AS/as-live.py73
-rw-r--r--testing/framework/TestCmdTests.py13
12 files changed, 239 insertions, 175 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index a55c53249..cf2ae52c4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -42,6 +42,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
registry query that returns a path that does not exist. Multiple invocation
paths were not prepared to handle the MissingConfiguration exception. The
MissingConfiguration exception type was removed.
+ - The MSCommon module import was changed from a relative import to a top-level
+ absolute import in the following Microsoft tools: midl, mslib, mslink, mssdk, msvc,
+ msvs. Moving any of these tools that used relative imports to the scons site tools
+ folder would fail on import (i.e., the relative import paths become invalid when
+ moved).
From Vitaly Cheptsov:
- Fix race condition in `Mkdir` which can happen when two `SConscript`
@@ -179,6 +184,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
Python stdlib types module.
- TeX tests: skip tests that use makeindex or epstopdf not installed, or
if `kpsewhich glossaries.sty` fails.
+ - Added a .note.GNU-stack section to the test assembler files to
+ avoid the GNU linker issuing warnings for its absence.
From Jonathon Reinhart:
diff --git a/RELEASE.txt b/RELEASE.txt
index 12bb3cacb..764cc4093 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -120,6 +120,11 @@ IMPROVEMENTS
------------
- Now tries to find mingw if it comes from Chocolatey install of msys2.
+- MSVC: Module imports were changed from a relative import to a top-level
+ absolute import in the following Microsoft tools: midl, mslib, mslink, mssdk, msvc,
+ msvs. Moving any of these tools that used relative imports to the scons site tools
+ folder would fail on import (i.e., the relative import paths become invalid when
+ moved).
PACKAGING
---------
diff --git a/SCons/Action.py b/SCons/Action.py
index e85e5e177..0dd02cc28 100644
--- a/SCons/Action.py
+++ b/SCons/Action.py
@@ -108,16 +108,16 @@ import subprocess
import sys
from abc import ABC, abstractmethod
from collections import OrderedDict
-from subprocess import DEVNULL
-from typing import Union
+from subprocess import DEVNULL, PIPE
import SCons.Debug
import SCons.Errors
import SCons.Subst
import SCons.Util
-from SCons.Debug import logInstanceCreation
# we use these a lot, so try to optimize them
+from SCons.Debug import logInstanceCreation
+from SCons.Subst import SUBST_SIG, SUBST_RAW
from SCons.Util import is_String, is_List
class _null:
@@ -387,9 +387,10 @@ def _object_instance_content(obj):
# print("Inst Methods :\n%s"%pp.pformat(methods))
def _actionAppend(act1, act2):
- # This function knows how to slap two actions together.
- # Mainly, it handles ListActions by concatenating into
- # a single ListAction.
+ """Joins two actions together.
+
+ Mainly, it handles ListActions by concatenating into a single ListAction.
+ """
a1 = Action(act1)
a2 = Action(act2)
if a1 is None:
@@ -399,13 +400,12 @@ def _actionAppend(act1, act2):
if isinstance(a1, ListAction):
if isinstance(a2, ListAction):
return ListAction(a1.list + a2.list)
- else:
- return ListAction(a1.list + [ a2 ])
- else:
- if isinstance(a2, ListAction):
- return ListAction([ a1 ] + a2.list)
- else:
- return ListAction([ a1, a2 ])
+ return ListAction(a1.list + [ a2 ])
+
+ if isinstance(a2, ListAction):
+ return ListAction([ a1 ] + a2.list)
+
+ return ListAction([ a1, a2 ])
def _do_create_keywords(args, kw):
@@ -468,11 +468,7 @@ def _do_create_action(act, kw):
return CommandAction(act, **kw)
if callable(act):
- try:
- gen = kw['generator']
- del kw['generator']
- except KeyError:
- gen = 0
+ gen = kw.pop('generator', False)
if gen:
action_type = CommandGeneratorAction
else:
@@ -480,7 +476,7 @@ def _do_create_action(act, kw):
return action_type(act, kw)
# Catch a common error case with a nice message:
- if isinstance(act, int) or isinstance(act, float):
+ if isinstance(act, (int, float)):
raise TypeError("Don't know how to create an Action from a number (%s)"%act)
# Else fail silently (???)
return None
@@ -504,10 +500,9 @@ def _do_create_list_action(act, kw) -> "ListAction":
acts.append(aa)
if not acts:
return ListAction([])
- elif len(acts) == 1:
+ if len(acts) == 1:
return acts[0]
- else:
- return ListAction(acts)
+ return ListAction(acts)
def Action(act, *args, **kw):
@@ -547,7 +542,7 @@ class ActionBase(ABC):
batch_key = no_batch_key
- def genstring(self, target, source, env):
+ def genstring(self, target, source, env, executor=None) -> str:
return str(self)
@abstractmethod
@@ -561,7 +556,7 @@ class ActionBase(ABC):
def get_contents(self, target, source, env):
result = self.get_presig(target, source, env)
- if not isinstance(result,(bytes, bytearray)):
+ if not isinstance(result, (bytes, bytearray)):
result = bytearray(result, 'utf-8')
else:
# Make a copy and put in bytearray, without this the contents returned by get_presig
@@ -579,17 +574,15 @@ class ActionBase(ABC):
for v in vl:
# do the subst this way to ignore $(...$) parts:
if isinstance(result, bytearray):
- result.extend(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source)))
+ result.extend(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SUBST_SIG, target, source)))
else:
raise Exception("WE SHOULD NEVER GET HERE result should be bytearray not:%s"%type(result))
- # result.append(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source)))
-
+ # result.append(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SUBST_SIG, target, source)))
- if isinstance(result, (bytes,bytearray)):
+ if isinstance(result, (bytes, bytearray)):
return result
- else:
- raise Exception("WE SHOULD NEVER GET HERE - #2 result should be bytearray not:%s" % type(result))
- # return b''.join(result)
+
+ raise Exception("WE SHOULD NEVER GET HERE - #2 result should be bytearray not:%s" % type(result))
def __add__(self, other):
return _actionAppend(self, other)
@@ -788,7 +781,7 @@ def get_default_ENV(env):
return env['ENV']
except KeyError:
if not default_ENV:
- import SCons.Environment
+ import SCons.Environment # pylint: disable=import-outside-toplevel,redefined-outer-name
# This is a hideously expensive way to get a default execution
# environment. What it really should do is run the platform
# setup to get the default ENV. Fortunately, it's incredibly
@@ -815,42 +808,47 @@ def _resolve_shell_env(env, target, source):
shell_gens = iter(shell_gen)
except TypeError:
raise SCons.Errors.UserError("SHELL_ENV_GENERATORS must be iteratable.")
- else:
- ENV = ENV.copy()
- for generator in shell_gens:
- ENV = generator(env, target, source, ENV)
- if not isinstance(ENV, dict):
- raise SCons.Errors.UserError(f"SHELL_ENV_GENERATORS function: {generator} must return a dict.")
- return ENV
+ ENV = ENV.copy()
+ for generator in shell_gens:
+ ENV = generator(env, target, source, ENV)
+ if not isinstance(ENV, dict):
+ raise SCons.Errors.UserError(f"SHELL_ENV_GENERATORS function: {generator} must return a dict.")
-def scons_subproc_run(
- scons_env, *args, error: str = None, **kwargs
-) -> subprocess.CompletedProcess:
- """Run a command with arguments using an SCons execution environment.
+ return ENV
- Does an underlyng call to :func:`subprocess.run` to run a command and
- returns a :class:`subprocess.CompletedProcess` instance with the results.
- Use when an external command needs to run in an "SCons context" -
- that is, with a crafted execution environment, rather than the user's
- existing environment, particularly when you need to collect output
- back. Typical case: run a tool's "version" option to find out which
- version you have installed.
- If supplied, the ``env`` keyword argument passes an
- execution environment to process into appropriate form before it is
- supplied to :mod:`subprocess`; if omitted, *scons_env* is used to derive
- a suitable default. The other keyword arguments are passed through,
- except that SCons legacy ``error` keyword is remapped to
- the subprocess ``check` keyword. The caller is responsible for
- setting up the desired arguments for :func:`subprocess.run`.
+def scons_subproc_run(scons_env, *args, **kwargs) -> subprocess.CompletedProcess:
+ """Run an external command using an SCons execution environment.
+
+ SCons normally runs external build commands using :mod:`subprocess`,
+ but does not harvest any output from such commands. This function
+ is a thin wrapper around :func:`subprocess.run` allowing running
+ a command in an SCons context (i.e. uses an "execution environment"
+ rather than the user's existing environment), and provides the ability
+ to return any output in a :class:`subprocess.CompletedProcess`
+ instance (this must be selected by setting ``stdout`` and/or
+ ``stderr`` to ``PIPE``, or setting ``capture_output=True`` - see
+ Keyword Arguments). Typical use case is to run a tool's "version"
+ option to find out the installed version.
+
+ If supplied, the ``env`` keyword argument provides an execution
+ environment to process into appropriate form before it is supplied
+ to :mod:`subprocess`; if omitted, *scons_env* is used to derive a
+ suitable default. The other keyword arguments are passed through,
+ except that the SCons legacy ``error`` keyword is remapped to the
+ subprocess ``check`` keyword; if both are omitted ``check=False``
+ will be passed. The caller is responsible for setting up the desired
+ arguments for :func:`subprocess.run`.
This function retains the legacy behavior of returning something
- vaguely usable even in the face of complete failure: it synthesizes
- a :class:`~subprocess.CompletedProcess` instance in this case.
+ vaguely usable even in the face of complete failure, unless
+ ``check=True`` (in which case an error is allowed to be raised):
+ it synthesizes a :class:`~subprocess.CompletedProcess` instance in
+ this case.
A subset of interesting keyword arguments follows; see the Python
- documentation of :mod:`subprocess` for a complete list.
+ documentation of :mod:`subprocess` for the complete list.
Keyword Arguments:
stdout: (and *stderr*, *stdin*) if set to :const:`subprocess.PIPE`.
@@ -858,12 +856,11 @@ def scons_subproc_run(
the subprocess; the default ``None`` does no redirection
(i.e. output or errors may go to the console or log file,
but is not captured); if set to :const:`subprocess.DEVNULL`
- they are explicitly thrown away. ``capture_output`` is a
+ they are explicitly thrown away. ``capture_output=True`` is a
synonym for setting both ``stdout`` and ``stderr``
to :const:`~subprocess.PIPE`.
text: open *stdin*, *stdout*, *stderr* in text mode. Default
- is binary mode. ``universal_newlines`` is a synonym -
- note ``text`` is not understood before Python 3.7.
+ is binary mode. ``universal_newlines`` is a synonym.
encoding: specifies an encoding. Changes to text mode.
errors: specified error handling. Changes to text mode.
input: a byte sequence to be passed to *stdin*, unless text
@@ -877,54 +874,48 @@ def scons_subproc_run(
.. versionadded:: 4.6
"""
# Figure out the execution environment to use
- ENV = kwargs.get('env', None)
- if ENV is None:
- ENV = get_default_ENV(scons_env)
- kwargs['env'] = SCons.Util.sanitize_shell_env(ENV)
-
- # backwards-compat with _subproc: accept 'error', map it to
- # ``check`` and remove, since it would not be recognized by run()
- check = kwargs.get('check')
- if check and error:
+ env = kwargs.get('env', None)
+ if env is None:
+ env = get_default_ENV(scons_env)
+ kwargs['env'] = SCons.Util.sanitize_shell_env(env)
+
+ # Backwards-compat with _subproc: accept 'error', map to 'check',
+ # and remove, since subprocess.run does not recognize.
+ # 'error' isn't True/False, it takes a string value (see _subproc)
+ error = kwargs.get('error')
+ if error and 'check' in kwargs:
raise ValueError('error and check arguments may not both be used.')
- if check is None:
- check = False # always supply some value, to pacify checkers (pylint).
+ check = kwargs.get('check', False) # always set a value for 'check'
if error is not None:
if error == 'raise':
check = True
del kwargs['error']
kwargs['check'] = check
- # Ensure that the ENV values are all strings:
- new_env = {}
- for key, value in ENV.items():
- if is_List(value):
- # If the value is a list, then we assume it is a path list,
- # because that's a pretty common list-like value to stick
- # in an environment variable:
- value = SCons.Util.flatten_sequence(value)
- new_env[key] = os.pathsep.join(str(v) for v in value)
- else:
- # If it's not a list type, "convert" it to str. This is
- # harmless if it's already a string, but gets us the right
- # thing for Dir and File instances and will produce something
- # reasonable for just about everything else:
- new_env[key] = str(value)
- kwargs['env'] = new_env
-
- # Some tools/tests expect no failures for things like missing files
- # unless raise/check is set. If set, let subprocess.run go ahead and
- # kill things, else catch and construct a dummy CompletedProcess instance.
+ # TODO: Python version-compat stuff: remap/remove too-new args if needed
+ if 'text' in kwargs and sys.version_info[:3] < (3, 7):
+ kwargs['universal_newlines'] = kwargs.pop('text')
+
+ if 'capture_output' in kwargs and sys.version_info[:3] < (3, 7):
+ capture_output = kwargs.pop('capture_output')
+ if capture_output:
+ kwargs['stdout'] = kwargs['stderr'] = PIPE
+
+ # Most SCons tools/tests expect not to fail on things like missing files.
+ # check=True (or error="raise") means we're okay to take an exception;
+ # else we catch the likely exception and construct a dummy
+ # CompletedProcess instance.
+ # Note pylint can't see we always include 'check' in kwargs: suppress.
if check:
- cp = subprocess.run(*args, **kwargs)
+ cp = subprocess.run(*args, **kwargs) # pylint: disable=subprocess-run-check
else:
try:
- cp = subprocess.run(*args, **kwargs)
+ cp = subprocess.run(*args, **kwargs) # pylint: disable=subprocess-run-check
except OSError as exc:
argline = ' '.join(*args)
- cp = subprocess.CompletedProcess(argline, 1)
- cp.stdout = ""
- cp.stderr = ""
+ cp = subprocess.CompletedProcess(
+ args=argline, returncode=1, stdout="", stderr=""
+ )
return cp
@@ -1044,7 +1035,6 @@ class CommandAction(_ActionAction):
if self.cmdstr is None:
return None
if self.cmdstr is not _null:
- from SCons.Subst import SUBST_RAW
if executor:
c = env.subst(self.cmdstr, SUBST_RAW, executor=executor, overrides=overrides)
else:
@@ -1077,12 +1067,11 @@ class CommandAction(_ActionAction):
spawn = env['SPAWN']
except KeyError:
raise SCons.Errors.UserError('Missing SPAWN construction variable.')
- else:
- if is_String(spawn):
- spawn = env.subst(spawn, raw=1, conv=lambda x: x)
- escape = env.get('ESCAPE', lambda x: x)
+ if is_String(spawn):
+ spawn = env.subst(spawn, raw=1, conv=lambda x: x)
+ escape = env.get('ESCAPE', lambda x: x)
ENV = _resolve_shell_env(env, target, source)
# Ensure that the ENV values are all strings:
@@ -1125,7 +1114,6 @@ class CommandAction(_ActionAction):
This strips $(-$) and everything in between the string,
since those parts don't affect signatures.
"""
- from SCons.Subst import SUBST_SIG
cmd = self.cmd_list
if is_List(cmd):
cmd = ' '.join(map(str, cmd))
@@ -1133,8 +1121,7 @@ class CommandAction(_ActionAction):
cmd = str(cmd)
if executor:
return env.subst_target_source(cmd, SUBST_SIG, executor=executor)
- else:
- return env.subst_target_source(cmd, SUBST_SIG, target, source)
+ return env.subst_target_source(cmd, SUBST_SIG, target, source)
def get_implicit_deps(self, target, source, env, executor=None):
"""Return the implicit dependencies of this action's command line."""
@@ -1154,17 +1141,15 @@ class CommandAction(_ActionAction):
# An integer value greater than 1 specifies the number of entries
# to scan. "all" means to scan all.
return self._get_implicit_deps_heavyweight(target, source, env, executor, icd_int)
- else:
- # Everything else (usually 1 or True) means that we want
- # lightweight dependency scanning.
- return self._get_implicit_deps_lightweight(target, source, env, executor)
+ # Everything else (usually 1 or True) means that we want
+ # lightweight dependency scanning.
+ return self._get_implicit_deps_lightweight(target, source, env, executor)
def _get_implicit_deps_lightweight(self, target, source, env, executor):
"""
Lightweight dependency scanning involves only scanning the first entry
in an action string, even if it contains &&.
"""
- from SCons.Subst import SUBST_SIG
if executor:
cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, executor=executor)
else:
@@ -1202,7 +1187,6 @@ class CommandAction(_ActionAction):
# Avoid circular and duplicate dependencies by not providing source,
# target, or executor to subst_list. This causes references to
# $SOURCES, $TARGETS, and all related variables to disappear.
- from SCons.Subst import SUBST_SIG
cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, conv=lambda x: x)
res = []
@@ -1281,7 +1265,7 @@ class CommandGeneratorAction(ActionBase):
def batch_key(self, env, target, source):
return self._generate(target, source, env, 1).batch_key(env, target, source)
- def genstring(self, target, source, env, executor=None):
+ def genstring(self, target, source, env, executor=None) -> str:
return self._generate(target, source, env, 1, executor).genstring(target, source, env)
def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
@@ -1409,7 +1393,6 @@ class FunctionAction(_ActionAction):
if self.cmdstr is None:
return None
if self.cmdstr is not _null:
- from SCons.Subst import SUBST_RAW
if executor:
c = env.subst(self.cmdstr, SUBST_RAW, executor=executor)
else:
@@ -1456,9 +1439,7 @@ class FunctionAction(_ActionAction):
rsources = list(map(rfile, source))
try:
result = self.execfunction(target=target, source=rsources, env=env)
- except KeyboardInterrupt as e:
- raise
- except SystemExit as e:
+ except (KeyboardInterrupt, SystemExit):
raise
except Exception as e:
result = e
@@ -1466,8 +1447,8 @@ class FunctionAction(_ActionAction):
if result:
result = SCons.Errors.convert_to_BuildError(result, exc_info)
- result.node=target
- result.action=self
+ result.node = target
+ result.action = self
try:
result.command=self.strfunction(target, source, env, executor)
except TypeError:
@@ -1480,7 +1461,7 @@ class FunctionAction(_ActionAction):
# some codes do not check the return value of Actions and I do
# not have the time to modify them at this point.
if (exc_info[1] and
- not isinstance(exc_info[1],EnvironmentError)):
+ not isinstance(exc_info[1], EnvironmentError)):
raise result
return result
@@ -1514,7 +1495,7 @@ class ListAction(ActionBase):
self.varlist = ()
self.targets = '$TARGETS'
- def genstring(self, target, source, env):
+ def genstring(self, target, source, env, executor=None) -> str:
return '\n'.join([a.genstring(target, source, env) for a in self.list])
def __str__(self) -> str:
@@ -1601,8 +1582,9 @@ class ActionCaller:
# was called by using this hard-coded value as a special return.
if s == '$__env__':
return env
- elif is_String(s):
+ if is_String(s):
return env.subst(s, 1, target, source)
+
return self.parent.convert(s)
def subst_args(self, target, source, env):
diff --git a/SCons/ActionTests.py b/SCons/ActionTests.py
index 7239f4f5e..7d99a2560 100644
--- a/SCons/ActionTests.py
+++ b/SCons/ActionTests.py
@@ -41,11 +41,13 @@ import os
import sys
import types
import unittest
+from unittest import mock
from subprocess import PIPE
import SCons.Action
import SCons.Environment
import SCons.Errors
+from SCons.Action import scons_subproc_run
import TestCmd
@@ -2329,7 +2331,7 @@ class ObjectContentsTestCase(unittest.TestCase):
def test_uncaught_exception_bubbles(self):
"""Test that scons_subproc_run bubbles uncaught exceptions"""
try:
- cp = SCons.Action.scons_subproc_run(Environment(), None, stdout=PIPE)
+ cp = scons_subproc_run(Environment(), None, stdout=PIPE)
except EnvironmentError:
pass
except Exception:
@@ -2338,6 +2340,56 @@ class ObjectContentsTestCase(unittest.TestCase):
raise Exception("expected a non-EnvironmentError exception")
+
+ def mock_subprocess_run(*args, **kwargs):
+ """Replacement subprocess.run: return kwargs for checking."""
+ kwargs.pop("env") # the value of env isn't interesting here
+ return kwargs
+
+ @mock.patch("subprocess.run", mock_subprocess_run)
+ def test_scons_subproc_run(self):
+ """Test the argument remapping options."""
+ # set phony Python versions to trigger the logic in scons_subproc_run:
+ # any version greater than 3.6, really
+ save_info, sys.version_info = sys.version_info, (3, 11, 1)
+ env = Environment()
+ self.assertEqual(scons_subproc_run(env), {"check": False})
+ with self.subTest():
+ self.assertEqual(
+ scons_subproc_run(env, error="raise"),
+ {"check": True}
+ )
+ with self.subTest():
+ self.assertEqual(
+ scons_subproc_run(env, capture_output=True),
+ {"capture_output": True, "check": False},
+ )
+ with self.subTest():
+ self.assertEqual(
+ scons_subproc_run(env, text=True),
+ {"text": True, "check": False},
+ )
+
+ # 3.6:
+ sys.version_info = (3, 6, 2)
+ with self.subTest():
+ self.assertEqual(
+ scons_subproc_run(env, capture_output=True),
+ {"check": False, "stdout": PIPE, "stderr": PIPE},
+ )
+ with self.subTest():
+ self.assertEqual(
+ scons_subproc_run(env, text=True),
+ {"check": False, "universal_newlines": True},
+ )
+ with self.subTest():
+ self.assertEqual(
+ scons_subproc_run(env, universal_newlines=True),
+ {"universal_newlines": True, "check": False},
+ )
+ sys.version_info = save_info
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/SCons/Tool/midl.py b/SCons/Tool/midl.py
index 0c640f509..2ae3f73d0 100644
--- a/SCons/Tool/midl.py
+++ b/SCons/Tool/midl.py
@@ -37,7 +37,7 @@ import SCons.Defaults
import SCons.Scanner.IDL
import SCons.Util
-from .MSCommon import msvc_setup_env_tool
+from SCons.Tool.MSCommon import msvc_setup_env_tool
tool_name = 'midl'
diff --git a/SCons/Tool/mslib.py b/SCons/Tool/mslib.py
index 6e15a808f..bdce135f8 100644
--- a/SCons/Tool/mslib.py
+++ b/SCons/Tool/mslib.py
@@ -41,7 +41,10 @@ import SCons.Tool.msvs
import SCons.Tool.msvc
import SCons.Util
-from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once
+from SCons.Tool.MSCommon import (
+ msvc_setup_env_tool,
+ msvc_setup_env_once,
+)
tool_name = 'mslib'
diff --git a/SCons/Tool/mslink.py b/SCons/Tool/mslink.py
index 1e5b71ae1..74ceaa857 100644
--- a/SCons/Tool/mslink.py
+++ b/SCons/Tool/mslink.py
@@ -43,8 +43,11 @@ import SCons.Tool.msvc
import SCons.Tool.msvs
import SCons.Util
-from .MSCommon import msvc_setup_env_once, msvc_setup_env_tool
-from .MSCommon.common import get_pch_node
+from SCons.Tool.MSCommon import (
+ msvc_setup_env_once,
+ msvc_setup_env_tool,
+)
+from SCons.Tool.MSCommon.common import get_pch_node
tool_name = 'mslink'
diff --git a/SCons/Tool/mssdk.py b/SCons/Tool/mssdk.py
index 0151eff2b..ef272c033 100644
--- a/SCons/Tool/mssdk.py
+++ b/SCons/Tool/mssdk.py
@@ -33,8 +33,10 @@ It will usually be imported through the generic SCons.Tool.Tool()
selection method.
"""
-from .MSCommon import mssdk_exists, \
- mssdk_setup_env
+from SCons.Tool.MSCommon import (
+ mssdk_exists,
+ mssdk_setup_env,
+)
def generate(env) -> None:
"""Add construction variables for an MS SDK to an Environment."""
diff --git a/SCons/Tool/msvc.py b/SCons/Tool/msvc.py
index 33a67d0f4..6afa171c9 100644
--- a/SCons/Tool/msvc.py
+++ b/SCons/Tool/msvc.py
@@ -44,8 +44,13 @@ import SCons.Util
import SCons.Warnings
import SCons.Scanner.RC
-from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once, msvc_version_to_maj_min, msvc_find_vswhere
-from .MSCommon.common import get_pch_node
+from SCons.Tool.MSCommon import (
+ msvc_setup_env_tool,
+ msvc_setup_env_once,
+ msvc_version_to_maj_min,
+ msvc_find_vswhere,
+)
+from SCons.Tool.MSCommon.common import get_pch_node
tool_name = 'msvc'
diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py
index 153b84ecd..16e422dac 100644
--- a/SCons/Tool/msvs.py
+++ b/SCons/Tool/msvs.py
@@ -45,7 +45,10 @@ import SCons.Util
import SCons.Warnings
from SCons.Defaults import processDefines
from SCons.compat import PICKLE_PROTOCOL
-from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once
+from SCons.Tool.MSCommon import (
+ msvc_setup_env_tool,
+ msvc_setup_env_once,
+)
tool_name = 'msvs'
diff --git a/test/AS/as-live.py b/test/AS/as-live.py
index 676b5375e..4a21fcf6f 100644
--- a/test/AS/as-live.py
+++ b/test/AS/as-live.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -20,9 +22,6 @@
# 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.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Verify correct use of the live 'as' assembler.
@@ -37,24 +36,22 @@ _exe = TestSCons._exe
test = TestSCons.TestSCons()
-
-
if not test.detect('AS', 'as'):
test.skip_test("as not found; skipping test\n")
x86 = (sys.platform == 'win32' or sys.platform.find('linux') != -1)
-
if not x86:
test.skip_test("skipping as test on non-x86 platform '%s'\n" % sys.platform)
namelbl = "name"
-testccc = """ccc = aaa.Clone(CPPPATH=['.'])
-ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c'])
+testccc = """\
+ccc = aaa.Clone(CPPPATH=['.'])
+ccc.Program(target='ccc', source=['ccc.S', 'ccc_main.c'])
"""
if sys.platform == "win32":
namelbl = "_name"
testccc = ""
-
+
test.write("wrapper.py", """\
import subprocess
import sys
@@ -66,30 +63,34 @@ subprocess.run(cmd, shell=True)
test.write('SConstruct', """\
aaa = Environment()
-aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c'])
-bbb = aaa.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('as'))
-bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c'])
+aaa.Program(target='aaa', source=['aaa.s', 'aaa_main.c'])
+bbb = aaa.Clone(AS=r'%(_python_)s wrapper.py ' + WhereIs('as'))
+bbb.Program(target='bbb', source=['bbb.s', 'bbb_main.c'])
%(testccc)s
""" % locals())
-test.write('aaa.s',
-""" .file "aaa.s"
-.data
-.align 4
-.globl %(namelbl)s
+test.write('aaa.s', """
+ .file "aaa.s"
+ .data
+ .align 4
+ .globl %(namelbl)s
%(namelbl)s:
- .ascii "aaa.s"
- .byte 0
+ .ascii "aaa.s"
+ .byte 0
+ .ident "handcrafted test assembly"
+ .section .note.GNU-stack,"",@progbits
""" % locals())
test.write('bbb.s', """\
-.file "bbb.s"
-.data
-.align 4
-.globl %(namelbl)s
+ .file "bbb.s"
+ .data
+ .align 4
+ .globl %(namelbl)s
%(namelbl)s:
- .ascii "bbb.s"
- .byte 0
+ .ascii "bbb.s"
+ .byte 0
+ .ident "handcrafted test assembly"
+ .section .note.GNU-stack,"",@progbits
""" % locals())
test.write('ccc.h', """\
@@ -98,13 +99,15 @@ test.write('ccc.h', """\
test.write('ccc.S', """\
#include <ccc.h>
-.file STRING
-.data
-.align 4
-.globl name
+ .file STRING
+ .data
+ .align 4
+ .globl name
name:
- .ascii STRING
- .byte 0
+ .ascii STRING
+ .byte 0
+ .ident "handcrafted test assembly"
+ .section .note.GNU-stack,"",@progbits
""")
test.write('aaa_main.c', r"""
@@ -171,13 +174,13 @@ test.run(program = test.workpath('bbb'), stdout = "bbb_main.c bbb.s\n")
if sys.platform != "win32":
test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.S\n")
-
+
test.must_match('wrapper.out', "wrapper.py: bbb.s\n")
-
+
test.write("ccc.h", """\
#define STRING "ccc.S 2"
""")
-
+
test.run()
test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.S 2\n")
diff --git a/testing/framework/TestCmdTests.py b/testing/framework/TestCmdTests.py
index dc752ba4e..7cabf445c 100644
--- a/testing/framework/TestCmdTests.py
+++ b/testing/framework/TestCmdTests.py
@@ -1601,10 +1601,10 @@ class rmdir_TestCase(TestCmdTestCase):
try:
test.rmdir(['no', 'such', 'dir'])
- except EnvironmentError:
+ except FileNotFoundError:
pass
else:
- raise Exception("did not catch expected SConsEnvironmentError")
+ raise Exception("did not catch expected FileNotFoundError")
test.subdir(['sub'],
['sub', 'dir'],
@@ -1616,19 +1616,19 @@ class rmdir_TestCase(TestCmdTestCase):
try:
test.rmdir(['sub'])
- except EnvironmentError:
+ except OSError:
pass
else:
- raise Exception("did not catch expected SConsEnvironmentError")
+ raise Exception("did not catch expected OSError")
assert os.path.isdir(s_d_o), f"{s_d_o} is gone?"
try:
test.rmdir(['sub'])
- except EnvironmentError:
+ except OSError:
pass
else:
- raise Exception("did not catch expected SConsEnvironmentError")
+ raise Exception("did not catch expected OSError")
assert os.path.isdir(s_d_o), f"{s_d_o} is gone?"
@@ -1647,7 +1647,6 @@ class rmdir_TestCase(TestCmdTestCase):
assert not os.path.exists(s), f"{s} exists?"
-
class run_TestCase(TestCmdTestCase):
def test_run(self) -> None:
"""Test run()"""