summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel <dmoody256@gmail.com>2020-05-08 17:44:27 (GMT)
committerWilliam Deegan <bill@baddogconsulting.com>2021-04-13 20:53:54 (GMT)
commit6eb1818c7b9b85e4645cd87e9e78c70f35fed35d (patch)
tree0a040625d61c357a23872dee01e61efea6c10c04
parentec8c313126709a4bca17f97ee53a3619ca23ef5d (diff)
downloadSCons-6eb1818c7b9b85e4645cd87e9e78c70f35fed35d.zip
SCons-6eb1818c7b9b85e4645cd87e9e78c70f35fed35d.tar.gz
SCons-6eb1818c7b9b85e4645cd87e9e78c70f35fed35d.tar.bz2
update tests to work on windows, added some environment support for windows and msvc
-rw-r--r--src/engine/SCons/Tool/ninja.py47
-rw-r--r--test/ninja/build_libraries.py41
-rw-r--r--test/ninja/copy_function_command.py10
-rw-r--r--test/ninja/generate_and_build.py9
-rw-r--r--test/ninja/generate_source.py22
-rw-r--r--test/ninja/iterative_speedup.py19
-rw-r--r--test/ninja/multi_env.py18
-rw-r--r--test/ninja/ninja-fixture/bar.c2
-rw-r--r--test/ninja/ninja-fixture/foo.c2
-rw-r--r--test/ninja/ninja-fixture/test1.c13
-rw-r--r--test/ninja/ninja-fixture/test_impl.c15
-rw-r--r--test/ninja/shell_command.py20
12 files changed, 142 insertions, 76 deletions
diff --git a/src/engine/SCons/Tool/ninja.py b/src/engine/SCons/Tool/ninja.py
index bf399e2..10e27f3 100644
--- a/src/engine/SCons/Tool/ninja.py
+++ b/src/engine/SCons/Tool/ninja.py
@@ -77,8 +77,8 @@ def _mkdir_action_function(env, node):
# to an invalid ninja file.
"variables": {
# On Windows mkdir "-p" is always on
- "cmd": "{mkdir} $out".format(
- mkdir="mkdir" if env["PLATFORM"] == "win32" else "mkdir -p",
+ "cmd": "{mkdir}".format(
+ mkdir="mkdir $out & exit 0" if env["PLATFORM"] == "win32" else "mkdir -p $out",
),
},
}
@@ -383,6 +383,7 @@ class NinjaState:
def __init__(self, env, ninja_file, writer_class):
self.env = env
self.ninja_file = ninja_file
+ self.ninja_bin_path = ''
self.writer_class = writer_class
self.__generated = False
self.translator = SConsToNinjaTranslator(env)
@@ -752,7 +753,7 @@ class NinjaState:
pool="console",
implicit=[str(self.ninja_file)],
variables={
- "cmd": "ninja -f {} -t compdb CC CXX > compile_commands.json".format(
+ "cmd": "{}/ninja -f {} -t compdb CC CXX > compile_commands.json".format(self.ninja_bin_path,
str(self.ninja_file)
)
},
@@ -1044,15 +1045,32 @@ def ninja_builder(env, target, source):
generated_build_ninja = target[0].get_abspath()
NINJA_STATE.generate()
+
+ if env["PLATFORM"] == "win32":
+ # this is not great, it executes everytime
+ # and its doesn't consider specific node environments
+ # also a bit quirky to use, but usually MSVC is not
+ # setup system wide for command line use so this is needed
+ # on the standard MSVC setup, this is only needed if
+ # running ninja directly from a command line that hasn't
+ # had the environment setup (vcvarsall.bat)
+ # todo: hook this into a command so that it only regnerates
+ # the .bat if the env['ENV'] changes
+ with open('ninja_env.bat', 'w') as f:
+ for key in env['ENV']:
+ f.write('set {}={}\n'.format(key, env['ENV'][key]))
+
if not env.get("DISABLE_AUTO_NINJA"):
print("Executing:", str(target[0]))
def execute_ninja():
- proc = subprocess.Popen( ['ninja', '-f', generated_build_ninja],
- stderr=subprocess.STDOUT,
+ env.AppendENVPath('PATH', NINJA_STATE.ninja_bin_path)
+ proc = subprocess.Popen(['ninja', '-f', generated_build_ninja],
+ stderr=sys.stderr,
stdout=subprocess.PIPE,
- universal_newlines=True
+ universal_newlines=True,
+ env=env['ENV']
)
for stdout_line in iter(proc.stdout.readline, ""):
yield stdout_line
@@ -1060,12 +1078,17 @@ def ninja_builder(env, target, source):
return_code = proc.wait()
if return_code:
raise subprocess.CalledProcessError(return_code, 'ninja')
-
+ erase_previous = False
for output in execute_ninja():
output = output.strip()
- sys.stdout.write('\x1b[2K') # erase previous line
- sys.stdout.write(output + "\r")
+ if erase_previous:
+ sys.stdout.write('\x1b[2K') # erase previous line
+ sys.stdout.write("\r")
+ else:
+ sys.stdout.write(os.linesep)
+ sys.stdout.write(output)
sys.stdout.flush()
+ erase_previous = output.startswith('[')
# pylint: disable=too-few-public-methods
class AlwaysExecAction(SCons.Action.FunctionAction):
@@ -1311,7 +1334,7 @@ def generate(env):
if env["PLATFORM"] == "win32":
from SCons.Tool.mslink import compositeLinkAction
- if env["LINKCOM"] == compositeLinkAction:
+ if env.get("LINKCOM", None) == compositeLinkAction:
env[
"LINKCOM"
] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows", "$LINKCOMSTR")}'
@@ -1459,10 +1482,10 @@ def generate(env):
ninja_syntax = importlib.import_module(ninja_syntax_mod_name)
else:
ninja_syntax = importlib.import_module(".ninja_syntax", package='ninja')
-
+
if NINJA_STATE is None:
NINJA_STATE = NinjaState(env, ninja_file[0], ninja_syntax.Writer)
-
+ NINJA_STATE.ninja_bin_path = os.path.abspath(os.path.join(ninja_syntax.__file__, os.pardir, 'data', 'bin'))
# Here we will force every builder to use an emitter which makes the ninja
# file depend on it's target. This forces the ninja file to the bottom of
# the DAG which is required so that we walk every target, and therefore add
diff --git a/test/ninja/build_libraries.py b/test/ninja/build_libraries.py
index 7e0ec23..5e491cc 100644
--- a/test/ninja/build_libraries.py
+++ b/test/ninja/build_libraries.py
@@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import TestSCons
+from TestCmd import IS_WINDOWS
_python_ = TestSCons._python_
_exe = TestSCons._exe
@@ -39,35 +40,38 @@ ninja = test.where_is('ninja', os.environ['PATH'])
if not ninja:
test.skip_test("Could not find ninja in environment")
+lib_suffix = '.lib' if IS_WINDOWS else '.so'
+staticlib_suffix = '.lib' if IS_WINDOWS else '.a'
+lib_prefix = '' if IS_WINDOWS else 'lib'
+
+win32 = ", 'WIN32'" if IS_WINDOWS else ''
+
test.write('SConstruct', """
env = Environment()
env.Tool('ninja')
-shared_lib = env.SharedLibrary(target = 'test_impl', source = 'test_impl.c')
-env.Program(target = 'test', source = 'test1.c', LIBS=[shared_lib], LIBPATH=['.'], RPATH='.')
+shared_lib = env.SharedLibrary(target = 'test_impl', source = 'test_impl.c', CPPDEFINES=['LIBRARY_BUILD'%(win32)s])
+env.Program(target = 'test', source = 'test1.c', LIBS=['test_impl'], LIBPATH=['.'], RPATH='.')
-static_lib = env.StaticLibrary(target = 'test_impl_static', source = 'test_impl.c')
-static_obj = env.Object(target = 'test_static.o', source = 'test1.c')
+static_obj = env.Object(target = 'test_impl_static', source = 'test_impl.c')
+static_lib = env.StaticLibrary(target = 'test_impl_static', source = static_obj)
+static_obj = env.Object(target = 'test_static', source = 'test1.c')
env.Program(target = 'test_static', source = static_obj, LIBS=[static_lib], LIBPATH=['.'])
-""")
+""" % locals())
# generate simple build
test.run(stdout=None)
test.must_contain_all_lines(test.stdout(),
['Generating: build.ninja', 'Executing: build.ninja'])
-test.run(program = test.workpath('test'), stdout="library_function" + os.linesep)
-test.run(program = test.workpath('test_static'), stdout="library_function" + os.linesep)
+test.run(program = test.workpath('test'), stdout="library_function")
+test.run(program = test.workpath('test_static'), stdout="library_function")
# clean build and ninja files
test.run(arguments='-c', stdout=None)
test.must_contain_all_lines(test.stdout(), [
- 'Removed test_impl.os',
- 'Removed libtest_impl.so',
- 'Removed test1.o',
- 'Removed test',
- 'Removed test_impl.o',
- 'Removed libtest_impl_static.a',
- 'Removed test_static.o',
- 'Removed test_static',
+ ('Removed %stest_impl' % lib_prefix) + lib_suffix,
+ 'Removed test' + _exe,
+ ('Removed %stest_impl_static' % lib_prefix) + staticlib_suffix,
+ 'Removed test_static' + _exe,
'Removed build.ninja'])
# only generate the ninja file
@@ -78,9 +82,10 @@ test.must_not_contain_any_line(test.stdout(),
['Executing: build.ninja'])
# run ninja independently
-test.run(program = ninja, stdout=None)
-test.run(program = test.workpath('test'), stdout="library_function" + os.linesep)
-test.run(program = test.workpath('test_static'), stdout="library_function" + os.linesep)
+program = ['ninja_env.bat', '&', ninja] if IS_WINDOWS else ninja
+test.run(program = program, stdout=None)
+test.run(program = test.workpath('test'), stdout="library_function")
+test.run(program = test.workpath('test_static'), stdout="library_function")
test.pass_test()
diff --git a/test/ninja/copy_function_command.py b/test/ninja/copy_function_command.py
index a1e72b7..06991d3 100644
--- a/test/ninja/copy_function_command.py
+++ b/test/ninja/copy_function_command.py
@@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import TestSCons
+from TestCmd import IS_WINDOWS
_python_ = TestSCons._python_
_exe = TestSCons._exe
@@ -50,14 +51,14 @@ env.Program(target = 'foo', source = 'foo2.c')
test.run(stdout=None)
test.must_contain_all_lines(test.stdout(),
['Generating: build.ninja', 'Executing: build.ninja'])
-test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
+test.run(program = test.workpath('foo'), stdout="foo.c")
# clean build and ninja files
test.run(arguments='-c', stdout=None)
test.must_contain_all_lines(test.stdout(), [
'Removed foo2.o',
'Removed foo2.c',
- 'Removed foo',
+ 'Removed foo' + _exe,
'Removed build.ninja'])
# only generate the ninja file
@@ -68,8 +69,9 @@ test.must_not_contain_any_line(test.stdout(),
['Executing: build.ninja'])
# run ninja independently
-test.run(program = ninja, stdout=None)
-test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
+program = ['ninja_env.bat', '&', ninja] if IS_WINDOWS else ninja
+test.run(program = program, stdout=None)
+test.run(program = test.workpath('foo'), stdout="foo.c")
test.pass_test()
diff --git a/test/ninja/generate_and_build.py b/test/ninja/generate_and_build.py
index 82aab5e..904e46a 100644
--- a/test/ninja/generate_and_build.py
+++ b/test/ninja/generate_and_build.py
@@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import TestSCons
+from TestCmd import IS_WINDOWS
_python_ = TestSCons._python_
_exe = TestSCons._exe
@@ -45,11 +46,12 @@ env.Tool('ninja')
env.Program(target = 'foo', source = 'foo.c')
""")
+
# generate simple build
test.run(stdout=None)
test.must_contain_all_lines(test.stdout(),
['Generating: build.ninja', 'Executing: build.ninja'])
-test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
+test.run(program = test.workpath('foo' + _exe), stdout="foo.c")
# clean build and ninja files
test.run(arguments='-c', stdout=None)
@@ -66,8 +68,9 @@ test.must_not_contain_any_line(test.stdout(),
['Executing: build.ninja'])
# run ninja independently
-test.run(program = ninja, stdout=None)
-test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
+program = ['ninja_env.bat', '&', ninja] if IS_WINDOWS else ninja
+test.run(program = program, stdout=None)
+test.run(program = test.workpath('foo' + _exe), stdout="foo.c")
test.pass_test()
diff --git a/test/ninja/generate_source.py b/test/ninja/generate_source.py
index d1bfe34..298d227 100644
--- a/test/ninja/generate_source.py
+++ b/test/ninja/generate_source.py
@@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import TestSCons
+from TestCmd import IS_WINDOWS
_python_ = TestSCons._python_
_exe = TestSCons._exe
@@ -39,13 +40,15 @@ ninja = test.where_is('ninja', os.environ['PATH'])
if not ninja:
test.skip_test("Could not find ninja in environment")
+shell = '' if IS_WINDOWS else './'
+
test.write('SConstruct', """
env = Environment()
env.Tool('ninja')
-env.Program(target = 'generate_source', source = 'generate_source.c')
-env.Command('generated_source.c', ['generate_source'], './generate_source')
+prog = env.Program(target = 'generate_source', source = 'generate_source.c')
+env.Command('generated_source.c', prog, '%(shell)sgenerate_source%(_exe)s')
env.Program(target = 'generated_source', source = 'generated_source.c')
-""")
+""" % locals())
test.write('generate_source.c', """
#include <stdio.h>
@@ -60,7 +63,7 @@ int main(int argc, char *argv[]) {
fprintf(fp, "int\\n");
fprintf(fp, "main(int argc, char *argv[])\\n");
fprintf(fp, "{\\n");
- fprintf(fp, " printf(\\"generated_source.c\\\\n\\");\\n");
+ fprintf(fp, " printf(\\"generated_source.c\\");\\n");
fprintf(fp, " exit (0);\\n");
fprintf(fp, "}\\n");
fclose(fp);
@@ -69,16 +72,16 @@ int main(int argc, char *argv[]) {
# generate simple build
test.run(stdout=None)
-test.run(program = test.workpath('generated_source'), stdout="generated_source.c" + os.linesep)
+test.run(program = test.workpath('generated_source' + _exe), stdout="generated_source.c")
# clean build and ninja files
test.run(arguments='-c', stdout=None)
test.must_contain_all_lines(test.stdout(), [
'Removed generate_source.o',
- 'Removed generate_source',
+ 'Removed generate_source' + _exe,
'Removed generated_source.c',
'Removed generated_source.o',
- 'Removed generated_source',
+ 'Removed generated_source' + _exe,
'Removed build.ninja'])
# only generate the ninja file
@@ -89,8 +92,9 @@ test.must_not_contain_any_line(test.stdout(),
['Executing: build.ninja'])
# run ninja independently
-test.run(program = ninja, stdout=None)
-test.run(program = test.workpath('generated_source'), stdout="generated_source.c" + os.linesep)
+program = ['ninja_env.bat', '&', ninja] if IS_WINDOWS else ninja
+test.run(program = program, stdout=None)
+test.run(program = test.workpath('generated_source' + _exe), stdout="generated_source.c")
test.pass_test()
diff --git a/test/ninja/iterative_speedup.py b/test/ninja/iterative_speedup.py
index cf999d8..6675bf3 100644
--- a/test/ninja/iterative_speedup.py
+++ b/test/ninja/iterative_speedup.py
@@ -28,6 +28,7 @@ import os
import time
import random
import TestSCons
+from TestCmd import IS_WINDOWS
_python_ = TestSCons._python_
_exe = TestSCons._exe
@@ -49,7 +50,8 @@ test.write('source_0.c', """
int
print_function0()
{
- printf("main print\\n");
+ printf("main print");
+ return 0;
}
""")
@@ -92,7 +94,7 @@ def generate_source(parent_source, current_source):
int
print_function%(current_source)s()
{
- print_function%(parent_source)s();
+ return print_function%(parent_source)s();
}
""" % locals())
@@ -132,7 +134,7 @@ def mod_source_orig(test_num):
int
print_function%(test_num)s()
{
- print_function%(parent_source)s();
+ return print_function%(parent_source)s();
}
""" % locals())
@@ -148,6 +150,7 @@ int
main()
{
print_function%(num_source)s();
+ exit(0);
}
""" % locals())
@@ -171,17 +174,19 @@ for _ in range(10):
tests_mods += [random.randrange(1, num_source, 1)]
jobs = '-j' + str(get_num_cpus())
+ninja_program = [test.workpath('ninja_env.bat'), '&', ninja, jobs] if IS_WINDOWS else [ninja, jobs]
+
start = time.perf_counter()
test.run(arguments='--disable-auto-ninja', stdout=None)
-test.run(program = ninja, arguments=[jobs], stdout=None)
+test.run(program = ninja_program, stdout=None)
stop = time.perf_counter()
ninja_times += [stop - start]
-test.run(program = test.workpath('print_bin'), stdout="main print" + os.linesep)
+test.run(program = test.workpath('print_bin'), stdout="main print")
for test_mod in tests_mods:
mod_source_return(test_mod)
start = time.perf_counter()
- test.run(program = ninja, arguments=[jobs], stdout=None)
+ test.run(program = ninja_program, stdout=None)
stop = time.perf_counter()
ninja_times += [stop - start]
@@ -197,7 +202,7 @@ start = time.perf_counter()
test.run(arguments = ["-f", "SConstruct_no_ninja", jobs], stdout=None)
stop = time.perf_counter()
scons_times += [stop - start]
-test.run(program = test.workpath('print_bin'), stdout="main print" + os.linesep)
+test.run(program = test.workpath('print_bin'), stdout="main print")
for test_mod in tests_mods:
mod_source_return(test_mod)
diff --git a/test/ninja/multi_env.py b/test/ninja/multi_env.py
index 5360fd2..087d392 100644
--- a/test/ninja/multi_env.py
+++ b/test/ninja/multi_env.py
@@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import TestSCons
+from TestCmd import IS_WINDOWS
_python_ = TestSCons._python_
_exe = TestSCons._exe
@@ -53,16 +54,16 @@ env2.Program(target = 'bar', source = 'bar.c')
test.run(stdout=None)
test.must_contain_all_lines(test.stdout(),
['Generating: build.ninja', 'Executing: build.ninja'])
-test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
-test.run(program = test.workpath('bar'), stdout="bar.c" + os.linesep)
+test.run(program = test.workpath('foo' + _exe), stdout="foo.c")
+test.run(program = test.workpath('bar' + _exe), stdout="bar.c")
# clean build and ninja files
test.run(arguments='-c', stdout=None)
test.must_contain_all_lines(test.stdout(), [
'Removed foo.o',
- 'Removed foo',
+ 'Removed foo' + _exe,
'Removed bar.o',
- 'Removed bar',
+ 'Removed bar' + _exe,
'Removed build.ninja'])
# only generate the ninja file
@@ -73,11 +74,10 @@ test.must_not_contain_any_line(test.stdout(),
['Executing: build.ninja'])
# run ninja independently
-test.run(program = ninja, stdout=None)
-test.run(program = test.workpath('foo'), stdout="foo.c" + os.linesep)
-test.run(program = test.workpath('bar'), stdout="bar.c" + os.linesep)
-
-
+program = ['ninja_env.bat', '&', ninja] if IS_WINDOWS else ninja
+test.run(program = program, stdout=None)
+test.run(program = test.workpath('foo' + _exe), stdout="foo.c")
+test.run(program = test.workpath('bar' + _exe), stdout="bar.c")
test.pass_test()
diff --git a/test/ninja/ninja-fixture/bar.c b/test/ninja/ninja-fixture/bar.c
index 3767857..15b2ecc 100644
--- a/test/ninja/ninja-fixture/bar.c
+++ b/test/ninja/ninja-fixture/bar.c
@@ -5,6 +5,6 @@ int
main(int argc, char *argv[])
{
argv[argc++] = "--";
- printf("bar.c\n");
+ printf("bar.c");
exit (0);
}
diff --git a/test/ninja/ninja-fixture/foo.c b/test/ninja/ninja-fixture/foo.c
index de1e6e5..ba35c68 100644
--- a/test/ninja/ninja-fixture/foo.c
+++ b/test/ninja/ninja-fixture/foo.c
@@ -5,6 +5,6 @@ int
main(int argc, char *argv[])
{
argv[argc++] = "--";
- printf("foo.c\n");
+ printf("foo.c");
exit (0);
}
diff --git a/test/ninja/ninja-fixture/test1.c b/test/ninja/ninja-fixture/test1.c
index c53f54a..678461f 100644
--- a/test/ninja/ninja-fixture/test1.c
+++ b/test/ninja/ninja-fixture/test1.c
@@ -1,10 +1,21 @@
#include <stdio.h>
#include <stdlib.h>
-extern int library_function(void);
+#ifdef WIN32
+#ifdef LIBRARY_BUILD
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT __declspec(dllimport)
+#endif
+#else
+#define DLLEXPORT
+#endif
+
+DLLEXPORT extern int library_function(void);
int
main(int argc, char *argv[])
{
library_function();
+ exit(0);
}
diff --git a/test/ninja/ninja-fixture/test_impl.c b/test/ninja/ninja-fixture/test_impl.c
index ae5effc..89c26ed 100644
--- a/test/ninja/ninja-fixture/test_impl.c
+++ b/test/ninja/ninja-fixture/test_impl.c
@@ -1,8 +1,19 @@
#include <stdio.h>
#include <stdlib.h>
-int
+#ifdef WIN32
+#ifdef LIBRARY_BUILD
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT __declspec(dllimport)
+#endif
+#else
+#define DLLEXPORT
+#endif
+
+
+DLLEXPORT int
library_function(void)
{
- printf("library_function\n");
+ printf("library_function");
}
diff --git a/test/ninja/shell_command.py b/test/ninja/shell_command.py
index b5c8323..5d49164 100644
--- a/test/ninja/shell_command.py
+++ b/test/ninja/shell_command.py
@@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import TestSCons
+from TestCmd import IS_WINDOWS
_python_ = TestSCons._python_
_exe = TestSCons._exe
@@ -39,24 +40,26 @@ ninja = test.where_is('ninja', os.environ['PATH'])
if not ninja:
test.skip_test("Could not find ninja in environment")
+shell = '' if IS_WINDOWS else './'
+
test.write('SConstruct', """
env = Environment()
env.Tool('ninja')
-env.Program(target = 'foo', source = 'foo.c')
-env.Command('foo.out', ['foo'], './foo > foo.out')
-""")
+prog = env.Program(target = 'foo', source = 'foo.c')
+env.Command('foo.out', prog, '%(shell)sfoo%(_exe)s > foo.out')
+""" % locals())
# generate simple build
test.run(stdout=None)
test.must_contain_all_lines(test.stdout(),
['Generating: build.ninja', 'Executing: build.ninja'])
-test.must_match('foo.out', 'foo.c' + os.linesep)
+test.must_match('foo.out', 'foo.c')
# clean build and ninja files
test.run(arguments='-c', stdout=None)
test.must_contain_all_lines(test.stdout(), [
'Removed foo.o',
- 'Removed foo',
+ 'Removed foo%(_exe)s' % locals(),
'Removed foo.out',
'Removed build.ninja'])
@@ -68,10 +71,9 @@ test.must_not_contain_any_line(test.stdout(),
['Executing: build.ninja'])
# run ninja independently
-test.run(program = ninja, stdout=None)
-test.must_match('foo.out', 'foo.c' + os.linesep)
-
-
+program = ['ninja_env.bat', '&', ninja] if IS_WINDOWS else ninja
+test.run(program = program, stdout=None)
+test.must_match('foo.out', 'foo.c')
test.pass_test()