"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "SCons/Tool/ninja/NinjaState.py" between
scons-4.2.0.tar.gz and SCons-4.3.0.tar.gz

About: SCons is a software construction tool (a Python script and a set of modules as a superior alternative to the classic "Make" build tool).

NinjaState.py  (scons-4.2.0):NinjaState.py  (SCons-4.3.0)
skipping to change at line 27 skipping to change at line 27
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import io import io
import os import os
import shutil
import sys import sys
from os.path import splitext from os.path import splitext
from tempfile import NamedTemporaryFile
import ninja import ninja
import SCons import SCons
from SCons.Script import COMMAND_LINE_TARGETS from SCons.Script import COMMAND_LINE_TARGETS
from SCons.Util import is_List from SCons.Util import is_List
from SCons.Errors import InternalError from SCons.Errors import InternalError
from .Globals import COMMAND_TYPES, NINJA_RULES, NINJA_POOLS, \ from .Globals import COMMAND_TYPES, NINJA_RULES, NINJA_POOLS, \
NINJA_CUSTOM_HANDLERS NINJA_CUSTOM_HANDLERS
from .Rules import _install_action_function, _mkdir_action_function, _lib_symlin k_action_function, _copy_action_function from .Rules import _install_action_function, _mkdir_action_function, _lib_symlin k_action_function, _copy_action_function
from .Utils import get_path, alias_to_ninja_build, generate_depfile, ninja_noop, get_order_only, \ from .Utils import get_path, alias_to_ninja_build, generate_depfile, ninja_noop, get_order_only, \
get_outputs, get_inputs, get_dependencies, get_rule, get_command_env get_outputs, get_inputs, get_dependencies, get_rule, get_command_env, to_esc aped_list
from .Methods import get_command from .Methods import get_command
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
class NinjaState: class NinjaState:
"""Maintains state of Ninja build system as it's translated from SCons.""" """Maintains state of Ninja build system as it's translated from SCons."""
def __init__(self, env, ninja_file, writer_class): def __init__(self, env, ninja_file, ninja_syntax):
self.env = env self.env = env
self.ninja_file = ninja_file self.ninja_file = ninja_file
self.ninja_bin_path = env.get('NINJA') self.ninja_bin_path = env.get('NINJA')
if not self.ninja_bin_path: if not self.ninja_bin_path:
# default to using ninja installed with python module # default to using ninja installed with python module
ninja_bin = 'ninja.exe' if env["PLATFORM"] == "win32" else 'ninja' ninja_bin = 'ninja.exe' if env["PLATFORM"] == "win32" else 'ninja'
self.ninja_bin_path = os.path.abspath(os.path.join( self.ninja_bin_path = os.path.abspath(os.path.join(
ninja.__file__, ninja.__file__,
os.pardir, os.pardir,
'data', 'data',
'bin', 'bin',
ninja_bin)) ninja_bin))
if not os.path.exists(self.ninja_bin_path): if not os.path.exists(self.ninja_bin_path):
# couldn't find it, just give the bin name and hope # couldn't find it, just give the bin name and hope
# its in the path later # its in the path later
self.ninja_bin_path = ninja_bin self.ninja_bin_path = ninja_bin
self.writer_class = writer_class self.writer_class = ninja_syntax.Writer
self.__generated = False self.__generated = False
self.translator = SConsToNinjaTranslator(env) self.translator = SConsToNinjaTranslator(env)
self.generated_suffixes = env.get("NINJA_GENERATED_SOURCE_SUFFIXES", []) self.generated_suffixes = env.get("NINJA_GENERATED_SOURCE_SUFFIXES", [])
# List of generated builds that will be written at a later stage # List of generated builds that will be written at a later stage
self.builds = dict() self.builds = dict()
# List of targets for which we have generated a build. This # List of targets for which we have generated a build. This
# allows us to take multiple Alias nodes as sources and to not # allows us to take multiple Alias nodes as sources and to not
# fail to build if they have overlapping targets. # fail to build if they have overlapping targets.
self.built = set() self.built = set()
# SCons sets this variable to a function which knows how to do # SCons sets this variable to a function which knows how to do
# shell quoting on whatever platform it's run on. Here we use it # shell quoting on whatever platform it's run on. Here we use it
# to make the SCONS_INVOCATION variable properly quoted for things # to make the SCONS_INVOCATION variable properly quoted for things
# like CCFLAGS # like CCFLAGS
escape = env.get("ESCAPE", lambda x: x) scons_escape = env.get("ESCAPE", lambda x: x)
# if SCons was invoked from python, we expect the first arg to be the sc ons.py # if SCons was invoked from python, we expect the first arg to be the sc ons.py
# script, otherwise scons was invoked from the scons script # script, otherwise scons was invoked from the scons script
python_bin = '' python_bin = ''
if os.path.basename(sys.argv[0]) == 'scons.py': if os.path.basename(sys.argv[0]) == 'scons.py':
python_bin = escape(sys.executable) python_bin = ninja_syntax.escape(scons_escape(sys.executable))
self.variables = { self.variables = {
"COPY": "cmd.exe /c 1>NUL copy" if sys.platform == "win32" else "cp" , "COPY": "cmd.exe /c 1>NUL copy" if sys.platform == "win32" else "cp" ,
"SCONS_INVOCATION": '{} {} --disable-ninja __NINJA_NO=1 $out'.format ( "SCONS_INVOCATION": '{} {} --disable-ninja __NINJA_NO=1 $out'.format (
python_bin, python_bin,
" ".join( " ".join(
[escape(arg) for arg in sys.argv if arg not in COMMAND_LINE_ TARGETS] [ninja_syntax.escape(scons_escape(arg)) for arg in sys.argv if arg not in COMMAND_LINE_TARGETS]
), ),
), ),
"SCONS_INVOCATION_W_TARGETS": "{} {}".format( "SCONS_INVOCATION_W_TARGETS": "{} {} NINJA_DISABLE_AUTO_RUN=1".forma
python_bin, " ".join([escape(arg) for arg in sys.argv]) t(
python_bin, " ".join([
ninja_syntax.escape(scons_escape(arg))
for arg in sys.argv
if arg != 'NINJA_DISABLE_AUTO_RUN=1'])
), ),
# This must be set to a global default per: # This must be set to a global default per:
# https://ninja-build.org/manual.html#_deps # https://ninja-build.org/manual.html#_deps
# English Visual Studio will have the default below, # English Visual Studio will have the default below,
# otherwise the user can define the variable in the first environmen t # otherwise the user can define the variable in the first environmen t
# that initialized ninja tool # that initialized ninja tool
"msvc_deps_prefix": env.get("NINJA_MSVC_DEPS_PREFIX", "Note: includi ng file:") "msvc_deps_prefix": env.get("NINJA_MSVC_DEPS_PREFIX", "Note: includi ng file:")
} }
self.rules = { self.rules = {
skipping to change at line 210 skipping to change at line 215
# targets. But since SCons is doing it's own up to # targets. But since SCons is doing it's own up to
# date-ness checks it may only update say one of # date-ness checks it may only update say one of
# them. Restat will find out which of the multiple # them. Restat will find out which of the multiple
# build targets did actually change then only rebuild # build targets did actually change then only rebuild
# those targets which depend specifically on that # those targets which depend specifically on that
# output. # output.
"restat": 1, "restat": 1,
}, },
"REGENERATE": { "REGENERATE": {
"command": "$SCONS_INVOCATION_W_TARGETS", "command": "$SCONS_INVOCATION_W_TARGETS",
"description": "Regenerating $out", "description": "Regenerating $self",
"generator": 1, "generator": 1,
"depfile": os.path.join(get_path(env['NINJA_DIR']), '$out.depfil
e'),
# Console pool restricts to 1 job running at a time,
# it additionally has some special handling about
# passing stdin, stdout, etc to process in this pool
# that we need for SCons to behave correctly when
# regenerating Ninja
"pool": "console", "pool": "console",
# Again we restat in case Ninja thought the
# build.ninja should be regenerated but SCons knew
# better.
"restat": 1, "restat": 1,
}, },
} }
if env['PLATFORM'] == 'darwin' and env['AR'] == 'ar': if env['PLATFORM'] == 'darwin' and env.get('AR', "") == 'ar':
self.rules["AR"] = { self.rules["AR"] = {
"command": "rm -f $out && $env$AR $rspc", "command": "rm -f $out && $env$AR $rspc",
"description": "Archiving $out", "description": "Archiving $out",
"pool": "local_pool", "pool": "local_pool",
} }
num_jobs = self.env.get('NINJA_MAX_JOBS', self.env.GetOption("num_jobs") ) num_jobs = self.env.get('NINJA_MAX_JOBS', self.env.GetOption("num_jobs") )
self.pools = { self.pools = {
"local_pool": num_jobs, "local_pool": num_jobs,
"install_pool": num_jobs / 2, "install_pool": num_jobs / 2,
skipping to change at line 301 skipping to change at line 297
return return
self.rules.update(self.env.get(NINJA_RULES, {})) self.rules.update(self.env.get(NINJA_RULES, {}))
self.pools.update(self.env.get(NINJA_POOLS, {})) self.pools.update(self.env.get(NINJA_POOLS, {}))
content = io.StringIO() content = io.StringIO()
ninja = self.writer_class(content, width=100) ninja = self.writer_class(content, width=100)
ninja.comment("Generated by scons. DO NOT EDIT.") ninja.comment("Generated by scons. DO NOT EDIT.")
ninja.variable("builddir", get_path(self.env['NINJA_DIR'])) ninja.variable("builddir", get_path(self.env.Dir(self.env['NINJA_DIR']). path))
for pool_name, size in self.pools.items(): for pool_name, size in self.pools.items():
ninja.pool(pool_name, min(self.env.get('NINJA_MAX_JOBS', size), size )) ninja.pool(pool_name, min(self.env.get('NINJA_MAX_JOBS', size), size ))
for var, val in self.variables.items(): for var, val in self.variables.items():
ninja.variable(var, val) ninja.variable(var, val)
for rule, kwargs in self.rules.items(): for rule, kwargs in self.rules.items():
if self.env.get('NINJA_MAX_JOBS') is not None and 'pool' not in kwar gs: if self.env.get('NINJA_MAX_JOBS') is not None and 'pool' not in kwar gs:
kwargs['pool'] = 'local_pool' kwargs['pool'] = 'local_pool'
skipping to change at line 449 skipping to change at line 445
if is_List(cur_val): if is_List(cur_val):
new_val += cur_val new_val += cur_val
else: else:
new_val.append(cur_val) new_val.append(cur_val)
template_builds[agg_key] = new_val template_builds[agg_key] = new_val
# Collect all other keys # Collect all other keys
template_builds.update(template_builder) template_builds.update(template_builder)
if template_builds.get("outputs", []): if template_builds.get("outputs", []):
# Try to clean up any dependency cycles. If we are passing an
# ouptut node to SCons, it will build any dependencys if ninja
# has not already.
for output in template_builds.get("outputs", []):
inputs = template_builds.get('inputs')
if inputs and output in inputs:
inputs.remove(output)
implicits = template_builds.get('implicit')
if implicits and output in implicits:
implicits.remove(output)
ninja.build(**template_builds) ninja.build(**template_builds)
# We have to glob the SCons files here to teach the ninja file # We have to glob the SCons files here to teach the ninja file
# how to regenerate itself. We'll never see ourselves in the # how to regenerate itself. We'll never see ourselves in the
# DAG walk so we can't rely on action_to_ninja_build to # DAG walk so we can't rely on action_to_ninja_build to
# generate this rule even though SCons should know we're # generate this rule even though SCons should know we're
# dependent on SCons files. # dependent on SCons files.
#
# The REGENERATE rule uses depfile, so we need to generate the depfile
# in case any of the SConscripts have changed. The depfile needs to be
# path with in the build and the passed ninja file is an abspath, so
# we will use SCons to give us the path within the build. Normally
# generate_depfile should not be called like this, but instead be called
# through the use of custom rules, and filtered out in the normal
# list of build generation about. However, because the generate rule
# is hardcoded here, we need to do this generate_depfile call manually.
ninja_file_path = self.env.File(self.ninja_file).path ninja_file_path = self.env.File(self.ninja_file).path
generate_depfile( regenerate_deps = to_escaped_list(self.env, self.env['NINJA_REGENERATE_D
self.env, EPS'])
ninja_file_path,
self.env['NINJA_REGENERATE_DEPS']
)
ninja.build( ninja.build(
ninja_file_path, ninja_file_path,
rule="REGENERATE", rule="REGENERATE",
implicit=[__file__], implicit=regenerate_deps,
variables={
"self": ninja_file_path,
}
)
ninja.build(
regenerate_deps,
rule="phony",
variables={
"self": ninja_file_path,
}
) )
# If we ever change the name/s of the rules that include # If we ever change the name/s of the rules that include
# compile commands (i.e. something like CC) we will need to # compile commands (i.e. something like CC) we will need to
# update this build to reflect that complete list. # update this build to reflect that complete list.
ninja.build( ninja.build(
"compile_commands.json", "compile_commands.json",
rule="CMD", rule="CMD",
pool="console", pool="console",
implicit=[str(self.ninja_file)], implicit=[str(self.ninja_file)],
skipping to change at line 516 skipping to change at line 523
for tgt in SCons.Script.DEFAULT_TARGETS for tgt in SCons.Script.DEFAULT_TARGETS
if get_path(tgt) in self.built if get_path(tgt) in self.built
] ]
# If we found an overlap between SCons's list of default # If we found an overlap between SCons's list of default
# targets and the targets we created ninja builds for then use # targets and the targets we created ninja builds for then use
# those as ninja's default as well. # those as ninja's default as well.
if scons_default_targets: if scons_default_targets:
ninja.default(" ".join(scons_default_targets)) ninja.default(" ".join(scons_default_targets))
with open(str(self.ninja_file), "w") as build_ninja: with NamedTemporaryFile(delete=False, mode='w') as temp_ninja_file:
build_ninja.write(content.getvalue()) temp_ninja_file.write(content.getvalue())
shutil.move(temp_ninja_file.name, ninja_file_path)
self.__generated = True self.__generated = True
class SConsToNinjaTranslator: class SConsToNinjaTranslator:
"""Translates SCons Actions into Ninja build objects.""" """Translates SCons Actions into Ninja build objects."""
def __init__(self, env): def __init__(self, env):
self.env = env self.env = env
self.func_handlers = { self.func_handlers = {
# Skip conftest builders # Skip conftest builders
"_createSource": ninja_noop, "_createSource": ninja_noop,
# SCons has a custom FunctionAction that just makes sure the # SCons has a custom FunctionAction that just makes sure the
# target isn't static. We let the commands that ninja runs do # target isn't static. We let the commands that ninja runs do
# this check for us. # this check for us.
"SharedFlagChecker": ninja_noop, "SharedFlagChecker": ninja_noop,
# The install builder is implemented as a function action. # The install builder is implemented as a function action.
# TODO: use command action #3573 # TODO: use command action #3573
"installFunc": _install_action_function, "installFunc": _install_action_function,
"MkdirFunc": _mkdir_action_function, "MkdirFunc": _mkdir_action_function,
"Mkdir": _mkdir_action_function,
"LibSymlinksActionFunction": _lib_symlink_action_function, "LibSymlinksActionFunction": _lib_symlink_action_function,
"Copy": _copy_action_function "Copy": _copy_action_function
} }
self.loaded_custom = False self.loaded_custom = False
# pylint: disable=too-many-return-statements # pylint: disable=too-many-return-statements
def action_to_ninja_build(self, node, action=None): def action_to_ninja_build(self, node, action=None):
"""Generate build arguments dictionary for node.""" """Generate build arguments dictionary for node."""
 End of changes. 20 change blocks. 
38 lines changed or deleted 48 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)