Skip to content
Merged
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
Note that these are called for every build command run by SCons. It could have considerable
performance impact if not used carefully.
to connect to the server during start up.
- Ninja: Added command line variable NINJA_CMD_ARGS that allows to pass through ninja command line args.
This can also be set in your Environment().


From Mats Wichmann:
- Tweak the way default site_scons paths on Windows are expressed to
Expand Down
5 changes: 4 additions & 1 deletion RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ NOTE: If you build with Python 3.10.0 and then rebuild with 3.10.1 (or higher),
NEW FUNCTIONALITY
-----------------

- Added MSVC_USE_SCRIPT_ARGS variable to pass arguments to MSVC_USE_SCRIPT.
- Added MSVC_USE_SCRIPT_ARGS Environment variable which specifies command line arguments
to pass to the script specified by MSVC_USE_SCRIPT.
- Added Configure.CheckMember() checker to check if struct/class has the specified member.
- Added SHELL_ENV_GENERATORS construction variable. This variable should be set to a list
(or an iterable) which contains functions to be called in order
Expand All @@ -24,6 +25,8 @@ NEW FUNCTIONALITY
performance impact if not used carefully.
- Added MSVC_USE_SETTINGS variable to pass a dictionary to configure the msvc compiler
system environment as an alternative to bypassing Visual Studio autodetection entirely.
- Ninja: Added command line variable NINJA_CMD_ARGS that allows to pass through ninja command line args.
This can also be set in your Environment().
- Added a global policy setting and an environment policy variable for specifying the action to
be taken when an msvc request cannot be satisfied. The available options are "error",
"exception", "warning", "warn", "ignore", and "suppress". The global policy variable may be
Expand Down
12 changes: 10 additions & 2 deletions SCons/Tool/ninja/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def ninja_builder(env, target, source):

if str(env.get("NINJA_DISABLE_AUTO_RUN")).lower() not in ['1', 'true']:
num_jobs = env.get('NINJA_MAX_JOBS', env.GetOption("num_jobs"))
cmd += ['-j' + str(num_jobs)] + NINJA_CMDLINE_TARGETS
cmd += ['-j' + str(num_jobs)] + env.get('NINJA_CMD_ARGS', '').split() + NINJA_CMDLINE_TARGETS
print(f"ninja will be run with command line targets: {' '.join(NINJA_CMDLINE_TARGETS)}")
print("Executing:", str(' '.join(cmd)))

Expand Down Expand Up @@ -125,6 +125,14 @@ def execute_ninja():
sys.stdout.write("\n")


def options(opts):
"""
Add command line Variables for Ninja builder.
"""
opts.AddVariables(
("NINJA_CMD_ARGS", "Arguments to pass to ninja"),
)

def exists(env):
"""Enable if called."""

Expand Down Expand Up @@ -197,7 +205,7 @@ def generate(env):
env["NINJA_SCONS_DAEMON_PORT"] = env.get('NINJA_SCONS_DAEMON_PORT', random.randint(10000, 60000))

if GetOption("disable_ninja"):
env.SConsignFile(os.path.join(str(env['NINJA_DIR']),'.ninja.sconsign'))
env.SConsignFile(os.path.join(str(env['NINJA_DIR']), '.ninja.sconsign'))

# here we allow multiple environments to construct rules and builds
# into the same ninja file
Expand Down
19 changes: 18 additions & 1 deletion SCons/Tool/ninja/ninja.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ See its __doc__ string for a discussion of the format.
<item>IMPLICIT_COMMAND_DEPENDENCIES</item>
<item>NINJA_SCONS_DAEMON_KEEP_ALIVE</item>
<item>NINJA_SCONS_DAEMON_PORT</item>

<item>NINJA_CMD_ARGS</item>

<!-- TODO: Document these -->
<!-- <item>NINJA_RULES</item>-->
Expand Down Expand Up @@ -395,5 +395,22 @@ python -m pip install ninja
</summary>
</cvar>

<cvar name="NINJA_CMD_ARGS">
<summary>
<para>
A string which will pass arguments through SCons to the ninja command when scons executes ninja.
Has no effect if &cv-NINJA_DISABLE_AUTO_RUN; is set.
</para>
<para>
This value can also be passed on the command line:
</para>
<example_commands>
scons NINJA_CMD_ARGS=-v
or
scons NINJA_CMD_ARGS="-v -j 3"
</example_commands>
</summary>
</cvar>


</sconsdoc>
3 changes: 2 additions & 1 deletion SCons/Tool/packaging/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,11 @@ def generate(env):
env['BUILDERS']['Package'] = Package
env['BUILDERS']['Tag'] = Tag


def exists(env):
return 1

# XXX

def options(opts):
opts.AddVariables(
EnumVariable('PACKAGETYPE',
Expand Down
7 changes: 6 additions & 1 deletion test/ninja/generate_and_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,17 @@
test.file_fixture('ninja_test_sconscripts/sconstruct_generate_and_build', 'SConstruct')

# generate simple build
test.run(stdout=None)
test.run(stdout=None, arguments='NINJA_CMD_ARGS=-v')
test.must_contain_all_lines(test.stdout(), ['Generating: build.ninja'])
test.must_contain_all(test.stdout(), 'Executing:')
test.must_contain_all(test.stdout(), 'ninja%(_exe)s -f' % locals())
test.must_contain_all(test.stdout(), ' -j1 -v')
test.run(program=test.workpath('foo' + _exe), stdout="foo.c")

# Test multiple args for NINJA_CMD_ARGS
test.run(stdout=None, arguments={'NINJA_CMD_ARGS':"-v -j3"})
test.must_contain_all(test.stdout(), ' -v -j3')

# clean build and ninja files
test.run(arguments='-c', stdout=None)
test.must_contain_all_lines(test.stdout(), [
Expand Down
6 changes: 6 additions & 0 deletions testing/framework/TestCmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,9 @@ def command_args(self, program=None, interpreter=None, arguments=None):
interpreter = [interpreter]
cmd = list(interpreter) + cmd
if arguments:
if isinstance(arguments, dict):
cmd.extend(["%s=%s" % (k, v) for k, v in arguments.items()])
return cmd
if isinstance(arguments, str):
arguments = arguments.split()
cmd.extend(arguments)
Expand Down Expand Up @@ -1569,6 +1572,9 @@ def run(self, program=None,

The specified program will have the original directory
prepended unless it is enclosed in a [list].

argument: If this is a dict() then will create arguments with KEY+VALUE for
each entry in the dict.
"""
if self.external:
if not program:
Expand Down
76 changes: 10 additions & 66 deletions testing/framework/TestCmdTests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2261,6 +2261,12 @@ def test_command_args(self):
expect = ['PYTHON', default_prog, 'arg3', 'arg4']
assert r == expect, (expect, r)

# Test arguments = dict
r = test.command_args(interpreter='PYTHON', arguments={'VAR1':'1'})
expect = ['PYTHON', default_prog, 'VAR1=1']
assert r == expect, (expect, r)


test.interpreter_set('default_python')

r = test.command_args()
Expand Down Expand Up @@ -2585,7 +2591,7 @@ def test_send(self):
with open(t.recv_out_path, 'rb') as f:
result = to_str(f.read())
expect = 'script_recv: ' + input
assert result == expect, repr(result)
assert result == expect, "Result:[%s] should match\nExpected:[%s]" % (result, expect)

p = test.start(stdin=1)
input = 'send() input to the receive script\n'
Expand Down Expand Up @@ -3103,7 +3109,7 @@ def test_workpath(self):
assert wpath == os.path.join(test.workdir, 'foo', 'bar')



@unittest.skipIf(sys.platform == 'win32', "Don't run on win32")
class readable_TestCase(TestCmdTestCase):
def test_readable(self):
"""Test readable()"""
Expand Down Expand Up @@ -3183,7 +3189,7 @@ def test_writable(self):
assert not _is_writable(test.workpath('file1'))



@unittest.skipIf(sys.platform == 'win32', "Don't run on win32")
class executable_TestCase(TestCmdTestCase):
def test_executable(self):
"""Test executable()"""
Expand Down Expand Up @@ -3331,70 +3337,8 @@ def test_variables(self):
assert stderr == "", stderr



if __name__ == "__main__":
tclasses = [
__init__TestCase,
basename_TestCase,
cleanup_TestCase,
chmod_TestCase,
combine_TestCase,
command_args_TestCase,
description_TestCase,
diff_TestCase,
diff_stderr_TestCase,
diff_stdout_TestCase,
exit_TestCase,
fail_test_TestCase,
interpreter_TestCase,
match_TestCase,
match_exact_TestCase,
match_re_dotall_TestCase,
match_re_TestCase,
match_stderr_TestCase,
match_stdout_TestCase,
no_result_TestCase,
pass_test_TestCase,
preserve_TestCase,
program_TestCase,
read_TestCase,
rmdir_TestCase,
run_TestCase,
run_verbose_TestCase,
set_diff_function_TestCase,
set_match_function_TestCase,
sleep_TestCase,
start_TestCase,
stderr_TestCase,
stdin_TestCase,
stdout_TestCase,
subdir_TestCase,
symlink_TestCase,
tempdir_TestCase,
timeout_TestCase,
unlink_TestCase,
touch_TestCase,
verbose_TestCase,
workdir_TestCase,
workdirs_TestCase,
workpath_TestCase,
writable_TestCase,
write_TestCase,
variables_TestCase,
]
if sys.platform != 'win32':
tclasses.extend([
executable_TestCase,
readable_TestCase,
])
suite = unittest.TestSuite()
for tclass in tclasses:
loader = unittest.TestLoader()
loader.testMethodPrefix = 'test_'
names = loader.getTestCaseNames(tclass)
suite.addTests([tclass(n) for n in names])
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
unittest.main()

# Local Variables:
# tab-width:4
Expand Down