2011-03-22 Adam Barth <abarth@webkit.org>
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Mar 2011 22:36:52 +0000 (22:36 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Mar 2011 22:36:52 +0000 (22:36 +0000)
        Reviewed by Eric Seidel.

        Add GYP to Source/ThirdParty
        https://bugs.webkit.org/show_bug.cgi?id=56870

        We probably don't need all the test files, but it seems cleaner to just
        check in the whole GYP tree.  GYP is BSD licensed, so it is compatible
        with the WebKit license.

        * Source/ThirdParty/gyp: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@81709 268f45cc-cd09-0410-ab3c-d52691b4dbfc

404 files changed:
ChangeLog
Source/ThirdParty/gyp/AUTHORS [new file with mode: 0644]
Source/ThirdParty/gyp/DEPS [new file with mode: 0644]
Source/ThirdParty/gyp/LICENSE [new file with mode: 0644]
Source/ThirdParty/gyp/MANIFEST [new file with mode: 0644]
Source/ThirdParty/gyp/PRESUBMIT.py [new file with mode: 0755]
Source/ThirdParty/gyp/README.WebKit [new file with mode: 0644]
Source/ThirdParty/gyp/codereview.settings [new file with mode: 0644]
Source/ThirdParty/gyp/gyp [new file with mode: 0755]
Source/ThirdParty/gyp/gyp.bat [new file with mode: 0755]
Source/ThirdParty/gyp/gyp_dummy.c [new file with mode: 0644]
Source/ThirdParty/gyp/gyptest.py [new file with mode: 0755]
Source/ThirdParty/gyp/pylib/gyp/MSVSNew.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/MSVSProject.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/MSVSSettings.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/MSVSSettings_test.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/MSVSToolFile.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/MSVSUserFile.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/MSVSVersion.py [new file with mode: 0755]
Source/ThirdParty/gyp/pylib/gyp/SCons.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/__init__.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/common.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/easy_xml.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/easy_xml_test.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/generator/__init__.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/generator/gypd.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/generator/gypsh.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/generator/make.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/generator/msvs.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/generator/scons.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/generator/xcode.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/input.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/system_test.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/xcodeproj_file.py [new file with mode: 0644]
Source/ThirdParty/gyp/pylib/gyp/xml_fix.py [new file with mode: 0644]
Source/ThirdParty/gyp/samples/samples [new file with mode: 0755]
Source/ThirdParty/gyp/samples/samples.bat [new file with mode: 0644]
Source/ThirdParty/gyp/setup.py [new file with mode: 0755]
Source/ThirdParty/gyp/test/actions-bare/gyptest-bare.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-bare/src/bare.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-bare/src/bare.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-multiple/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-multiple/src/actions.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-multiple/src/copy.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-multiple/src/filter.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-multiple/src/foo.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-multiple/src/input.txt [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-multiple/src/main.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-subdir/gyptest-action.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-subdir/src/make-file.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-subdir/src/none.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-subdir/src/subdir/make-subdir-file.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions-subdir/src/subdir/subdir.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/gyptest-errors.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/action_missing_name.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/actions.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/confirm-dep-files.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir1/counter.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir1/executable.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir1/make-prog1.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir1/make-prog2.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir1/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir2/make-file.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir2/none.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir3/generate_main.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/actions/src/subdir3/null_input.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/additional-targets/gyptest-additional.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/additional-targets/src/all.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/additional-targets/src/dir1/actions.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/additional-targets/src/dir1/emit.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/additional-targets/src/dir1/lib1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/assembly/gyptest-assembly.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/assembly/src/as.bat [new file with mode: 0644]
Source/ThirdParty/gyp/test/assembly/src/assembly.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/assembly/src/lib1.S [new file with mode: 0644]
Source/ThirdParty/gyp/test/assembly/src/lib1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/assembly/src/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/builddir.gypi [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/func1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/func2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/func3.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/func4.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/func5.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/prog1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/prog1.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/prog2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/prog2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/subdir3/prog3.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/subdir3/prog3.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/subdir3/subdir4/prog4.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/subdir3/subdir4/prog4.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/subdir3/subdir4/subdir5/prog5.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/builddir/src/subdir2/subdir3/subdir4/subdir5/prog5.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/cflags/cflags.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/cflags/cflags.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/cflags/gyptest-cflags.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/compilable/gyptest-headers.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/compilable/src/headers.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/compilable/src/lib1.cpp [new file with mode: 0644]
Source/ThirdParty/gyp/test/compilable/src/lib1.hpp [new file with mode: 0644]
Source/ThirdParty/gyp/test/compilable/src/program.cpp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/basics/configurations.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/basics/configurations.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/basics/gyptest-configurations.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/inheritance/configurations.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/inheritance/configurations.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/inheritance/gyptest-inheritance.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/actions.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/all_dependent_settings.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/configurations.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/dependencies.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/direct_dependent_settings.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/gyptest-configurations.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/libraries.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/link_settings.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/sources.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/target_name.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/invalid/type.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/target_platform/configurations.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/target_platform/front.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/target_platform/gyptest-target_platform.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/target_platform/left.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/target_platform/right.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/x64/configurations.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/x64/configurations.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/configurations/x64/gyptest-x86.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies-link/gyptest-copies-link.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies-link/src/copies-link.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies-link/src/copy.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies-link/src/func1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies-link/src/main.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/src/copies.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/src/directory/file3 [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/src/directory/file4 [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/src/directory/subdir/file5 [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/src/file1 [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/src/file2 [new file with mode: 0644]
Source/ThirdParty/gyp/test/copies/src/parentdir/subdir/file6 [new file with mode: 0644]
Source/ThirdParty/gyp/test/cxxflags/cxxflags.cc [new file with mode: 0644]
Source/ThirdParty/gyp/test/cxxflags/cxxflags.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/cxxflags/gyptest-cxxflags.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines-escaping/defines-escaping.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines-escaping/defines-escaping.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines-escaping/gyptest-defines-escaping.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines/defines-env.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines/defines.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines/defines.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines/gyptest-define-override.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines/gyptest-defines-env-regyp.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines/gyptest-defines-env.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/defines/gyptest-defines.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependencies/a.c [new file with mode: 0755]
Source/ThirdParty/gyp/test/dependencies/b/b.c [new file with mode: 0755]
Source/ThirdParty/gyp/test/dependencies/b/b.gyp [new file with mode: 0755]
Source/ThirdParty/gyp/test/dependencies/c/c.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependencies/c/c.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependencies/c/d.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependencies/extra_targets.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependencies/gyptest-extra-targets.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependencies/gyptest-lib-only.py [new file with mode: 0755]
Source/ThirdParty/gyp/test/dependencies/lib_only.gyp [new file with mode: 0755]
Source/ThirdParty/gyp/test/dependency-copy/gyptest-copy.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependency-copy/src/copies.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependency-copy/src/file1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/dependency-copy/src/file2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/exclusion/exclusion.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/exclusion/gyptest-exclusion.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/exclusion/hello.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/actions.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir1/actions-out/README.txt [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir1/executable.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir1/make-prog1.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir1/make-prog2.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir1/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir2/actions-out/README.txt [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir2/make-file.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/actions/subdir2/none.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/copies-out/README.txt [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/copies.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/file1 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/file2 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/subdir/copies-out/README.txt [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/subdir/file3 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/subdir/file4 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/copies/subdir/subdir.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/gyptest-actions.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/gyptest-copies.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/gyptest-relocate.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/gyptest-rules.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/gyptest-subdir2-deep.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/gyptest-top-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/copy-file.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/rules.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir1/define3.in0 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir1/define4.in0 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir1/executable.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir1/function1.in1 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir1/function2.in1 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir1/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir2/file1.in0 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir2/file2.in0 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir2/file3.in1 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir2/file4.in1 [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir2/none.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/rules/subdir2/rules-out/README.txt [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/inc.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/inc1/include1.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/prog1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/prog1.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir2/deeper/deeper.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir2/deeper/deeper.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir2/deeper/deeper.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir2/inc2/include2.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir2/prog2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir2/prog2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir3/inc3/include3.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir3/prog3.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/subdir3/prog3.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/generator-output/src/symroot.gypi [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/gyptest-disable-regyp.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/gyptest-regyp.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/gyptest-target.py [new file with mode: 0755]
Source/ThirdParty/gyp/test/hello/hello.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/hello.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/hello2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/hello/hello2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/home_dot_gyp/gyptest-home-includes-regyp.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/home_dot_gyp/gyptest-home-includes.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/home_dot_gyp/home/.gyp/include.gypi [new file with mode: 0644]
Source/ThirdParty/gyp/test/home_dot_gyp/home2/.gyp/include.gypi [new file with mode: 0644]
Source/ThirdParty/gyp/test/home_dot_gyp/src/all.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/home_dot_gyp/src/printfoo.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/inc.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/inc1/include1.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/includes.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/includes.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/shadow1/shadow.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/shadow2/shadow.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/subdir/inc.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/subdir/inc2/include2.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/subdir/subdir_includes.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/include_dirs/src/subdir/subdir_includes.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/lib/README.txt [new file with mode: 0644]
Source/ThirdParty/gyp/test/lib/TestCmd.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/lib/TestCommon.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/lib/TestGyp.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/gyptest-shared-obj-install-path.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/gyptest-shared.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/gyptest-static.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/src/lib1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/src/lib1_moveable.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/src/lib2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/src/lib2_moveable.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/src/library.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/src/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/library/src/shared_dependency.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/link-objects/base.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/link-objects/extra.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/link-objects/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/link-objects/link-objects.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/dependencies.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/gyptest-dependencies.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/gyptest-noload.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/main.cc [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/main.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/noload/all.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/noload/lib/shared.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/noload/lib/shared.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/noload/lib/shared.h [new file with mode: 0644]
Source/ThirdParty/gyp/test/make/noload/main.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/module/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/module/src/lib1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/module/src/lib2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/module/src/module.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/module/src/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/express/base/base.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/express/express.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/express/gyptest-express.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/precompiled/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/precompiled/hello.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/precompiled/hello.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/precompiled/hello2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/msvs/precompiled/precomp.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/multiple-targets/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/multiple-targets/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/multiple-targets/src/common.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/multiple-targets/src/multiple.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/multiple-targets/src/prog1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/multiple-targets/src/prog2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/no-output/gyptest-no-output.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/no-output/src/nooutput.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/product/gyptest-product.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/product/hello.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/product/product.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules-rebuild/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules-rebuild/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules-rebuild/src/main.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules-rebuild/src/make-sources.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules-rebuild/src/prog1.in [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules-rebuild/src/prog2.in [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules-rebuild/src/same_target.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/actions.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/copy-file.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir1/executable.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir1/function1.in [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir1/function2.in [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir1/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir2/file1.in [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir2/file2.in [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir2/never_used.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir2/no_inputs.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir2/none.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir3/executable2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir3/function3.in [new file with mode: 0644]
Source/ThirdParty/gyp/test/rules/src/subdir3/program.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-gyp-name/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-gyp-name/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-gyp-name/src/all.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-gyp-name/src/subdir1/executable.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-gyp-name/src/subdir1/main1.cc [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-gyp-name/src/subdir2/executable.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-gyp-name/src/subdir2/main2.cc [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/gyptest-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/src/all.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/src/func.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/src/prog1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/src/prog2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/src/subdir1/func.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-name/src/subdir2/func.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-target-name/gyptest-same-target-name.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-target-name/src/all.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-target-name/src/executable1.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/same-target-name/src/executable2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/scons_tools/gyptest-tools.py [new file with mode: 0755]
Source/ThirdParty/gyp/test/scons_tools/site_scons/site_tools/this_tool.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/scons_tools/tools.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/scons_tools/tools.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/sibling/gyptest-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/sibling/gyptest-relocate.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/sibling/src/prog1/prog1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/sibling/src/prog1/prog1.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/sibling/src/prog2/prog2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/sibling/src/prog2/prog2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/small/gyptest-small.py [new file with mode: 0755]
Source/ThirdParty/gyp/test/subdirectory/gyptest-SYMROOT-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/gyptest-SYMROOT-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/gyptest-subdir-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/gyptest-subdir-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/gyptest-subdir2-deep.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/gyptest-top-all.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/gyptest-top-default.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/src/prog1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/src/prog1.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/src/subdir/prog2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/src/subdir/prog2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/src/subdir/subdir2/prog3.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/src/subdir/subdir2/prog3.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/subdirectory/src/symroot.gypi [new file with mode: 0644]
Source/ThirdParty/gyp/test/toolsets/gyptest-toolsets.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/toolsets/main.cc [new file with mode: 0644]
Source/ThirdParty/gyp/test/toolsets/toolsets.cc [new file with mode: 0644]
Source/ThirdParty/gyp/test/toolsets/toolsets.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/toplevel-dir/gyptest-toplevel-dir.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/toplevel-dir/src/sub1/main.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/toplevel-dir/src/sub1/prog1.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/toplevel-dir/src/sub2/prog2.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/toplevel-dir/src/sub2/prog2.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands-repeated.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands-repeated.gyp.stdout [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands-repeated.gypd.golden [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands.gyp.ignore-env.stdout [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands.gyp.stdout [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands.gypd.golden [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/commands.gypi [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/gyptest-commands-ignore-env.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/gyptest-commands-repeated.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/gyptest-commands.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/commands/update_golden [new file with mode: 0755]
Source/ThirdParty/gyp/test/variables/filelist/filelist.gyp.stdout [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/filelist/filelist.gypd.golden [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/filelist/gyptest-filelist.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/filelist/src/filelist.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/test/variables/filelist/update_golden [new file with mode: 0755]
Source/ThirdParty/gyp/test/variants/gyptest-variants.py [new file with mode: 0644]
Source/ThirdParty/gyp/test/variants/src/variants.c [new file with mode: 0644]
Source/ThirdParty/gyp/test/variants/src/variants.gyp [new file with mode: 0644]
Source/ThirdParty/gyp/tools/README [new file with mode: 0644]
Source/ThirdParty/gyp/tools/pretty_gyp.py [new file with mode: 0644]
Source/ThirdParty/gyp/tools/pretty_sln.py [new file with mode: 0755]
Source/ThirdParty/gyp/tools/pretty_vcproj.py [new file with mode: 0755]

index 397db1e..a0a6f9e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2011-03-22  Adam Barth  <abarth@webkit.org>
+
+        Reviewed by Eric Seidel.
+
+        Add GYP to Source/ThirdParty
+        https://bugs.webkit.org/show_bug.cgi?id=56870
+
+        We probably don't need all the test files, but it seems cleaner to just
+        check in the whole GYP tree.  GYP is BSD licensed, so it is compatible
+        with the WebKit license.
+
+        * Source/ThirdParty/gyp: Added.
+
 2011-03-21  Alejandro G. Castro  <alex@igalia.com>
 
         Reviewed by Martin Robinson.
diff --git a/Source/ThirdParty/gyp/AUTHORS b/Source/ThirdParty/gyp/AUTHORS
new file mode 100644 (file)
index 0000000..f0b6752
--- /dev/null
@@ -0,0 +1,5 @@
+# Names should be added to this file like so:
+# Name or Organization <email address>
+
+Google Inc.
+Steven Knight <knight@baldmt.com>
diff --git a/Source/ThirdParty/gyp/DEPS b/Source/ThirdParty/gyp/DEPS
new file mode 100644 (file)
index 0000000..0e56c06
--- /dev/null
@@ -0,0 +1,8 @@
+# DEPS file for gclient use in buildbot execution of gyp tests.
+#
+# (You don't need to use gclient for normal GYP development work.)
+
+deps = {
+  "scons":
+    "http://src.chromium.org/svn/trunk/src/third_party/scons@44099",
+}
diff --git a/Source/ThirdParty/gyp/LICENSE b/Source/ThirdParty/gyp/LICENSE
new file mode 100644 (file)
index 0000000..ab6b011
--- /dev/null
@@ -0,0 +1,27 @@
+Copyright (c) 2009 Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Source/ThirdParty/gyp/MANIFEST b/Source/ThirdParty/gyp/MANIFEST
new file mode 100644 (file)
index 0000000..925ecc1
--- /dev/null
@@ -0,0 +1,21 @@
+setup.py
+gyp
+LICENSE
+AUTHORS
+pylib/gyp/MSVSNew.py
+pylib/gyp/MSVSProject.py
+pylib/gyp/MSVSToolFile.py
+pylib/gyp/MSVSUserFile.py
+pylib/gyp/MSVSVersion.py
+pylib/gyp/SCons.py
+pylib/gyp/__init__.py
+pylib/gyp/common.py
+pylib/gyp/input.py
+pylib/gyp/xcodeproj_file.py
+pylib/gyp/generator/__init__.py
+pylib/gyp/generator/gypd.py
+pylib/gyp/generator/gypsh.py
+pylib/gyp/generator/make.py
+pylib/gyp/generator/msvs.py
+pylib/gyp/generator/scons.py
+pylib/gyp/generator/xcode.py
diff --git a/Source/ThirdParty/gyp/PRESUBMIT.py b/Source/ThirdParty/gyp/PRESUBMIT.py
new file mode 100755 (executable)
index 0000000..4c99288
--- /dev/null
@@ -0,0 +1,53 @@
+# Copyright 2010, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+EXCLUDED_PATHS = ()
+
+
+def CheckChangeOnUpload(input_api, output_api):
+  report = []
+  black_list = input_api.DEFAULT_BLACK_LIST + EXCLUDED_PATHS
+  sources = lambda x: input_api.FilterSourceFile(x, black_list=black_list)
+  report.extend(input_api.canned_checks.CheckChangeSvnEolStyle(
+      input_api, output_api, sources))
+  return report
+
+
+def CheckChangeOnCommit(input_api, output_api):
+  report = []
+  black_list = input_api.DEFAULT_BLACK_LIST + EXCLUDED_PATHS
+  sources = lambda x: input_api.FilterSourceFile(x, black_list=black_list)
+  report.extend(input_api.canned_checks.CheckChangeSvnEolStyle(
+      input_api, output_api, sources))
+  report.extend(input_api.canned_checks.CheckTreeIsOpen(
+      input_api, output_api,
+      'http://gyp-status.appspot.com/status',
+      'http://gyp-status.appspot.com/current'))
+  return report
diff --git a/Source/ThirdParty/gyp/README.WebKit b/Source/ThirdParty/gyp/README.WebKit
new file mode 100644 (file)
index 0000000..9eed075
--- /dev/null
@@ -0,0 +1 @@
+This directory is a copy of http://gyp.googlecode.com/svn/trunk/ at revision 903.
diff --git a/Source/ThirdParty/gyp/codereview.settings b/Source/ThirdParty/gyp/codereview.settings
new file mode 100644 (file)
index 0000000..a04a244
--- /dev/null
@@ -0,0 +1,10 @@
+# This file is used by gcl to get repository specific information.
+CODE_REVIEW_SERVER: codereview.chromium.org
+CC_LIST: gyp-developer@googlegroups.com
+VIEW_VC: http://code.google.com/p/gyp/source/detail?r=
+TRY_ON_UPLOAD: True
+TRYSERVER_PROJECT: gyp
+TRYSERVER_PATCHLEVEL: 0
+TRYSERVER_ROOT: trunk
+TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-nacl
+
diff --git a/Source/ThirdParty/gyp/gyp b/Source/ThirdParty/gyp/gyp
new file mode 100755 (executable)
index 0000000..d52e711
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+
+# TODO(mark): sys.path manipulation is some temporary testing stuff.
+try:
+  import gyp
+except ImportError, e:
+  import os.path
+  sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), 'pylib'))
+  import gyp
+
+if __name__ == '__main__':
+  sys.exit(gyp.main(sys.argv[1:]))
diff --git a/Source/ThirdParty/gyp/gyp.bat b/Source/ThirdParty/gyp/gyp.bat
new file mode 100755 (executable)
index 0000000..90fbc6d
--- /dev/null
@@ -0,0 +1,5 @@
+@rem Copyright (c) 2009 Google Inc. All rights reserved.\r
+@rem Use of this source code is governed by a BSD-style license that can be\r
+@rem found in the LICENSE file.\r
+\r
+@python "%~dp0/gyp" %*\r
diff --git a/Source/ThirdParty/gyp/gyp_dummy.c b/Source/ThirdParty/gyp/gyp_dummy.c
new file mode 100644 (file)
index 0000000..fb55bbc
--- /dev/null
@@ -0,0 +1,7 @@
+/* Copyright (c) 2009 Google Inc. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+int main() {
+  return 0;
+}
diff --git a/Source/ThirdParty/gyp/gyptest.py b/Source/ThirdParty/gyp/gyptest.py
new file mode 100755 (executable)
index 0000000..d9677db
--- /dev/null
@@ -0,0 +1,255 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+__doc__ = """
+gyptest.py -- test runner for GYP tests.
+"""
+
+import os
+import optparse
+import subprocess
+import sys
+
+class CommandRunner:
+  """
+  Executor class for commands, including "commands" implemented by
+  Python functions.
+  """
+  verbose = True
+  active = True
+
+  def __init__(self, dictionary={}):
+    self.subst_dictionary(dictionary)
+
+  def subst_dictionary(self, dictionary):
+    self._subst_dictionary = dictionary
+
+  def subst(self, string, dictionary=None):
+    """
+    Substitutes (via the format operator) the values in the specified
+    dictionary into the specified command.
+
+    The command can be an (action, string) tuple.  In all cases, we
+    perform substitution on strings and don't worry if something isn't
+    a string.  (It's probably a Python function to be executed.)
+    """
+    if dictionary is None:
+      dictionary = self._subst_dictionary
+    if dictionary:
+      try:
+        string = string % dictionary
+      except TypeError:
+        pass
+    return string
+
+  def display(self, command, stdout=None, stderr=None):
+    if not self.verbose:
+      return
+    if type(command) == type(()):
+      func = command[0]
+      args = command[1:]
+      s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
+    if type(command) == type([]):
+      # TODO:  quote arguments containing spaces
+      # TODO:  handle meta characters?
+      s = ' '.join(command)
+    else:
+      s = self.subst(command)
+    if not s.endswith('\n'):
+      s += '\n'
+    sys.stdout.write(s)
+    sys.stdout.flush()
+
+  def execute(self, command, stdout=None, stderr=None):
+    """
+    Executes a single command.
+    """
+    if not self.active:
+      return 0
+    if type(command) == type(''):
+      command = self.subst(command)
+      cmdargs = shlex.split(command)
+      if cmdargs[0] == 'cd':
+         command = (os.chdir,) + tuple(cmdargs[1:])
+    if type(command) == type(()):
+      func = command[0]
+      args = command[1:]
+      return func(*args)
+    else:
+      if stdout is sys.stdout:
+        # Same as passing sys.stdout, except python2.4 doesn't fail on it.
+        subout = None
+      else:
+        # Open pipe for anything else so Popen works on python2.4.
+        subout = subprocess.PIPE
+      if stderr is sys.stderr:
+        # Same as passing sys.stderr, except python2.4 doesn't fail on it.
+        suberr = None
+      elif stderr is None:
+        # Merge with stdout if stderr isn't specified.
+        suberr = subprocess.STDOUT
+      else:
+        # Open pipe for anything else so Popen works on python2.4.
+        suberr = subprocess.PIPE
+      p = subprocess.Popen(command,
+                           shell=(sys.platform == 'win32'),
+                           stdout=subout,
+                           stderr=suberr)
+      p.wait()
+      if stdout is None:
+        self.stdout = p.stdout.read()
+      elif stdout is not sys.stdout:
+        stdout.write(p.stdout.read())
+      if stderr not in (None, sys.stderr):
+        stderr.write(p.stderr.read())
+      return p.returncode
+
+  def run(self, command, display=None, stdout=None, stderr=None):
+    """
+    Runs a single command, displaying it first.
+    """
+    if display is None:
+      display = command
+    self.display(display)
+    return self.execute(command, stdout, stderr)
+
+
+class Unbuffered:
+  def __init__(self, fp):
+    self.fp = fp
+  def write(self, arg):
+    self.fp.write(arg)
+    self.fp.flush()
+  def __getattr__(self, attr):
+    return getattr(self.fp, attr)
+
+sys.stdout = Unbuffered(sys.stdout)
+sys.stderr = Unbuffered(sys.stderr)
+
+
+def find_all_gyptest_files(directory):
+    result = []
+    for root, dirs, files in os.walk(directory):
+      if '.svn' in dirs:
+        dirs.remove('.svn')
+      result.extend([ os.path.join(root, f) for f in files
+                     if f.startswith('gyptest') and f.endswith('.py') ])
+    result.sort()
+    return result
+
+
+def main(argv=None):
+  if argv is None:
+    argv = sys.argv
+
+  usage = "gyptest.py [-ahlnq] [-f formats] [test ...]"
+  parser = optparse.OptionParser(usage=usage)
+  parser.add_option("-a", "--all", action="store_true",
+            help="run all tests")
+  parser.add_option("-C", "--chdir", action="store", default=None,
+            help="chdir to the specified directory")
+  parser.add_option("-f", "--format", action="store", default='',
+            help="run tests with the specified formats")
+  parser.add_option("-l", "--list", action="store_true",
+            help="list available tests and exit")
+  parser.add_option("-n", "--no-exec", action="store_true",
+            help="no execute, just print the command line")
+  parser.add_option("--passed", action="store_true",
+            help="report passed tests")
+  parser.add_option("--path", action="append", default=[],
+            help="additional $PATH directory")
+  parser.add_option("-q", "--quiet", action="store_true",
+            help="quiet, don't print test command lines")
+  opts, args = parser.parse_args(argv[1:])
+
+  if opts.chdir:
+    os.chdir(opts.chdir)
+
+  if opts.path:
+    os.environ['PATH'] += ':' + ':'.join(opts.path)
+
+  if not args:
+    if not opts.all:
+      sys.stderr.write('Specify -a to get all tests.\n')
+      return 1
+    args = ['test']
+
+  tests = []
+  for arg in args:
+    if os.path.isdir(arg):
+      tests.extend(find_all_gyptest_files(os.path.normpath(arg)))
+    else:
+      tests.append(arg)
+
+  if opts.list:
+    for test in tests:
+      print test
+    sys.exit(0)
+
+  CommandRunner.verbose = not opts.quiet
+  CommandRunner.active = not opts.no_exec
+  cr = CommandRunner()
+
+  os.environ['PYTHONPATH'] = os.path.abspath('test/lib')
+  if not opts.quiet:
+    sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH'])
+
+  passed = []
+  failed = []
+  no_result = []
+
+  if opts.format:
+    format_list = opts.format.split(',')
+  else:
+    # TODO:  not duplicate this mapping from pylib/gyp/__init__.py
+    format_list = [ {
+      'freebsd7': 'make',
+      'freebsd8': 'make',
+      'cygwin':   'msvs',
+      'win32':    'msvs',
+      'linux2':   'make',
+      'darwin':   'xcode',
+    }[sys.platform] ]
+
+  for format in format_list:
+    os.environ['TESTGYP_FORMAT'] = format
+    if not opts.quiet:
+      sys.stdout.write('TESTGYP_FORMAT=%s\n' % format)
+
+    for test in tests:
+      status = cr.run([sys.executable, test],
+                      stdout=sys.stdout,
+                      stderr=sys.stderr)
+      if status == 2:
+        no_result.append(test)
+      elif status:
+        failed.append(test)
+      else:
+        passed.append(test)
+
+  if not opts.quiet:
+    def report(description, tests):
+      if tests:
+        if len(tests) == 1:
+          sys.stdout.write("\n%s the following test:\n" % description)
+        else:
+          fmt = "\n%s the following %d tests:\n"
+          sys.stdout.write(fmt % (description, len(tests)))
+        sys.stdout.write("\t" + "\n\t".join(tests) + "\n")
+
+    if opts.passed:
+      report("Passed", passed)
+    report("Failed", failed)
+    report("No result from", no_result)
+
+  if failed:
+    return 1
+  else:
+    return 0
+
+
+if __name__ == "__main__":
+  sys.exit(main())
diff --git a/Source/ThirdParty/gyp/pylib/gyp/MSVSNew.py b/Source/ThirdParty/gyp/pylib/gyp/MSVSNew.py
new file mode 100644 (file)
index 0000000..1277d4a
--- /dev/null
@@ -0,0 +1,341 @@
+#!/usr/bin/python2.4
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""New implementation of Visual Studio project generation for SCons."""
+
+import common
+import os
+import random
+
+import gyp.common
+
+# hashlib is supplied as of Python 2.5 as the replacement interface for md5
+# and other secure hashes.  In 2.6, md5 is deprecated.  Import hashlib if
+# available, avoiding a deprecation warning under 2.6.  Import md5 otherwise,
+# preserving 2.4 compatibility.
+try:
+  import hashlib
+  _new_md5 = hashlib.md5
+except ImportError:
+  import md5
+  _new_md5 = md5.new
+
+
+# Initialize random number generator
+random.seed()
+
+# GUIDs for project types
+ENTRY_TYPE_GUIDS = {
+    'project': '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}',
+    'folder': '{2150E333-8FDC-42A3-9474-1A3956D46DE8}',
+}
+
+#------------------------------------------------------------------------------
+# Helper functions
+
+
+def MakeGuid(name, seed='msvs_new'):
+  """Returns a GUID for the specified target name.
+
+  Args:
+    name: Target name.
+    seed: Seed for MD5 hash.
+  Returns:
+    A GUID-line string calculated from the name and seed.
+
+  This generates something which looks like a GUID, but depends only on the
+  name and seed.  This means the same name/seed will always generate the same
+  GUID, so that projects and solutions which refer to each other can explicitly
+  determine the GUID to refer to explicitly.  It also means that the GUID will
+  not change when the project for a target is rebuilt.
+  """
+  # Calculate a MD5 signature for the seed and name.
+  d = _new_md5(str(seed) + str(name)).hexdigest().upper()
+  # Convert most of the signature to GUID form (discard the rest)
+  guid = ('{' + d[:8] + '-' + d[8:12] + '-' + d[12:16] + '-' + d[16:20]
+          + '-' + d[20:32] + '}')
+  return guid
+
+#------------------------------------------------------------------------------
+
+
+class MSVSFolder:
+  """Folder in a Visual Studio project or solution."""
+
+  def __init__(self, path, name = None, entries = None,
+               guid = None, items = None):
+    """Initializes the folder.
+
+    Args:
+      path: Full path to the folder.
+      name: Name of the folder.
+      entries: List of folder entries to nest inside this folder.  May contain
+          Folder or Project objects.  May be None, if the folder is empty.
+      guid: GUID to use for folder, if not None.
+      items: List of solution items to include in the folder project.  May be
+          None, if the folder does not directly contain items.
+    """
+    if name:
+      self.name = name
+    else:
+      # Use last layer.
+      self.name = os.path.basename(path)
+
+    self.path = path
+    self.guid = guid
+
+    # Copy passed lists (or set to empty lists)
+    self.entries = list(entries or [])
+    self.items = list(items or [])
+
+    self.entry_type_guid = ENTRY_TYPE_GUIDS['folder']
+
+  def get_guid(self):
+    if self.guid is None:
+      # Use consistent guids for folders (so things don't regenerate).
+      self.guid = MakeGuid(self.path, seed='msvs_folder')
+    return self.guid
+
+
+#------------------------------------------------------------------------------
+
+
+class MSVSProject:
+  """Visual Studio project."""
+
+  def __init__(self, path, name = None, dependencies = None, guid = None,
+               spec = None, build_file = None, config_platform_overrides = None,
+               fixpath_prefix = None):
+    """Initializes the project.
+
+    Args:
+      path: Absolute path to the project file.
+      name: Name of project.  If None, the name will be the same as the base
+          name of the project file.
+      dependencies: List of other Project objects this project is dependent
+          upon, if not None.
+      guid: GUID to use for project, if not None.
+      spec: Dictionary specifying how to build this project.
+      build_file: Filename of the .gyp file that the vcproj file comes from.
+      config_platform_overrides: optional dict of configuration platforms to
+          used in place of the default for this target.
+      fixpath_prefix: the path used to adjust the behavior of _fixpath
+    """
+    self.path = path
+    self.guid = guid
+    self.spec = spec
+    self.build_file = build_file
+    # Use project filename if name not specified
+    self.name = name or os.path.splitext(os.path.basename(path))[0]
+
+    # Copy passed lists (or set to empty lists)
+    self.dependencies = list(dependencies or [])
+
+    self.entry_type_guid = ENTRY_TYPE_GUIDS['project']
+
+    if config_platform_overrides:
+      self.config_platform_overrides = config_platform_overrides
+    else:
+      self.config_platform_overrides = {}
+    self.fixpath_prefix = fixpath_prefix
+
+  def set_dependencies(self, dependencies):
+    self.dependencies = list(dependencies or [])
+  
+  def get_guid(self):
+    if self.guid is None:
+      # Set GUID from path
+      # TODO(rspangler): This is fragile.
+      # 1. We can't just use the project filename sans path, since there could
+      #    be multiple projects with the same base name (for example,
+      #    foo/unittest.vcproj and bar/unittest.vcproj).
+      # 2. The path needs to be relative to $SOURCE_ROOT, so that the project
+      #    GUID is the same whether it's included from base/base.sln or
+      #    foo/bar/baz/baz.sln.
+      # 3. The GUID needs to be the same each time this builder is invoked, so
+      #    that we don't need to rebuild the solution when the project changes.
+      # 4. We should be able to handle pre-built project files by reading the
+      #    GUID from the files.
+      self.guid = MakeGuid(self.name)
+    return self.guid
+
+#------------------------------------------------------------------------------
+
+
+class MSVSSolution:
+  """Visual Studio solution."""
+
+  def __init__(self, path, version, entries=None, variants=None,
+               websiteProperties=True):
+    """Initializes the solution.
+
+    Args:
+      path: Path to solution file.
+      version: Format version to emit.
+      entries: List of entries in solution.  May contain Folder or Project
+          objects.  May be None, if the folder is empty.
+      variants: List of build variant strings.  If none, a default list will
+          be used.
+      websiteProperties: Flag to decide if the website properties section
+          is generated.
+    """
+    self.path = path
+    self.websiteProperties = websiteProperties
+    self.version = version
+
+    # Copy passed lists (or set to empty lists)
+    self.entries = list(entries or [])
+
+    if variants:
+      # Copy passed list
+      self.variants = variants[:]
+    else:
+      # Use default
+      self.variants = ['Debug|Win32', 'Release|Win32']
+    # TODO(rspangler): Need to be able to handle a mapping of solution config
+    # to project config.  Should we be able to handle variants being a dict,
+    # or add a separate variant_map variable?  If it's a dict, we can't
+    # guarantee the order of variants since dict keys aren't ordered.
+
+
+    # TODO(rspangler): Automatically write to disk for now; should delay until
+    # node-evaluation time.
+    self.Write()
+
+
+  def Write(self, writer=common.WriteOnDiff):
+    """Writes the solution file to disk.
+
+    Raises:
+      IndexError: An entry appears multiple times.
+    """
+    # Walk the entry tree and collect all the folders and projects.
+    all_entries = []
+    entries_to_check = self.entries[:]
+    while entries_to_check:
+      # Pop from the beginning of the list to preserve the user's order.
+      e = entries_to_check.pop(0)
+
+      # A project or folder can only appear once in the solution's folder tree.
+      # This also protects from cycles.
+      if e in all_entries:
+        #raise IndexError('Entry "%s" appears more than once in solution' %
+        #                 e.name)
+        continue
+
+      all_entries.append(e)
+
+      # If this is a folder, check its entries too.
+      if isinstance(e, MSVSFolder):
+        entries_to_check += e.entries
+
+    # Sort by name then guid (so things are in order on vs2008).
+    def NameThenGuid(a, b):
+      if a.name < b.name: return -1
+      if a.name > b.name: return 1
+      if a.get_guid() < b.get_guid(): return -1
+      if a.get_guid() > b.get_guid(): return 1
+      return 0
+
+    all_entries = sorted(all_entries, NameThenGuid)
+
+    # Open file and print header
+    f = writer(self.path)
+    f.write('Microsoft Visual Studio Solution File, '
+            'Format Version %s\r\n' % self.version.SolutionVersion())
+    f.write('# %s\r\n' % self.version.Description())
+
+    # Project entries
+    sln_root = os.path.split(self.path)[0]
+    for e in all_entries:
+      relative_path = gyp.common.RelativePath(e.path, sln_root)
+      f.write('Project("%s") = "%s", "%s", "%s"\r\n' % (
+          e.entry_type_guid,          # Entry type GUID
+          e.name,                     # Folder name
+          relative_path.replace('/', '\\'),  # Folder name (again)
+          e.get_guid(),               # Entry GUID
+      ))
+
+      # TODO(rspangler): Need a way to configure this stuff
+      if self.websiteProperties:
+        f.write('\tProjectSection(WebsiteProperties) = preProject\r\n'
+                '\t\tDebug.AspNetCompiler.Debug = "True"\r\n'
+                '\t\tRelease.AspNetCompiler.Debug = "False"\r\n'
+                '\tEndProjectSection\r\n')
+
+      if isinstance(e, MSVSFolder):
+        if e.items:
+          f.write('\tProjectSection(SolutionItems) = preProject\r\n')
+          for i in e.items:
+            f.write('\t\t%s = %s\r\n' % (i, i))
+          f.write('\tEndProjectSection\r\n')
+
+      if isinstance(e, MSVSProject):
+        if e.dependencies:
+          f.write('\tProjectSection(ProjectDependencies) = postProject\r\n')
+          for d in e.dependencies:
+            f.write('\t\t%s = %s\r\n' % (d.get_guid(), d.get_guid()))
+          f.write('\tEndProjectSection\r\n')
+
+      f.write('EndProject\r\n')
+
+    # Global section
+    f.write('Global\r\n')
+
+    # Configurations (variants)
+    f.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n')
+    for v in self.variants:
+      f.write('\t\t%s = %s\r\n' % (v, v))
+    f.write('\tEndGlobalSection\r\n')
+
+    # Sort config guids for easier diffing of solution changes.
+    config_guids = []
+    config_guids_overrides = {}
+    for e in all_entries:
+      if isinstance(e, MSVSProject):
+        config_guids.append(e.get_guid())
+        config_guids_overrides[e.get_guid()] = e.config_platform_overrides
+    config_guids.sort()
+
+    f.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n')
+    for g in config_guids:
+      for v in self.variants:
+        nv = config_guids_overrides[g].get(v, v)
+        # Pick which project configuration to build for this solution
+        # configuration.
+        f.write('\t\t%s.%s.ActiveCfg = %s\r\n' % (
+            g,              # Project GUID
+            v,              # Solution build configuration
+            nv,             # Project build config for that solution config
+        ))
+
+        # Enable project in this solution configuration.
+        f.write('\t\t%s.%s.Build.0 = %s\r\n' % (
+            g,              # Project GUID
+            v,              # Solution build configuration
+            nv,             # Project build config for that solution config
+        ))
+    f.write('\tEndGlobalSection\r\n')
+
+    # TODO(rspangler): Should be able to configure this stuff too (though I've
+    # never seen this be any different)
+    f.write('\tGlobalSection(SolutionProperties) = preSolution\r\n')
+    f.write('\t\tHideSolutionNode = FALSE\r\n')
+    f.write('\tEndGlobalSection\r\n')
+
+    # Folder mappings
+    # TODO(rspangler): Should omit this section if there are no folders
+    f.write('\tGlobalSection(NestedProjects) = preSolution\r\n')
+    for e in all_entries:
+      if not isinstance(e, MSVSFolder):
+        continue        # Does not apply to projects, only folders
+      for subentry in e.entries:
+        f.write('\t\t%s = %s\r\n' % (subentry.get_guid(), e.get_guid()))
+    f.write('\tEndGlobalSection\r\n')
+
+    f.write('EndGlobal\r\n')
+
+    f.close()
diff --git a/Source/ThirdParty/gyp/pylib/gyp/MSVSProject.py b/Source/ThirdParty/gyp/pylib/gyp/MSVSProject.py
new file mode 100644 (file)
index 0000000..1246fdd
--- /dev/null
@@ -0,0 +1,245 @@
+#!/usr/bin/python2.4
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Visual Studio project reader/writer."""
+
+import common
+import xml.dom
+import xml_fix
+
+#------------------------------------------------------------------------------
+
+
+class Tool(object):
+  """Visual Studio tool."""
+
+  def __init__(self, name, attrs=None):
+    """Initializes the tool.
+
+    Args:
+      name: Tool name.
+      attrs: Dict of tool attributes; may be None.
+    """
+    self.name = name
+    self.attrs = attrs or {}
+
+  def CreateElement(self, doc):
+    """Creates an element for the tool.
+
+    Args:
+      doc: xml.dom.Document object to use for node creation.
+
+    Returns:
+      A new xml.dom.Element for the tool.
+    """
+    node = doc.createElement('Tool')
+    node.setAttribute('Name', self.name)
+    for k, v in self.attrs.items():
+      node.setAttribute(k, v)
+    return node
+
+
+class Filter(object):
+  """Visual Studio filter - that is, a virtual folder."""
+
+  def __init__(self, name, contents=None):
+    """Initializes the folder.
+
+    Args:
+      name: Filter (folder) name.
+      contents: List of filenames and/or Filter objects contained.
+    """
+    self.name = name
+    self.contents = list(contents or [])
+
+
+#------------------------------------------------------------------------------
+
+
+class Writer(object):
+  """Visual Studio XML project writer."""
+
+  def __init__(self, project_path, version):
+    """Initializes the project.
+
+    Args:
+      project_path: Path to the project file.
+      version: Format version to emit.
+    """
+    self.project_path = project_path
+    self.doc = None
+    self.version = version
+
+  def Create(self, name, guid=None, platforms=None):
+    """Creates the project document.
+
+    Args:
+      name: Name of the project.
+      guid: GUID to use for project, if not None.
+    """
+    self.name = name
+    self.guid = guid
+
+    # Default to Win32 for platforms.
+    if not platforms:
+      platforms = ['Win32']
+
+    # Create XML doc
+    xml_impl = xml.dom.getDOMImplementation()
+    self.doc = xml_impl.createDocument(None, 'VisualStudioProject', None)
+
+    # Add attributes to root element
+    self.n_root = self.doc.documentElement
+    self.n_root.setAttribute('ProjectType', 'Visual C++')
+    self.n_root.setAttribute('Version', self.version.ProjectVersion())
+    self.n_root.setAttribute('Name', self.name)
+    self.n_root.setAttribute('ProjectGUID', self.guid)
+    self.n_root.setAttribute('RootNamespace', self.name)
+    self.n_root.setAttribute('Keyword', 'Win32Proj')
+
+    # Add platform list
+    n_platform = self.doc.createElement('Platforms')
+    self.n_root.appendChild(n_platform)
+    for platform in platforms:
+      n = self.doc.createElement('Platform')
+      n.setAttribute('Name', platform)
+      n_platform.appendChild(n)
+
+    # Add tool files section
+    self.n_tool_files = self.doc.createElement('ToolFiles')
+    self.n_root.appendChild(self.n_tool_files)
+
+    # Add configurations section
+    self.n_configs = self.doc.createElement('Configurations')
+    self.n_root.appendChild(self.n_configs)
+
+    # Add empty References section
+    self.n_root.appendChild(self.doc.createElement('References'))
+
+    # Add files section
+    self.n_files = self.doc.createElement('Files')
+    self.n_root.appendChild(self.n_files)
+    # Keep a dict keyed on filename to speed up access.
+    self.n_files_dict = dict()
+
+    # Add empty Globals section
+    self.n_root.appendChild(self.doc.createElement('Globals'))
+
+  def AddToolFile(self, path):
+    """Adds a tool file to the project.
+
+    Args:
+      path: Relative path from project to tool file.
+    """
+    n_tool = self.doc.createElement('ToolFile')
+    n_tool.setAttribute('RelativePath', path)
+    self.n_tool_files.appendChild(n_tool)
+
+  def _AddConfigToNode(self, parent, config_type, config_name, attrs=None,
+                       tools=None):
+    """Adds a configuration to the parent node.
+
+    Args:
+      parent: Destination node.
+      config_type: Type of configuration node.
+      config_name: Configuration name.
+      attrs: Dict of configuration attributes; may be None.
+      tools: List of tools (strings or Tool objects); may be None.
+    """
+    # Handle defaults
+    if not attrs:
+      attrs = {}
+    if not tools:
+      tools = []
+
+    # Add configuration node and its attributes
+    n_config = self.doc.createElement(config_type)
+    n_config.setAttribute('Name', config_name)
+    for k, v in attrs.items():
+      n_config.setAttribute(k, v)
+    parent.appendChild(n_config)
+
+    # Add tool nodes and their attributes
+    if tools:
+      for t in tools:
+        if isinstance(t, Tool):
+          n_config.appendChild(t.CreateElement(self.doc))
+        else:
+          n_config.appendChild(Tool(t).CreateElement(self.doc))
+
+  def AddConfig(self, name, attrs=None, tools=None):
+    """Adds a configuration to the project.
+
+    Args:
+      name: Configuration name.
+      attrs: Dict of configuration attributes; may be None.
+      tools: List of tools (strings or Tool objects); may be None.
+    """
+    self._AddConfigToNode(self.n_configs, 'Configuration', name, attrs, tools)
+
+  def _AddFilesToNode(self, parent, files):
+    """Adds files and/or filters to the parent node.
+
+    Args:
+      parent: Destination node
+      files: A list of Filter objects and/or relative paths to files.
+
+    Will call itself recursively, if the files list contains Filter objects.
+    """
+    for f in files:
+      if isinstance(f, Filter):
+        node = self.doc.createElement('Filter')
+        node.setAttribute('Name', f.name)
+        self._AddFilesToNode(node, f.contents)
+      else:
+        node = self.doc.createElement('File')
+        node.setAttribute('RelativePath', f)
+        self.n_files_dict[f] = node
+      parent.appendChild(node)
+
+  def AddFiles(self, files):
+    """Adds files to the project.
+
+    Args:
+      files: A list of Filter objects and/or relative paths to files.
+
+    This makes a copy of the file/filter tree at the time of this call.  If you
+    later add files to a Filter object which was passed into a previous call
+    to AddFiles(), it will not be reflected in this project.
+    """
+    self._AddFilesToNode(self.n_files, files)
+    # TODO(rspangler) This also doesn't handle adding files to an existing
+    # filter.  That is, it doesn't merge the trees.
+
+  def AddFileConfig(self, path, config, attrs=None, tools=None):
+    """Adds a configuration to a file.
+
+    Args:
+      path: Relative path to the file.
+      config: Name of configuration to add.
+      attrs: Dict of configuration attributes; may be None.
+      tools: List of tools (strings or Tool objects); may be None.
+
+    Raises:
+      ValueError: Relative path does not match any file added via AddFiles().
+    """
+    # Find the file node with the right relative path
+    parent = self.n_files_dict.get(path)
+    if not parent:
+      raise ValueError('AddFileConfig: file "%s" not in project.' % path)
+
+    # Add the config to the file node
+    self._AddConfigToNode(parent, 'FileConfiguration', config, attrs, tools)
+
+  def Write(self, writer=common.WriteOnDiff):
+    """Writes the project file."""
+    f = writer(self.project_path)
+    fix = xml_fix.XmlFix()
+    self.doc.writexml(f, encoding='Windows-1252', addindent='  ', newl='\r\n')
+    fix.Cleanup()
+    f.close()
+
+#------------------------------------------------------------------------------
diff --git a/Source/ThirdParty/gyp/pylib/gyp/MSVSSettings.py b/Source/ThirdParty/gyp/pylib/gyp/MSVSSettings.py
new file mode 100644 (file)
index 0000000..5b79dd5
--- /dev/null
@@ -0,0 +1,980 @@
+#!/usr/bin/python
+
+# Copyright (c) 2011 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+""" Code to validate and convert settings of the Microsoft build tools.
+
+This file contains code to validate and convert settings of the Microsoft
+build tools.  The function ConvertToMsBuildSettings(), ValidateMSVSSettings(),
+and ValidateMSBuildSettings() are the entry points.
+
+This file was created by comparing the projects created by Visual Studio 2008
+and Visual Studio 2010 for all available settings through the user interface.
+The MSBuild schemas were also considered.  They are typically found in the
+MSBuild install directory, e.g. c:\Program Files (x86)\MSBuild
+"""
+
+import sys
+
+
+# Dictionaries of settings validators. The key is the tool name, the value is
+# a dictionary mapping setting names to validation functions.
+_msvs_validators = {}
+_msbuild_validators = {}
+
+
+# A dictionary of settings converters. The key is the tool name, the value is
+# a dictionary mapping setting names to conversion functions.
+_msvs_to_msbuild_converters = {}
+
+
+# Tool name mapping from MSVS to MSBuild.
+_msbuild_name_of_tool = {}
+
+
+def _AddTool(names):
+  """ Adds a tool to the four dictionaries used to process settings.
+
+  This only defines the tool.  Each setting also needs to be added.
+
+  Args:
+    names: a dictionary of the MSVS and MSBuild names of this tool.
+  """
+  msvs_name = names['msvs']
+  msbuild_name = names['msbuild']
+  _msvs_validators[msvs_name] = {}
+  _msbuild_validators[msbuild_name] = {}
+  _msvs_to_msbuild_converters[msvs_name] = {}
+  _msbuild_name_of_tool[msvs_name] = msbuild_name
+
+
+def _GetMsBuildToolSettings(msbuild_settings, tool):
+  """ Returns an MSBuild tool dictionary.  Creates it if needed. """
+  tool_name = tool['msbuild']
+  return _GetOrCreateSubDictionary(msbuild_settings, tool_name)
+
+
+def _GetOrCreateSubDictionary(dict, name):
+  """ Returns or creates one of the sub-dictionary of dict. """
+  if not name in dict:
+    dict[name] = {}
+  return dict[name]
+
+
+class _Type:
+  """ Type of settings (Base class). """
+  def ValidateMSVS(self, value):
+    """ Raises ValueError if value is not valid for MSVS. """
+    pass
+  def ValidateMSBuild(self, value):
+    """ Raises ValueError if value is not valid for MSBuild. """
+    pass
+  def ConvertToMSBuild(self, value):
+    """ Returns the MSBuild equivalent of the MSVS value given.
+
+    Raises ValueError if value is not valid.
+    """
+    return value
+
+
+class _String(_Type):
+  """ A setting that's just a string. """
+  def ValidateMSVS(self, value):
+    if not isinstance(value, str):
+      raise ValueError
+  def ValidateMSBuild(self, value):
+    if not isinstance(value, str):
+      raise ValueError
+  def ConvertToMSBuild(self, value):
+    # Convert the macros
+    return _ConvertVCMacrosToMsBuild(value)
+
+
+class _StringList(_Type):
+  """ A settings that's a list of strings. """
+  def ValidateMSVS(self, value):
+    if not isinstance(value, str) and not isinstance(value, list):
+      raise ValueError
+  def ValidateMSBuild(self, value):
+    if not isinstance(value, str) and not isinstance(value, list):
+      raise ValueError
+  def ConvertToMSBuild(self, value):
+    # Convert the macros
+    if isinstance(value, list):
+      return [_ConvertVCMacrosToMsBuild(i) for i in value]
+    else:
+      return _ConvertVCMacrosToMsBuild(value)
+
+
+class _Boolean(_Type):
+  """ Boolean settings, can have the values 'false' or 'true'. """
+  def _Validate(self, value):
+    if value != 'true' and value != 'false':
+      raise ValueError
+  def ValidateMSVS(self, value):
+    self._Validate(value)
+  def ValidateMSBuild(self, value):
+    self._Validate(value)
+  def ConvertToMSBuild(self, value):
+    self._Validate(value)
+    return value
+
+
+class _Integer(_Type):
+  """ Integer settings. """
+  def __init__(self, msbuild_base=10):
+    self.msbuild_base = msbuild_base
+  def ValidateMSVS(self, value):
+    # Try to convert, this will raise ValueError if invalid.
+    self.ConvertToMSBuild(value)
+  def ValidateMSBuild(self, value):
+    # Try to convert, this will raise ValueError if invalid.
+    int(value, self.msbuild_base)
+  def ConvertToMSBuild(self, value):
+    format = (self.msbuild_base == 10) and '%d' or '0x%04x'
+    return format % int(value)
+
+
+class _Enumeration(_Type):
+  """ Type of settings that is an enumeration.
+
+  In MSVS, the values are indexes like '0', '1', and '2'.
+  MSBuild uses text labels that are more representative, like 'Win32'.
+
+  Constructor args:
+    label_list: an array of MSBuild labels that correspond to the MSVS index.
+        In the rare cases where MSVS has skipped an index value, None is
+        used in the array to indicate the unused spot.
+    new: an array of labels that are new to MSBuild.
+  """
+  def __init__(self, label_list, new=[]):
+    self.label_list = label_list
+    self.msbuild_values = set()
+    for value in label_list:
+      if not value is None:
+        self.msbuild_values.add(value)
+    for value in new:
+      self.msbuild_values.add(value)
+  def ValidateMSVS(self, value):
+    # Try to convert.  It will raise an exception if not valid.
+    self.ConvertToMSBuild(value)
+  def ValidateMSBuild(self, value):
+    if not value in self.msbuild_values:
+      raise ValueError
+  def ConvertToMSBuild(self, value):
+    index = int(value)
+    if index < 0 or index >= len(self.label_list):
+      raise ValueError
+    label = self.label_list[index]
+    if label is None:
+      raise ValueError
+    return label
+
+
+# Instantiate the various generic types.
+_boolean = _Boolean()
+_integer = _Integer()
+# For now, we don't do any special validation on these types:
+_string = _String()
+_file_name = _String()
+_folder_name = _String()
+_file_list = _StringList()
+_folder_list = _StringList()
+_string_list = _StringList()
+# Some boolean settings went from numerical values to boolean.  The
+# mapping is 0: default, 1: false, 2: true.
+_newly_boolean = _Enumeration(['', 'false', 'true'])
+
+
+def _Same(tool, name, type):
+  """ Defines a setting that has the same name in MSVS and MSBuild.
+
+  Args:
+    tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
+    name: the name of the setting.
+    type: the type of this setting.
+  """
+  _Renamed(tool, name, name, type)
+
+
+def _Renamed(tool, msvs_name, msbuild_name, type):
+  """ Defines a setting for which the name has changed.
+
+  Args:
+    tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
+    msvs_name: the name of the MSVS setting.
+    msbuild_name: the name of the MSBuild setting.
+    type: the type of this setting.
+  """
+  def _Translate(value, msbuild_settings):
+    msbuild_tool_settings = _GetMsBuildToolSettings(msbuild_settings, tool)
+    msbuild_tool_settings[msbuild_name] = type.ConvertToMSBuild(value)
+  msvs_tool_name = tool['msvs']
+  msbuild_tool_name = tool['msbuild']
+  _msvs_validators[msvs_tool_name][msvs_name] = type.ValidateMSVS
+  _msbuild_validators[msbuild_tool_name][msbuild_name] = type.ValidateMSBuild
+  _msvs_to_msbuild_converters[msvs_tool_name][msvs_name] = _Translate
+
+
+def _Moved(tool, settings_name, msbuild_tool_name, type):
+    _MovedAndRenamed(tool, settings_name, msbuild_tool_name, settings_name,
+                     type)
+
+
+def _MovedAndRenamed(tool, msvs_settings_name, msbuild_tool_name,
+                     msbuild_settings_name, type):
+  """ Defines a setting that may have moved to a new section.
+
+  Args:
+    tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
+    msvs_settings_name: the MSVS name of the setting.
+    msbuild_tool_name: the name of the MSBuild tool to place the setting under.
+    msbuild_settings_name: the MSBuild name of the setting.
+    type: the type of this setting.
+  """
+  def _Translate(value, msbuild_settings):
+    tool_settings = _GetOrCreateSubDictionary(msbuild_settings,
+                                              msbuild_tool_name)
+    tool_settings[msbuild_settings_name] = type.ConvertToMSBuild(value)
+  msvs_tool_name = tool['msvs']
+  _msvs_validators[msvs_tool_name][msvs_settings_name] = type.ValidateMSVS
+  validator = type.ValidateMSBuild
+  _msbuild_validators[msbuild_tool_name][msbuild_settings_name] = validator
+  _msvs_to_msbuild_converters[msvs_tool_name][msvs_settings_name] = _Translate
+
+
+def _MSVSOnly(tool, name, type):
+  """ Defines a setting that is only found in MSVS.
+
+  Args:
+    tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
+    name: the name of the setting.
+    type: the type of this setting.
+  """
+  def _Translate(value, msbuild_settings):
+    pass
+  msvs_tool_name = tool['msvs']
+  _msvs_validators[msvs_tool_name][name] = type.ValidateMSVS
+  _msvs_to_msbuild_converters[msvs_tool_name][name] = _Translate
+
+
+def _MSBuildOnly(tool, name, type):
+  """ Defines a setting that is only found in MSBuild.
+
+  Args:
+    tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
+    name: the name of the setting.
+    type: the type of this setting.
+  """
+  msbuild_tool_name = tool['msbuild']
+  _msbuild_validators[msbuild_tool_name][name] = type.ValidateMSBuild
+
+
+def _ConvertedToAdditionalOption(tool, msvs_name, flag):
+  """ Defines a setting that's handled via a command line option in MSBuild.
+
+  Args:
+    tool: a dictionary that gives the names of the tool for MSVS and MSBuild.
+    msvs_name: the name of the MSVS setting that if 'true' becomes a flag
+    flag: the flag to insert at the end of the AdditionalOptions
+  """
+  def _Translate(value, msbuild_settings):
+    if value == 'true':
+      tool_settings = _GetMsBuildToolSettings(msbuild_settings, tool)
+      if 'AdditionalOptions' in tool_settings:
+        new_flags = "%s %s" % (tool_settings['AdditionalOptions'], flag)
+      else:
+        new_flags = flag
+      tool_settings['AdditionalOptions'] = new_flags
+  msvs_tool_name = tool['msvs']
+  _msvs_validators[msvs_tool_name][msvs_name] = _boolean.ValidateMSVS
+  _msvs_to_msbuild_converters[msvs_tool_name][msvs_name] = _Translate
+
+
+def _CustomGeneratePreprocessedFile(tool, msvs_name):
+  def _Translate(value, msbuild_settings):
+      tool_settings = _GetMsBuildToolSettings(msbuild_settings, tool)
+      if value == '0':
+        tool_settings['PreprocessToFile'] = 'false'
+        tool_settings['PreprocessSuppressLineNumbers'] = 'false'
+      elif value == '1':  # /P
+        tool_settings['PreprocessToFile'] = 'true'
+        tool_settings['PreprocessSuppressLineNumbers'] = 'false'
+      elif value == '2':  # /EP /P
+        tool_settings['PreprocessToFile'] = 'true'
+        tool_settings['PreprocessSuppressLineNumbers'] = 'true'
+      else:
+        raise ValueError
+  msvs_tool_name = tool['msvs']
+  # Create a bogus validator that looks for '0', '1', or '2'
+  msvs_validator = _Enumeration(['a', 'b', 'c']).ValidateMSVS
+  _msvs_validators[msvs_tool_name][msvs_name] = msvs_validator
+  msbuild_validator = _boolean.ValidateMSBuild
+  msbuild_tool_validators = _msbuild_validators[tool['msbuild']]
+  msbuild_tool_validators['PreprocessToFile'] = msbuild_validator
+  msbuild_tool_validators['PreprocessSuppressLineNumbers'] = msbuild_validator
+  _msvs_to_msbuild_converters[msvs_tool_name][msvs_name] = _Translate
+
+
+def _ConvertVCMacrosToMsBuild(s):
+  if (s.find('$') >= 0):
+    s = s.replace('$(ConfigurationName)', '$(Configuration)')
+    s = s.replace('$(InputDir)', '%(RootDir)%(Directory)')
+    s = s.replace('$(InputExt)', '%(Extension)')
+    s = s.replace('$(InputFileName)', '%(Filename)%(Extension)')
+    s = s.replace('$(InputName)', '%(Filename)')
+    s = s.replace('$(InputPath)', '%(FullPath)')
+    s = s.replace('$(ParentName)', '$(ProjectFileName)')
+    s = s.replace('$(PlatformName)', '$(Platform)')
+    s = s.replace('$(SafeInputName)', '%(Filename)')
+
+    s = s.replace('$(IntDir)\\', '$(IntDir)')
+    s = s.replace('$(OutDir)\\', '$(OutDir)')
+    s = s.replace('$(IntDir)/', '$(IntDir)')
+    s = s.replace('$(OutDir)/', '$(OutDir)')
+  return s
+
+
+def ConvertToMsBuildSettings(msvs_settings, stderr=sys.stderr):
+  """ Converts MSVS settings (VS2008 and earlier) to MSBuild settings (VS2010+).
+
+  Args:
+      msvs_settings: A dictionary.  The key is the tool name.  The values are
+                     themselves dictionaries of settings and their values.
+      stderr: The stream receiving the error messages.
+  Returns:
+      A dictionary of MSBuild settings.  The key is either the MSBuild tool name
+      or the empty string (for the global settings).  The values are themselves
+      dictionaries of settings and their values.
+  """
+  msbuild_settings = {}
+  for msvs_tool_name, msvs_tool_settings in msvs_settings.iteritems():
+    if msvs_tool_name in _msvs_to_msbuild_converters:
+      msvs_tool = _msvs_to_msbuild_converters[msvs_tool_name]
+      for msvs_setting, msvs_value in msvs_tool_settings.iteritems():
+        if msvs_setting in msvs_tool:
+          # Invoke the translation function.
+          try:
+            msvs_tool[msvs_setting](msvs_value, msbuild_settings)
+          except ValueError:
+            print >> stderr, ('Warning: unrecognized value "%s" for %s/%s '
+                'while converting to MSBuild.' %
+                (msvs_value, msvs_tool_name, msvs_setting))
+        else:
+          # We don't know this setting.  Give a warning.
+          print >> stderr, ('Warning: unrecognized setting %s/%s '
+              'while converting to MSBuild.' % (msvs_tool_name, msvs_setting))
+    else:
+      print >> stderr, ('Warning: unrecognized tool %s while converting to '
+                        'MSBuild.' % msvs_tool_name)
+  return msbuild_settings
+
+
+def ValidateMSVSSettings(settings, stderr=sys.stderr):
+  """ Validates that the names of the settings are valid for MSVS.
+
+  Args:
+      settings: A dictionary.  The key is the tool name.  The values are
+                themselves dictionaries of settings and their values.
+      stderr: The stream receiving the error messages.
+  """
+  _ValidateSettings(_msvs_validators, settings, stderr)
+
+
+def ValidateMSBuildSettings(settings, stderr=sys.stderr):
+  """ Validates that the names of the settings are valid for MSBuild.
+
+  Args:
+      settings: A dictionary.  The key is the tool name.  The values are
+                themselves dictionaries of settings and their values.
+      stderr: The stream receiving the error messages.
+  """
+  _ValidateSettings(_msbuild_validators, settings, stderr)
+
+
+def _ValidateSettings(validators, settings, stderr):
+  """ Validates that the settings are valid for MSBuild or MSVS.
+
+  We currently only validate the names of the settings, not their values.
+
+  Args:
+      validators: A dictionary of tools and their validators.
+      settings: A dictionary.  The key is the tool name.  The values are
+                themselves dictionaries of settings and their values.
+      stderr: The stream receiving the error messages.
+  """
+  for tool_name in settings:
+    if tool_name in validators:
+      tool_validators = validators[tool_name]
+      for setting, value in settings[tool_name].iteritems():
+        if setting in tool_validators:
+          try:
+            tool_validators[setting](value)
+          except ValueError:
+            print >> stderr, ('Warning: unrecognized value "%s" for %s/%s' %
+                              (value, tool_name, setting))
+          #except TypeError:  #(jeanluc)
+          #  print ('***value "%s" for %s/%s' % (value, tool_name, setting))
+        else:
+          print >> stderr, ('Warning: unrecognized setting %s/%s' %
+                            (tool_name, setting))
+    else:
+      print >> stderr, ('Warning: unrecognized tool %s' % tool_name)
+
+
+# MSVS and MBuild names of the tools.
+_compile = {'msvs': 'VCCLCompilerTool', 'msbuild': 'ClCompile'}
+_link = {'msvs': 'VCLinkerTool', 'msbuild': 'Link'}
+_midl = {'msvs': 'VCMIDLTool', 'msbuild': 'Midl'}
+_rc = {'msvs': 'VCResourceCompilerTool', 'msbuild': 'ResourceCompile'}
+_lib = {'msvs': 'VCLibrarianTool', 'msbuild': 'Lib'}
+_manifest = {'msvs': 'VCManifestTool', 'msbuild': 'Mt'}
+
+
+_AddTool(_compile)
+_AddTool(_link)
+_AddTool(_midl)
+_AddTool(_rc)
+_AddTool(_lib)
+_AddTool(_manifest)
+# Add sections only found in the MSBuild settings.
+_msbuild_validators[''] = {}
+_msbuild_validators['ProjectReference'] = {}
+_msbuild_validators['ManifestResourceCompile'] = {}
+
+# Descriptions of the compiler options, i.e. VCCLCompilerTool in MSVS and
+# ClCompile in MSBuild.
+# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\cl.xml" for
+# the schema of the MSBuild ClCompile settings.
+
+# Options that have the same name in MSVS and MSBuild
+_Same(_compile, 'AdditionalIncludeDirectories', _folder_list)  # /I
+_Same(_compile, 'AdditionalOptions', _string_list)
+_Same(_compile, 'AdditionalUsingDirectories', _folder_list)  # /AI
+_Same(_compile, 'AssemblerListingLocation', _file_name)  # /Fa
+_Same(_compile, 'BrowseInformationFile', _file_name)
+_Same(_compile, 'BufferSecurityCheck', _boolean)  # /GS
+_Same(_compile, 'DisableLanguageExtensions', _boolean)  # /Za
+_Same(_compile, 'DisableSpecificWarnings', _string_list)  # /wd
+_Same(_compile, 'EnableFiberSafeOptimizations', _boolean)  # /GT
+_Same(_compile, 'EnablePREfast', _boolean)  # /analyze Visible='false'
+_Same(_compile, 'ExpandAttributedSource', _boolean)  # /Fx
+_Same(_compile, 'FloatingPointExceptions', _boolean)  # /fp:except
+_Same(_compile, 'ForceConformanceInForLoopScope', _boolean)  # /Zc:forScope
+_Same(_compile, 'ForcedIncludeFiles', _file_list)  # /FI
+_Same(_compile, 'ForcedUsingFiles', _file_list)  # /FU
+_Same(_compile, 'GenerateXMLDocumentationFiles', _boolean)  # /doc
+_Same(_compile, 'IgnoreStandardIncludePath', _boolean)  # /X
+_Same(_compile, 'MinimalRebuild', _boolean)  # /Gm
+_Same(_compile, 'OmitDefaultLibName', _boolean)  # /Zl
+_Same(_compile, 'OmitFramePointers', _boolean)  # /Oy
+_Same(_compile, 'PreprocessorDefinitions', _string_list)  # /D
+_Same(_compile, 'ProgramDataBaseFileName', _file_name)  # /Fd
+_Same(_compile, 'RuntimeTypeInfo', _boolean)  # /GR
+_Same(_compile, 'ShowIncludes', _boolean)  # /showIncludes
+_Same(_compile, 'SmallerTypeCheck', _boolean)  # /RTCc
+_Same(_compile, 'StringPooling', _boolean)  # /GF
+_Same(_compile, 'SuppressStartupBanner', _boolean)  # /nologo
+_Same(_compile, 'TreatWChar_tAsBuiltInType', _boolean)  # /Zc:wchar_t
+_Same(_compile, 'UndefineAllPreprocessorDefinitions', _boolean)  # /u
+_Same(_compile, 'UndefinePreprocessorDefinitions', _string_list)  # /U
+_Same(_compile, 'UseFullPaths', _boolean)  # /FC
+_Same(_compile, 'WholeProgramOptimization', _boolean)  # /GL
+_Same(_compile, 'XMLDocumentationFileName', _file_name)
+
+_Same(_compile, 'AssemblerOutput',
+      _Enumeration(['NoListing',
+                    'AssemblyCode',  # /FA
+                    'All',  # /FAcs
+                    'AssemblyAndMachineCode',  # /FAc
+                    'AssemblyAndSourceCode']))  # /FAs
+_Same(_compile, 'BasicRuntimeChecks',
+      _Enumeration(['Default',
+                    'StackFrameRuntimeCheck',  # /RTCs
+                    'UninitializedLocalUsageCheck',  # /RTCu
+                    'EnableFastChecks']))  # /RTC1
+_Same(_compile, 'BrowseInformation',
+      _Enumeration(['false',
+                    'true',  # /FR
+                    'true']))  # /Fr
+_Same(_compile, 'CallingConvention',
+      _Enumeration(['Cdecl',  # /Gd
+                    'FastCall',  # /Gr
+                    'StdCall']))  # /Gz
+_Same(_compile, 'CompileAs',
+      _Enumeration(['Default',
+                    'CompileAsC',  # /TC
+                    'CompileAsCpp']))  # /TP
+_Same(_compile, 'DebugInformationFormat',
+      _Enumeration(['',  # Disabled
+                    'OldStyle',  # /Z7
+                    None,
+                    'ProgramDatabase',  # /Zi
+                    'EditAndContinue']))  # /ZI
+_Same(_compile, 'EnableEnhancedInstructionSet',
+      _Enumeration(['NotSet',
+                    'StreamingSIMDExtensions',  # /arch:SSE
+                    'StreamingSIMDExtensions2']))  # /arch:SSE2
+_Same(_compile, 'ErrorReporting',
+      _Enumeration(['None',  # /errorReport:none
+                    'Prompt',  # /errorReport:prompt
+                    'Queue'],  # /errorReport:queue
+                   new=['Send']))  # /errorReport:send"
+_Same(_compile, 'ExceptionHandling',
+      _Enumeration(['false',
+                    'Sync',  # /EHsc
+                    'Async'],  # /EHa
+                   new=['SyncCThrow']))  # /EHs
+_Same(_compile, 'FavorSizeOrSpeed',
+      _Enumeration(['Neither',
+                    'Speed',  # /Ot
+                    'Size']))  # /Os
+_Same(_compile, 'FloatingPointModel',
+      _Enumeration(['Precise',  # /fp:precise
+                    'Strict',  # /fp:strict
+                    'Fast']))  # /fp:fast
+_Same(_compile, 'InlineFunctionExpansion',
+      _Enumeration(['Default',
+                    'OnlyExplicitInline',  # /Ob1
+                    'AnySuitable'],  # /Ob2
+                   new=['Disabled']))  # /Ob0
+_Same(_compile, 'Optimization',
+      _Enumeration(['Disabled',  # /Od
+                    'MinSpace',  # /O1
+                    'MaxSpeed',  # /O2
+                    'Full']))  # /Ox
+_Same(_compile, 'RuntimeLibrary',
+      _Enumeration(['MultiThreaded',  # /MT
+                    'MultiThreadedDebug',  # /MTd
+                    'MultiThreadedDLL',  # /MD
+                    'MultiThreadedDebugDLL']))  # /MDd
+_Same(_compile, 'StructMemberAlignment',
+      _Enumeration(['Default',
+                    '1Byte',  # /Zp1
+                    '2Bytes',  # /Zp2
+                    '4Bytes',  # /Zp4
+                    '8Bytes',  # /Zp8
+                    '16Bytes']))  # /Zp16
+_Same(_compile, 'WarningLevel',
+      _Enumeration(['TurnOffAllWarnings',  # /W0
+                    'Level1',  # /W1
+                    'Level2',  # /W2
+                    'Level3',  # /W3
+                    'Level4'],  # /W4
+                   new=['EnableAllWarnings']))  # /Wall
+
+# Options found in MSVS that have been renamed in MSBuild.
+_Renamed(_compile, 'EnableFunctionLevelLinking', 'FunctionLevelLinking',
+         _boolean)  # /Gy
+_Renamed(_compile, 'EnableIntrinsicFunctions', 'IntrinsicFunctions',
+         _boolean)  # /Oi
+_Renamed(_compile, 'KeepComments', 'PreprocessKeepComments', _boolean)  # /C
+_Renamed(_compile, 'ObjectFile', 'ObjectFileName', _file_name)  # /Fo
+_Renamed(_compile, 'OpenMP', 'OpenMPSupport', _boolean)  # /openmp
+_Renamed(_compile, 'PrecompiledHeaderThrough',  'PrecompiledHeaderFile',
+         _file_name)  # Used with /Yc and /Yu
+_Renamed(_compile, 'PrecompiledHeaderFile', 'PrecompiledHeaderOutputFile',
+         _file_name)  # /Fp
+_Renamed(_compile, 'UsePrecompiledHeader', 'PrecompiledHeader',
+         _Enumeration(['NotUsing',  # VS recognized '' for this value too.
+                       'Create',   # /Yc
+                       'Use']))  # /Yu
+_Renamed(_compile, 'WarnAsError', 'TreatWarningAsError', _boolean)  # /WX
+
+_ConvertedToAdditionalOption(_compile, 'DefaultCharIsUnsigned', '/J')
+
+# MSVS options not found in MSBuild.
+_MSVSOnly(_compile, 'Detect64BitPortabilityProblems', _boolean)
+_MSVSOnly(_compile, 'UseUnicodeResponseFiles', _boolean)
+
+# MSBuild options not found in MSVS.
+_MSBuildOnly(_compile, 'BuildingInIDE', _boolean)
+_MSBuildOnly(_compile, 'CompileAsManaged',
+             _Enumeration([], new=['false',
+                                   'true',  # /clr
+                                   'Pure',  # /clr:pure
+                                   'Safe',  # /clr:safe
+                                   'OldSyntax']))  # /clr:oldSyntax
+_MSBuildOnly(_compile, 'CreateHotpatchableImage', _boolean)  # /hotpatch
+_MSBuildOnly(_compile, 'MultiProcessorCompilation', _boolean)  # /MP
+_MSBuildOnly(_compile, 'PreprocessOutputPath', _string)  # /Fi
+_MSBuildOnly(_compile, 'ProcessorNumber', _integer)  # the number of processors
+_MSBuildOnly(_compile, 'TrackerLogDirectory', _folder_name)
+_MSBuildOnly(_compile, 'TreatSpecificWarningsAsErrors', _string_list)  # /we
+_MSBuildOnly(_compile, 'UseUnicodeForAssemblerListing', _boolean)  # /FAu
+
+# Defines a setting that needs very customized processing
+_CustomGeneratePreprocessedFile(_compile, 'GeneratePreprocessedFile')
+
+
+# Directives for converting MSVS VCLinkerTool to MSBuild Link.
+# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\link.xml" for
+# the schema of the MSBuild Link settings.
+
+# Options that have the same name in MSVS and MSBuild
+_Same(_link, 'AdditionalDependencies', _file_list)
+_Same(_link, 'AdditionalLibraryDirectories', _folder_list)  # /LIBPATH
+_Same(_link, 'AdditionalManifestDependencies', _file_list) # /MANIFESTDEPENDENCY
+_Same(_link, 'AdditionalOptions', _string_list)
+_Same(_link, 'AddModuleNamesToAssembly', _file_list)  # /ASSEMBLYMODULE
+_Same(_link, 'AllowIsolation', _boolean)  # /ALLOWISOLATION
+_Same(_link, 'AssemblyLinkResource', _file_list)  # /ASSEMBLYLINKRESOURCE
+_Same(_link, 'BaseAddress', _string)  # /BASE
+_Same(_link, 'CLRUnmanagedCodeCheck', _boolean)  # /CLRUNMANAGEDCODECHECK
+_Same(_link, 'DelayLoadDLLs', _file_list)  # /DELAYLOAD
+_Same(_link, 'DelaySign', _boolean)  # /DELAYSIGN
+_Same(_link, 'EmbedManagedResourceFile', _file_list)  # /ASSEMBLYRESOURCE
+_Same(_link, 'EnableUAC', _boolean)  # /MANIFESTUAC
+_Same(_link, 'EntryPointSymbol', _string)  # /ENTRY
+_Same(_link, 'ForceSymbolReferences', _file_list)  # /INCLUDE
+_Same(_link, 'FunctionOrder', _file_name)  # /ORDER
+_Same(_link, 'GenerateDebugInformation', _boolean)  # /DEBUG
+_Same(_link, 'GenerateMapFile', _boolean)  # /MAP
+_Same(_link, 'HeapCommitSize', _string)
+_Same(_link, 'HeapReserveSize', _string)  # /HEAP
+_Same(_link, 'IgnoreAllDefaultLibraries', _boolean)  # /NODEFAULTLIB
+_Same(_link, 'IgnoreEmbeddedIDL', _boolean)  # /IGNOREIDL
+_Same(_link, 'ImportLibrary', _file_name)  # /IMPLIB
+_Same(_link, 'KeyContainer', _file_name)  # /KEYCONTAINER
+_Same(_link, 'KeyFile', _file_name)  # /KEYFILE
+_Same(_link, 'ManifestFile', _file_name)  # /ManifestFile
+_Same(_link, 'MapExports', _boolean)  # /MAPINFO:EXPORTS
+_Same(_link, 'MapFileName', _file_name)
+_Same(_link, 'MergedIDLBaseFileName', _file_name)  # /IDLOUT
+_Same(_link, 'MergeSections', _string)  # /MERGE
+_Same(_link, 'MidlCommandFile', _file_name)  # /MIDL
+_Same(_link, 'ModuleDefinitionFile', _file_name)  # /DEF
+_Same(_link, 'OutputFile', _file_name)  # /OUT
+_Same(_link, 'PerUserRedirection', _boolean)
+_Same(_link, 'Profile', _boolean)  # /PROFILE
+_Same(_link, 'ProfileGuidedDatabase', _file_name)  # /PGD
+_Same(_link, 'ProgramDatabaseFile', _file_name)  # /PDB
+_Same(_link, 'RegisterOutput', _boolean)
+_Same(_link, 'SetChecksum', _boolean)  # /RELEASE
+_Same(_link, 'StackCommitSize', _string)
+_Same(_link, 'StackReserveSize', _string)  # /STACK
+_Same(_link, 'StripPrivateSymbols', _file_name)  # /PDBSTRIPPED
+_Same(_link, 'SupportUnloadOfDelayLoadedDLL', _boolean)  # /DELAY:UNLOAD
+_Same(_link, 'SuppressStartupBanner', _boolean)  # /NOLOGO
+_Same(_link, 'SwapRunFromCD', _boolean)  # /SWAPRUN:CD
+_Same(_link, 'TurnOffAssemblyGeneration', _boolean)  # /NOASSEMBLY
+_Same(_link, 'TypeLibraryFile', _file_name)  # /TLBOUT
+_Same(_link, 'TypeLibraryResourceID', _integer)  # /TLBID
+_Same(_link, 'UACUIAccess', _boolean)  # /uiAccess='true'
+_Same(_link, 'Version', _string)  # /VERSION
+
+_Same(_link, 'EnableCOMDATFolding', _newly_boolean)  # /OPT:ICF
+_Same(_link, 'FixedBaseAddress', _newly_boolean)  # /FIXED
+_Same(_link, 'LargeAddressAware', _newly_boolean)  # /LARGEADDRESSAWARE
+_Same(_link, 'OptimizeReferences', _newly_boolean)  # /OPT:REF
+_Same(_link, 'RandomizedBaseAddress', _newly_boolean)  # /DYNAMICBASE
+_Same(_link, 'TerminalServerAware', _newly_boolean)  # /TSAWARE
+
+_subsystem_enumeration = _Enumeration([
+    'NotSet',
+    'Console',  # /SUBSYSTEM:CONSOLE
+    'Windows',  # /SUBSYSTEM:WINDOWS
+    'Native',  # /SUBSYSTEM:NATIVE
+    'EFI Application',  # /SUBSYSTEM:EFI_APPLICATION
+    'EFI Boot Service Driver',  # /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER
+    'EFI ROM',  # /SUBSYSTEM:EFI_ROM
+    'EFI Runtime',  # /SUBSYSTEM:EFI_RUNTIME_DRIVER
+    'WindowsCE'],  # /SUBSYSTEM:WINDOWSCE
+    new=['POSIX'])  # /SUBSYSTEM:POSIX
+
+_target_machine_enumeration = _Enumeration([
+    'NotSet',
+    'MachineX86',  # /MACHINE:X86
+    None,
+    'MachineARM',  # /MACHINE:ARM
+    'MachineEBC',  # /MACHINE:EBC
+    'MachineIA64',  # /MACHINE:IA64
+    None,
+    'MachineMIPS',  # /MACHINE:MIPS
+    'MachineMIPS16',  # /MACHINE:MIPS16
+    'MachineMIPSFPU',  # /MACHINE:MIPSFPU
+    'MachineMIPSFPU16',  # /MACHINE:MIPSFPU16
+    None,
+    None,
+    None,
+    'MachineSH4',  # /MACHINE:SH4
+    None,
+    'MachineTHUMB',  # /MACHINE:THUMB
+    'MachineX64'])  # /MACHINE:X64
+
+_Same(_link, 'AssemblyDebug',
+      _Enumeration(['',
+                    'true',  # /ASSEMBLYDEBUG
+                    'false']))  # /ASSEMBLYDEBUG:DISABLE
+_Same(_link, 'CLRImageType',
+      _Enumeration(['Default',
+                    'ForceIJWImage',  # /CLRIMAGETYPE:IJW
+                    'ForcePureILImage',  # /Switch="CLRIMAGETYPE:PURE
+                    'ForceSafeILImage']))  # /Switch="CLRIMAGETYPE:SAFE
+_Same(_link, 'CLRThreadAttribute',
+      _Enumeration(['DefaultThreadingAttribute',  # /CLRTHREADATTRIBUTE:NONE
+                    'MTAThreadingAttribute',  # /CLRTHREADATTRIBUTE:MTA
+                    'STAThreadingAttribute']))  # /CLRTHREADATTRIBUTE:STA
+_Same(_link, 'DataExecutionPrevention',
+      _Enumeration(['',
+                    'false',  # /NXCOMPAT:NO
+                    'true']))  # /NXCOMPAT
+_Same(_link, 'Driver',
+      _Enumeration(['NotSet',
+                    'Driver',  # /Driver
+                    'UpOnly',  # /DRIVER:UPONLY
+                    'WDM']))  # /DRIVER:WDM
+_Same(_link, 'LinkTimeCodeGeneration',
+      _Enumeration(['Default',
+                    'UseLinkTimeCodeGeneration',  # /LTCG
+                    'PGInstrument',  # /LTCG:PGInstrument
+                    'PGOptimization',  # /LTCG:PGOptimize
+                    'PGUpdate']))  # /LTCG:PGUpdate
+_Same(_link, 'ShowProgress',
+      _Enumeration(['NotSet',
+                    'LinkVerbose',  # /VERBOSE
+                    'LinkVerboseLib'],  # /VERBOSE:Lib
+                   new=['LinkVerboseICF',  # /VERBOSE:ICF
+                        'LinkVerboseREF',  # /VERBOSE:REF
+                        'LinkVerboseSAFESEH',  # /VERBOSE:SAFESEH
+                        'LinkVerboseCLR']))  # /VERBOSE:CLR
+_Same(_link, 'SubSystem', _subsystem_enumeration)
+_Same(_link, 'TargetMachine', _target_machine_enumeration)
+_Same(_link, 'UACExecutionLevel',
+      _Enumeration(['AsInvoker',  # /level='asInvoker'
+                    'HighestAvailable',  # /level='highestAvailable'
+                    'RequireAdministrator']))  # /level='requireAdministrator'
+
+
+# Options found in MSVS that have been renamed in MSBuild.
+_Renamed(_link, 'ErrorReporting', 'LinkErrorReporting',
+         _Enumeration(['NoErrorReport',  # /ERRORREPORT:NONE
+                       'PromptImmediately',  # /ERRORREPORT:PROMPT
+                       'QueueForNextLogin'],  # /ERRORREPORT:QUEUE
+                      new=['SendErrorReport']))  # /ERRORREPORT:SEND
+_Renamed(_link, 'IgnoreDefaultLibraryNames', 'IgnoreSpecificDefaultLibraries',
+         _file_list)  # /NODEFAULTLIB
+_Renamed(_link, 'ResourceOnlyDLL', 'NoEntryPoint', _boolean)  # /NOENTRY
+_Renamed(_link, 'SwapRunFromNet', 'SwapRunFromNET', _boolean)  # /SWAPRUN:NET
+
+_Moved(_link, 'GenerateManifest', '', _boolean)
+_Moved(_link, 'IgnoreImportLibrary', '', _boolean)
+_Moved(_link, 'LinkIncremental', '', _newly_boolean)
+_Moved(_link, 'LinkLibraryDependencies', 'ProjectReference', _boolean)
+_Moved(_link, 'UseLibraryDependencyInputs', 'ProjectReference', _boolean)
+
+# MSVS options not found in MSBuild.
+_MSVSOnly(_link, 'OptimizeForWindows98', _newly_boolean)
+_MSVSOnly(_link, 'UseUnicodeResponseFiles', _boolean)
+# TODO(jeanluc) I don't think these are genuine settings but byproducts of Gyp.
+_MSVSOnly(_link, 'AdditionalLibraryDirectories_excluded', _folder_list)
+
+# MSBuild options not found in MSVS.
+_MSBuildOnly(_link, 'BuildingInIDE', _boolean)
+_MSBuildOnly(_link, 'ImageHasSafeExceptionHandlers', _boolean)  # /SAFESEH
+_MSBuildOnly(_link, 'LinkDLL', _boolean)  # /DLL Visible='false'
+_MSBuildOnly(_link, 'LinkStatus', _boolean)  # /LTCG:STATUS
+_MSBuildOnly(_link, 'PreventDllBinding', _boolean)  # /ALLOWBIND
+_MSBuildOnly(_link, 'SupportNobindOfDelayLoadedDLL', _boolean)  # /DELAY:NOBIND
+_MSBuildOnly(_link, 'TrackerLogDirectory', _folder_name)
+_MSBuildOnly(_link, 'TreatLinkerWarningAsErrors', _boolean)  # /WX
+_MSBuildOnly(_link, 'MinimumRequiredVersion', _string)
+_MSBuildOnly(_link, 'MSDOSStubFileName', _file_name)  # /STUB Visible='false'
+_MSBuildOnly(_link, 'SectionAlignment', _integer)  # /ALIGN
+_MSBuildOnly(_link, 'SpecifySectionAttributes', _string)  # /SECTION
+_MSBuildOnly(_link, 'ForceFileOutput',
+             _Enumeration([], new=['Enabled',  # /FORCE
+                                   'MultiplyDefinedSymbolOnly', #/FORCE:MULTIPLE
+                                   'UndefinedSymbolOnly']))  # /FORCE:UNRESOLVED
+_MSBuildOnly(_link, 'CreateHotPatchableImage',
+             _Enumeration([], new=['Enabled',  # /FUNCTIONPADMIN
+                                   'X86Image',  # /FUNCTIONPADMIN:5
+                                   'X64Image',  # /FUNCTIONPADMIN:6
+                                   'ItaniumImage']))  # /FUNCTIONPADMIN:16
+_MSBuildOnly(_link, 'CLRSupportLastError',
+             _Enumeration([], new=['Enabled',  # /CLRSupportLastError
+                                   'Disabled',  # /CLRSupportLastError:NO
+                                   # /CLRSupportLastError:SYSTEMDLL
+                                   'SystemDlls']))
+
+
+# Directives for converting VCResourceCompilerTool to ResourceCompile.
+# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\rc.xml" for
+# the schema of the MSBuild ResourceCompile settings.
+
+_Same(_rc, 'AdditionalOptions', _string_list)
+_Same(_rc, 'AdditionalIncludeDirectories', _folder_list)  # /I
+_Same(_rc, 'Culture', _Integer(msbuild_base=16))
+_Same(_rc, 'IgnoreStandardIncludePath', _boolean)  # /X
+_Same(_rc, 'PreprocessorDefinitions', _string_list)  # /D
+_Same(_rc, 'ResourceOutputFileName', _string)  # /fo
+_Same(_rc, 'ShowProgress', _boolean)  # /v
+# There is no UI in VisualStudio 2008 to set the following properties.
+# However they are found in CL and other tools.  Include them here for
+# completeness, as they are very likely to have the same usage pattern.
+_Same(_rc, 'SuppressStartupBanner', _boolean)  # /nologo
+_Same(_rc, 'UndefinePreprocessorDefinitions', _string_list)  # /u
+
+# MSBuild options not found in MSVS.
+_MSBuildOnly(_rc, 'NullTerminateStrings', _boolean)  # /n
+_MSBuildOnly(_rc, 'TrackerLogDirectory', _folder_name)
+
+
+# Directives for converting VCMIDLTool to Midl.
+# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\midl.xml" for
+# the schema of the MSBuild Midl settings.
+
+_Same(_midl, 'AdditionalIncludeDirectories', _folder_list)  # /I
+_Same(_midl, 'AdditionalOptions', _string_list)
+_Same(_midl, 'CPreprocessOptions', _string)  # /cpp_opt
+_Same(_midl, 'ErrorCheckAllocations', _boolean)  # /error allocation
+_Same(_midl, 'ErrorCheckBounds', _boolean)  # /error bounds_check
+_Same(_midl, 'ErrorCheckEnumRange', _boolean)  # /error enum
+_Same(_midl, 'ErrorCheckRefPointers', _boolean)  # /error ref
+_Same(_midl, 'ErrorCheckStubData', _boolean)  # /error stub_data
+_Same(_midl, 'GenerateStublessProxies', _boolean)  # /Oicf
+_Same(_midl, 'GenerateTypeLibrary', _boolean)
+_Same(_midl, 'HeaderFileName', _file_name)  # /h
+_Same(_midl, 'IgnoreStandardIncludePath', _boolean)  # /no_def_idir
+_Same(_midl, 'InterfaceIdentifierFileName', _file_name)  # /iid
+_Same(_midl, 'MkTypLibCompatible', _boolean)  # /mktyplib203
+_Same(_midl, 'OutputDirectory', _string)  # /out
+_Same(_midl, 'PreprocessorDefinitions', _string_list)  # /D
+_Same(_midl, 'ProxyFileName', _file_name)  # /proxy
+_Same(_midl, 'RedirectOutputAndErrors', _file_name)  # /o
+_Same(_midl, 'SuppressStartupBanner', _boolean)  # /nologo
+_Same(_midl, 'TypeLibraryName', _file_name)  # /tlb
+_Same(_midl, 'UndefinePreprocessorDefinitions', _string_list)  # /U
+_Same(_midl, 'WarnAsError', _boolean)  # /WX
+
+_Same(_midl, 'DefaultCharType',
+      _Enumeration(['Unsigned',  # /char unsigned
+                    'Signed',  # /char signed
+                    'Ascii']))  # /char ascii7
+_Same(_midl, 'TargetEnvironment',
+      _Enumeration(['NotSet',
+                    'Win32',  # /env win32
+                    'Itanium',  # /env ia64
+                    'X64']))  # /env x64
+_Same(_midl, 'EnableErrorChecks',
+      _Enumeration(['EnableCustom',
+                    'None',  # /error none
+                    'All']))  # /error all
+_Same(_midl, 'StructMemberAlignment',
+      _Enumeration(['NotSet',
+                    '1',  # Zp1
+                    '2',  # Zp2
+                    '4',  # Zp4
+                    '8']))  # Zp8
+_Same(_midl, 'WarningLevel',
+      _Enumeration(['0',  # /W0
+                    '1',  # /W1
+                    '2',  # /W2
+                    '3',  # /W3
+                    '4']))  # /W4
+
+_Renamed(_midl, 'DLLDataFileName', 'DllDataFileName', _file_name)  # /dlldata
+_Renamed(_midl, 'ValidateParameters', 'ValidateAllParameters',
+         _boolean)  # /robust
+
+# MSBuild options not found in MSVS.
+_MSBuildOnly(_midl, 'ApplicationConfigurationMode', _boolean)  # /app_config
+_MSBuildOnly(_midl, 'ClientStubFile', _file_name)  # /cstub
+_MSBuildOnly(_midl, 'GenerateClientFiles',
+             _Enumeration([], new=['Stub',  # /client stub
+                                   'None']))  # /client none
+_MSBuildOnly(_midl, 'GenerateServerFiles',
+             _Enumeration([], new=['Stub',  # /client stub
+                                   'None']))  # /client none
+_MSBuildOnly(_midl, 'LocaleID', _integer)  # /lcid DECIMAL
+_MSBuildOnly(_midl, 'ServerStubFile', _file_name)  # /sstub
+_MSBuildOnly(_midl, 'SuppressCompilerWarnings', _boolean)  # /no_warn
+_MSBuildOnly(_midl, 'TrackerLogDirectory', _folder_name)
+_MSBuildOnly(_midl, 'TypeLibFormat',
+             _Enumeration([], new=['NewFormat',  # /newtlb
+                                   'OldFormat']))  # /oldtlb
+
+
+# Directives for converting VCLibrarianTool to Lib.
+# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\lib.xml" for
+# the schema of the MSBuild Lib settings.
+
+_Same(_lib, 'AdditionalDependencies', _file_list)
+_Same(_lib, 'AdditionalLibraryDirectories', _folder_list)  # /LIBPATH
+_Same(_lib, 'AdditionalOptions', _string_list)
+_Same(_lib, 'ExportNamedFunctions', _string_list)  # /EXPORT
+_Same(_lib, 'ForceSymbolReferences', _string)  # /INCLUDE
+_Same(_lib, 'IgnoreAllDefaultLibraries', _boolean)  # /NODEFAULTLIB
+_Same(_lib, 'IgnoreSpecificDefaultLibraries', _file_list)  # /NODEFAULTLIB
+_Same(_lib, 'ModuleDefinitionFile', _file_name)  # /DEF
+_Same(_lib, 'OutputFile', _file_name)  # /OUT
+_Same(_lib, 'SuppressStartupBanner', _boolean)  # /NOLOGO
+_Same(_lib, 'UseUnicodeResponseFiles', _boolean)
+
+# TODO(jeanluc) _link defines the same value that gets moved to
+# ProjectReference.  We may want to validate that they are consistent.
+_Moved(_lib, 'LinkLibraryDependencies', 'ProjectReference', _boolean)
+
+# TODO(jeanluc) I don't think these are genuine settings but byproducts of Gyp.
+_MSVSOnly(_lib, 'AdditionalLibraryDirectories_excluded', _folder_list)
+
+_MSBuildOnly(_lib, 'DisplayLibrary', _string)  # /LIST Visible='false'
+_MSBuildOnly(_lib, 'ErrorReporting',
+             _Enumeration([], new=['PromptImmediately',  # /ERRORREPORT:PROMPT
+                                   'QueueForNextLogin',  # /ERRORREPORT:QUEUE
+                                   'SendErrorReport',  # /ERRORREPORT:SEND
+                                   'NoErrorReport']))  # /ERRORREPORT:NONE
+_MSBuildOnly(_lib, 'LinkTimeCodeGeneration', _boolean)  # /LTCG
+_MSBuildOnly(_lib, 'MinimumRequiredVersion', _string)
+_MSBuildOnly(_lib, 'Name', _file_name)  # /NAME
+_MSBuildOnly(_lib, 'RemoveObjects', _file_list)  # /REMOVE
+_MSBuildOnly(_lib, 'SubSystem', _subsystem_enumeration)
+_MSBuildOnly(_lib, 'TargetMachine', _target_machine_enumeration)
+_MSBuildOnly(_lib, 'TrackerLogDirectory', _folder_name)
+_MSBuildOnly(_lib, 'TreatLibWarningAsErrors', _boolean)  # /WX
+_MSBuildOnly(_lib, 'Verbose', _boolean)
+
+
+# Directives for converting VCManifestTool to Mt.
+# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\mt.xml" for
+# the schema of the MSBuild Lib settings.
+
+# Options that have the same name in MSVS and MSBuild
+_Same(_manifest, 'AdditionalManifestFiles', _file_list)  # /manifest
+_Same(_manifest, 'AdditionalOptions', _string_list)
+_Same(_manifest, 'AssemblyIdentity', _string)  # /identity:
+_Same(_manifest, 'ComponentFileName', _file_name)  # /dll
+_Same(_manifest, 'GenerateCatalogFiles', _boolean)  # /makecdfs
+_Same(_manifest, 'InputResourceManifests', _string)  # /inputresource
+_Same(_manifest, 'OutputManifestFile', _file_name)  # /out
+_Same(_manifest, 'RegistrarScriptFile', _file_name)  # /rgs
+_Same(_manifest, 'ReplacementsFile', _file_name)  # /replacements
+_Same(_manifest, 'SuppressStartupBanner', _boolean)  # /nologo
+_Same(_manifest, 'TypeLibraryFile', _file_name)  # /tlb:
+_Same(_manifest, 'UpdateFileHashes', _boolean)  # /hashupdate
+_Same(_manifest, 'UpdateFileHashesSearchPath', _file_name)
+_Same(_manifest, 'VerboseOutput', _boolean)  # /verbose
+
+# Options that have moved location.
+_MovedAndRenamed(_manifest, 'ManifestResourceFile',
+                 'ManifestResourceCompile',
+                 'ResourceOutputFileName',
+                 _file_name)
+_Moved(_manifest, 'EmbedManifest', '', _boolean)
+
+# MSVS options not found in MSBuild.
+_MSVSOnly(_manifest, 'DependencyInformationFile', _file_name)
+_MSVSOnly(_manifest, 'UseFAT32Workaround', _boolean)
+_MSVSOnly(_manifest, 'UseUnicodeResponseFiles', _boolean)
+
+# MSBuild options not found in MSVS.
+_MSBuildOnly(_manifest, 'EnableDPIAwareness', _boolean)
+_MSBuildOnly(_manifest, 'GenerateCategoryTags', _boolean)  # /category
+_MSBuildOnly(_manifest, 'ManifestFromManagedAssembly',
+             _file_name)  # /managedassemblyname
+_MSBuildOnly(_manifest, 'OutputResourceManifests', _string)  # /outputresource
+_MSBuildOnly(_manifest, 'SuppressDependencyElement', _boolean)  # /nodependency
+_MSBuildOnly(_manifest, 'TrackerLogDirectory', _folder_name)
+
diff --git a/Source/ThirdParty/gyp/pylib/gyp/MSVSSettings_test.py b/Source/ThirdParty/gyp/pylib/gyp/MSVSSettings_test.py
new file mode 100644 (file)
index 0000000..c9ca7fd
--- /dev/null
@@ -0,0 +1,1478 @@
+#!/usr/bin/python
+
+# Copyright (c) 2011 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+""" Unit tests for the MSVSSettings.py file. """
+
+import sys
+import unittest
+import MSVSSettings
+import StringIO
+
+
+class TestSequenceFunctions(unittest.TestCase):
+
+  def setUp(self):
+    self.stderr = StringIO.StringIO()
+
+  def _ExpectedWarnings(self, expected):
+    """ Compares recorded lines to expected warnings. """
+    self.stderr.seek(0)
+    actual = self.stderr.read().split('\n')
+    actual = [line for line in actual if line != '']
+    self.assertEqual(sorted(expected), sorted(actual))
+
+  def test_ValidateMSVSSettings_tool_names(self):
+    """ Tests that only MSVS tool names are allowed. """
+    MSVSSettings.ValidateMSVSSettings({
+        'VCCLCompilerTool': {},
+        'VCLinkerTool': {},
+        'VCMIDLTool': {},
+        'foo': {},
+        'VCResourceCompilerTool': {},
+        'VCLibrarianTool': {},
+        'VCManifestTool': {},
+        'ClCompile': {}},
+        self.stderr)
+    self._ExpectedWarnings([
+        'Warning: unrecognized tool foo',
+        'Warning: unrecognized tool ClCompile'])
+
+  def test_ValidateMSVSSettings_settings(self):
+    """ Tests that for invalid MSVS settings. """
+    MSVSSettings.ValidateMSVSSettings({
+        'VCCLCompilerTool': {
+            'AdditionalIncludeDirectories': 'folder1;folder2',
+            'AdditionalOptions': ['string1', 'string2'],
+            'AdditionalUsingDirectories': 'folder1;folder2',
+            'AssemblerListingLocation': 'a_file_name',
+            'AssemblerOutput': '0',
+            'BasicRuntimeChecks': '5',
+            'BrowseInformation': 'fdkslj',
+            'BrowseInformationFile': 'a_file_name',
+            'BufferSecurityCheck': 'true',
+            'CallingConvention': '-1',
+            'CompileAs': '1',
+            'DebugInformationFormat': '2',
+            'DefaultCharIsUnsigned': 'true',
+            'Detect64BitPortabilityProblems': 'true',
+            'DisableLanguageExtensions': 'true',
+            'DisableSpecificWarnings': 'string1;string2',
+            'EnableEnhancedInstructionSet': '1',
+            'EnableFiberSafeOptimizations': 'true',
+            'EnableFunctionLevelLinking': 'true',
+            'EnableIntrinsicFunctions': 'true',
+            'EnablePREfast': 'true',
+            'Enableprefast': 'bogus',
+            'ErrorReporting': '1',
+            'ExceptionHandling': '1',
+            'ExpandAttributedSource': 'true',
+            'FavorSizeOrSpeed': '1',
+            'FloatingPointExceptions': 'true',
+            'FloatingPointModel': '1',
+            'ForceConformanceInForLoopScope': 'true',
+            'ForcedIncludeFiles': 'file1;file2',
+            'ForcedUsingFiles': 'file1;file2',
+            'GeneratePreprocessedFile': '1',
+            'GenerateXMLDocumentationFiles': 'true',
+            'IgnoreStandardIncludePath': 'true',
+            'InlineFunctionExpansion': '1',
+            'KeepComments': 'true',
+            'MinimalRebuild': 'true',
+            'ObjectFile': 'a_file_name',
+            'OmitDefaultLibName': 'true',
+            'OmitFramePointers': 'true',
+            'OpenMP': 'true',
+            'Optimization': '1',
+            'PrecompiledHeaderFile': 'a_file_name',
+            'PrecompiledHeaderThrough': 'a_file_name',
+            'PreprocessorDefinitions': 'string1;string2',
+            'ProgramDataBaseFileName': 'a_file_name',
+            'RuntimeLibrary': '1',
+            'RuntimeTypeInfo': 'true',
+            'ShowIncludes': 'true',
+            'SmallerTypeCheck': 'true',
+            'StringPooling': 'true',
+            'StructMemberAlignment': '1',
+            'SuppressStartupBanner': 'true',
+            'TreatWChar_tAsBuiltInType': 'true',
+            'UndefineAllPreprocessorDefinitions': 'true',
+            'UndefinePreprocessorDefinitions': 'string1;string2',
+            'UseFullPaths': 'true',
+            'UsePrecompiledHeader': '1',
+            'UseUnicodeResponseFiles': 'true',
+            'WarnAsError': 'true',
+            'WarningLevel': '1',
+            'WholeProgramOptimization': 'true',
+            'XMLDocumentationFileName': 'a_file_name',
+            'ZZXYZ': 'bogus'},
+        'VCLinkerTool': {
+            'AdditionalDependencies': 'file1;file2',
+            'AdditionalLibraryDirectories': 'folder1;folder2',
+            'AdditionalManifestDependencies': 'file1;file2',
+            'AdditionalOptions': 'a string1',
+            'AddModuleNamesToAssembly': 'file1;file2',
+            'AllowIsolation': 'true',
+            'AssemblyDebug': '2',
+            'AssemblyLinkResource': 'file1;file2',
+            'BaseAddress': 'a string1',
+            'CLRImageType': '2',
+            'CLRThreadAttribute': '2',
+            'CLRUnmanagedCodeCheck': 'true',
+            'DataExecutionPrevention': '2',
+            'DelayLoadDLLs': 'file1;file2',
+            'DelaySign': 'true',
+            'Driver': '2',
+            'EmbedManagedResourceFile': 'file1;file2',
+            'EnableCOMDATFolding': '2',
+            'EnableUAC': 'true',
+            'EntryPointSymbol': 'a string1',
+            'ErrorReporting': '2',
+            'FixedBaseAddress': '2',
+            'ForceSymbolReferences': 'file1;file2',
+            'FunctionOrder': 'a_file_name',
+            'GenerateDebugInformation': 'true',
+            'GenerateManifest': 'true',
+            'GenerateMapFile': 'true',
+            'HeapCommitSize': 'a string1',
+            'HeapReserveSize': 'a string1',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreDefaultLibraryNames': 'file1;file2',
+            'IgnoreEmbeddedIDL': 'true',
+            'IgnoreImportLibrary': 'true',
+            'ImportLibrary': 'a_file_name',
+            'KeyContainer': 'a_file_name',
+            'KeyFile': 'a_file_name',
+            'LargeAddressAware': '2',
+            'LinkIncremental': '2',
+            'LinkLibraryDependencies': 'true',
+            'LinkTimeCodeGeneration': '2',
+            'ManifestFile': 'a_file_name',
+            'MapExports': 'true',
+            'MapFileName': 'a_file_name',
+            'MergedIDLBaseFileName': 'a_file_name',
+            'MergeSections': 'a string1',
+            'MidlCommandFile': 'a_file_name',
+            'ModuleDefinitionFile': 'a_file_name',
+            'OptimizeForWindows98': '1',
+            'OptimizeReferences': '2',
+            'OutputFile': 'a_file_name',
+            'PerUserRedirection': 'true',
+            'Profile': 'true',
+            'ProfileGuidedDatabase': 'a_file_name',
+            'ProgramDatabaseFile': 'a_file_name',
+            'RandomizedBaseAddress': '2',
+            'RegisterOutput': 'true',
+            'ResourceOnlyDLL': 'true',
+            'SetChecksum': 'true',
+            'ShowProgress': '2',
+            'StackCommitSize': 'a string1',
+            'StackReserveSize': 'a string1',
+            'StripPrivateSymbols': 'a_file_name',
+            'SubSystem': '2',
+            'SupportUnloadOfDelayLoadedDLL': 'true',
+            'SuppressStartupBanner': 'true',
+            'SwapRunFromCD': 'true',
+            'SwapRunFromNet': 'true',
+            'TargetMachine': '2',
+            'TerminalServerAware': '2',
+            'TurnOffAssemblyGeneration': 'true',
+            'TypeLibraryFile': 'a_file_name',
+            'TypeLibraryResourceID': '33',
+            'UACExecutionLevel': '2',
+            'UACUIAccess': 'true',
+            'UseLibraryDependencyInputs': 'true',
+            'UseUnicodeResponseFiles': 'true',
+            'Version': 'a string1'},
+        'VCMIDLTool': {
+            'AdditionalIncludeDirectories': 'folder1;folder2',
+            'AdditionalOptions': 'a string1',
+            'CPreprocessOptions': 'a string1',
+            'DefaultCharType': '1',
+            'DLLDataFileName': 'a_file_name',
+            'EnableErrorChecks': '1',
+            'ErrorCheckAllocations': 'true',
+            'ErrorCheckBounds': 'true',
+            'ErrorCheckEnumRange': 'true',
+            'ErrorCheckRefPointers': 'true',
+            'ErrorCheckStubData': 'true',
+            'GenerateStublessProxies': 'true',
+            'GenerateTypeLibrary': 'true',
+            'HeaderFileName': 'a_file_name',
+            'IgnoreStandardIncludePath': 'true',
+            'InterfaceIdentifierFileName': 'a_file_name',
+            'MkTypLibCompatible': 'true',
+            'notgood': 'bogus',
+            'OutputDirectory': 'a string1',
+            'PreprocessorDefinitions': 'string1;string2',
+            'ProxyFileName': 'a_file_name',
+            'RedirectOutputAndErrors': 'a_file_name',
+            'StructMemberAlignment': '1',
+            'SuppressStartupBanner': 'true',
+            'TargetEnvironment': '1',
+            'TypeLibraryName': 'a_file_name',
+            'UndefinePreprocessorDefinitions': 'string1;string2',
+            'ValidateParameters': 'true',
+            'WarnAsError': 'true',
+            'WarningLevel': '1'},
+        'VCResourceCompilerTool': {
+            'AdditionalOptions': 'a string1',
+            'AdditionalIncludeDirectories': 'folder1;folder2',
+            'Culture': '1003',
+            'IgnoreStandardIncludePath': 'true',
+            'notgood2': 'bogus',
+            'PreprocessorDefinitions': 'string1;string2',
+            'ResourceOutputFileName': 'a string1',
+            'ShowProgress': 'true',
+            'SuppressStartupBanner': 'true',
+            'UndefinePreprocessorDefinitions': 'string1;string2'},
+        'VCLibrarianTool': {
+            'AdditionalDependencies': 'file1;file2',
+            'AdditionalLibraryDirectories': 'folder1;folder2',
+            'AdditionalOptions': 'a string1',
+            'ExportNamedFunctions': 'string1;string2',
+            'ForceSymbolReferences': 'a string1',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreSpecificDefaultLibraries': 'file1;file2',
+            'LinkLibraryDependencies': 'true',
+            'ModuleDefinitionFile': 'a_file_name',
+            'OutputFile': 'a_file_name',
+            'SuppressStartupBanner': 'true',
+            'UseUnicodeResponseFiles': 'true'},
+        'VCManifestTool': {
+            'AdditionalManifestFiles': 'file1;file2',
+            'AdditionalOptions': 'a string1',
+            'AssemblyIdentity': 'a string1',
+            'ComponentFileName': 'a_file_name',
+            'DependencyInformationFile': 'a_file_name',
+            'GenerateCatalogFiles': 'true',
+            'InputResourceManifests': 'a string1',
+            'ManifestResourceFile': 'a_file_name',
+            'OutputManifestFile': 'a_file_name',
+            'RegistrarScriptFile': 'a_file_name',
+            'ReplacementsFile': 'a_file_name',
+            'SuppressStartupBanner': 'true',
+            'TypeLibraryFile': 'a_file_name',
+            'UpdateFileHashes': 'truel',
+            'UpdateFileHashesSearchPath': 'a_file_name',
+            'UseFAT32Workaround': 'true',
+            'UseUnicodeResponseFiles': 'true',
+            'VerboseOutput': 'true'}},
+        self.stderr)
+    self._ExpectedWarnings([
+        'Warning: unrecognized value "5" for VCCLCompilerTool/'
+            'BasicRuntimeChecks',
+        'Warning: unrecognized value "fdkslj" for VCCLCompilerTool/'
+            'BrowseInformation',
+        'Warning: unrecognized value "-1" for VCCLCompilerTool/'
+            'CallingConvention',
+        'Warning: unrecognized value "2" for VCCLCompilerTool/'
+            'DebugInformationFormat',
+        'Warning: unrecognized setting VCCLCompilerTool/Enableprefast',
+        'Warning: unrecognized setting VCCLCompilerTool/ZZXYZ',
+        'Warning: unrecognized value "2" for VCLinkerTool/TargetMachine',
+        'Warning: unrecognized setting VCMIDLTool/notgood',
+        'Warning: unrecognized setting VCResourceCompilerTool/notgood2',
+        'Warning: unrecognized value "truel" for VCManifestTool/'
+            'UpdateFileHashes'])
+
+  def test_ValidateMSBuildSettings_settings(self):
+    """ Tests that for invalid MSBuild settings. """
+    MSVSSettings.ValidateMSBuildSettings({
+        'ClCompile': {
+            'AdditionalIncludeDirectories': 'folder1;folder2',
+            'AdditionalOptions': ['string1', 'string2'],
+            'AdditionalUsingDirectories': 'folder1;folder2',
+            'AssemblerListingLocation': 'a_file_name',
+            'AssemblerOutput': 'NoListing',
+            'BasicRuntimeChecks': 'StackFrameRuntimeCheck',
+            'BrowseInformation': 'false',
+            'BrowseInformationFile': 'a_file_name',
+            'BufferSecurityCheck': 'true',
+            'BuildingInIDE': 'true',
+            'CallingConvention': 'Cdecl',
+            'CompileAs': 'CompileAsC',
+            'CompileAsManaged': 'Pure',
+            'CreateHotpatchableImage': 'true',
+            'DebugInformationFormat': 'ProgramDatabase',
+            'DisableLanguageExtensions': 'true',
+            'DisableSpecificWarnings': 'string1;string2',
+            'EnableEnhancedInstructionSet': 'StreamingSIMDExtensions',
+            'EnableFiberSafeOptimizations': 'true',
+            'EnablePREfast': 'true',
+            'Enableprefast': 'bogus',
+            'ErrorReporting': 'Prompt',
+            'ExceptionHandling': 'SyncCThrow',
+            'ExpandAttributedSource': 'true',
+            'FavorSizeOrSpeed': 'Neither',
+            'FloatingPointExceptions': 'true',
+            'FloatingPointModel': 'Precise',
+            'ForceConformanceInForLoopScope': 'true',
+            'ForcedIncludeFiles': 'file1;file2',
+            'ForcedUsingFiles': 'file1;file2',
+            'FunctionLevelLinking': 'false',
+            'GenerateXMLDocumentationFiles': 'true',
+            'IgnoreStandardIncludePath': 'true',
+            'InlineFunctionExpansion': 'OnlyExplicitInline',
+            'IntrinsicFunctions': 'false',
+            'MinimalRebuild': 'true',
+            'MultiProcessorCompilation': 'true',
+            'ObjectFileName': 'a_file_name',
+            'OmitDefaultLibName': 'true',
+            'OmitFramePointers': 'true',
+            'OpenMPSupport': 'true',
+            'Optimization': 'Disabled',
+            'PrecompiledHeader': 'NotUsing',
+            'PrecompiledHeaderFile': 'a_file_name',
+            'PrecompiledHeaderOutputFile': 'a_file_name',
+            'PreprocessKeepComments': 'true',
+            'PreprocessorDefinitions': 'string1;string2',
+            'PreprocessOutputPath': 'a string1',
+            'PreprocessSuppressLineNumbers': 'false',
+            'PreprocessToFile': 'false',
+            'ProcessorNumber': '33',
+            'ProgramDataBaseFileName': 'a_file_name',
+            'RuntimeLibrary': 'MultiThreaded',
+            'RuntimeTypeInfo': 'true',
+            'ShowIncludes': 'true',
+            'SmallerTypeCheck': 'true',
+            'StringPooling': 'true',
+            'StructMemberAlignment': '1Byte',
+            'SuppressStartupBanner': 'true',
+            'TrackerLogDirectory': 'a_folder',
+            'TreatSpecificWarningsAsErrors': 'string1;string2',
+            'TreatWarningAsError': 'true',
+            'TreatWChar_tAsBuiltInType': 'true',
+            'UndefineAllPreprocessorDefinitions': 'true',
+            'UndefinePreprocessorDefinitions': 'string1;string2',
+            'UseFullPaths': 'true',
+            'UseUnicodeForAssemblerListing': 'true',
+            'WarningLevel': 'TurnOffAllWarnings',
+            'WholeProgramOptimization': 'true',
+            'XMLDocumentationFileName': 'a_file_name',
+            'ZZXYZ': 'bogus'},
+        'Link': {
+            'AdditionalDependencies': 'file1;file2',
+            'AdditionalLibraryDirectories': 'folder1;folder2',
+            'AdditionalManifestDependencies': 'file1;file2',
+            'AdditionalOptions': 'a string1',
+            'AddModuleNamesToAssembly': 'file1;file2',
+            'AllowIsolation': 'true',
+            'AssemblyDebug': '',
+            'AssemblyLinkResource': 'file1;file2',
+            'BaseAddress': 'a string1',
+            'BuildingInIDE': 'true',
+            'CLRImageType': 'ForceIJWImage',
+            'CLRSupportLastError': 'Enabled',
+            'CLRThreadAttribute': 'MTAThreadingAttribute',
+            'CLRUnmanagedCodeCheck': 'true',
+            'CreateHotPatchableImage': 'X86Image',
+            'DataExecutionPrevention': 'false',
+            'DelayLoadDLLs': 'file1;file2',
+            'DelaySign': 'true',
+            'Driver': 'NotSet',
+            'EmbedManagedResourceFile': 'file1;file2',
+            'EnableCOMDATFolding': 'false',
+            'EnableUAC': 'true',
+            'EntryPointSymbol': 'a string1',
+            'FixedBaseAddress': 'false',
+            'ForceFileOutput': 'Enabled',
+            'ForceSymbolReferences': 'file1;file2',
+            'FunctionOrder': 'a_file_name',
+            'GenerateDebugInformation': 'true',
+            'GenerateMapFile': 'true',
+            'HeapCommitSize': 'a string1',
+            'HeapReserveSize': 'a string1',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreEmbeddedIDL': 'true',
+            'IgnoreSpecificDefaultLibraries': 'a_file_list',
+            'ImageHasSafeExceptionHandlers': 'true',
+            'ImportLibrary': 'a_file_name',
+            'KeyContainer': 'a_file_name',
+            'KeyFile': 'a_file_name',
+            'LargeAddressAware': 'false',
+            'LinkDLL': 'true',
+            'LinkErrorReporting': 'SendErrorReport',
+            'LinkStatus': 'true',
+            'LinkTimeCodeGeneration': 'UseLinkTimeCodeGeneration',
+            'ManifestFile': 'a_file_name',
+            'MapExports': 'true',
+            'MapFileName': 'a_file_name',
+            'MergedIDLBaseFileName': 'a_file_name',
+            'MergeSections': 'a string1',
+            'MidlCommandFile': 'a_file_name',
+            'MinimumRequiredVersion': 'a string1',
+            'ModuleDefinitionFile': 'a_file_name',
+            'MSDOSStubFileName': 'a_file_name',
+            'NoEntryPoint': 'true',
+            'OptimizeReferences': 'false',
+            'OutputFile': 'a_file_name',
+            'PerUserRedirection': 'true',
+            'PreventDllBinding': 'true',
+            'Profile': 'true',
+            'ProfileGuidedDatabase': 'a_file_name',
+            'ProgramDatabaseFile': 'a_file_name',
+            'RandomizedBaseAddress': 'false',
+            'RegisterOutput': 'true',
+            'SectionAlignment': '33',
+            'SetChecksum': 'true',
+            'ShowProgress': 'LinkVerboseREF',
+            'SpecifySectionAttributes': 'a string1',
+            'StackCommitSize': 'a string1',
+            'StackReserveSize': 'a string1',
+            'StripPrivateSymbols': 'a_file_name',
+            'SubSystem': 'Console',
+            'SupportNobindOfDelayLoadedDLL': 'true',
+            'SupportUnloadOfDelayLoadedDLL': 'true',
+            'SuppressStartupBanner': 'true',
+            'SwapRunFromCD': 'true',
+            'SwapRunFromNET': 'true',
+            'TargetMachine': 'MachineX86',
+            'TerminalServerAware': 'false',
+            'TrackerLogDirectory': 'a_folder',
+            'TreatLinkerWarningAsErrors': 'true',
+            'TurnOffAssemblyGeneration': 'true',
+            'TypeLibraryFile': 'a_file_name',
+            'TypeLibraryResourceID': '33',
+            'UACExecutionLevel': 'AsInvoker',
+            'UACUIAccess': 'true',
+            'Version': 'a string1'},
+        'ResourceCompile': {
+            'AdditionalIncludeDirectories': 'folder1;folder2',
+            'AdditionalOptions': 'a string1',
+            'Culture': '0x236',
+            'IgnoreStandardIncludePath': 'true',
+            'NullTerminateStrings': 'true',
+            'PreprocessorDefinitions': 'string1;string2',
+            'ResourceOutputFileName': 'a string1',
+            'ShowProgress': 'true',
+            'SuppressStartupBanner': 'true',
+            'TrackerLogDirectory': 'a_folder',
+            'UndefinePreprocessorDefinitions': 'string1;string2'},
+        'Midl': {
+            'AdditionalIncludeDirectories': 'folder1;folder2',
+            'AdditionalOptions': 'a string1',
+            'ApplicationConfigurationMode': 'true',
+            'ClientStubFile': 'a_file_name',
+            'CPreprocessOptions': 'a string1',
+            'DefaultCharType': 'Signed',
+            'DllDataFileName': 'a_file_name',
+            'EnableErrorChecks': 'EnableCustom',
+            'ErrorCheckAllocations': 'true',
+            'ErrorCheckBounds': 'true',
+            'ErrorCheckEnumRange': 'true',
+            'ErrorCheckRefPointers': 'true',
+            'ErrorCheckStubData': 'true',
+            'GenerateClientFiles': 'Stub',
+            'GenerateServerFiles': 'None',
+            'GenerateStublessProxies': 'true',
+            'GenerateTypeLibrary': 'true',
+            'HeaderFileName': 'a_file_name',
+            'IgnoreStandardIncludePath': 'true',
+            'InterfaceIdentifierFileName': 'a_file_name',
+            'LocaleID': '33',
+            'MkTypLibCompatible': 'true',
+            'OutputDirectory': 'a string1',
+            'PreprocessorDefinitions': 'string1;string2',
+            'ProxyFileName': 'a_file_name',
+            'RedirectOutputAndErrors': 'a_file_name',
+            'ServerStubFile': 'a_file_name',
+            'StructMemberAlignment': 'NotSet',
+            'SuppressCompilerWarnings': 'true',
+            'SuppressStartupBanner': 'true',
+            'TargetEnvironment': 'Itanium',
+            'TrackerLogDirectory': 'a_folder',
+            'TypeLibFormat': 'NewFormat',
+            'TypeLibraryName': 'a_file_name',
+            'UndefinePreprocessorDefinitions': 'string1;string2',
+            'ValidateAllParameters': 'true',
+            'WarnAsError': 'true',
+            'WarningLevel': '1'},
+        'Lib': {
+            'AdditionalDependencies': 'file1;file2',
+            'AdditionalLibraryDirectories': 'folder1;folder2',
+            'AdditionalOptions': 'a string1',
+            'DisplayLibrary': 'a string1',
+            'ErrorReporting': 'PromptImmediately',
+            'ExportNamedFunctions': 'string1;string2',
+            'ForceSymbolReferences': 'a string1',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreSpecificDefaultLibraries': 'file1;file2',
+            'LinkTimeCodeGeneration': 'true',
+            'MinimumRequiredVersion': 'a string1',
+            'ModuleDefinitionFile': 'a_file_name',
+            'Name': 'a_file_name',
+            'OutputFile': 'a_file_name',
+            'RemoveObjects': 'file1;file2',
+            'SubSystem': 'Console',
+            'SuppressStartupBanner': 'true',
+            'TargetMachine': 'MachineX86i',
+            'TrackerLogDirectory': 'a_folder',
+            'TreatLibWarningAsErrors': 'true',
+            'UseUnicodeResponseFiles': 'true',
+            'Verbose': 'true'},
+        'Mt': {
+            'AdditionalManifestFiles': 'file1;file2',
+            'AdditionalOptions': 'a string1',
+            'AssemblyIdentity': 'a string1',
+            'ComponentFileName': 'a_file_name',
+            'EnableDPIAwareness': 'fal',
+            'GenerateCatalogFiles': 'truel',
+            'GenerateCategoryTags': 'true',
+            'InputResourceManifests': 'a string1',
+            'ManifestFromManagedAssembly': 'a_file_name',
+            'notgood3': 'bogus',
+            'OutputManifestFile': 'a_file_name',
+            'OutputResourceManifests': 'a string1',
+            'RegistrarScriptFile': 'a_file_name',
+            'ReplacementsFile': 'a_file_name',
+            'SuppressDependencyElement': 'true',
+            'SuppressStartupBanner': 'true',
+            'TrackerLogDirectory': 'a_folder',
+            'TypeLibraryFile': 'a_file_name',
+            'UpdateFileHashes': 'true',
+            'UpdateFileHashesSearchPath': 'a_file_name',
+            'VerboseOutput': 'true'},
+        'ProjectReference': {
+            'LinkLibraryDependencies': 'true',
+            'UseLibraryDependencyInputs': 'true'},
+        'ManifestResourceCompile': {
+            'ResourceOutputFileName': 'a_file_name'},
+        '': {
+            'EmbedManifest': 'true',
+            'GenerateManifest': 'true',
+            'IgnoreImportLibrary': 'true',
+            'LinkIncremental': 'false'}},
+        self.stderr)
+    self._ExpectedWarnings([
+        'Warning: unrecognized setting ClCompile/Enableprefast',
+        'Warning: unrecognized setting ClCompile/ZZXYZ',
+        'Warning: unrecognized setting Mt/notgood3',
+        'Warning: unrecognized value "truel" for Mt/GenerateCatalogFiles',
+        'Warning: unrecognized value "MachineX86i" for Lib/TargetMachine',
+        'Warning: unrecognized value "fal" for Mt/EnableDPIAwareness'])
+
+  def test_ConvertToMsBuildSettings_empty(self):
+    """ Tests an empty conversion. """
+    msvs_settings = {}
+    expected_msbuild_settings = {}
+    actual_msbuild_settings = MSVSSettings.ConvertToMsBuildSettings(
+        msvs_settings,
+        self.stderr)
+    self.assertEqual(expected_msbuild_settings, actual_msbuild_settings)
+    self._ExpectedWarnings([])
+
+  def test_ConvertToMsBuildSettings_minimal(self):
+    """ Tests a minimal conversion. """
+    msvs_settings = {
+        'VCCLCompilerTool': {
+            'AdditionalIncludeDirectories': 'dir1',
+            'AdditionalOptions': '/foo',
+            'BasicRuntimeChecks': '0',
+            },
+        'VCLinkerTool': {
+            'LinkTimeCodeGeneration': '1',
+            'ErrorReporting': '1',
+            'DataExecutionPrevention': '2',
+            },
+        }
+    expected_msbuild_settings = {
+        'ClCompile': {
+            'AdditionalIncludeDirectories': 'dir1',
+            'AdditionalOptions': '/foo',
+            'BasicRuntimeChecks': 'Default',
+            },
+        'Link': {
+            'LinkTimeCodeGeneration': 'UseLinkTimeCodeGeneration',
+            'LinkErrorReporting': 'PromptImmediately',
+            'DataExecutionPrevention': 'true',
+            },
+        }
+    actual_msbuild_settings = MSVSSettings.ConvertToMsBuildSettings(
+        msvs_settings,
+        self.stderr)
+    self.assertEqual(expected_msbuild_settings, actual_msbuild_settings)
+    self._ExpectedWarnings([])
+
+  def test_ConvertToMsBuildSettings_warnings(self):
+    """ Tests conversion that generates warnings. """
+    msvs_settings = {
+        'VCCLCompilerTool': {
+            'AdditionalIncludeDirectories': '1',
+            'AdditionalOptions': '2',
+            # These are incorrect values:
+            'BasicRuntimeChecks': '12',
+            'BrowseInformation': '21',
+            'UsePrecompiledHeader': '13',
+            'GeneratePreprocessedFile': '14'},
+        'VCLinkerTool': {
+            # These are incorrect values:
+            'Driver': '10',
+            'LinkTimeCodeGeneration': '31',
+            'ErrorReporting': '21',
+            'FixedBaseAddress': '6'},
+        'VCResourceCompilerTool': {
+            # Custom
+            'Culture': '1003'}}
+    expected_msbuild_settings = {
+        'ClCompile': {
+            'AdditionalIncludeDirectories': '1',
+            'AdditionalOptions': '2'},
+        'Link': {},
+        'ResourceCompile': {
+            # Custom
+            'Culture': '0x03eb'}}
+    actual_msbuild_settings = MSVSSettings.ConvertToMsBuildSettings(
+        msvs_settings,
+        self.stderr)
+    self.assertEqual(expected_msbuild_settings, actual_msbuild_settings)
+    self._ExpectedWarnings([
+        'Warning: unrecognized value "12" for VCCLCompilerTool/'
+            'BasicRuntimeChecks while converting to MSBuild.',
+        'Warning: unrecognized value "21" for VCCLCompilerTool/'
+            'BrowseInformation while converting to MSBuild.',
+        'Warning: unrecognized value "13" for VCCLCompilerTool/'
+            'UsePrecompiledHeader while converting to MSBuild.',
+        'Warning: unrecognized value "14" for VCCLCompilerTool/'
+            'GeneratePreprocessedFile while converting to MSBuild.',
+
+        'Warning: unrecognized value "10" for VCLinkerTool/'
+            'Driver while converting to MSBuild.',
+        'Warning: unrecognized value "31" for VCLinkerTool/'
+            'LinkTimeCodeGeneration while converting to MSBuild.',
+        'Warning: unrecognized value "21" for VCLinkerTool/'
+            'ErrorReporting while converting to MSBuild.',
+        'Warning: unrecognized value "6" for VCLinkerTool/'
+            'FixedBaseAddress while converting to MSBuild.',
+        ])
+
+  def test_ConvertToMsBuildSettings_full_synthetic(self):
+    """ Tests conversion of all the MsBuild settings. """
+    msvs_settings = {
+        'VCCLCompilerTool': {
+            'AdditionalIncludeDirectories': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string',
+            'AdditionalUsingDirectories': 'folder1;folder2;folder3',
+            'AssemblerListingLocation': 'a_file_name',
+            'AssemblerOutput': '0',
+            'BasicRuntimeChecks': '1',
+            'BrowseInformation': '2',
+            'BrowseInformationFile': 'a_file_name',
+            'BufferSecurityCheck': 'true',
+            'CallingConvention': '0',
+            'CompileAs': '1',
+            'DebugInformationFormat': '4',
+            'DefaultCharIsUnsigned': 'true',
+            'Detect64BitPortabilityProblems': 'true',
+            'DisableLanguageExtensions': 'true',
+            'DisableSpecificWarnings': 'd1;d2;d3',
+            'EnableEnhancedInstructionSet': '0',
+            'EnableFiberSafeOptimizations': 'true',
+            'EnableFunctionLevelLinking': 'true',
+            'EnableIntrinsicFunctions': 'true',
+            'EnablePREfast': 'true',
+            'ErrorReporting': '1',
+            'ExceptionHandling': '2',
+            'ExpandAttributedSource': 'true',
+            'FavorSizeOrSpeed': '0',
+            'FloatingPointExceptions': 'true',
+            'FloatingPointModel': '1',
+            'ForceConformanceInForLoopScope': 'true',
+            'ForcedIncludeFiles': 'file1;file2;file3',
+            'ForcedUsingFiles': 'file1;file2;file3',
+            'GeneratePreprocessedFile': '1',
+            'GenerateXMLDocumentationFiles': 'true',
+            'IgnoreStandardIncludePath': 'true',
+            'InlineFunctionExpansion': '2',
+            'KeepComments': 'true',
+            'MinimalRebuild': 'true',
+            'ObjectFile': 'a_file_name',
+            'OmitDefaultLibName': 'true',
+            'OmitFramePointers': 'true',
+            'OpenMP': 'true',
+            'Optimization': '3',
+            'PrecompiledHeaderFile': 'a_file_name',
+            'PrecompiledHeaderThrough': 'a_file_name',
+            'PreprocessorDefinitions': 'd1;d2;d3',
+            'ProgramDataBaseFileName': 'a_file_name',
+            'RuntimeLibrary': '0',
+            'RuntimeTypeInfo': 'true',
+            'ShowIncludes': 'true',
+            'SmallerTypeCheck': 'true',
+            'StringPooling': 'true',
+            'StructMemberAlignment': '1',
+            'SuppressStartupBanner': 'true',
+            'TreatWChar_tAsBuiltInType': 'true',
+            'UndefineAllPreprocessorDefinitions': 'true',
+            'UndefinePreprocessorDefinitions': 'd1;d2;d3',
+            'UseFullPaths': 'true',
+            'UsePrecompiledHeader': '1',
+            'UseUnicodeResponseFiles': 'true',
+            'WarnAsError': 'true',
+            'WarningLevel': '2',
+            'WholeProgramOptimization': 'true',
+            'XMLDocumentationFileName': 'a_file_name'},
+        'VCLinkerTool': {
+            'AdditionalDependencies': 'file1;file2;file3',
+            'AdditionalLibraryDirectories': 'folder1;folder2;folder3',
+            'AdditionalLibraryDirectories_excluded': 'folder1;folder2;folder3',
+            'AdditionalManifestDependencies': 'file1;file2;file3',
+            'AdditionalOptions': 'a_string',
+            'AddModuleNamesToAssembly': 'file1;file2;file3',
+            'AllowIsolation': 'true',
+            'AssemblyDebug': '0',
+            'AssemblyLinkResource': 'file1;file2;file3',
+            'BaseAddress': 'a_string',
+            'CLRImageType': '1',
+            'CLRThreadAttribute': '2',
+            'CLRUnmanagedCodeCheck': 'true',
+            'DataExecutionPrevention': '0',
+            'DelayLoadDLLs': 'file1;file2;file3',
+            'DelaySign': 'true',
+            'Driver': '1',
+            'EmbedManagedResourceFile': 'file1;file2;file3',
+            'EnableCOMDATFolding': '0',
+            'EnableUAC': 'true',
+            'EntryPointSymbol': 'a_string',
+            'ErrorReporting': '0',
+            'FixedBaseAddress': '1',
+            'ForceSymbolReferences': 'file1;file2;file3',
+            'FunctionOrder': 'a_file_name',
+            'GenerateDebugInformation': 'true',
+            'GenerateManifest': 'true',
+            'GenerateMapFile': 'true',
+            'HeapCommitSize': 'a_string',
+            'HeapReserveSize': 'a_string',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreDefaultLibraryNames': 'file1;file2;file3',
+            'IgnoreEmbeddedIDL': 'true',
+            'IgnoreImportLibrary': 'true',
+            'ImportLibrary': 'a_file_name',
+            'KeyContainer': 'a_file_name',
+            'KeyFile': 'a_file_name',
+            'LargeAddressAware': '2',
+            'LinkIncremental': '1',
+            'LinkLibraryDependencies': 'true',
+            'LinkTimeCodeGeneration': '2',
+            'ManifestFile': 'a_file_name',
+            'MapExports': 'true',
+            'MapFileName': 'a_file_name',
+            'MergedIDLBaseFileName': 'a_file_name',
+            'MergeSections': 'a_string',
+            'MidlCommandFile': 'a_file_name',
+            'ModuleDefinitionFile': 'a_file_name',
+            'OptimizeForWindows98': '1',
+            'OptimizeReferences': '0',
+            'OutputFile': 'a_file_name',
+            'PerUserRedirection': 'true',
+            'Profile': 'true',
+            'ProfileGuidedDatabase': 'a_file_name',
+            'ProgramDatabaseFile': 'a_file_name',
+            'RandomizedBaseAddress': '1',
+            'RegisterOutput': 'true',
+            'ResourceOnlyDLL': 'true',
+            'SetChecksum': 'true',
+            'ShowProgress': '0',
+            'StackCommitSize': 'a_string',
+            'StackReserveSize': 'a_string',
+            'StripPrivateSymbols': 'a_file_name',
+            'SubSystem': '2',
+            'SupportUnloadOfDelayLoadedDLL': 'true',
+            'SuppressStartupBanner': 'true',
+            'SwapRunFromCD': 'true',
+            'SwapRunFromNet': 'true',
+            'TargetMachine': '3',
+            'TerminalServerAware': '2',
+            'TurnOffAssemblyGeneration': 'true',
+            'TypeLibraryFile': 'a_file_name',
+            'TypeLibraryResourceID': '33',
+            'UACExecutionLevel': '1',
+            'UACUIAccess': 'true',
+            'UseLibraryDependencyInputs': 'false',
+            'UseUnicodeResponseFiles': 'true',
+            'Version': 'a_string'},
+        'VCResourceCompilerTool': {
+            'AdditionalIncludeDirectories': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string',
+            'Culture': '1003',
+            'IgnoreStandardIncludePath': 'true',
+            'PreprocessorDefinitions': 'd1;d2;d3',
+            'ResourceOutputFileName': 'a_string',
+            'ShowProgress': 'true',
+            'SuppressStartupBanner': 'true',
+            'UndefinePreprocessorDefinitions': 'd1;d2;d3'},
+        'VCMIDLTool': {
+            'AdditionalIncludeDirectories': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string',
+            'CPreprocessOptions': 'a_string',
+            'DefaultCharType': '0',
+            'DLLDataFileName': 'a_file_name',
+            'EnableErrorChecks': '2',
+            'ErrorCheckAllocations': 'true',
+            'ErrorCheckBounds': 'true',
+            'ErrorCheckEnumRange': 'true',
+            'ErrorCheckRefPointers': 'true',
+            'ErrorCheckStubData': 'true',
+            'GenerateStublessProxies': 'true',
+            'GenerateTypeLibrary': 'true',
+            'HeaderFileName': 'a_file_name',
+            'IgnoreStandardIncludePath': 'true',
+            'InterfaceIdentifierFileName': 'a_file_name',
+            'MkTypLibCompatible': 'true',
+            'OutputDirectory': 'a_string',
+            'PreprocessorDefinitions': 'd1;d2;d3',
+            'ProxyFileName': 'a_file_name',
+            'RedirectOutputAndErrors': 'a_file_name',
+            'StructMemberAlignment': '3',
+            'SuppressStartupBanner': 'true',
+            'TargetEnvironment': '1',
+            'TypeLibraryName': 'a_file_name',
+            'UndefinePreprocessorDefinitions': 'd1;d2;d3',
+            'ValidateParameters': 'true',
+            'WarnAsError': 'true',
+            'WarningLevel': '4'},
+        'VCLibrarianTool': {
+            'AdditionalDependencies': 'file1;file2;file3',
+            'AdditionalLibraryDirectories': 'folder1;folder2;folder3',
+            'AdditionalLibraryDirectories_excluded': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string',
+            'ExportNamedFunctions': 'd1;d2;d3',
+            'ForceSymbolReferences': 'a_string',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreSpecificDefaultLibraries': 'file1;file2;file3',
+            'LinkLibraryDependencies': 'true',
+            'ModuleDefinitionFile': 'a_file_name',
+            'OutputFile': 'a_file_name',
+            'SuppressStartupBanner': 'true',
+            'UseUnicodeResponseFiles': 'true'},
+        'VCManifestTool': {
+            'AdditionalManifestFiles': 'file1;file2;file3',
+            'AdditionalOptions': 'a_string',
+            'AssemblyIdentity': 'a_string',
+            'ComponentFileName': 'a_file_name',
+            'DependencyInformationFile': 'a_file_name',
+            'EmbedManifest': 'true',
+            'GenerateCatalogFiles': 'true',
+            'InputResourceManifests': 'a_string',
+            'ManifestResourceFile': 'my_name',
+            'OutputManifestFile': 'a_file_name',
+            'RegistrarScriptFile': 'a_file_name',
+            'ReplacementsFile': 'a_file_name',
+            'SuppressStartupBanner': 'true',
+            'TypeLibraryFile': 'a_file_name',
+            'UpdateFileHashes': 'true',
+            'UpdateFileHashesSearchPath': 'a_file_name',
+            'UseFAT32Workaround': 'true',
+            'UseUnicodeResponseFiles': 'true',
+            'VerboseOutput': 'true'}}
+    expected_msbuild_settings = {
+        'ClCompile': {
+            'AdditionalIncludeDirectories': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string /J',
+            'AdditionalUsingDirectories': 'folder1;folder2;folder3',
+            'AssemblerListingLocation': 'a_file_name',
+            'AssemblerOutput': 'NoListing',
+            'BasicRuntimeChecks': 'StackFrameRuntimeCheck',
+            'BrowseInformation': 'true',
+            'BrowseInformationFile': 'a_file_name',
+            'BufferSecurityCheck': 'true',
+            'CallingConvention': 'Cdecl',
+            'CompileAs': 'CompileAsC',
+            'DebugInformationFormat': 'EditAndContinue',
+            'DisableLanguageExtensions': 'true',
+            'DisableSpecificWarnings': 'd1;d2;d3',
+            'EnableEnhancedInstructionSet': 'NotSet',
+            'EnableFiberSafeOptimizations': 'true',
+            'EnablePREfast': 'true',
+            'ErrorReporting': 'Prompt',
+            'ExceptionHandling':  'Async',
+            'ExpandAttributedSource': 'true',
+            'FavorSizeOrSpeed': 'Neither',
+            'FloatingPointExceptions': 'true',
+            'FloatingPointModel': 'Strict',
+            'ForceConformanceInForLoopScope': 'true',
+            'ForcedIncludeFiles': 'file1;file2;file3',
+            'ForcedUsingFiles': 'file1;file2;file3',
+            'FunctionLevelLinking': 'true',
+            'GenerateXMLDocumentationFiles': 'true',
+            'IgnoreStandardIncludePath': 'true',
+            'InlineFunctionExpansion': 'AnySuitable',
+            'IntrinsicFunctions': 'true',
+            'MinimalRebuild': 'true',
+            'ObjectFileName': 'a_file_name',
+            'OmitDefaultLibName': 'true',
+            'OmitFramePointers': 'true',
+            'OpenMPSupport': 'true',
+            'Optimization': 'Full',
+            'PrecompiledHeader': 'Create',
+            'PrecompiledHeaderFile': 'a_file_name',
+            'PrecompiledHeaderOutputFile': 'a_file_name',
+            'PreprocessKeepComments': 'true',
+            'PreprocessorDefinitions': 'd1;d2;d3',
+            'PreprocessSuppressLineNumbers': 'false',
+            'PreprocessToFile': 'true',
+            'ProgramDataBaseFileName': 'a_file_name',
+            'RuntimeLibrary': 'MultiThreaded',
+            'RuntimeTypeInfo': 'true',
+            'ShowIncludes': 'true',
+            'SmallerTypeCheck': 'true',
+            'StringPooling': 'true',
+            'StructMemberAlignment': '1Byte',
+            'SuppressStartupBanner': 'true',
+            'TreatWarningAsError': 'true',
+            'TreatWChar_tAsBuiltInType': 'true',
+            'UndefineAllPreprocessorDefinitions': 'true',
+            'UndefinePreprocessorDefinitions': 'd1;d2;d3',
+            'UseFullPaths': 'true',
+            'WarningLevel': 'Level2',
+            'WholeProgramOptimization': 'true',
+            'XMLDocumentationFileName': 'a_file_name'},
+        'Link': {
+            'AdditionalDependencies': 'file1;file2;file3',
+            'AdditionalLibraryDirectories': 'folder1;folder2;folder3',
+            'AdditionalManifestDependencies': 'file1;file2;file3',
+            'AdditionalOptions': 'a_string',
+            'AddModuleNamesToAssembly': 'file1;file2;file3',
+            'AllowIsolation': 'true',
+            'AssemblyDebug': '',
+            'AssemblyLinkResource': 'file1;file2;file3',
+            'BaseAddress': 'a_string',
+            'CLRImageType': 'ForceIJWImage',
+            'CLRThreadAttribute': 'STAThreadingAttribute',
+            'CLRUnmanagedCodeCheck': 'true',
+            'DataExecutionPrevention':  '',
+            'DelayLoadDLLs': 'file1;file2;file3',
+            'DelaySign': 'true',
+            'Driver': 'Driver',
+            'EmbedManagedResourceFile': 'file1;file2;file3',
+            'EnableCOMDATFolding': '',
+            'EnableUAC': 'true',
+            'EntryPointSymbol': 'a_string',
+            'FixedBaseAddress': 'false',
+            'ForceSymbolReferences': 'file1;file2;file3',
+            'FunctionOrder': 'a_file_name',
+            'GenerateDebugInformation': 'true',
+            'GenerateMapFile': 'true',
+            'HeapCommitSize': 'a_string',
+            'HeapReserveSize': 'a_string',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreEmbeddedIDL': 'true',
+            'IgnoreSpecificDefaultLibraries': 'file1;file2;file3',
+            'ImportLibrary': 'a_file_name',
+            'KeyContainer': 'a_file_name',
+            'KeyFile': 'a_file_name',
+            'LargeAddressAware': 'true',
+            'LinkErrorReporting': 'NoErrorReport',
+            'LinkTimeCodeGeneration': 'PGInstrument',
+            'ManifestFile': 'a_file_name',
+            'MapExports': 'true',
+            'MapFileName': 'a_file_name',
+            'MergedIDLBaseFileName': 'a_file_name',
+            'MergeSections': 'a_string',
+            'MidlCommandFile': 'a_file_name',
+            'ModuleDefinitionFile': 'a_file_name',
+            'NoEntryPoint': 'true',
+            'OptimizeReferences': '',
+            'OutputFile': 'a_file_name',
+            'PerUserRedirection': 'true',
+            'Profile': 'true',
+            'ProfileGuidedDatabase': 'a_file_name',
+            'ProgramDatabaseFile': 'a_file_name',
+            'RandomizedBaseAddress': 'false',
+            'RegisterOutput': 'true',
+            'SetChecksum': 'true',
+            'ShowProgress': 'NotSet',
+            'StackCommitSize': 'a_string',
+            'StackReserveSize': 'a_string',
+            'StripPrivateSymbols': 'a_file_name',
+            'SubSystem': 'Windows',
+            'SupportUnloadOfDelayLoadedDLL': 'true',
+            'SuppressStartupBanner': 'true',
+            'SwapRunFromCD': 'true',
+            'SwapRunFromNET': 'true',
+            'TargetMachine': 'MachineARM',
+            'TerminalServerAware': 'true',
+            'TurnOffAssemblyGeneration': 'true',
+            'TypeLibraryFile': 'a_file_name',
+            'TypeLibraryResourceID': '33',
+            'UACExecutionLevel': 'HighestAvailable',
+            'UACUIAccess': 'true',
+            'Version': 'a_string'},
+        'ResourceCompile': {
+            'AdditionalIncludeDirectories': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string',
+            'Culture': '0x03eb',
+            'IgnoreStandardIncludePath': 'true',
+            'PreprocessorDefinitions': 'd1;d2;d3',
+            'ResourceOutputFileName': 'a_string',
+            'ShowProgress': 'true',
+            'SuppressStartupBanner': 'true',
+            'UndefinePreprocessorDefinitions': 'd1;d2;d3'},
+        'Midl': {
+            'AdditionalIncludeDirectories': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string',
+            'CPreprocessOptions': 'a_string',
+            'DefaultCharType':  'Unsigned',
+            'DllDataFileName': 'a_file_name',
+            'EnableErrorChecks': 'All',
+            'ErrorCheckAllocations': 'true',
+            'ErrorCheckBounds': 'true',
+            'ErrorCheckEnumRange': 'true',
+            'ErrorCheckRefPointers': 'true',
+            'ErrorCheckStubData': 'true',
+            'GenerateStublessProxies': 'true',
+            'GenerateTypeLibrary': 'true',
+            'HeaderFileName': 'a_file_name',
+            'IgnoreStandardIncludePath': 'true',
+            'InterfaceIdentifierFileName': 'a_file_name',
+            'MkTypLibCompatible': 'true',
+            'OutputDirectory': 'a_string',
+            'PreprocessorDefinitions': 'd1;d2;d3',
+            'ProxyFileName': 'a_file_name',
+            'RedirectOutputAndErrors': 'a_file_name',
+            'StructMemberAlignment': '4',
+            'SuppressStartupBanner': 'true',
+            'TargetEnvironment': 'Win32',
+            'TypeLibraryName': 'a_file_name',
+            'UndefinePreprocessorDefinitions': 'd1;d2;d3',
+            'ValidateAllParameters': 'true',
+            'WarnAsError': 'true',
+            'WarningLevel': '4'},
+        'Lib': {
+            'AdditionalDependencies': 'file1;file2;file3',
+            'AdditionalLibraryDirectories': 'folder1;folder2;folder3',
+            'AdditionalOptions': 'a_string',
+            'ExportNamedFunctions': 'd1;d2;d3',
+            'ForceSymbolReferences': 'a_string',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreSpecificDefaultLibraries': 'file1;file2;file3',
+            'ModuleDefinitionFile': 'a_file_name',
+            'OutputFile': 'a_file_name',
+            'SuppressStartupBanner': 'true',
+            'UseUnicodeResponseFiles': 'true'},
+        'Mt': {
+            'AdditionalManifestFiles': 'file1;file2;file3',
+            'AdditionalOptions': 'a_string',
+            'AssemblyIdentity': 'a_string',
+            'ComponentFileName': 'a_file_name',
+            'GenerateCatalogFiles': 'true',
+            'InputResourceManifests': 'a_string',
+            'OutputManifestFile': 'a_file_name',
+            'RegistrarScriptFile': 'a_file_name',
+            'ReplacementsFile': 'a_file_name',
+            'SuppressStartupBanner': 'true',
+            'TypeLibraryFile': 'a_file_name',
+            'UpdateFileHashes': 'true',
+            'UpdateFileHashesSearchPath': 'a_file_name',
+            'VerboseOutput': 'true'},
+        'ManifestResourceCompile': {
+            'ResourceOutputFileName': 'my_name'},
+        'ProjectReference': {
+            'LinkLibraryDependencies': 'true',
+            'UseLibraryDependencyInputs': 'false'},
+        '': {
+            'EmbedManifest': 'true',
+            'GenerateManifest': 'true',
+            'IgnoreImportLibrary': 'true',
+            'LinkIncremental': 'false'}}
+    actual_msbuild_settings = MSVSSettings.ConvertToMsBuildSettings(
+        msvs_settings,
+        self.stderr)
+    self.assertEqual(expected_msbuild_settings, actual_msbuild_settings)
+    self._ExpectedWarnings([])
+
+  def test_ConvertToMsBuildSettings_actual(self):
+    """ Tests the conversion of an actual project.
+
+    A VS2008 project with most of the options defined was created through the
+    VS2008 IDE.  It was then converted to VS2010.  The tool settings found in
+    the .vcproj and .vcxproj files were converted to the two dictionaries
+    msvs_settings and expected_msbuild_settings.
+
+    Note that for many settings, the VS2010 converter adds macros like
+    %(AdditionalIncludeDirectories) to make sure than inherited values are
+    included.  Since the Gyp projects we generate do not use inheritance,
+    we removed these macros.  They were:
+        ClCompile:
+            AdditionalIncludeDirectories:  ';%(AdditionalIncludeDirectories)'
+            AdditionalOptions:  ' %(AdditionalOptions)'
+            AdditionalUsingDirectories:  ';%(AdditionalUsingDirectories)'
+            DisableSpecificWarnings: ';%(DisableSpecificWarnings)',
+            ForcedIncludeFiles:  ';%(ForcedIncludeFiles)',
+            ForcedUsingFiles:  ';%(ForcedUsingFiles)',
+            PreprocessorDefinitions:  ';%(PreprocessorDefinitions)',
+            UndefinePreprocessorDefinitions:
+                ';%(UndefinePreprocessorDefinitions)',
+        Link:
+            AdditionalDependencies:  ';%(AdditionalDependencies)',
+            AdditionalLibraryDirectories:  ';%(AdditionalLibraryDirectories)',
+            AdditionalManifestDependencies:
+                ';%(AdditionalManifestDependencies)',
+            AdditionalOptions:  ' %(AdditionalOptions)',
+            AddModuleNamesToAssembly:  ';%(AddModuleNamesToAssembly)',
+            AssemblyLinkResource:  ';%(AssemblyLinkResource)',
+            DelayLoadDLLs:  ';%(DelayLoadDLLs)',
+            EmbedManagedResourceFile:  ';%(EmbedManagedResourceFile)',
+            ForceSymbolReferences:  ';%(ForceSymbolReferences)',
+            IgnoreSpecificDefaultLibraries:
+                ';%(IgnoreSpecificDefaultLibraries)',
+        ResourceCompile:
+            AdditionalIncludeDirectories:  ';%(AdditionalIncludeDirectories)',
+            AdditionalOptions:  ' %(AdditionalOptions)',
+            PreprocessorDefinitions:  ';%(PreprocessorDefinitions)',
+        Mt:
+            AdditionalManifestFiles:  ';%(AdditionalManifestFiles)',
+            AdditionalOptions:  ' %(AdditionalOptions)',
+            InputResourceManifests:  ';%(InputResourceManifests)',
+    """
+    msvs_settings = {
+        'VCCLCompilerTool': {
+            'AdditionalIncludeDirectories': 'dir1',
+            'AdditionalOptions': '/more',
+            'AdditionalUsingDirectories': 'test',
+            'AssemblerListingLocation': '$(IntDir)\\a',
+            'AssemblerOutput': '1',
+            'BasicRuntimeChecks': '3',
+            'BrowseInformation': '1',
+            'BrowseInformationFile': '$(IntDir)\\e',
+            'BufferSecurityCheck': 'false',
+            'CallingConvention': '1',
+            'CompileAs': '1',
+            'DebugInformationFormat': '4',
+            'DefaultCharIsUnsigned': 'true',
+            'Detect64BitPortabilityProblems': 'true',
+            'DisableLanguageExtensions': 'true',
+            'DisableSpecificWarnings': 'abc',
+            'EnableEnhancedInstructionSet': '1',
+            'EnableFiberSafeOptimizations': 'true',
+            'EnableFunctionLevelLinking': 'true',
+            'EnableIntrinsicFunctions': 'true',
+            'EnablePREfast': 'true',
+            'ErrorReporting': '2',
+            'ExceptionHandling': '2',
+            'ExpandAttributedSource': 'true',
+            'FavorSizeOrSpeed': '2',
+            'FloatingPointExceptions': 'true',
+            'FloatingPointModel': '1',
+            'ForceConformanceInForLoopScope': 'false',
+            'ForcedIncludeFiles': 'def',
+            'ForcedUsingFiles': 'ge',
+            'GeneratePreprocessedFile': '2',
+            'GenerateXMLDocumentationFiles': 'true',
+            'IgnoreStandardIncludePath': 'true',
+            'InlineFunctionExpansion': '1',
+            'KeepComments': 'true',
+            'MinimalRebuild': 'true',
+            'ObjectFile': '$(IntDir)\\b',
+            'OmitDefaultLibName': 'true',
+            'OmitFramePointers': 'true',
+            'OpenMP': 'true',
+            'Optimization': '3',
+            'PrecompiledHeaderFile': '$(IntDir)\\$(TargetName).pche',
+            'PrecompiledHeaderThrough': 'StdAfx.hd',
+            'PreprocessorDefinitions': 'WIN32;_DEBUG;_CONSOLE',
+            'ProgramDataBaseFileName': '$(IntDir)\\vc90b.pdb',
+            'RuntimeLibrary': '3',
+            'RuntimeTypeInfo': 'false',
+            'ShowIncludes': 'true',
+            'SmallerTypeCheck': 'true',
+            'StringPooling': 'true',
+            'StructMemberAlignment': '3',
+            'SuppressStartupBanner': 'false',
+            'TreatWChar_tAsBuiltInType': 'false',
+            'UndefineAllPreprocessorDefinitions': 'true',
+            'UndefinePreprocessorDefinitions': 'wer',
+            'UseFullPaths': 'true',
+            'UsePrecompiledHeader': '0',
+            'UseUnicodeResponseFiles': 'false',
+            'WarnAsError': 'true',
+            'WarningLevel': '3',
+            'WholeProgramOptimization': 'true',
+            'XMLDocumentationFileName': '$(IntDir)\\c'},
+        'VCLinkerTool': {
+            'AdditionalDependencies': 'zx',
+            'AdditionalLibraryDirectories': 'asd',
+            'AdditionalManifestDependencies': 's2',
+            'AdditionalOptions': '/mor2',
+            'AddModuleNamesToAssembly': 'd1',
+            'AllowIsolation': 'false',
+            'AssemblyDebug': '1',
+            'AssemblyLinkResource': 'd5',
+            'BaseAddress': '23423',
+            'CLRImageType': '3',
+            'CLRThreadAttribute': '1',
+            'CLRUnmanagedCodeCheck': 'true',
+            'DataExecutionPrevention': '0',
+            'DelayLoadDLLs': 'd4',
+            'DelaySign': 'true',
+            'Driver': '2',
+            'EmbedManagedResourceFile': 'd2',
+            'EnableCOMDATFolding': '1',
+            'EnableUAC': 'false',
+            'EntryPointSymbol': 'f5',
+            'ErrorReporting': '2',
+            'FixedBaseAddress': '1',
+            'ForceSymbolReferences': 'd3',
+            'FunctionOrder': 'fssdfsd',
+            'GenerateDebugInformation': 'true',
+            'GenerateManifest': 'false',
+            'GenerateMapFile': 'true',
+            'HeapCommitSize': '13',
+            'HeapReserveSize': '12',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreDefaultLibraryNames': 'flob;flok',
+            'IgnoreEmbeddedIDL': 'true',
+            'IgnoreImportLibrary': 'true',
+            'ImportLibrary': 'f4',
+            'KeyContainer': 'f7',
+            'KeyFile': 'f6',
+            'LargeAddressAware': '2',
+            'LinkIncremental': '0',
+            'LinkLibraryDependencies': 'false',
+            'LinkTimeCodeGeneration': '1',
+            'ManifestFile':
+                '$(IntDir)\\$(TargetFileName).2intermediate.manifest',
+            'MapExports': 'true',
+            'MapFileName': 'd5',
+            'MergedIDLBaseFileName': 'f2',
+            'MergeSections': 'f5',
+            'MidlCommandFile': 'f1',
+            'ModuleDefinitionFile': 'sdsd',
+            'OptimizeForWindows98': '2',
+            'OptimizeReferences': '2',
+            'OutputFile': '$(OutDir)\\$(ProjectName)2.exe',
+            'PerUserRedirection': 'true',
+            'Profile': 'true',
+            'ProfileGuidedDatabase': '$(TargetDir)$(TargetName).pgdd',
+            'ProgramDatabaseFile': 'Flob.pdb',
+            'RandomizedBaseAddress': '1',
+            'RegisterOutput': 'true',
+            'ResourceOnlyDLL': 'true',
+            'SetChecksum': 'false',
+            'ShowProgress': '1',
+            'StackCommitSize': '15',
+            'StackReserveSize': '14',
+            'StripPrivateSymbols': 'd3',
+            'SubSystem': '1',
+            'SupportUnloadOfDelayLoadedDLL': 'true',
+            'SuppressStartupBanner': 'false',
+            'SwapRunFromCD': 'true',
+            'SwapRunFromNet': 'true',
+            'TargetMachine': '1',
+            'TerminalServerAware': '1',
+            'TurnOffAssemblyGeneration': 'true',
+            'TypeLibraryFile': 'f3',
+            'TypeLibraryResourceID': '12',
+            'UACExecutionLevel': '2',
+            'UACUIAccess': 'true',
+            'UseLibraryDependencyInputs': 'true',
+            'UseUnicodeResponseFiles': 'false',
+            'Version': '333'},
+        'VCResourceCompilerTool': {
+            'AdditionalIncludeDirectories': 'f3',
+            'AdditionalOptions': '/more3',
+            'Culture': '3084',
+            'IgnoreStandardIncludePath': 'true',
+            'PreprocessorDefinitions': '_UNICODE;UNICODE2',
+            'ResourceOutputFileName': '$(IntDir)/$(InputName)3.res',
+            'ShowProgress': 'true'},
+        'VCManifestTool': {
+            'AdditionalManifestFiles': 'sfsdfsd',
+            'AdditionalOptions': 'afdsdafsd',
+            'AssemblyIdentity': 'sddfdsadfsa',
+            'ComponentFileName': 'fsdfds',
+            'DependencyInformationFile': '$(IntDir)\\mt.depdfd',
+            'EmbedManifest': 'false',
+            'GenerateCatalogFiles': 'true',
+            'InputResourceManifests': 'asfsfdafs',
+            'ManifestResourceFile':
+                '$(IntDir)\\$(TargetFileName).embed.manifest.resfdsf',
+            'OutputManifestFile': '$(TargetPath).manifestdfs',
+            'RegistrarScriptFile': 'sdfsfd',
+            'ReplacementsFile': 'sdffsd',
+            'SuppressStartupBanner': 'false',
+            'TypeLibraryFile': 'sfsd',
+            'UpdateFileHashes': 'true',
+            'UpdateFileHashesSearchPath': 'sfsd',
+            'UseFAT32Workaround': 'true',
+            'UseUnicodeResponseFiles': 'false',
+            'VerboseOutput': 'true'}}
+    expected_msbuild_settings = {
+        'ClCompile': {
+            'AdditionalIncludeDirectories': 'dir1',
+            'AdditionalOptions': '/more /J',
+            'AdditionalUsingDirectories': 'test',
+            'AssemblerListingLocation': '$(IntDir)a',
+            'AssemblerOutput': 'AssemblyCode',
+            'BasicRuntimeChecks': 'EnableFastChecks',
+            'BrowseInformation': 'true',
+            'BrowseInformationFile': '$(IntDir)e',
+            'BufferSecurityCheck': 'false',
+            'CallingConvention': 'FastCall',
+            'CompileAs': 'CompileAsC',
+            'DebugInformationFormat': 'EditAndContinue',
+            'DisableLanguageExtensions': 'true',
+            'DisableSpecificWarnings': 'abc',
+            'EnableEnhancedInstructionSet': 'StreamingSIMDExtensions',
+            'EnableFiberSafeOptimizations': 'true',
+            'EnablePREfast': 'true',
+            'ErrorReporting': 'Queue',
+            'ExceptionHandling': 'Async',
+            'ExpandAttributedSource': 'true',
+            'FavorSizeOrSpeed': 'Size',
+            'FloatingPointExceptions': 'true',
+            'FloatingPointModel': 'Strict',
+            'ForceConformanceInForLoopScope': 'false',
+            'ForcedIncludeFiles': 'def',
+            'ForcedUsingFiles': 'ge',
+            'FunctionLevelLinking': 'true',
+            'GenerateXMLDocumentationFiles': 'true',
+            'IgnoreStandardIncludePath': 'true',
+            'InlineFunctionExpansion': 'OnlyExplicitInline',
+            'IntrinsicFunctions': 'true',
+            'MinimalRebuild': 'true',
+            'ObjectFileName': '$(IntDir)b',
+            'OmitDefaultLibName': 'true',
+            'OmitFramePointers': 'true',
+            'OpenMPSupport': 'true',
+            'Optimization': 'Full',
+            'PrecompiledHeader': 'NotUsing',  # Actual conversion gives ''
+            'PrecompiledHeaderFile': 'StdAfx.hd',
+            'PrecompiledHeaderOutputFile': '$(IntDir)$(TargetName).pche',
+            'PreprocessKeepComments': 'true',
+            'PreprocessorDefinitions': 'WIN32;_DEBUG;_CONSOLE',
+            'PreprocessSuppressLineNumbers': 'true',
+            'PreprocessToFile': 'true',
+            'ProgramDataBaseFileName': '$(IntDir)vc90b.pdb',
+            'RuntimeLibrary': 'MultiThreadedDebugDLL',
+            'RuntimeTypeInfo': 'false',
+            'ShowIncludes': 'true',
+            'SmallerTypeCheck': 'true',
+            'StringPooling': 'true',
+            'StructMemberAlignment': '4Bytes',
+            'SuppressStartupBanner': 'false',
+            'TreatWarningAsError': 'true',
+            'TreatWChar_tAsBuiltInType': 'false',
+            'UndefineAllPreprocessorDefinitions': 'true',
+            'UndefinePreprocessorDefinitions': 'wer',
+            'UseFullPaths': 'true',
+            'WarningLevel': 'Level3',
+            'WholeProgramOptimization': 'true',
+            'XMLDocumentationFileName': '$(IntDir)c'},
+        'Link': {
+            'AdditionalDependencies': 'zx',
+            'AdditionalLibraryDirectories': 'asd',
+            'AdditionalManifestDependencies': 's2',
+            'AdditionalOptions': '/mor2',
+            'AddModuleNamesToAssembly': 'd1',
+            'AllowIsolation': 'false',
+            'AssemblyDebug': 'true',
+            'AssemblyLinkResource': 'd5',
+            'BaseAddress': '23423',
+            'CLRImageType': 'ForceSafeILImage',
+            'CLRThreadAttribute': 'MTAThreadingAttribute',
+            'CLRUnmanagedCodeCheck': 'true',
+            'DataExecutionPrevention': '',
+            'DelayLoadDLLs': 'd4',
+            'DelaySign': 'true',
+            'Driver': 'UpOnly',
+            'EmbedManagedResourceFile': 'd2',
+            'EnableCOMDATFolding': 'false',
+            'EnableUAC': 'false',
+            'EntryPointSymbol': 'f5',
+            'FixedBaseAddress': 'false',
+            'ForceSymbolReferences': 'd3',
+            'FunctionOrder': 'fssdfsd',
+            'GenerateDebugInformation': 'true',
+            'GenerateMapFile': 'true',
+            'HeapCommitSize': '13',
+            'HeapReserveSize': '12',
+            'IgnoreAllDefaultLibraries': 'true',
+            'IgnoreEmbeddedIDL': 'true',
+            'IgnoreSpecificDefaultLibraries': 'flob;flok',
+            'ImportLibrary': 'f4',
+            'KeyContainer': 'f7',
+            'KeyFile': 'f6',
+            'LargeAddressAware': 'true',
+            'LinkErrorReporting': 'QueueForNextLogin',
+            'LinkTimeCodeGeneration': 'UseLinkTimeCodeGeneration',
+            'ManifestFile': '$(IntDir)$(TargetFileName).2intermediate.manifest',
+            'MapExports': 'true',
+            'MapFileName': 'd5',
+            'MergedIDLBaseFileName': 'f2',
+            'MergeSections': 'f5',
+            'MidlCommandFile': 'f1',
+            'ModuleDefinitionFile': 'sdsd',
+            'NoEntryPoint': 'true',
+            'OptimizeReferences': 'true',
+            'OutputFile': '$(OutDir)$(ProjectName)2.exe',
+            'PerUserRedirection': 'true',
+            'Profile': 'true',
+            'ProfileGuidedDatabase': '$(TargetDir)$(TargetName).pgdd',
+            'ProgramDatabaseFile': 'Flob.pdb',
+            'RandomizedBaseAddress': 'false',
+            'RegisterOutput': 'true',
+            'SetChecksum': 'false',
+            'ShowProgress': 'LinkVerbose',
+            'StackCommitSize': '15',
+            'StackReserveSize': '14',
+            'StripPrivateSymbols': 'd3',
+            'SubSystem': 'Console',
+            'SupportUnloadOfDelayLoadedDLL': 'true',
+            'SuppressStartupBanner': 'false',
+            'SwapRunFromCD': 'true',
+            'SwapRunFromNET': 'true',
+            'TargetMachine': 'MachineX86',
+            'TerminalServerAware': 'false',
+            'TurnOffAssemblyGeneration': 'true',
+            'TypeLibraryFile': 'f3',
+            'TypeLibraryResourceID': '12',
+            'UACExecutionLevel': 'RequireAdministrator',
+            'UACUIAccess': 'true',
+            'Version': '333'},
+        'ResourceCompile': {
+            'AdditionalIncludeDirectories': 'f3',
+            'AdditionalOptions': '/more3',
+            'Culture': '0x0c0c',
+            'IgnoreStandardIncludePath': 'true',
+            'PreprocessorDefinitions': '_UNICODE;UNICODE2',
+            'ResourceOutputFileName': '$(IntDir)%(Filename)3.res',
+            'ShowProgress': 'true'},
+        'Mt': {
+            'AdditionalManifestFiles': 'sfsdfsd',
+            'AdditionalOptions': 'afdsdafsd',
+            'AssemblyIdentity': 'sddfdsadfsa',
+            'ComponentFileName': 'fsdfds',
+            'GenerateCatalogFiles': 'true',
+            'InputResourceManifests': 'asfsfdafs',
+            'OutputManifestFile': '$(TargetPath).manifestdfs',
+            'RegistrarScriptFile': 'sdfsfd',
+            'ReplacementsFile': 'sdffsd',
+            'SuppressStartupBanner': 'false',
+            'TypeLibraryFile': 'sfsd',
+            'UpdateFileHashes': 'true',
+            'UpdateFileHashesSearchPath': 'sfsd',
+            'VerboseOutput': 'true'},
+        'ProjectReference': {
+            'LinkLibraryDependencies': 'false',
+            'UseLibraryDependencyInputs': 'true'},
+        '': {
+            'EmbedManifest': 'false',
+            'GenerateManifest': 'false',
+            'IgnoreImportLibrary': 'true',
+            'LinkIncremental': ''
+            },
+        'ManifestResourceCompile': {
+            'ResourceOutputFileName':
+                '$(IntDir)$(TargetFileName).embed.manifest.resfdsf'}
+        }
+    actual_msbuild_settings = MSVSSettings.ConvertToMsBuildSettings(
+        msvs_settings,
+        self.stderr)
+    self.assertEqual(expected_msbuild_settings, actual_msbuild_settings)
+    self._ExpectedWarnings([])
+
+if __name__ == '__main__':
+  unittest.main()
\ No newline at end of file
diff --git a/Source/ThirdParty/gyp/pylib/gyp/MSVSToolFile.py b/Source/ThirdParty/gyp/pylib/gyp/MSVSToolFile.py
new file mode 100644 (file)
index 0000000..493a9c4
--- /dev/null
@@ -0,0 +1,81 @@
+#!/usr/bin/python2.4
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Visual Studio project reader/writer."""
+
+import common
+import xml.dom
+import xml_fix
+
+
+#------------------------------------------------------------------------------
+
+
+class Writer(object):
+  """Visual Studio XML tool file writer."""
+
+  def __init__(self, tool_file_path):
+    """Initializes the tool file.
+
+    Args:
+      tool_file_path: Path to the tool file.
+    """
+    self.tool_file_path = tool_file_path
+    self.doc = None
+
+  def Create(self, name):
+    """Creates the tool file document.
+
+    Args:
+      name: Name of the tool file.
+    """
+    self.name = name
+
+    # Create XML doc
+    xml_impl = xml.dom.getDOMImplementation()
+    self.doc = xml_impl.createDocument(None, 'VisualStudioToolFile', None)
+
+    # Add attributes to root element
+    self.n_root = self.doc.documentElement
+    self.n_root.setAttribute('Version', '8.00')
+    self.n_root.setAttribute('Name', self.name)
+
+    # Add rules section
+    self.n_rules = self.doc.createElement('Rules')
+    self.n_root.appendChild(self.n_rules)
+
+  def AddCustomBuildRule(self, name, cmd, description,
+                         additional_dependencies,
+                         outputs, extensions):
+    """Adds a rule to the tool file.
+
+    Args:
+      name: Name of the rule.
+      description: Description of the rule.
+      cmd: Command line of the rule.
+      additional_dependencies: other files which may trigger the rule.
+      outputs: outputs of the rule.
+      extensions: extensions handled by the rule.
+    """
+    n_rule = self.doc.createElement('CustomBuildRule')
+    n_rule.setAttribute('Name', name)
+    n_rule.setAttribute('ExecutionDescription', description)
+    n_rule.setAttribute('CommandLine', cmd)
+    n_rule.setAttribute('Outputs', ';'.join(outputs))
+    n_rule.setAttribute('FileExtensions', ';'.join(extensions))
+    n_rule.setAttribute('AdditionalDependencies',
+                        ';'.join(additional_dependencies))
+    self.n_rules.appendChild(n_rule)
+
+  def Write(self, writer=common.WriteOnDiff):
+    """Writes the tool file."""
+    f = writer(self.tool_file_path)
+    fix = xml_fix.XmlFix()
+    self.doc.writexml(f, encoding='Windows-1252', addindent='  ', newl='\r\n')
+    fix.Cleanup()
+    f.close()
+
+#------------------------------------------------------------------------------
diff --git a/Source/ThirdParty/gyp/pylib/gyp/MSVSUserFile.py b/Source/ThirdParty/gyp/pylib/gyp/MSVSUserFile.py
new file mode 100644 (file)
index 0000000..ba166a9
--- /dev/null
@@ -0,0 +1,182 @@
+#!/usr/bin/python2.4
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Visual Studio user preferences file writer."""
+
+import common
+import os
+import re
+import socket # for gethostname
+import xml.dom
+import xml_fix
+
+
+#------------------------------------------------------------------------------
+
+def _FindCommandInPath(command):
+  """If there are no slashes in the command given, this function
+     searches the PATH env to find the given command, and converts it
+     to an absolute path.  We have to do this because MSVS is looking
+     for an actual file to launch a debugger on, not just a command
+     line.  Note that this happens at GYP time, so anything needing to
+     be built needs to have a full path."""
+  if '/' in command or '\\' in command:
+    # If the command already has path elements (either relative or
+    # absolute), then assume it is constructed properly.
+    return command
+  else:
+    # Search through the path list and find an existing file that
+    # we can access.
+    paths = os.environ.get('PATH','').split(os.pathsep)
+    for path in paths:
+      item = os.path.join(path, command)
+      if os.path.isfile(item) and os.access(item, os.X_OK):
+        return item
+  return command
+
+def _QuoteWin32CommandLineArgs(args):
+  new_args = []
+  for arg in args:
+    # Replace all double-quotes with double-double-quotes to escape
+    # them for cmd shell, and then quote the whole thing if there
+    # are any.
+    if arg.find('"') != -1:
+      arg = '""'.join(arg.split('"'))
+      arg = '"%s"' % arg
+
+    # Otherwise, if there are any spaces, quote the whole arg.
+    elif re.search(r'[ \t\n]', arg):
+      arg = '"%s"' % arg
+    new_args.append(arg)
+  return new_args
+
+class Writer(object):
+  """Visual Studio XML user user file writer."""
+
+  def __init__(self, user_file_path, version):
+    """Initializes the user file.
+
+    Args:
+      user_file_path: Path to the user file.
+    """
+    self.user_file_path = user_file_path
+    self.version = version
+    self.doc = None
+
+  def Create(self, name):
+    """Creates the user file document.
+
+    Args:
+      name: Name of the user file.
+    """
+    self.name = name
+
+    # Create XML doc
+    xml_impl = xml.dom.getDOMImplementation()
+    self.doc = xml_impl.createDocument(None, 'VisualStudioUserFile', None)
+
+    # Add attributes to root element
+    self.n_root = self.doc.documentElement
+    self.n_root.setAttribute('Version', self.version.ProjectVersion())
+    self.n_root.setAttribute('Name', self.name)
+
+    # Add configurations section
+    self.n_configs = self.doc.createElement('Configurations')
+    self.n_root.appendChild(self.n_configs)
+
+  def _AddConfigToNode(self, parent, config_type, config_name):
+    """Adds a configuration to the parent node.
+
+    Args:
+      parent: Destination node.
+      config_type: Type of configuration node.
+      config_name: Configuration name.
+    """
+    # Add configuration node and its attributes
+    n_config = self.doc.createElement(config_type)
+    n_config.setAttribute('Name', config_name)
+    parent.appendChild(n_config)
+
+  def AddConfig(self, name):
+    """Adds a configuration to the project.
+
+    Args:
+      name: Configuration name.
+    """
+    self._AddConfigToNode(self.n_configs, 'Configuration', name)
+
+
+  def AddDebugSettings(self, config_name, command, environment = {},
+                       working_directory=""):
+    """Adds a DebugSettings node to the user file for a particular config.
+
+    Args:
+      command: command line to run.  First element in the list is the
+        executable.  All elements of the command will be quoted if
+        necessary.
+      working_directory: other files which may trigger the rule. (optional)
+    """
+    command = _QuoteWin32CommandLineArgs(command)
+
+    n_cmd = self.doc.createElement('DebugSettings')
+    abs_command = _FindCommandInPath(command[0])
+    n_cmd.setAttribute('Command', abs_command)
+    n_cmd.setAttribute('WorkingDirectory', working_directory)
+    n_cmd.setAttribute('CommandArguments', " ".join(command[1:]))
+    n_cmd.setAttribute('RemoteMachine', socket.gethostname())
+
+    if environment and isinstance(environment, dict):
+      n_cmd.setAttribute('Environment',
+                         " ".join(['%s="%s"' % (key, val)
+                                   for (key,val) in environment.iteritems()]))
+    else:
+      n_cmd.setAttribute('Environment', '')
+
+    n_cmd.setAttribute('EnvironmentMerge', 'true')
+
+    # Currently these are all "dummy" values that we're just setting
+    # in the default manner that MSVS does it.  We could use some of
+    # these to add additional capabilities, I suppose, but they might
+    # not have parity with other platforms then.
+    n_cmd.setAttribute('Attach', 'false')
+    n_cmd.setAttribute('DebuggerType', '3') # 'auto' debugger
+    n_cmd.setAttribute('Remote', '1')
+    n_cmd.setAttribute('RemoteCommand', '')
+    n_cmd.setAttribute('HttpUrl', '')
+    n_cmd.setAttribute('PDBPath', '')
+    n_cmd.setAttribute('SQLDebugging', '')
+    n_cmd.setAttribute('DebuggerFlavor', '0')
+    n_cmd.setAttribute('MPIRunCommand', '')
+    n_cmd.setAttribute('MPIRunArguments', '')
+    n_cmd.setAttribute('MPIRunWorkingDirectory', '')
+    n_cmd.setAttribute('ApplicationCommand', '')
+    n_cmd.setAttribute('ApplicationArguments', '')
+    n_cmd.setAttribute('ShimCommand', '')
+    n_cmd.setAttribute('MPIAcceptMode', '')
+    n_cmd.setAttribute('MPIAcceptFilter', '')
+
+    # Find the config, and add it if it doesn't exist.
+    found = False
+    for config in self.n_configs.childNodes:
+      if config.getAttribute("Name") == config_name:
+        found = True
+
+    if not found:
+      self.AddConfig(config_name)
+
+    # Add the DebugSettings onto the appropriate config.
+    for config in self.n_configs.childNodes:
+      if config.getAttribute("Name") == config_name:
+        config.appendChild(n_cmd)
+        break
+
+  def Write(self, writer=common.WriteOnDiff):
+    """Writes the user file."""
+    f = writer(self.user_file_path)
+    self.doc.writexml(f, encoding='Windows-1252', addindent='  ', newl='\r\n')
+    f.close()
+
+#------------------------------------------------------------------------------
diff --git a/Source/ThirdParty/gyp/pylib/gyp/MSVSVersion.py b/Source/ThirdParty/gyp/pylib/gyp/MSVSVersion.py
new file mode 100755 (executable)
index 0000000..f206eb6
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Handle version information related to Visual Stuio."""
+
+import os
+import re
+import subprocess
+import sys
+
+
+class VisualStudioVersion:
+  """Information regarding a version of Visual Studio."""
+
+  def __init__(self, short_name, description,
+               solution_version, project_version, flat_sln, uses_vcxproj):
+    self.short_name = short_name
+    self.description = description
+    self.solution_version = solution_version
+    self.project_version = project_version
+    self.flat_sln = flat_sln
+    self.uses_vcxproj = uses_vcxproj
+
+  def ShortName(self):
+    return self.short_name
+
+  def Description(self):
+    """Get the full description of the version."""
+    return self.description
+
+  def SolutionVersion(self):
+    """Get the version number of the sln files."""
+    return self.solution_version
+
+  def ProjectVersion(self):
+    """Get the version number of the vcproj or vcxproj files."""
+    return self.project_version
+
+  def FlatSolution(self):
+    return self.flat_sln
+
+  def UsesVcxproj(self):
+    """Returns true if this version uses a vcxproj file."""
+    return self.uses_vcxproj
+
+  def ProjectExtension(self):
+    """Returns the file extension for the project."""
+    return self.uses_vcxproj and '.vcxproj' or '.vcproj'
+
+def _RegistryGetValue(key, value):
+  """Use reg.exe to read a paricular key.
+
+  While ideally we might use the win32 module, we would like gyp to be
+  python neutral, so for instance cygwin python lacks this module.
+
+  Arguments:
+    key: The registry key to read from.
+    value: The particular value to read.
+  Return:
+    The contents there, or None for failure.
+  """
+  # Skip if not on Windows.
+  if sys.platform not in ('win32', 'cygwin'):
+    return None
+  # Run reg.exe.
+  cmd = [os.path.join(os.environ.get('WINDIR', ''), 'System32', 'reg.exe'),
+         'query', key, '/v', value]
+  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+  text = p.communicate()[0]
+  # Require a successful return value.
+  if p.returncode:
+    return None
+  # Extract value.
+  match = re.search(r'REG_\w+\s+([^\r]+)\r\n', text)
+  if not match:
+    return None
+  return match.group(1)
+
+
+def _RegistryKeyExists(key):
+  """Use reg.exe to see if a key exists.
+
+  Args:
+    key: The registry key to check.
+  Return:
+    True if the key exists
+  """
+  # Skip if not on Windows.
+  if sys.platform not in ('win32', 'cygwin'):
+    return None
+  # Run reg.exe.
+  cmd = [os.path.join(os.environ.get('WINDIR', ''), 'System32', 'reg.exe'),
+         'query', key]
+  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+  return p.returncode == 0
+
+
+def _CreateVersion(name):
+  versions = {
+      '2010': VisualStudioVersion('2010',
+                                  'Visual Studio 2010',
+                                  solution_version='11.00',
+                                  project_version='4.0',
+                                  flat_sln=False,
+                                  uses_vcxproj=True),
+      '2008': VisualStudioVersion('2008',
+                                  'Visual Studio 2008',
+                                  solution_version='10.00',
+                                  project_version='9.00',
+                                  flat_sln=False,
+                                  uses_vcxproj=False),
+      '2008e': VisualStudioVersion('2008e',
+                                   'Visual Studio 2008',
+                                   solution_version='10.00',
+                                   project_version='9.00',
+                                   flat_sln=True,
+                                   uses_vcxproj=False),
+      '2005': VisualStudioVersion('2005',
+                                  'Visual Studio 2005',
+                                  solution_version='9.00',
+                                  project_version='8.00',
+                                  flat_sln=False,
+                                  uses_vcxproj=False),
+      '2005e': VisualStudioVersion('2005e',
+                                   'Visual Studio 2005',
+                                   solution_version='9.00',
+                                   project_version='8.00',
+                                   flat_sln=True,
+                                   uses_vcxproj=False),
+  }
+  return versions[str(name)]
+
+
+def _DetectVisualStudioVersions():
+  """Collect the list of installed visual studio versions.
+
+  Returns:
+    A list of visual studio versions installed in descending order of
+    usage preference.
+    Base this on the registry and a quick check if devenv.exe exists.
+    Only versions 8-10 are considered.
+    Possibilities are:
+      2005 - Visual Studio 2005 (8)
+      2008 - Visual Studio 2008 (9)
+      2010 - Visual Studio 2010 (10)
+  """
+  version_to_year = {'8.0': '2005', '9.0': '2008', '10.0': '2010'}
+  versions = []
+  # For now, prefer versions before VS2010
+  for version in ('9.0', '8.0', '10.0'):
+    # Check if VS2010 and later is installed as specified by
+    # http://msdn.microsoft.com/en-us/library/bb164659.aspx
+    key32 = r'HKLM\SOFTWARE\Microsoft\DevDiv\VS\Servicing\%s' % version
+    key64 = r'HKLM\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS\Servicing\%sD' % (
+         version)
+    if _RegistryKeyExists(key32) or _RegistryKeyExists(key64):
+      # Add this one.
+      # TODO(jeanluc) This does not check for an express version.
+      # TODO(jeanluc) Uncomment this line when ready to support VS2010:
+      # versions.append(_CreateVersion(version_to_year[version]))
+      continue
+    # Get the install dir for this version.
+    key = r'HKLM\Software\Microsoft\VisualStudio\%s' % version
+    path = _RegistryGetValue(key, 'InstallDir')
+    if not path:
+      continue
+    # Check for full.
+    if os.path.exists(os.path.join(path, 'devenv.exe')):
+      # Add this one.
+      versions.append(_CreateVersion(version_to_year[version]))
+    # Check for express.
+    elif os.path.exists(os.path.join(path, 'vcexpress.exe')):
+      # Add this one.
+      versions.append(_CreateVersion(version_to_year[version] + 'e'))
+  return versions
+
+
+def SelectVisualStudioVersion(version='auto'):
+  """Select which version of Visual Studio projects to generate.
+
+  Arguments:
+    version: Hook to allow caller to force a particular version (vs auto).
+  Returns:
+    An object representing a visual studio project format version.
+  """
+  # In auto mode, check environment variable for override.
+  if version == 'auto':
+    version = os.environ.get('GYP_MSVS_VERSION', 'auto')
+  # In auto mode, pick the most preferred version present.
+  if version == 'auto':
+    versions = _DetectVisualStudioVersions()
+    if not versions:
+      # Default to 2005.
+      return _CreateVersion('2005')
+    return versions[0]
+  # Convert version string into a version object.
+  return _CreateVersion(version)
diff --git a/Source/ThirdParty/gyp/pylib/gyp/SCons.py b/Source/ThirdParty/gyp/pylib/gyp/SCons.py
new file mode 100644 (file)
index 0000000..9c57bcb
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+SCons generator.
+
+This contains class definitions and supporting functions for generating
+pieces of SCons files for the different types of GYP targets.
+"""
+
+import os
+
+
+def WriteList(fp, list, prefix='',
+                        separator=',\n    ',
+                        preamble=None,
+                        postamble=None):
+  fp.write(preamble or '')
+  fp.write((separator or ' ').join([prefix + l for l in list]))
+  fp.write(postamble or '')
+
+
+class TargetBase(object):
+  """
+  Base class for a SCons representation of a GYP target.
+  """
+  is_ignored = False
+  target_prefix = ''
+  target_suffix = ''
+  def __init__(self, spec):
+    self.spec = spec
+  def full_product_name(self):
+    """
+    Returns the full name of the product being built:
+
+      * Uses 'product_name' if it's set, else prefix + 'target_name'.
+      * Prepends 'product_dir' if set.
+      * Appends SCons suffix variables for the target type (or
+        product_extension).
+    """
+    suffix = self.target_suffix
+    product_extension = self.spec.get('product_extension')
+    if product_extension:
+      suffix = '.' + product_extension
+    prefix = self.spec.get('product_prefix', self.target_prefix)
+    name = self.spec['target_name']
+    name = prefix + self.spec.get('product_name', name) + suffix
+    product_dir = self.spec.get('product_dir')
+    if product_dir:
+      name = os.path.join(product_dir, name)
+    else:
+      name = os.path.join(self.out_dir, name)
+    return name
+
+  def write_input_files(self, fp):
+    """
+    Writes the definition of the input files (sources).
+    """
+    sources = self.spec.get('sources')
+    if not sources:
+      fp.write('\ninput_files = []\n')
+      return
+    preamble = '\ninput_files = [\n    '
+    postamble = ',\n]\n'
+    WriteList(fp, map(repr, sources), preamble=preamble, postamble=postamble)
+
+  def builder_call(self):
+    """
+    Returns the actual SCons builder call to build this target.
+    """
+    name = self.full_product_name()
+    return 'env.%s(env.File(%r), input_files)' % (self.builder_name, name)
+  def write_target(self, fp, src_dir='', pre=''):
+    """
+    Writes the lines necessary to build this target.
+    """
+    fp.write('\n' + pre)
+    fp.write('_outputs = %s\n' % self.builder_call())
+    fp.write('target_files.extend(_outputs)\n')
+
+
+class NoneTarget(TargetBase):
+  """
+  A GYP target type of 'none', implicitly or explicitly.
+  """
+  def write_target(self, fp, pre=''):
+    fp.write('\ntarget_files.extend(input_files)\n')
+
+
+class SettingsTarget(TargetBase):
+  """
+  A GYP target type of 'settings'.
+  """
+  is_ignored = True
+
+
+compilable_sources_template = """
+_result = []
+for infile in input_files:
+  if env.compilable(infile):
+    if (type(infile) == type('')
+        and (infile.startswith(%(src_dir)r)
+             or not os.path.isabs(env.subst(infile)))):
+      # Force files below the build directory by replacing all '..'
+      # elements in the path with '__':
+      base, ext = os.path.splitext(os.path.normpath(infile))
+      base = [d == '..' and '__' or d for d in base.split('/')]
+      base = os.path.join(*base)
+      object = '${OBJ_DIR}/${COMPONENT_NAME}/${TARGET_NAME}/' + base
+      if not infile.startswith(%(src_dir)r):
+        infile = %(src_dir)r + infile
+      infile = env.%(name)s(object, infile)[0]
+    else:
+      infile = env.%(name)s(infile)[0]
+  _result.append(infile)
+input_files = _result
+"""
+
+class CompilableSourcesTargetBase(TargetBase):
+  """
+  An abstract base class for targets that compile their source files.
+
+  We explicitly transform compilable files into object files,
+  even though SCons could infer that for us, because we want
+  to control where the object file ends up.  (The implicit rules
+  in SCons always put the object file next to the source file.)
+  """
+  intermediate_builder_name = None
+  def write_target(self, fp, src_dir='', pre=''):
+    if self.intermediate_builder_name is None:
+      raise NotImplementedError
+    if src_dir and not src_dir.endswith('/'):
+      src_dir += '/'
+    variables = {
+        'src_dir': src_dir,
+        'name': self.intermediate_builder_name,
+    }
+    fp.write(compilable_sources_template % variables)
+    super(CompilableSourcesTargetBase, self).write_target(fp)
+
+
+class ProgramTarget(CompilableSourcesTargetBase):
+  """
+  A GYP target type of 'executable'.
+  """
+  builder_name = 'GypProgram'
+  intermediate_builder_name = 'StaticObject'
+  target_prefix = '${PROGPREFIX}'
+  target_suffix = '${PROGSUFFIX}'
+  out_dir = '${TOP_BUILDDIR}'
+
+
+class StaticLibraryTarget(CompilableSourcesTargetBase):
+  """
+  A GYP target type of 'static_library'.
+  """
+  builder_name = 'GypStaticLibrary'
+  intermediate_builder_name = 'StaticObject'
+  target_prefix = '${LIBPREFIX}'
+  target_suffix = '${LIBSUFFIX}'
+  out_dir = '${LIB_DIR}'
+
+
+class SharedLibraryTarget(CompilableSourcesTargetBase):
+  """
+  A GYP target type of 'shared_library'.
+  """
+  builder_name = 'GypSharedLibrary'
+  intermediate_builder_name = 'SharedObject'
+  target_prefix = '${SHLIBPREFIX}'
+  target_suffix = '${SHLIBSUFFIX}'
+  out_dir = '${LIB_DIR}'
+
+
+class LoadableModuleTarget(CompilableSourcesTargetBase):
+  """
+  A GYP target type of 'loadable_module'.
+  """
+  builder_name = 'GypLoadableModule'
+  intermediate_builder_name = 'SharedObject'
+  target_prefix = '${SHLIBPREFIX}'
+  target_suffix = '${SHLIBSUFFIX}'
+  out_dir = '${TOP_BUILDDIR}'
+
+
+TargetMap = {
+  None : NoneTarget,
+  'none' : NoneTarget,
+  'settings' : SettingsTarget,
+  'executable' : ProgramTarget,
+  'static_library' : StaticLibraryTarget,
+  'shared_library' : SharedLibraryTarget,
+  'loadable_module' : LoadableModuleTarget,
+}
+
+def Target(spec):
+  return TargetMap[spec.get('type')](spec)
diff --git a/Source/ThirdParty/gyp/pylib/gyp/__init__.py b/Source/ThirdParty/gyp/pylib/gyp/__init__.py
new file mode 100644 (file)
index 0000000..4b088f6
--- /dev/null
@@ -0,0 +1,461 @@
+#!/usr/bin/python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import copy
+import gyp.input
+import optparse
+import os.path
+import re
+import shlex
+import sys
+
+# Default debug modes for GYP
+debug = {}
+
+# List of "official" debug modes, but you can use anything you like.
+DEBUG_GENERAL = 'general'
+DEBUG_VARIABLES = 'variables'
+DEBUG_INCLUDES = 'includes'
+
+def DebugOutput(mode, message):
+  if mode in gyp.debug.keys():
+    print "%s: %s" % (mode.upper(), message)
+
+def FindBuildFiles():
+  extension = '.gyp'
+  files = os.listdir(os.getcwd())
+  build_files = []
+  for file in files:
+    if file[-len(extension):] == extension:
+      build_files.append(file)
+  return build_files
+
+
+def Load(build_files, format, default_variables={},
+         includes=[], depth='.', params={}, check=False, circular_check=True):
+  """
+  Loads one or more specified build files.
+  default_variables and includes will be copied before use.
+  Returns the generator for the specified format and the
+  data returned by loading the specified build files.
+  """
+  default_variables = copy.copy(default_variables)
+
+  # Default variables provided by this program and its modules should be
+  # named WITH_CAPITAL_LETTERS to provide a distinct "best practice" namespace,
+  # avoiding collisions with user and automatic variables.
+  default_variables['GENERATOR'] = format
+
+  generator_name = 'gyp.generator.' + format
+  # These parameters are passed in order (as opposed to by key)
+  # because ActivePython cannot handle key parameters to __import__.
+  generator = __import__(generator_name, globals(), locals(), generator_name)
+  for (key, val) in generator.generator_default_variables.items():
+    default_variables.setdefault(key, val)
+
+  # Give the generator the opportunity to set additional variables based on
+  # the params it will receive in the output phase.
+  if getattr(generator, 'CalculateVariables', None):
+    generator.CalculateVariables(default_variables, params)
+
+  # Fetch the generator specific info that gets fed to input, we use getattr
+  # so we can default things and the generators only have to provide what
+  # they need.
+  generator_input_info = {
+    'generator_wants_absolute_build_file_paths':
+        getattr(generator, 'generator_wants_absolute_build_file_paths', False),
+    'generator_handles_variants':
+        getattr(generator, 'generator_handles_variants', False),
+    'non_configuration_keys':
+        getattr(generator, 'generator_additional_non_configuration_keys', []),
+    'path_sections':
+        getattr(generator, 'generator_additional_path_sections', []),
+    'extra_sources_for_rules':
+        getattr(generator, 'generator_extra_sources_for_rules', []),
+    'generator_supports_multiple_toolsets':
+        getattr(generator, 'generator_supports_multiple_toolsets', False),
+  }
+
+  # Process the input specific to this generator.
+  result = gyp.input.Load(build_files, default_variables, includes[:],
+                          depth, generator_input_info, check, circular_check)
+  return [generator] + result
+
+def NameValueListToDict(name_value_list):
+  """
+  Takes an array of strings of the form 'NAME=VALUE' and creates a dictionary
+  of the pairs.  If a string is simply NAME, then the value in the dictionary
+  is set to True.  If VALUE can be converted to an integer, it is.
+  """
+  result = { }
+  for item in name_value_list:
+    tokens = item.split('=', 1)
+    if len(tokens) == 2:
+      # If we can make it an int, use that, otherwise, use the string.
+      try:
+        token_value = int(tokens[1])
+      except ValueError:
+        token_value = tokens[1]
+      # Set the variable to the supplied value.
+      result[tokens[0]] = token_value
+    else:
+      # No value supplied, treat it as a boolean and set it.
+      result[tokens[0]] = True
+  return result
+
+def ShlexEnv(env_name):
+  flags = os.environ.get(env_name, [])
+  if flags:
+    flags = shlex.split(flags)
+  return flags
+
+def FormatOpt(opt, value):
+  if opt.startswith('--'):
+    return '%s=%s' % (opt, value)
+  return opt + value
+
+def RegenerateAppendFlag(flag, values, predicate, env_name, options):
+  """Regenerate a list of command line flags, for an option of action='append'.
+
+  The |env_name|, if given, is checked in the environment and used to generate
+  an initial list of options, then the options that were specified on the
+  command line (given in |values|) are appended.  This matches the handling of
+  environment variables and command line flags where command line flags override
+  the environment, while not requiring the environment to be set when the flags
+  are used again.
+  """
+  flags = []
+  if options.use_environment and env_name:
+    for flag_value in ShlexEnv(env_name):
+      flags.append(FormatOpt(flag, predicate(flag_value)))
+  if values:
+    for flag_value in values:
+      flags.append(FormatOpt(flag, predicate(flag_value)))
+  return flags
+
+def RegenerateFlags(options):
+  """Given a parsed options object, and taking the environment variables into
+  account, returns a list of flags that should regenerate an equivalent options
+  object (even in the absence of the environment variables.)
+
+  Any path options will be normalized relative to depth.
+
+  The format flag is not included, as it is assumed the calling generator will
+  set that as appropriate.
+  """
+  def FixPath(path):
+    path = gyp.common.FixIfRelativePath(path, options.depth)
+    if not path:
+      return os.path.curdir
+    return path
+
+  def Noop(value):
+    return value
+
+  # We always want to ignore the environment when regenerating, to avoid
+  # duplicate or changed flags in the environment at the time of regeneration.
+  flags = ['--ignore-environment']
+  for name, metadata in options._regeneration_metadata.iteritems():
+    opt = metadata['opt']
+    value = getattr(options, name)
+    value_predicate = metadata['type'] == 'path' and FixPath or Noop
+    action = metadata['action']
+    env_name = metadata['env_name']
+    if action == 'append':
+      flags.extend(RegenerateAppendFlag(opt, value, value_predicate,
+                                        env_name, options))
+    elif action in ('store', None):  # None is a synonym for 'store'.
+      if value:
+        flags.append(FormatOpt(opt, value_predicate(value)))
+      elif options.use_environment and env_name and os.environ.get(env_name):
+        flags.append(FormatOpt(opt, value_predicate(os.environ.get(env_name))))
+    elif action in ('store_true', 'store_false'):
+      if ((action == 'store_true' and value) or
+          (action == 'store_false' and not value)):
+        flags.append(opt)
+      elif options.use_environment and env_name:
+        print >>sys.stderr, ('Warning: environment regeneration unimplemented '
+                             'for %s flag %r env_name %r' % (action, opt,
+                                                             env_name))
+    else:
+      print >>sys.stderr, ('Warning: regeneration unimplemented for action %r '
+                           'flag %r' % (action, opt))
+
+  return flags
+
+class RegeneratableOptionParser(optparse.OptionParser):
+  def __init__(self):
+    self.__regeneratable_options = {}
+    optparse.OptionParser.__init__(self)
+
+  def add_option(self, *args, **kw):
+    """Add an option to the parser.
+
+    This accepts the same arguments as OptionParser.add_option, plus the
+    following:
+      regenerate: can be set to False to prevent this option from being included
+                  in regeneration.
+      env_name: name of environment variable that additional values for this
+                option come from.
+      type: adds type='path', to tell the regenerator that the values of
+            this option need to be made relative to options.depth
+    """
+    env_name = kw.pop('env_name', None)
+    if 'dest' in kw and kw.pop('regenerate', True):
+      dest = kw['dest']
+
+      # The path type is needed for regenerating, for optparse we can just treat
+      # it as a string.
+      type = kw.get('type')
+      if type == 'path':
+        kw['type'] = 'string'
+
+      self.__regeneratable_options[dest] = {
+          'action': kw.get('action'),
+          'type': type,
+          'env_name': env_name,
+          'opt': args[0],
+        }
+
+    optparse.OptionParser.add_option(self, *args, **kw)
+
+  def parse_args(self, *args):
+    values, args = optparse.OptionParser.parse_args(self, *args)
+    values._regeneration_metadata = self.__regeneratable_options
+    return values, args
+
+def main(args):
+  my_name = os.path.basename(sys.argv[0])
+
+  parser = RegeneratableOptionParser()
+  usage = 'usage: %s [options ...] [build_file ...]'
+  parser.set_usage(usage.replace('%s', '%prog'))
+  parser.add_option('-D', dest='defines', action='append', metavar='VAR=VAL',
+                    env_name='GYP_DEFINES',
+                    help='sets variable VAR to value VAL')
+  parser.add_option('-f', '--format', dest='formats', action='append',
+                    env_name='GYP_GENERATORS', regenerate=False,
+                    help='output formats to generate')
+  parser.add_option('--msvs-version', dest='msvs_version',
+                    regenerate=False,
+                    help='Deprecated; use -G msvs_version=MSVS_VERSION instead')
+  parser.add_option('-I', '--include', dest='includes', action='append',
+                    metavar='INCLUDE', type='path',
+                    help='files to include in all loaded .gyp files')
+  parser.add_option('--depth', dest='depth', metavar='PATH', type='path',
+                    help='set DEPTH gyp variable to a relative path to PATH')
+  parser.add_option('-d', '--debug', dest='debug', metavar='DEBUGMODE',
+                    action='append', default=[], help='turn on a debugging '
+                    'mode for debugging GYP.  Supported modes are "variables" '
+                    'and "general"')
+  parser.add_option('-S', '--suffix', dest='suffix', default='',
+                    help='suffix to add to generated files')
+  parser.add_option('-G', dest='generator_flags', action='append', default=[],
+                    metavar='FLAG=VAL', env_name='GYP_GENERATOR_FLAGS',
+                    help='sets generator flag FLAG to VAL')
+  parser.add_option('--generator-output', dest='generator_output',
+                    action='store', default=None, metavar='DIR', type='path',
+                    env_name='GYP_GENERATOR_OUTPUT',
+                    help='puts generated build files under DIR')
+  parser.add_option('--ignore-environment', dest='use_environment',
+                    action='store_false', default=True, regenerate=False,
+                    help='do not read options from environment variables')
+  parser.add_option('--check', dest='check', action='store_true',
+                    help='check format of gyp files')
+  parser.add_option('--toplevel-dir', dest='toplevel_dir', action='store',
+                    default=None, metavar='DIR', type='path',
+                    help='directory to use as the root of the source tree')
+  # --no-circular-check disables the check for circular relationships between
+  # .gyp files.  These relationships should not exist, but they've only been
+  # observed to be harmful with the Xcode generator.  Chromium's .gyp files
+  # currently have some circular relationships on non-Mac platforms, so this
+  # option allows the strict behavior to be used on Macs and the lenient
+  # behavior to be used elsewhere.
+  # TODO(mark): Remove this option when http://crbug.com/35878 is fixed.
+  parser.add_option('--no-circular-check', dest='circular_check',
+                    action='store_false', default=True, regenerate=False,
+                    help="don't check for circular relationships between files")
+
+  # We read a few things from ~/.gyp, so set up a var for that.
+  home_vars = ['HOME']
+  if sys.platform in ('cygwin', 'win32'):
+    home_vars.append('USERPROFILE')
+  home = None
+  home_dot_gyp = None
+  for home_var in home_vars:
+    home = os.getenv(home_var)
+    if home != None:
+      home_dot_gyp = os.path.join(home, '.gyp')
+      if not os.path.exists(home_dot_gyp):
+        home_dot_gyp = None
+      else:
+        break
+
+  # TODO(thomasvl): add support for ~/.gyp/defaults
+
+  options, build_files_arg = parser.parse_args(args)
+  build_files = build_files_arg
+
+  if not options.formats:
+    # If no format was given on the command line, then check the env variable.
+    generate_formats = []
+    if options.use_environment:
+      generate_formats = os.environ.get('GYP_GENERATORS', [])
+    if generate_formats:
+      generate_formats = re.split('[\s,]', generate_formats)
+    if generate_formats:
+      options.formats = generate_formats
+    else:
+      # Nothing in the variable, default based on platform.
+      options.formats = [ {'darwin':   'xcode',
+                           'win32':    'msvs',
+                           'cygwin':   'msvs',
+                           'freebsd7': 'make',
+                           'freebsd8': 'make',
+                           'linux2':   'make',
+                           'openbsd4': 'make',
+                           'sunos5':   'make',}[sys.platform] ]
+
+  if not options.generator_output and options.use_environment:
+    g_o = os.environ.get('GYP_GENERATOR_OUTPUT')
+    if g_o:
+      options.generator_output = g_o
+
+  for mode in options.debug:
+    gyp.debug[mode] = 1
+
+  # Do an extra check to avoid work when we're not debugging.
+  if DEBUG_GENERAL in gyp.debug.keys():
+    DebugOutput(DEBUG_GENERAL, 'running with these options:')
+    for option, value in sorted(options.__dict__.items()):
+      if option[0] == '_':
+        continue
+      if isinstance(value, basestring):
+        DebugOutput(DEBUG_GENERAL, "  %s: '%s'" % (option, value))
+      else:
+        DebugOutput(DEBUG_GENERAL, "  %s: %s" % (option, str(value)))
+
+  if not build_files:
+    build_files = FindBuildFiles()
+  if not build_files:
+    print >>sys.stderr, (usage + '\n\n%s: error: no build_file') % \
+                        (my_name, my_name)
+    return 1
+
+  # TODO(mark): Chromium-specific hack!
+  # For Chromium, the gyp "depth" variable should always be a relative path
+  # to Chromium's top-level "src" directory.  If no depth variable was set
+  # on the command line, try to find a "src" directory by looking at the
+  # absolute path to each build file's directory.  The first "src" component
+  # found will be treated as though it were the path used for --depth.
+  if not options.depth:
+    for build_file in build_files:
+      build_file_dir = os.path.abspath(os.path.dirname(build_file))
+      build_file_dir_components = build_file_dir.split(os.path.sep)
+      components_len = len(build_file_dir_components)
+      for index in xrange(components_len - 1, -1, -1):
+        if build_file_dir_components[index] == 'src':
+          options.depth = os.path.sep.join(build_file_dir_components)
+          break
+        del build_file_dir_components[index]
+
+      # If the inner loop found something, break without advancing to another
+      # build file.
+      if options.depth:
+        break
+
+    if not options.depth:
+      raise Exception, \
+            'Could not automatically locate src directory.  This is a ' + \
+            'temporary Chromium feature that will be removed.  Use ' + \
+            '--depth as a workaround.'
+
+  # If toplevel-dir is not set, we assume that depth is the root of our source
+  # tree.
+  if not options.toplevel_dir:
+    options.toplevel_dir = options.depth
+
+  # -D on the command line sets variable defaults - D isn't just for define,
+  # it's for default.  Perhaps there should be a way to force (-F?) a
+  # variable's value so that it can't be overridden by anything else.
+  cmdline_default_variables = {}
+  defines = []
+  if options.use_environment:
+    defines += ShlexEnv('GYP_DEFINES')
+  if options.defines:
+    defines += options.defines
+  cmdline_default_variables = NameValueListToDict(defines)
+  if DEBUG_GENERAL in gyp.debug.keys():
+    DebugOutput(DEBUG_GENERAL,
+                "cmdline_default_variables: %s" % cmdline_default_variables)
+
+  # Set up includes.
+  includes = []
+
+  # If ~/.gyp/include.gypi exists, it'll be forcibly included into every
+  # .gyp file that's loaded, before anything else is included.
+  if home_dot_gyp != None:
+    default_include = os.path.join(home_dot_gyp, 'include.gypi')
+    if os.path.exists(default_include):
+      includes.append(default_include)
+
+  # Command-line --include files come after the default include.
+  if options.includes:
+    includes.extend(options.includes)
+
+  # Generator flags should be prefixed with the target generator since they
+  # are global across all generator runs.
+  gen_flags = []
+  if options.use_environment:
+    gen_flags += ShlexEnv('GYP_GENERATOR_FLAGS')
+  if options.generator_flags:
+    gen_flags += options.generator_flags
+  generator_flags = NameValueListToDict(gen_flags)
+  if DEBUG_GENERAL in gyp.debug.keys():
+    DebugOutput(DEBUG_GENERAL, "generator_flags: %s" % generator_flags)
+
+  # TODO: Remove this and the option after we've gotten folks to move to the
+  # generator flag.
+  if options.msvs_version:
+    print >>sys.stderr, \
+      'DEPRECATED: Use generator flag (-G msvs_version=' + \
+      options.msvs_version + ') instead of --msvs-version=' + \
+      options.msvs_version
+    generator_flags['msvs_version'] = options.msvs_version
+
+  # Generate all requested formats (use a set in case we got one format request
+  # twice)
+  for format in set(options.formats):
+    params = {'options': options,
+              'build_files': build_files,
+              'generator_flags': generator_flags,
+              'cwd': os.getcwd(),
+              'build_files_arg': build_files_arg,
+              'gyp_binary': sys.argv[0],
+              'home_dot_gyp': home_dot_gyp}
+
+    # Start with the default variables from the command line.
+    [generator, flat_list, targets, data] = Load(build_files, format,
+                                                 cmdline_default_variables,
+                                                 includes, options.depth,
+                                                 params, options.check,
+                                                 options.circular_check)
+
+    # TODO(mark): Pass |data| for now because the generator needs a list of
+    # build files that came in.  In the future, maybe it should just accept
+    # a list, and not the whole data dict.
+    # NOTE: flat_list is the flattened dependency graph specifying the order
+    # that targets may be built.  Build systems that operate serially or that
+    # need to have dependencies defined before dependents reference them should
+    # generate targets in the order specified in flat_list.
+    generator.GenerateOutput(flat_list, targets, data, params)
+
+  # Done
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))
diff --git a/Source/ThirdParty/gyp/pylib/gyp/common.py b/Source/ThirdParty/gyp/pylib/gyp/common.py
new file mode 100644 (file)
index 0000000..bae3ae7
--- /dev/null
@@ -0,0 +1,345 @@
+#!/usr/bin/python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import errno
+import filecmp
+import os.path
+import re
+import tempfile
+import sys
+
+def ExceptionAppend(e, msg):
+  """Append a message to the given exception's message."""
+  if not e.args:
+    e.args = (msg,)
+  elif len(e.args) == 1:
+    e.args = (str(e.args[0]) + ' ' + msg,)
+  else:
+    e.args = (str(e.args[0]) + ' ' + msg,) + e.args[1:]
+
+
+def ParseQualifiedTarget(target):
+  # Splits a qualified target into a build file, target name and toolset.
+
+  # NOTE: rsplit is used to disambiguate the Windows drive letter separator.
+  target_split = target.rsplit(':', 1)
+  if len(target_split) == 2:
+    [build_file, target] = target_split
+  else:
+    build_file = None
+
+  target_split = target.rsplit('#', 1)
+  if len(target_split) == 2:
+    [target, toolset] = target_split
+  else:
+    toolset = None
+
+  return [build_file, target, toolset]
+
+
+def ResolveTarget(build_file, target, toolset):
+  # This function resolves a target into a canonical form:
+  # - a fully defined build file, either absolute or relative to the current
+  # directory
+  # - a target name
+  # - a toolset
+  #
+  # build_file is the file relative to which 'target' is defined.
+  # target is the qualified target.
+  # toolset is the default toolset for that target.
+  [parsed_build_file, target, parsed_toolset] = ParseQualifiedTarget(target)
+
+  if parsed_build_file:
+    if build_file:
+      # If a relative path, parsed_build_file is relative to the directory
+      # containing build_file.  If build_file is not in the current directory,
+      # parsed_build_file is not a usable path as-is.  Resolve it by
+      # interpreting it as relative to build_file.  If parsed_build_file is
+      # absolute, it is usable as a path regardless of the current directory,
+      # and os.path.join will return it as-is.
+      build_file = os.path.normpath(os.path.join(os.path.dirname(build_file),
+                                                 parsed_build_file))
+    else:
+      build_file = parsed_build_file
+
+  if parsed_toolset:
+    toolset = parsed_toolset
+
+  return [build_file, target, toolset]
+
+
+def BuildFile(fully_qualified_target):
+  # Extracts the build file from the fully qualified target.
+  return ParseQualifiedTarget(fully_qualified_target)[0]
+
+
+def QualifiedTarget(build_file, target, toolset):
+  # "Qualified" means the file that a target was defined in and the target
+  # name, separated by a colon, suffixed by a # and the toolset name:
+  # /path/to/file.gyp:target_name#toolset
+  fully_qualified = build_file + ':' + target
+  if toolset:
+    fully_qualified = fully_qualified + '#' + toolset
+  return fully_qualified
+
+
+def RelativePath(path, relative_to):
+  # Assuming both |path| and |relative_to| are relative to the current
+  # directory, returns a relative path that identifies path relative to
+  # relative_to.
+
+  # Convert to absolute (and therefore normalized paths).
+  path = os.path.abspath(path)
+  relative_to = os.path.abspath(relative_to)
+
+  # Split the paths into components.
+  path_split = path.split(os.path.sep)
+  relative_to_split = relative_to.split(os.path.sep)
+
+  # Determine how much of the prefix the two paths share.
+  prefix_len = len(os.path.commonprefix([path_split, relative_to_split]))
+
+  # Put enough ".." components to back up out of relative_to to the common
+  # prefix, and then append the part of path_split after the common prefix.
+  relative_split = [os.path.pardir] * (len(relative_to_split) - prefix_len) + \
+                   path_split[prefix_len:]
+
+  if len(relative_split) == 0:
+    # The paths were the same.
+    return ''
+
+  # Turn it back into a string and we're done.
+  return os.path.join(*relative_split)
+
+
+def FixIfRelativePath(path, relative_to):
+  # Like RelativePath but returns |path| unchanged if it is absolute.
+  if os.path.isabs(path):
+    return path
+  return RelativePath(path, relative_to)
+
+
+def UnrelativePath(path, relative_to):
+  # Assuming that |relative_to| is relative to the current directory, and |path|
+  # is a path relative to the dirname of |relative_to|, returns a path that
+  # identifies |path| relative to the current directory.
+  rel_dir = os.path.dirname(relative_to)
+  return os.path.normpath(os.path.join(rel_dir, path))
+
+
+# re objects used by EncodePOSIXShellArgument.  See IEEE 1003.1 XCU.2.2 at
+# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_02
+# and the documentation for various shells.
+
+# _quote is a pattern that should match any argument that needs to be quoted
+# with double-quotes by EncodePOSIXShellArgument.  It matches the following
+# characters appearing anywhere in an argument:
+#   \t, \n, space  parameter separators
+#   #              comments
+#   $              expansions (quoted to always expand within one argument)
+#   %              called out by IEEE 1003.1 XCU.2.2
+#   &              job control
+#   '              quoting
+#   (, )           subshell execution
+#   *, ?, [        pathname expansion
+#   ;              command delimiter
+#   <, >, |        redirection
+#   =              assignment
+#   {, }           brace expansion (bash)
+#   ~              tilde expansion
+# It also matches the empty string, because "" (or '') is the only way to
+# represent an empty string literal argument to a POSIX shell.
+#
+# This does not match the characters in _escape, because those need to be
+# backslash-escaped regardless of whether they appear in a double-quoted
+# string.
+_quote = re.compile('[\t\n #$%&\'()*;<=>?[{|}~]|^$')
+
+# _escape is a pattern that should match any character that needs to be
+# escaped with a backslash, whether or not the argument matched the _quote
+# pattern.  _escape is used with re.sub to backslash anything in _escape's
+# first match group, hence the (parentheses) in the regular expression.
+#
+# _escape matches the following characters appearing anywhere in an argument:
+#   "  to prevent POSIX shells from interpreting this character for quoting
+#   \  to prevent POSIX shells from interpreting this character for escaping
+#   `  to prevent POSIX shells from interpreting this character for command
+#      substitution
+# Missing from this list is $, because the desired behavior of
+# EncodePOSIXShellArgument is to permit parameter (variable) expansion.
+#
+# Also missing from this list is !, which bash will interpret as the history
+# expansion character when history is enabled.  bash does not enable history
+# by default in non-interactive shells, so this is not thought to be a problem.
+# ! was omitted from this list because bash interprets "\!" as a literal string
+# including the backslash character (avoiding history expansion but retaining
+# the backslash), which would not be correct for argument encoding.  Handling
+# this case properly would also be problematic because bash allows the history
+# character to be changed with the histchars shell variable.  Fortunately,
+# as history is not enabled in non-interactive shells and
+# EncodePOSIXShellArgument is only expected to encode for non-interactive
+# shells, there is no room for error here by ignoring !.
+_escape = re.compile(r'(["\\`])')
+
+def EncodePOSIXShellArgument(argument):
+  """Encodes |argument| suitably for consumption by POSIX shells.
+
+  argument may be quoted and escaped as necessary to ensure that POSIX shells
+  treat the returned value as a literal representing the argument passed to
+  this function.  Parameter (variable) expansions beginning with $ are allowed
+  to remain intact without escaping the $, to allow the argument to contain
+  references to variables to be expanded by the shell.
+  """
+
+  if not isinstance(argument, str):
+    argument = str(argument)
+
+  if _quote.search(argument):
+    quote = '"'
+  else:
+    quote = ''
+
+  encoded = quote + re.sub(_escape, r'\\\1', argument) + quote
+
+  return encoded
+
+
+def EncodePOSIXShellList(list):
+  """Encodes |list| suitably for consumption by POSIX shells.
+
+  Returns EncodePOSIXShellArgument for each item in list, and joins them
+  together using the space character as an argument separator.
+  """
+
+  encoded_arguments = []
+  for argument in list:
+    encoded_arguments.append(EncodePOSIXShellArgument(argument))
+  return ' '.join(encoded_arguments)
+
+
+def DeepDependencyTargets(target_dicts, roots):
+  """Returns the recursive list of target dependencies."""
+  dependencies = set()
+  pending = set(roots)
+  while pending:
+    # Pluck out one.
+    r = pending.pop()
+    # Skip if visited already.
+    if r in dependencies:
+      continue
+    # Add it.
+    dependencies.add(r)
+    # Add its children.
+    spec = target_dicts[r]
+    pending.update(set(spec.get('dependencies', [])))
+    pending.update(set(spec.get('dependencies_original', [])))
+  return list(dependencies - set(roots))
+
+
+def BuildFileTargets(target_list, build_file):
+  """From a target_list, returns the subset from the specified build_file.
+  """
+  return [p for p in target_list if BuildFile(p) == build_file]
+
+
+def AllTargets(target_list, target_dicts, build_file):
+  """Returns all targets (direct and dependencies) for the specified build_file.
+  """
+  bftargets = BuildFileTargets(target_list, build_file)
+  deptargets = DeepDependencyTargets(target_dicts, bftargets)
+  return bftargets + deptargets
+
+
+def WriteOnDiff(filename):
+  """Write to a file only if the new contents differ.
+
+  Arguments:
+    filename: name of the file to potentially write to.
+  Returns:
+    A file like object which will write to temporary file and only overwrite
+    the target if it differs (on close).
+  """
+
+  class Writer:
+    """Wrapper around file which only covers the target if it differs."""
+    def __init__(self):
+      # Pick temporary file.
+      tmp_fd, self.tmp_path = tempfile.mkstemp(
+          suffix='.tmp',
+          prefix=os.path.split(filename)[1] + '.gyp.',
+          dir=os.path.split(filename)[0])
+      try:
+        self.tmp_file = os.fdopen(tmp_fd, 'wb')
+      except Exception:
+        # Don't leave turds behind.
+        os.unlink(self.tmp_path)
+        raise
+
+    def __getattr__(self, attrname):
+      # Delegate everything else to self.tmp_file
+      return getattr(self.tmp_file, attrname)
+
+    def close(self):
+      try:
+        # Close tmp file.
+        self.tmp_file.close()
+        # Determine if different.
+        same = False
+        try:
+          same = filecmp.cmp(self.tmp_path, filename, False)
+        except OSError, e:
+          if e.errno != errno.ENOENT:
+            raise
+
+        if same:
+          # The new file is identical to the old one, just get rid of the new
+          # one.
+          os.unlink(self.tmp_path)
+        else:
+          # The new file is different from the old one, or there is no old one.
+          # Rename the new file to the permanent name.
+          #
+          # tempfile.mkstemp uses an overly restrictive mode, resulting in a
+          # file that can only be read by the owner, regardless of the umask.
+          # There's no reason to not respect the umask here, which means that
+          # an extra hoop is required to fetch it and reset the new file's mode.
+          #
+          # No way to get the umask without setting a new one?  Set a safe one
+          # and then set it back to the old value.
+          umask = os.umask(077)
+          os.umask(umask)
+          os.chmod(self.tmp_path, 0666 & ~umask)
+          if sys.platform == 'win32' and os.path.exists(filename):
+            # NOTE: on windows (but not cygwin) rename will not replace an
+            # existing file, so it must be preceded with a remove. Sadly there
+            # is no way to make the switch atomic.
+            os.remove(filename)
+          os.rename(self.tmp_path, filename)
+      except Exception:
+        # Don't leave turds behind.
+        os.unlink(self.tmp_path)
+        raise
+
+  return Writer()
+
+
+# From Alex Martelli,
+# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560
+# ASPN: Python Cookbook: Remove duplicates from a sequence
+# First comment, dated 2001/10/13.
+# (Also in the printed Python Cookbook.)
+
+def uniquer(seq, idfun=None):
+    if idfun is None:
+        def idfun(x): return x
+    seen = {}
+    result = []
+    for item in seq:
+        marker = idfun(item)
+        if marker in seen: continue
+        seen[marker] = 1
+        result.append(item)
+    return result
diff --git a/Source/ThirdParty/gyp/pylib/gyp/easy_xml.py b/Source/ThirdParty/gyp/pylib/gyp/easy_xml.py
new file mode 100644 (file)
index 0000000..98e2923
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/python
+
+# Copyright (c) 2011 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import xml.dom
+import xml_fix
+import common
+
+class EasyXml(object):
+  """ Class to easily create XML files with substantial pre-defined structures.
+
+  Visual Studio files have a lot of pre-defined structures.  This class makes
+  it easy to represent these structures as Python data structures, instead of
+  having to create a lot of function calls.
+
+  For this class, an XML element is represented as a list composed of:
+  1. The name of the element, a string,
+  2. The attributes of the element, an dictionary (optional), and
+  3+. The content of the element, if any.  Strings are simple text nodes and
+      lists are child elements.
+
+  Example 1:
+      <test/>
+  becomes
+      ['test']
+
+  Example 2:
+      <myelement a='value1' b='value2'>
+         <childtype>This is</childtype>
+         <childtype>it!</childtype>
+      </myelement>
+
+  becomes
+      ['myelement', {'a':'value1', 'b':'value2'},
+         ['childtype', 'This is'],
+         ['childtype', 'it!'],
+      ]
+  """
+
+  def __init__(self, name, attributes=None):
+    """ Constructs an object representing an XML document.
+
+    Args:
+      name:  A string, the name of the root element.
+      attributes:  A dictionary, the attributes of the root.
+    """
+    xml_impl = xml.dom.getDOMImplementation()
+    self.doc = xml_impl.createDocument(None, name, None)
+    if attributes:
+      self.SetAttributes(self.doc.documentElement, attributes)
+
+  def AppendChildren(self, parent, children_specifications):
+    """ Appends multiple children.
+
+    Args:
+      parent:  The node to which the children will be added.
+      children_specifications:  A list of node specifications.
+    """
+    for specification in children_specifications:
+      # If it's a string, append a text node.
+      # Otherwise append an XML node.
+      if isinstance(specification, str):
+        parent.appendChild(self.doc.createTextNode(specification))
+      else:
+        self.AppendNode(parent, specification)
+
+  def AppendNode(self, parent, specification):
+    """ Appends multiple children.
+
+    Args:
+      parent:  The node to which the child will be added.
+      children_specifications:  A list, the node specification.  The first
+          entry is the name of the element.  If the second entry is a
+          dictionary, it is the attributes.  The remaining entries of the
+          list are the sub-elements.
+    Returns:
+      The XML element created.
+    """
+    name = specification[0]
+    if not isinstance(name, str):
+      raise Exception('The first item of an EasyXml specification should be '
+                      'a string.  Specification was ' + str(specification))
+    element = self.doc.createElement(name)
+    parent.appendChild(element)
+    rest = specification[1:]
+    # The second element is optionally a dictionary of the attributes.
+    if rest and isinstance(rest[0], dict):
+      self.SetAttributes(element, rest[0])
+      rest = rest[1:]
+    if rest:
+      self.AppendChildren(element, rest)
+    return element
+
+  def SetAttributes(self, element, attribute_description):
+    """ Sets the attributes of an element.
+
+    Args:
+      element:  The node to which the child will be added.
+      attribute_description:  A dictionary that maps attribute names to
+          attribute values.
+    """
+    for attribute, value in attribute_description.iteritems():
+      element.setAttribute(attribute, value)
+
+  def Root(self):
+    """ Returns the root element. """
+    return self.doc.documentElement
+
+  def WriteIfChanged(self, path):
+    """ Writes the XML doc but don't touch the file if unchanged. """
+    f = common.WriteOnDiff(path)
+    fix = xml_fix.XmlFix()
+    self.doc.writexml(f, encoding='utf-8', addindent='', newl='')
+    fix.Cleanup()
+    f.close()
+
+  def __str__(self):
+    """ Converts the doc to a string. """
+    return self.doc.toxml()
diff --git a/Source/ThirdParty/gyp/pylib/gyp/easy_xml_test.py b/Source/ThirdParty/gyp/pylib/gyp/easy_xml_test.py
new file mode 100644 (file)
index 0000000..e34821f
--- /dev/null
@@ -0,0 +1,92 @@
+#!/usr/bin/python
+
+# Copyright (c) 2011 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+""" Unit tests for the easy_xml.py file. """
+
+import easy_xml
+import unittest
+import StringIO
+
+
+class TestSequenceFunctions(unittest.TestCase):
+
+  def setUp(self):
+    self.stderr = StringIO.StringIO()
+
+  def test_EasyXml_simple(self):
+    xml = easy_xml.EasyXml('test')
+    self.assertEqual(str(xml), '<?xml version="1.0" ?><test/>')
+
+  def test_EasyXml_simple_with_attributes(self):
+    xml = easy_xml.EasyXml('test2', {'a': 'value1', 'b': 'value2'})
+    self.assertEqual(str(xml),
+                     '<?xml version="1.0" ?><test2 a="value1" b="value2"/>')
+
+  def test_EasyXml_add_node(self):
+    # We want to create:
+    target = ('<?xml version="1.0" ?>'
+        '<test3>'
+          '<GrandParent>'
+            '<Parent1>'
+               '<Child/>'
+            '</Parent1>'
+            '<Parent2/>'
+          '</GrandParent>'
+        '</test3>')
+
+    # Do it the hard way first:
+    xml = easy_xml.EasyXml('test3')
+    grand_parent = xml.AppendNode(xml.Root(), ['GrandParent'])
+    parent1 = xml.AppendNode(grand_parent, ['Parent1'])
+    parent2 = xml.AppendNode(grand_parent, ['Parent2'])
+    xml.AppendNode(parent1, ['Child'])
+    self.assertEqual(str(xml), target)
+
+    # Do it the easier way:
+    xml = easy_xml.EasyXml('test3')
+    xml.AppendNode(xml.Root(),
+        ['GrandParent',
+            ['Parent1', ['Child']],
+            ['Parent2']])
+    self.assertEqual(str(xml), target)
+
+  def test_EasyXml_complex(self):
+    # We want to create:
+    target = ('<?xml version="1.0" ?>'
+        '<Project>'
+          '<PropertyGroup Label="Globals">'
+            '<ProjectGuid>{D2250C20-3A94-4FB9-AF73-11BC5B73884B}</ProjectGuid>'
+            '<Keyword>Win32Proj</Keyword>'
+            '<RootNamespace>automated_ui_tests</RootNamespace>'
+          '</PropertyGroup>'
+          '<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props"/>'
+          '<PropertyGroup Condition="\'$(Configuration)|$(Platform)\'==\''
+                                      'Debug|Win32\'" Label="Configuration">'
+            '<ConfigurationType>Application</ConfigurationType>'
+            '<CharacterSet>Unicode</CharacterSet>'
+          '</PropertyGroup>'
+        '</Project>')
+
+    xml = easy_xml.EasyXml('Project')
+    xml.AppendChildren(xml.Root(), [
+        ['PropertyGroup', {'Label': 'Globals'},
+            ['ProjectGuid', '{D2250C20-3A94-4FB9-AF73-11BC5B73884B}'],
+            ['Keyword', 'Win32Proj'],
+            ['RootNamespace', 'automated_ui_tests']
+        ],
+        ['Import', {'Project': '$(VCTargetsPath)\\Microsoft.Cpp.props'}],
+        ['PropertyGroup',
+            {'Condition': "'$(Configuration)|$(Platform)'=='Debug|Win32'",
+                'Label': 'Configuration'},
+            ['ConfigurationType', 'Application'],
+            ['CharacterSet', 'Unicode']
+        ]
+    ])
+    self.assertEqual(str(xml), target)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/Source/ThirdParty/gyp/pylib/gyp/generator/__init__.py b/Source/ThirdParty/gyp/pylib/gyp/generator/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Source/ThirdParty/gyp/pylib/gyp/generator/gypd.py b/Source/ThirdParty/gyp/pylib/gyp/generator/gypd.py
new file mode 100644 (file)
index 0000000..948f0b8
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""gypd output module
+
+This module produces gyp input as its output.  Output files are given the
+.gypd extension to avoid overwriting the .gyp files that they are generated
+from.  Internal references to .gyp files (such as those found in
+"dependencies" sections) are not adjusted to point to .gypd files instead;
+unlike other paths, which are relative to the .gyp or .gypd file, such paths
+are relative to the directory from which gyp was run to create the .gypd file.
+
+This generator module is intended to be a sample and a debugging aid, hence
+the "d" for "debug" in .gypd.  It is useful to inspect the results of the
+various merges, expansions, and conditional evaluations performed by gyp
+and to see a representation of what would be fed to a generator module.
+
+It's not advisable to rename .gypd files produced by this module to .gyp,
+because they will have all merges, expansions, and evaluations already
+performed and the relevant constructs not present in the output; paths to
+dependencies may be wrong; and various sections that do not belong in .gyp
+files such as such as "included_files" and "*_excluded" will be present.
+Output will also be stripped of comments.  This is not intended to be a
+general-purpose gyp pretty-printer; for that, you probably just want to
+run "pprint.pprint(eval(open('source.gyp').read()))", which will still strip
+comments but won't do all of the other things done to this module's output.
+
+The specific formatting of the output generated by this module is subject
+to change.
+"""
+
+
+import gyp.common
+import errno
+import os
+import pprint
+
+
+# These variables should just be spit back out as variable references.
+_generator_identity_variables = [
+  'EXECUTABLE_PREFIX',
+  'EXECUTABLE_SUFFIX',
+  'INTERMEDIATE_DIR',
+  'PRODUCT_DIR',
+  'RULE_INPUT_ROOT',
+  'RULE_INPUT_EXT',
+  'RULE_INPUT_NAME',
+  'RULE_INPUT_PATH',
+  'SHARED_INTERMEDIATE_DIR',
+]
+
+# gypd doesn't define a default value for OS like many other generator
+# modules.  Specify "-D OS=whatever" on the command line to provide a value.
+generator_default_variables = {
+}
+
+# gypd supports multiple toolsets
+generator_supports_multiple_toolsets = True
+
+# TODO(mark): This always uses <, which isn't right.  The input module should
+# notify the generator to tell it which phase it is operating in, and this
+# module should use < for the early phase and then switch to > for the late
+# phase.  Bonus points for carrying @ back into the output too.
+for v in _generator_identity_variables:
+  generator_default_variables[v] = '<(%s)' % v
+
+
+def GenerateOutput(target_list, target_dicts, data, params):
+  output_files = {}
+  for qualified_target in target_list:
+    [input_file, target] = \
+        gyp.common.ParseQualifiedTarget(qualified_target)[0:2]
+
+    if input_file[-4:] != '.gyp':
+      continue
+    input_file_stem = input_file[:-4]
+    output_file = input_file_stem + params['options'].suffix + '.gypd'
+
+    if not output_file in output_files:
+      output_files[output_file] = input_file
+
+  for output_file, input_file in output_files.iteritems():
+    output = open(output_file, 'w')
+    pprint.pprint(data[input_file], output)
+    output.close()
diff --git a/Source/ThirdParty/gyp/pylib/gyp/generator/gypsh.py b/Source/ThirdParty/gyp/pylib/gyp/generator/gypsh.py
new file mode 100644 (file)
index 0000000..f48b03f
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""gypsh output module
+
+gypsh is a GYP shell.  It's not really a generator per se.  All it does is
+fire up an interactive Python session with a few local variables set to the
+variables passed to the generator.  Like gypd, it's intended as a debugging
+aid, to facilitate the exploration of .gyp structures after being processed
+by the input module.
+
+The expected usage is "gyp -f gypsh -D OS=desired_os".
+"""
+
+
+import code
+import sys
+
+
+# All of this stuff about generator variables was lovingly ripped from gypd.py.
+# That module has a much better description of what's going on and why.
+_generator_identity_variables = [
+  'EXECUTABLE_PREFIX',
+  'EXECUTABLE_SUFFIX',
+  'INTERMEDIATE_DIR',
+  'PRODUCT_DIR',
+  'RULE_INPUT_ROOT',
+  'RULE_INPUT_EXT',
+  'RULE_INPUT_NAME',
+  'RULE_INPUT_PATH',
+  'SHARED_INTERMEDIATE_DIR',
+]
+
+generator_default_variables = {
+}
+
+for v in _generator_identity_variables:
+  generator_default_variables[v] = '<(%s)' % v
+
+
+def GenerateOutput(target_list, target_dicts, data, params):
+  locals = {
+        'target_list':  target_list,
+        'target_dicts': target_dicts,
+        'data':         data,
+      }
+
+  # Use a banner that looks like the stock Python one and like what
+  # code.interact uses by default, but tack on something to indicate what
+  # locals are available, and identify gypsh.
+  banner='Python %s on %s\nlocals.keys() = %s\ngypsh' % \
+         (sys.version, sys.platform, repr(sorted(locals.keys())))
+
+  code.interact(banner, local=locals)
diff --git a/Source/ThirdParty/gyp/pylib/gyp/generator/make.py b/Source/ThirdParty/gyp/pylib/gyp/generator/make.py
new file mode 100644 (file)
index 0000000..e72c0fb
--- /dev/null
@@ -0,0 +1,1423 @@
+#!/usr/bin/python
+
+# Copyright (c) 2009 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Notes:
+#
+# This is all roughly based on the Makefile system used by the Linux
+# kernel, but is a non-recursive make -- we put the entire dependency
+# graph in front of make and let it figure it out.
+#
+# The code below generates a separate .mk file for each target, but
+# all are sourced by the top-level Makefile.  This means that all
+# variables in .mk-files clobber one another.  Be careful to use :=
+# where appropriate for immediate evaluation, and similarly to watch
+# that you're not relying on a variable value to last beween different
+# .mk files.
+#
+# TODOs:
+#
+# Global settings and utility functions are currently stuffed in the
+# toplevel Makefile.  It may make sense to generate some .mk files on
+# the side to keep the the files readable.
+
+import gyp
+import gyp.common
+import gyp.system_test
+import os.path
+import os
+
+# Debugging-related imports -- remove me once we're solid.
+import code
+import pprint
+
+generator_default_variables = {
+  'EXECUTABLE_PREFIX': '',
+  'EXECUTABLE_SUFFIX': '',
+  'OS': 'linux',
+  'STATIC_LIB_PREFIX': 'lib',
+  'SHARED_LIB_PREFIX': 'lib',
+  'STATIC_LIB_SUFFIX': '.a',
+  'SHARED_LIB_SUFFIX': '.so',
+  'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/geni',
+  'SHARED_INTERMEDIATE_DIR': '$(obj)/gen',
+  'PRODUCT_DIR': '$(builddir)',
+  'SHARED_LIB_DIR': '$(builddir)/lib.$(TOOLSET)',
+  'LIB_DIR': '$(obj).$(TOOLSET)',
+  'RULE_INPUT_ROOT': '%(INPUT_ROOT)s',  # This gets expanded by Python.
+  'RULE_INPUT_PATH': '$(abspath $<)',
+  'RULE_INPUT_EXT': '$(suffix $<)',
+  'RULE_INPUT_NAME': '$(notdir $<)',
+
+  # This appears unused --- ?
+  'CONFIGURATION_NAME': '$(BUILDTYPE)',
+}
+
+# Make supports multiple toolsets
+generator_supports_multiple_toolsets = True
+
+def ensure_directory_exists(path):
+  dir = os.path.dirname(path)
+  if dir and not os.path.exists(dir):
+    os.makedirs(dir)
+
+# Header of toplevel Makefile.
+# This should go into the build tree, but it's easier to keep it here for now.
+SHARED_HEADER = ("""\
+# We borrow heavily from the kernel build setup, though we are simpler since
+# we don't have Kconfig tweaking settings on us.
+
+# The implicit make rules have it looking for RCS files, among other things.
+# We instead explicitly write all the rules we care about.
+# It's even quicker (saves ~200ms) to pass -r on the command line.
+MAKEFLAGS=-r
+
+# The source directory tree.
+srcdir := %(srcdir)s
+
+# The name of the builddir.
+builddir_name ?= %(builddir)s
+
+# The V=1 flag on command line makes us verbosely print command lines.
+ifdef V
+  quiet=
+else
+  quiet=quiet_
+endif
+
+# Specify BUILDTYPE=Release on the command line for a release build.
+BUILDTYPE ?= %(default_configuration)s
+
+# Directory all our build output goes into.
+# Note that this must be two directories beneath src/ for unit tests to pass,
+# as they reach into the src/ directory for data with relative paths.
+builddir ?= $(builddir_name)/$(BUILDTYPE)
+abs_builddir := $(abspath $(builddir))
+depsdir := $(builddir)/.deps
+
+# Object output directory.
+obj := $(builddir)/obj
+abs_obj := $(abspath $(obj))
+
+# We build up a list of every single one of the targets so we can slurp in the
+# generated dependency rule Makefiles in one pass.
+all_deps :=
+
+# C++ apps need to be linked with g++.  Not sure what's appropriate.
+#
+# Note, the flock is used to seralize linking. Linking is a memory-intensive
+# process so running parallel links can often lead to thrashing.  To disable
+# the serialization, override LINK via an envrionment variable as follows:
+#
+#   export LINK="$(CXX)"
+#
+# This will allow make to invoke N linker processes as specified in -jN.
+LINK ?= flock $(builddir)/linker.lock $(CXX) %(LINK_flags)s
+
+CC.target ?= $(CC)
+CFLAGS.target ?= $(CFLAGS)
+CXX.target ?= $(CXX)
+CXXFLAGS.target ?= $(CXXFLAGS)
+LINK.target ?= $(LINK)
+LDFLAGS.target ?= $(LDFLAGS)
+AR.target ?= $(AR)
+ARFLAGS.target ?= %(ARFLAGS.target)s
+
+# N.B.: the logic of which commands to run should match the computation done
+# in gyp's make.py where ARFLAGS.host etc. is computed.
+# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
+# to replicate this environment fallback in make as well.
+CC.host ?= gcc
+CFLAGS.host ?=
+CXX.host ?= g++
+CXXFLAGS.host ?=
+LINK.host ?= g++
+LDFLAGS.host ?=
+AR.host ?= ar
+ARFLAGS.host := %(ARFLAGS.host)s
+
+# Flags to make gcc output dependency info.  Note that you need to be
+# careful here to use the flags that ccache and distcc can understand.
+# We write to a dep file on the side first and then rename at the end
+# so we can't end up with a broken dep file.
+depfile = $(depsdir)/$@.d
+DEPFLAGS = -MMD -MF $(depfile).raw
+
+# We have to fixup the deps output in a few ways.
+# (1) the file output should mention the proper .o file.
+# ccache or distcc lose the path to the target, so we convert a rule of
+# the form:
+#   foobar.o: DEP1 DEP2
+# into
+#   path/to/foobar.o: DEP1 DEP2
+# (2) we want missing files not to cause us to fail to build.
+# We want to rewrite
+#   foobar.o: DEP1 DEP2 \\
+#               DEP3
+# to
+#   DEP1:
+#   DEP2:
+#   DEP3:
+# so if the files are missing, they're just considered phony rules.
+# We have to do some pretty insane escaping to get those backslashes
+# and dollar signs past make, the shell, and sed at the same time."""
+r"""
+define fixup_dep
+# The depfile may not exist if the input file didn't have any #includes.
+touch $(depfile).raw
+# Fixup path as in (1).
+sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
+# Add extra rules as in (2).
+# We remove slashes and replace spaces with new lines;
+# remove blank lines;
+# delete the first line and append a colon to the remaining lines.
+sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
+  grep -v '^$$'                             |\
+  sed -e 1d -e 's|$$|:|'                     \
+    >> $(depfile)
+rm $(depfile).raw
+endef
+"""
+"""
+# Command definitions:
+# - cmd_foo is the actual command to run;
+# - quiet_cmd_foo is the brief-output summary of the command.
+
+quiet_cmd_cc = CC($(TOOLSET)) $@
+cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
+
+quiet_cmd_cxx = CXX($(TOOLSET)) $@
+cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
+
+quiet_cmd_alink = AR($(TOOLSET)) $@
+cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %%.o,$^)
+
+quiet_cmd_touch = TOUCH $@
+cmd_touch = touch $@
+
+quiet_cmd_copy = COPY $@
+# send stderr to /dev/null to ignore messages when linking directories.
+cmd_copy = ln -f $< $@ 2>/dev/null || cp -af $< $@
+
+# Due to circular dependencies between libraries :(, we wrap the
+# special "figure out circular dependencies" flags around the entire
+# input list during linking.
+quiet_cmd_link = LINK($(TOOLSET)) $@
+cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
+
+# Shared-object link (for generating .so).
+# Set SONAME to the library filename so our binaries don't reference the local,
+# absolute paths used on the link command-line.
+# TODO: perhaps this can share with the LINK command above?
+quiet_cmd_solink = SOLINK($(TOOLSET)) $@
+cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
+"""
+r"""
+# Define an escape_quotes function to escape single quotes.
+# This allows us to handle quotes properly as long as we always use
+# use single quotes and escape_quotes.
+escape_quotes = $(subst ','\'',$(1))
+# This comment is here just to include a ' to unconfuse syntax highlighting.
+# Define an escape_vars function to escape '$' variable syntax.
+# This allows us to read/write command lines with shell variables (e.g.
+# $LD_LIBRARY_PATH), without triggering make substitution.
+escape_vars = $(subst $$,$$$$,$(1))
+# Helper that expands to a shell command to echo a string exactly as it is in
+# make. This uses printf instead of echo because printf's behaviour with respect
+# to escape sequences is more portable than echo's across different shells
+# (e.g., dash, bash).
+exact_echo = printf '%%s\n' '$(call escape_quotes,$(1))'
+"""
+"""
+# Helper to compare the command we're about to run against the command
+# we logged the last time we ran the command.  Produces an empty
+# string (false) when the commands match.
+# Tricky point: Make has no string-equality test function.
+# The kernel uses the following, but it seems like it would have false
+# positives, where one string reordered its arguments.
+#   arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \\
+#                       $(filter-out $(cmd_$@), $(cmd_$(1))))
+# We instead substitute each for the empty string into the other, and
+# say they're equal if both substitutions produce the empty string.
+command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$@)),\\
+                       $(subst $(cmd_$@),,$(cmd_$(1))))
+
+# Helper that is non-empty when a prerequisite changes.
+# Normally make does this implicitly, but we force rules to always run
+# so we can check their command lines.
+#   $? -- new prerequisites
+#   $| -- order-only dependencies
+prereq_changed = $(filter-out $|,$?)
+
+# do_cmd: run a command via the above cmd_foo names, if necessary.
+# Should always run for a given target to handle command-line changes.
+# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
+define do_cmd
+$(if $(or $(command_changed),$(prereq_changed)),
+  @$(call exact_echo,  $($(quiet)cmd_$(1)))
+  @mkdir -p $(dir $@) $(dir $(depfile))
+  @$(cmd_$(1))
+  @$(call exact_echo,$(call escape_vars,cmd_$@ := $(cmd_$(1)))) > $(depfile)
+  @$(if $(2),$(fixup_dep))
+)
+endef
+
+# Declare "all" target first so it is the default, even though we don't have the
+# deps yet.
+.PHONY: all
+all:
+
+# Use FORCE_DO_CMD to force a target to run.  Should be coupled with
+# do_cmd.
+.PHONY: FORCE_DO_CMD
+FORCE_DO_CMD:
+
+""")
+
+ROOT_HEADER_SUFFIX_RULES = ("""\
+# Suffix rules, putting all outputs into $(obj).
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+
+# Try building from generated source, too.
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+
+$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+""")
+
+SHARED_HEADER_SUFFIX_RULES_COMMENT1 = ("""\
+# Suffix rules, putting all outputs into $(obj).
+""")
+
+SHARED_HEADER_SUFFIX_RULES_SRCDIR = {
+    '.c': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+"""),
+    '.s': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+"""),
+    '.S': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+"""),
+    '.cpp': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+"""),
+    '.cc': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+"""),
+    '.cxx': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+"""),
+}
+
+SHARED_HEADER_SUFFIX_RULES_COMMENT2 = ("""\
+# Try building from generated source, too.
+""")
+
+SHARED_HEADER_SUFFIX_RULES_OBJDIR1 = {
+    '.c': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+"""),
+    '.cc': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+"""),
+    '.cpp': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+"""),
+}
+
+SHARED_HEADER_SUFFIX_RULES_OBJDIR2 = {
+    '.c': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
+       @$(call do_cmd,cc,1)
+"""),
+    '.cc': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+"""),
+    '.cpp': ("""\
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
+       @$(call do_cmd,cxx,1)
+"""),
+}
+
+SHARED_HEADER_SUFFIX_RULES = (
+    SHARED_HEADER_SUFFIX_RULES_COMMENT1 +
+    ''.join(SHARED_HEADER_SUFFIX_RULES_SRCDIR.values()) +
+    SHARED_HEADER_SUFFIX_RULES_COMMENT2 +
+    ''.join(SHARED_HEADER_SUFFIX_RULES_OBJDIR1.values()) +
+    ''.join(SHARED_HEADER_SUFFIX_RULES_OBJDIR2.values())
+)
+
+SHARED_FOOTER = """\
+# "all" is a concatenation of the "all" targets from all the included
+# sub-makefiles. This is just here to clarify.
+all:
+
+# Add in dependency-tracking rules.  $(all_deps) is the list of every single
+# target in our tree.  First, only consider targets that already have been
+# built, as unbuilt targets will be built regardless of dependency info:
+all_deps := $(wildcard $(sort $(all_deps)))
+# Of those, only consider the ones with .d (dependency) info:
+d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
+ifneq ($(d_files),)
+  # Rather than include each individual .d file, concatenate them into a
+  # single file which make is able to load faster.  We split this into
+  # commands that take 1000 files at a time to avoid overflowing the
+  # command line.
+  $(shell cat $(wordlist 1,1000,$(d_files)) > $(depsdir)/all.deps)
+%(generate_all_deps)s
+  # make looks for ways to re-generate included makefiles, but in our case, we
+  # don't have a direct way. Explicitly telling make that it has nothing to do
+  # for them makes it go faster.
+  $(depsdir)/all.deps: ;
+
+  include $(depsdir)/all.deps
+endif
+"""
+
+header = """\
+# This file is generated by gyp; do not edit.
+
+"""
+
+
+def Compilable(filename):
+  """Return true if the file is compilable (should be in OBJS)."""
+  for res in (filename.endswith(e) for e
+             in ['.c', '.cc', '.cpp', '.cxx', '.s', '.S']):
+    if res:
+      return True
+  return False
+
+
+def Linkable(filename):
+  """Return true if the file is linkable (should be on the link line)."""
+  return filename.endswith('.o')
+
+
+def Target(filename):
+  """Translate a compilable filename to its .o target."""
+  return os.path.splitext(filename)[0] + '.o'
+
+
+def EscapeShellArgument(s):
+  """Quotes an argument so that it will be interpreted literally by a POSIX
+     shell. Taken from
+     http://stackoverflow.com/questions/35817/whats-the-best-way-to-escape-ossystem-calls-in-python
+     """
+  return "'" + s.replace("'", "'\\''") + "'"
+
+
+def EscapeMakeVariableExpansion(s):
+  """Make has its own variable expansion syntax using $. We must escape it for
+     string to be interpreted literally."""
+  return s.replace('$', '$$')
+
+
+def EscapeCppDefine(s):
+  """Escapes a CPP define so that it will reach the compiler unaltered."""
+  s = EscapeShellArgument(s)
+  s = EscapeMakeVariableExpansion(s)
+  return s
+
+
+def QuoteIfNecessary(string):
+  """TODO: Should this ideally be replaced with one or more of the above
+     functions?"""
+  if '"' in string:
+    string = '"' + string.replace('"', '\\"') + '"'
+  return string
+
+
+def StringToMakefileVariable(string):
+  """Convert a string to a value that is acceptable as a make variable name."""
+  # TODO: replace other metacharacters that we encounter.
+  return string.replace(' ', '_')
+
+
+srcdir_prefix = ''
+def Sourceify(path):
+  """Convert a path to its source directory form."""
+  if '$(' in path:
+    return path
+  if os.path.isabs(path):
+    return path
+  return srcdir_prefix + path
+
+
+# Map from qualified target to path to output.
+target_outputs = {}
+# Map from qualified target to a list of all linker dependencies,
+# transitively expanded.
+# Used in building shared-library-based executables.
+target_link_deps = {}
+
+
+class MakefileWriter:
+  """MakefileWriter packages up the writing of one target-specific foobar.mk.
+
+  Its only real entry point is Write(), and is mostly used for namespacing.
+  """
+
+  def __init__(self):
+    # Keep track of the total number of outputs for this makefile.
+    self._num_outputs = 0
+
+
+  def NumOutputs(self):
+    return self._num_outputs
+
+
+  def Write(self, qualified_target, base_path, output_filename, spec, configs,
+            part_of_all):
+    """The main entry point: writes a .mk file for a single target.
+
+    Arguments:
+      qualified_target: target we're generating
+      base_path: path relative to source root we're building in, used to resolve
+                 target-relative paths
+      output_filename: output .mk file name to write
+      spec, configs: gyp info
+      part_of_all: flag indicating this target is part of 'all'
+    """
+    ensure_directory_exists(output_filename)
+
+    self.fp = open(output_filename, 'w')
+
+    self.fp.write(header)
+
+    self.path = base_path
+    self.target = spec['target_name']
+    self.type = spec['type']
+    self.toolset = spec['toolset']
+
+    deps, link_deps = self.ComputeDeps(spec)
+
+    # Some of the generation below can add extra output, sources, or
+    # link dependencies.  All of the out params of the functions that
+    # follow use names like extra_foo.
+    extra_outputs = []
+    extra_sources = []
+    extra_link_deps = []
+
+    self.output = self.ComputeOutput(spec)
+    self._INSTALLABLE_TARGETS = ('executable', 'loadable_module',
+                                 'shared_library')
+    if self.type in self._INSTALLABLE_TARGETS:
+      self.alias = os.path.basename(self.output)
+      install_path = self._InstallableTargetInstallPath()
+    else:
+      self.alias = self.output
+      install_path = self.output
+
+    self.WriteLn("TOOLSET := " + self.toolset)
+    self.WriteLn("TARGET := " + self.target)
+
+    # Actions must come first, since they can generate more OBJs for use below.
+    if 'actions' in spec:
+      self.WriteActions(spec['actions'], extra_sources, extra_outputs,
+                        part_of_all)
+
+    # Rules must be early like actions.
+    if 'rules' in spec:
+      self.WriteRules(spec['rules'], extra_sources, extra_outputs, part_of_all)
+
+    if 'copies' in spec:
+      self.WriteCopies(spec['copies'], extra_outputs, part_of_all)
+
+    all_sources = spec.get('sources', []) + extra_sources
+    if all_sources:
+      self.WriteSources(configs, deps, all_sources,
+                        extra_outputs, extra_link_deps, part_of_all)
+      sources = filter(Compilable, all_sources)
+      if sources:
+        self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT1)
+        extensions = set([os.path.splitext(s)[1] for s in sources])
+        for ext in extensions:
+          if ext in SHARED_HEADER_SUFFIX_RULES_SRCDIR:
+            self.WriteLn(SHARED_HEADER_SUFFIX_RULES_SRCDIR[ext])
+        self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT2)
+        for ext in extensions:
+          if ext in SHARED_HEADER_SUFFIX_RULES_OBJDIR1:
+            self.WriteLn(SHARED_HEADER_SUFFIX_RULES_OBJDIR1[ext])
+        for ext in extensions:
+          if ext in SHARED_HEADER_SUFFIX_RULES_OBJDIR2:
+            self.WriteLn(SHARED_HEADER_SUFFIX_RULES_OBJDIR2[ext])
+        self.WriteLn('# End of this set of suffix rules')
+
+
+    self.WriteTarget(spec, configs, deps,
+                     extra_link_deps + link_deps, extra_outputs, part_of_all)
+
+    # Update global list of target outputs, used in dependency tracking.
+    target_outputs[qualified_target] = install_path
+
+    # Update global list of link dependencies.
+    if self.type == 'static_library':
+      target_link_deps[qualified_target] = [self.output]
+    elif self.type == 'shared_library':
+      # Anyone that uses us transitively depend on all of our link
+      # dependencies.
+      target_link_deps[qualified_target] = [self.output] + link_deps
+
+    self.fp.close()
+
+
+  def WriteSubMake(self, output_filename, makefile_path, targets, build_dir):
+    """Write a "sub-project" Makefile.
+
+    This is a small, wrapper Makefile that calls the top-level Makefile to build
+    the targets from a single gyp file (i.e. a sub-project).
+
+    Arguments:
+      output_filename: sub-project Makefile name to write
+      makefile_path: path to the top-level Makefile
+      targets: list of "all" targets for this sub-project
+      build_dir: build output directory, relative to the sub-project
+    """
+    ensure_directory_exists(output_filename)
+    self.fp = open(output_filename, 'w')
+    self.fp.write(header)
+    # For consistency with other builders, put sub-project build output in the
+    # sub-project dir (see test/subdirectory/gyptest-subdir-all.py).
+    self.WriteLn('export builddir_name ?= %s' %
+                 os.path.join(os.path.dirname(output_filename), build_dir))
+    self.WriteLn('.PHONY: all')
+    self.WriteLn('all:')
+    if makefile_path:
+      makefile_path = ' -C ' + makefile_path
+    self.WriteLn('\t$(MAKE)%s %s' % (makefile_path, ' '.join(targets)))
+    self.fp.close()
+
+
+  def WriteActions(self, actions, extra_sources, extra_outputs, part_of_all):
+    """Write Makefile code for any 'actions' from the gyp input.
+
+    extra_sources: a list that will be filled in with newly generated source
+                   files, if any
+    extra_outputs: a list that will be filled in with any outputs of these
+                   actions (used to make other pieces dependent on these
+                   actions)
+    part_of_all: flag indicating this target is part of 'all'
+    """
+    for action in actions:
+      name = self.target + '_' + StringToMakefileVariable(action['action_name'])
+      self.WriteLn('### Rules for action "%s":' % action['action_name'])
+      inputs = action['inputs']
+      outputs = action['outputs']
+
+      # Build up a list of outputs.
+      # Collect the output dirs we'll need.
+      dirs = set()
+      for out in outputs:
+        dir = os.path.split(out)[0]
+        if dir:
+          dirs.add(dir)
+      if int(action.get('process_outputs_as_sources', False)):
+        extra_sources += outputs
+
+      # Write the actual command.
+      command = gyp.common.EncodePOSIXShellList(action['action'])
+      if 'message' in action:
+        self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, action['message']))
+      else:
+        self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, name))
+      if len(dirs) > 0:
+        command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command
+      # Set LD_LIBRARY_PATH in case the action runs an executable from this
+      # build which links to shared libs from this build.
+      if self.path:
+        cd_action = 'cd %s; ' % Sourceify(self.path)
+      else:
+        cd_action = ''
+      # actions run on the host, so they should in theory only use host
+      # libraries, but until everything is made cross-compile safe, also use
+      # target libraries.
+      # TODO(piman): when everything is cross-compile safe, remove lib.target
+      self.WriteLn('cmd_%s = export LD_LIBRARY_PATH=$(builddir)/lib.host:'
+                   '$(builddir)/lib.target:$$LD_LIBRARY_PATH; %s%s'
+                   % (name, cd_action, command))
+      self.WriteLn()
+      outputs = map(self.Absolutify, outputs)
+      # The makefile rules are all relative to the top dir, but the gyp actions
+      # are defined relative to their containing dir.  This replaces the obj
+      # variable for the action rule with an absolute version so that the output
+      # goes in the right place.
+      # Only write the 'obj' and 'builddir' rules for the "primary" output (:1);
+      # it's superfluous for the "extra outputs", and this avoids accidentally
+      # writing duplicate dummy rules for those outputs.
+      self.WriteMakeRule(outputs[:1], ['obj := $(abs_obj)'])
+      self.WriteMakeRule(outputs[:1], ['builddir := $(abs_builddir)'])
+      self.WriteDoCmd(outputs, map(Sourceify, map(self.Absolutify, inputs)),
+                      part_of_all=part_of_all, command=name)
+
+      # Stuff the outputs in a variable so we can refer to them later.
+      outputs_variable = 'action_%s_outputs' % name
+      self.WriteLn('%s := %s' % (outputs_variable, ' '.join(outputs)))
+      extra_outputs.append('$(%s)' % outputs_variable)
+      self.WriteLn()
+
+    self.WriteLn()
+
+
+  def WriteRules(self, rules, extra_sources, extra_outputs, part_of_all):
+    """Write Makefile code for any 'rules' from the gyp input.
+
+    extra_sources: a list that will be filled in with newly generated source
+                   files, if any
+    extra_outputs: a list that will be filled in with any outputs of these
+                   rules (used to make other pieces dependent on these rules)
+    part_of_all: flag indicating this target is part of 'all'
+    """
+    for rule in rules:
+      name = self.target + '_' + StringToMakefileVariable(rule['rule_name'])
+      count = 0
+      self.WriteLn('### Generated for rule %s:' % name)
+
+      all_outputs = []
+
+      for rule_source in rule.get('rule_sources', []):
+        dirs = set()
+        rule_source_basename = os.path.basename(rule_source)
+        (rule_source_root, rule_source_ext) = \
+            os.path.splitext(rule_source_basename)
+
+        outputs = [self.ExpandInputRoot(out, rule_source_root)
+                   for out in rule['outputs']]
+        for out in outputs:
+          dir = os.path.dirname(out)
+          if dir:
+            dirs.add(dir)
+          if int(rule.get('process_outputs_as_sources', False)):
+            extra_sources.append(out)
+        all_outputs += outputs
+        inputs = map(Sourceify, map(self.Absolutify, [rule_source] +
+                                    rule.get('inputs', [])))
+        actions = ['$(call do_cmd,%s_%d)' % (name, count)]
+
+        if name == 'resources_grit':
+          # HACK: This is ugly.  Grit intentionally doesn't touch the
+          # timestamp of its output file when the file doesn't change,
+          # which is fine in hash-based dependency systems like scons
+          # and forge, but not kosher in the make world.  After some
+          # discussion, hacking around it here seems like the least
+          # amount of pain.
+          actions += ['@touch --no-create $@']
+
+        # Only write the 'obj' and 'builddir' rules for the "primary" output
+        # (:1); it's superfluous for the "extra outputs", and this avoids
+        # accidentally writing duplicate dummy rules for those outputs.
+        self.WriteMakeRule(outputs[:1], ['obj := $(abs_obj)'])
+        self.WriteMakeRule(outputs[:1], ['builddir := $(abs_builddir)'])
+        self.WriteMakeRule(outputs, inputs + ['FORCE_DO_CMD'], actions)
+        self.WriteLn('all_deps += %s' % ' '.join(outputs))
+        self._num_outputs += len(outputs)
+
+        action = [self.ExpandInputRoot(ac, rule_source_root)
+                  for ac in rule['action']]
+        mkdirs = ''
+        if len(dirs) > 0:
+          mkdirs = 'mkdir -p %s; ' % ' '.join(dirs)
+        if self.path:
+          cd_action = 'cd %s; ' % Sourceify(self.path)
+        else:
+          cd_action = ''
+        # Set LD_LIBRARY_PATH in case the rule runs an executable from this
+        # build which links to shared libs from this build.
+        # rules run on the host, so they should in theory only use host
+        # libraries, but until everything is made cross-compile safe, also use
+        # target libraries.
+        # TODO(piman): when everything is cross-compile safe, remove lib.target
+        self.WriteLn(
+            "cmd_%(name)s_%(count)d = export LD_LIBRARY_PATH="
+              "$(builddir)/lib.host:$(builddir)/lib.target:$$LD_LIBRARY_PATH; "
+              "%(cd_action)s%(mkdirs)s%(action)s" % {
+          'action': gyp.common.EncodePOSIXShellList(action),
+          'cd_action': cd_action,
+          'count': count,
+          'mkdirs': mkdirs,
+          'name': name,
+        })
+        self.WriteLn(
+            'quiet_cmd_%(name)s_%(count)d = RULE %(name)s_%(count)d $@' % {
+          'count': count,
+          'name': name,
+        })
+        self.WriteLn()
+        count += 1
+
+      outputs_variable = 'rule_%s_outputs' % name
+      self.WriteList(all_outputs, outputs_variable)
+      extra_outputs.append('$(%s)' % outputs_variable)
+
+      self.WriteLn('### Finished generating for rule: %s' % name)
+      self.WriteLn()
+    self.WriteLn('### Finished generating for all rules')
+    self.WriteLn('')
+
+
+  def WriteCopies(self, copies, extra_outputs, part_of_all):
+    """Write Makefile code for any 'copies' from the gyp input.
+
+    extra_outputs: a list that will be filled in with any outputs of this action
+                   (used to make other pieces dependent on this action)
+    part_of_all: flag indicating this target is part of 'all'
+    """
+    self.WriteLn('### Generated for copy rule.')
+
+    variable = self.target + '_copies'
+    outputs = []
+    for copy in copies:
+      for path in copy['files']:
+        path = Sourceify(self.Absolutify(path))
+        filename = os.path.split(path)[1]
+        output = Sourceify(self.Absolutify(os.path.join(copy['destination'],
+                                                        filename)))
+        self.WriteDoCmd([output], [path], 'copy', part_of_all)
+        outputs.append(output)
+    self.WriteLn('%s = %s' % (variable, ' '.join(outputs)))
+    extra_outputs.append('$(%s)' % variable)
+    self.WriteLn()
+
+
+  def WriteSources(self, configs, deps, sources,
+                   extra_outputs, extra_link_deps,
+                   part_of_all):
+    """Write Makefile code for any 'sources' from the gyp input.
+    These are source files necessary to build the current target.
+
+    configs, deps, sources: input from gyp.
+    extra_outputs: a list of extra outputs this action should be dependent on;
+                   used to serialize action/rules before compilation
+    extra_link_deps: a list that will be filled in with any outputs of
+                     compilation (to be used in link lines)
+    part_of_all: flag indicating this target is part of 'all'
+    """
+
+    # Write configuration-specific variables for CFLAGS, etc.
+    for configname in sorted(configs.keys()):
+      config = configs[configname]
+      self.WriteList(config.get('defines'), 'DEFS_%s' % configname, prefix='-D',
+          quoter=EscapeCppDefine)
+      self.WriteLn("# Flags passed to both C and C++ files.");
+      self.WriteList(config.get('cflags'), 'CFLAGS_%s' % configname)
+      self.WriteLn("# Flags passed to only C (and not C++) files.");
+      self.WriteList(config.get('cflags_c'), 'CFLAGS_C_%s' % configname)
+      self.WriteLn("# Flags passed to only C++ (and not C) files.");
+      self.WriteList(config.get('cflags_cc'), 'CFLAGS_CC_%s' % configname)
+      includes = config.get('include_dirs')
+      if includes:
+        includes = map(Sourceify, map(self.Absolutify, includes))
+      self.WriteList(includes, 'INCS_%s' % configname, prefix='-I')
+
+    compilable = filter(Compilable, sources)
+    objs = map(self.Objectify, map(self.Absolutify, map(Target, compilable)))
+    self.WriteList(objs, 'OBJS')
+
+    self.WriteLn('# Add to the list of files we specially track '
+                 'dependencies for.')
+    self.WriteLn('all_deps += $(OBJS)')
+    self._num_outputs += len(objs)
+    self.WriteLn()
+
+    # Make sure our dependencies are built first.
+    if deps:
+      self.WriteMakeRule(['$(OBJS)'], deps,
+                         comment = 'Make sure our dependencies are built '
+                                   'before any of us.',
+                         order_only = True)
+
+    # Make sure the actions and rules run first.
+    # If they generate any extra headers etc., the per-.o file dep tracking
+    # will catch the proper rebuilds, so order only is still ok here.
+    if extra_outputs:
+      self.WriteMakeRule(['$(OBJS)'], extra_outputs,
+                         comment = 'Make sure our actions/rules run '
+                                   'before any of us.',
+                         order_only = True)
+
+    if objs:
+      extra_link_deps.append('$(OBJS)')
+      self.WriteLn("""\
+# CFLAGS et al overrides must be target-local.
+# See "Target-specific Variable Values" in the GNU Make manual.""")
+      self.WriteLn("$(OBJS): TOOLSET := $(TOOLSET)")
+      self.WriteLn("$(OBJS): GYP_CFLAGS := "
+                   "$(DEFS_$(BUILDTYPE)) "
+                   "$(INCS_$(BUILDTYPE)) "
+                   "$(CFLAGS_$(BUILDTYPE)) "
+                   "$(CFLAGS_C_$(BUILDTYPE))")
+      self.WriteLn("$(OBJS): GYP_CXXFLAGS := "
+                   "$(DEFS_$(BUILDTYPE)) "
+                   "$(INCS_$(BUILDTYPE)) "
+                   "$(CFLAGS_$(BUILDTYPE)) "
+                   "$(CFLAGS_CC_$(BUILDTYPE))")
+
+    # If there are any object files in our input file list, link them into our
+    # output.
+    extra_link_deps += filter(Linkable, sources)
+
+    self.WriteLn()
+
+
+  def ComputeOutput(self, spec):
+    """Return the 'output' (full output path) of a gyp spec.
+
+    E.g., the loadable module 'foobar' in directory 'baz' will produce
+      '$(obj)/baz/libfoobar.so'
+    """
+    output = None
+    target = spec['target_name']
+    target_prefix = ''
+    target_ext = ''
+    path = os.path.join('$(obj).' + self.toolset, self.path)
+    if self.type == 'static_library':
+      if target[:3] == 'lib':
+        target = target[3:]
+      target_prefix = 'lib'
+      target_ext = '.a'
+    elif self.type in ('loadable_module', 'shared_library'):
+      if target[:3] == 'lib':
+        target = target[3:]
+      target_prefix = 'lib'
+      target_ext = '.so'
+    elif self.type == 'none':
+      target = '%s.stamp' % target
+    elif self.type == 'settings':
+      return None
+    elif self.type == 'executable':
+      path = os.path.join('$(builddir)')
+    else:
+      print ("ERROR: What output file should be generated?",
+             "typ", self.type, "target", target)
+
+    path = spec.get('product_dir', path)
+    target_prefix = spec.get('product_prefix', target_prefix)
+    target = spec.get('product_name', target)
+    product_ext = spec.get('product_extension')
+    if product_ext:
+      target_ext = '.' + product_ext
+
+    return os.path.join(path, target_prefix + target + target_ext)
+
+
+  def ComputeDeps(self, spec):
+    """Compute the dependencies of a gyp spec.
+
+    Returns a tuple (deps, link_deps), where each is a list of
+    filenames that will need to be put in front of make for either
+    building (deps) or linking (link_deps).
+    """
+    deps = []
+    link_deps = []
+    if 'dependencies' in spec:
+      deps.extend([target_outputs[dep] for dep in spec['dependencies']
+                   if target_outputs[dep]])
+      for dep in spec['dependencies']:
+        if dep in target_link_deps:
+          link_deps.extend(target_link_deps[dep])
+      deps.extend(link_deps)
+      # TODO: It seems we need to transitively link in libraries (e.g. -lfoo)?
+      # This hack makes it work:
+      # link_deps.extend(spec.get('libraries', []))
+    return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps))
+
+
+  def WriteTarget(self, spec, configs, deps, link_deps, extra_outputs,
+                  part_of_all):
+    """Write Makefile code to produce the final target of the gyp spec.
+
+    spec, configs: input from gyp.
+    deps, link_deps: dependency lists; see ComputeDeps()
+    extra_outputs: any extra outputs that our target should depend on
+    part_of_all: flag indicating this target is part of 'all'
+    """
+
+    self.WriteLn('### Rules for final target.')
+
+    if extra_outputs:
+      self.WriteMakeRule([self.output], extra_outputs,
+                         comment = 'Build our special outputs first.',
+                         order_only = True)
+      self.WriteMakeRule(extra_outputs, deps,
+                         comment=('Preserve order dependency of '
+                                  'special output on deps.'),
+                         order_only = True,
+                         multiple_output_trick = False)
+
+    if self.type not in ('settings', 'none'):
+      for configname in sorted(configs.keys()):
+        config = configs[configname]
+        self.WriteList(config.get('ldflags'), 'LDFLAGS_%s' % configname)
+      libraries = spec.get('libraries')
+      if libraries:
+        # Remove duplicate entries
+        libraries = gyp.common.uniquer(libraries)
+      self.WriteList(libraries, 'LIBS')
+      self.WriteLn('%s: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))' % self.output)
+      self.WriteLn('%s: LIBS := $(LIBS)' % self.output)
+
+    if self.type == 'executable':
+      self.WriteDoCmd([self.output], link_deps, 'link', part_of_all)
+    elif self.type == 'static_library':
+      self.WriteDoCmd([self.output], link_deps, 'alink', part_of_all)
+    elif self.type in ('loadable_module', 'shared_library'):
+      self.WriteDoCmd([self.output], link_deps, 'solink', part_of_all)
+    elif self.type == 'none':
+      # Write a stamp line.
+      self.WriteDoCmd([self.output], deps, 'touch', part_of_all)
+    elif self.type == 'settings':
+      # Only used for passing flags around.
+      pass
+    else:
+      print "WARNING: no output for", self.type, target
+
+    # Add an alias for each target (if there are any outputs).
+    # Installable target aliases are created below.
+    if ((self.output and self.output != self.target) and
+        (self.type not in self._INSTALLABLE_TARGETS)):
+      self.WriteMakeRule([self.target], [self.output],
+                         comment='Add target alias', phony = True)
+      if part_of_all:
+        self.WriteMakeRule(['all'], [self.target],
+                           comment = 'Add target alias to "all" target.',
+                           phony = True)
+
+    # Add special-case rules for our installable targets.
+    # 1) They need to install to the build dir or "product" dir.
+    # 2) They get shortcuts for building (e.g. "make chrome").
+    # 3) They are part of "make all".
+    if self.type in self._INSTALLABLE_TARGETS:
+      if self.type == 'shared_library':
+        file_desc = 'shared library'
+      else:
+        file_desc = 'executable'
+      install_path = self._InstallableTargetInstallPath()
+      installable_deps = [self.output]
+      # Point the target alias to the final binary output.
+      self.WriteMakeRule([self.target], [install_path],
+                         comment='Add target alias', phony = True)
+      if install_path != self.output:
+        self.WriteDoCmd([install_path], [self.output], 'copy',
+                        comment = 'Copy this to the %s output path.' %
+                        file_desc, part_of_all=part_of_all)
+        installable_deps.append(install_path)
+      if self.output != self.alias and self.alias != self.target:
+        self.WriteMakeRule([self.alias], installable_deps,
+                           comment = 'Short alias for building this %s.' %
+                           file_desc, phony = True)
+      if part_of_all:
+        self.WriteMakeRule(['all'], [install_path],
+                           comment = 'Add %s to "all" target.' % file_desc,
+                           phony = True)
+
+
+  def WriteList(self, list, variable=None, prefix='', quoter=QuoteIfNecessary):
+    """Write a variable definition that is a list of values.
+
+    E.g. WriteList(['a','b'], 'foo', prefix='blah') writes out
+         foo = blaha blahb
+    but in a pretty-printed style.
+    """
+    self.fp.write(variable + " := ")
+    if list:
+      list = [quoter(prefix + l) for l in list]
+      self.fp.write(" \\\n\t".join(list))
+    self.fp.write("\n\n")
+
+
+  def WriteDoCmd(self, outputs, inputs, command, part_of_all, comment=None):
+    """Write a Makefile rule that uses do_cmd.
+
+    This makes the outputs dependent on the command line that was run,
+    as well as support the V= make command line flag.
+    """
+    self.WriteMakeRule(outputs, inputs,
+                       actions = ['$(call do_cmd,%s)' % command],
+                       comment = comment,
+                       force = True)
+    # Add our outputs to the list of targets we read depfiles from.
+    self.WriteLn('all_deps += %s' % ' '.join(outputs))
+    self._num_outputs += len(outputs)
+
+
+  def WriteMakeRule(self, outputs, inputs, actions=None, comment=None,
+                    order_only=False, force=False, phony=False,
+                    multiple_output_trick=True):
+    """Write a Makefile rule, with some extra tricks.
+
+    outputs: a list of outputs for the rule (note: this is not directly
+             supported by make; see comments below)
+    inputs: a list of inputs for the rule
+    actions: a list of shell commands to run for the rule
+    comment: a comment to put in the Makefile above the rule (also useful
+             for making this Python script's code self-documenting)
+    order_only: if true, makes the dependency order-only
+    force: if true, include FORCE_DO_CMD as an order-only dep
+    phony: if true, the rule does not actually generate the named output, the
+           output is just a name to run the rule
+    multiple_output_trick: if true (the default), perform tricks such as dummy
+           rules to avoid problems with multiple outputs.
+    """
+    if comment:
+      self.WriteLn('# ' + comment)
+    if phony:
+      self.WriteLn('.PHONY: ' + ' '.join(outputs))
+    # TODO(evanm): just make order_only a list of deps instead of these hacks.
+    if order_only:
+      order_insert = '| '
+    else:
+      order_insert = ''
+    if force:
+      force_append = ' FORCE_DO_CMD'
+    else:
+      force_append = ''
+    if actions:
+      self.WriteLn("%s: TOOLSET := $(TOOLSET)" % outputs[0])
+    self.WriteLn('%s: %s%s%s' % (outputs[0], order_insert, ' '.join(inputs),
+                                 force_append))
+    if actions:
+      for action in actions:
+        self.WriteLn('\t%s' % action)
+    if multiple_output_trick and len(outputs) > 1:
+      # If we have more than one output, a rule like
+      #   foo bar: baz
+      # that for *each* output we must run the action, potentially
+      # in parallel.  That is not what we're trying to write -- what
+      # we want is that we run the action once and it generates all
+      # the files.
+      # http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html
+      # discusses this problem and has this solution:
+      # 1) Write the naive rule that would produce parallel runs of
+      # the action.
+      # 2) Make the outputs seralized on each other, so we won't start
+      # a parallel run until the first run finishes, at which point
+      # we'll have generated all the outputs and we're done.
+      self.WriteLn('%s: %s' % (' '.join(outputs[1:]), outputs[0]))
+      # Add a dummy command to the "extra outputs" rule, otherwise make seems to
+      # think these outputs haven't (couldn't have?) changed, and thus doesn't
+      # flag them as changed (i.e. include in '$?') when evaluating dependent
+      # rules, which in turn causes do_cmd() to skip running dependent commands.
+      self.WriteLn('%s: ;' % (' '.join(outputs[1:])))
+    self.WriteLn()
+
+
+  def WriteLn(self, text=''):
+    self.fp.write(text + '\n')
+
+
+  def Objectify(self, path):
+    """Convert a path to its output directory form."""
+    if '$(' in path:
+      path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/' % self.toolset)
+      return path
+    return '$(obj).%s/$(TARGET)/%s' % (self.toolset, path)
+
+  def Absolutify(self, path):
+    """Convert a subdirectory-relative path into a base-relative path.
+    Skips over paths that contain variables."""
+    if '$(' in path:
+      return path
+    return os.path.normpath(os.path.join(self.path, path))
+
+
+  def FixupArgPath(self, arg):
+    if '/' in arg or '.h.' in arg:
+      return self.Absolutify(arg)
+    return arg
+
+
+  def ExpandInputRoot(self, template, expansion):
+    if '%(INPUT_ROOT)s' not in template:
+      return template
+    path = template % { 'INPUT_ROOT': expansion }
+    if not os.path.dirname(path):
+      # If it's just the file name, turn it into a path so FixupArgPath()
+      # will know to Absolutify() it.
+      path = os.path.join('.', path)
+    return path
+
+
+  def _InstallableTargetInstallPath(self):
+    """Returns the location of the final output for an installable target."""
+    if self.type == 'shared_library':
+      # Install all shared libs into a common directory (per toolset) for
+      # convenient access with LD_LIBRARY_PATH.
+      return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias)
+    return '$(builddir)/' + self.alias
+
+
+def WriteAutoRegenerationRule(params, root_makefile, makefile_name,
+                              build_files):
+  """Write the target to regenerate the Makefile."""
+  options = params['options']
+  build_files_args = [gyp.common.RelativePath(filename, options.toplevel_dir)
+                      for filename in params['build_files_arg']]
+  gyp_binary = gyp.common.FixIfRelativePath(params['gyp_binary'],
+                                            options.toplevel_dir)
+  if not gyp_binary.startswith(os.sep):
+    gyp_binary = os.path.join('.', gyp_binary)
+  root_makefile.write(
+      "quiet_cmd_regen_makefile = ACTION Regenerating $@\n"
+      "cmd_regen_makefile = %(cmd)s\n"
+      "%(makefile_name)s: %(deps)s\n"
+      "\t$(call do_cmd,regen_makefile)\n\n" % {
+          'makefile_name': makefile_name,
+          'deps': ' '.join(map(Sourceify, build_files)),
+          'cmd': gyp.common.EncodePOSIXShellList(
+                     [gyp_binary, '-fmake'] +
+                     gyp.RegenerateFlags(options) +
+                     build_files_args)})
+
+
+def RunSystemTests():
+  """Run tests against the system to compute default settings for commands.
+
+  Returns:
+    dictionary of settings matching the block of command-lines used in
+    SHARED_HEADER.  E.g. the dictionary will contain a ARFLAGS.target
+    key for the default ARFLAGS for the target ar command.
+  """
+  # Compute flags used for building static archives.
+  # N.B.: this fallback logic should match the logic in SHARED_HEADER.
+  # See comment there for more details.
+  ar_target = os.environ.get('AR.target', os.environ.get('AR', 'ar'))
+  cc_target = os.environ.get('CC.target', os.environ.get('CC', 'cc'))
+  arflags_target = 'crs'
+  if gyp.system_test.TestArSupportsT(ar_command=ar_target,
+                                     cc_command=cc_target):
+    arflags_target = 'crsT'
+
+  ar_host = os.environ.get('AR.host', 'ar')
+  cc_host = os.environ.get('CC.host', 'gcc')
+  arflags_host = 'crs'
+  # It feels redundant to compute this again given that most builds aren't
+  # cross-compiles, but due to quirks of history CC.host defaults to 'gcc'
+  # while CC.target defaults to 'cc', so the commands really are different
+  # even though they're nearly guaranteed to run the same code underneath.
+  if gyp.system_test.TestArSupportsT(ar_command=ar_host, cc_command=cc_host):
+    arflags_host = 'crsT'
+
+  link_flags = ''
+  if gyp.system_test.TestLinkerSupportsThreads(cc_command=cc_target):
+    # N.B. we don't test for cross-compilation; as currently written, we
+    # don't even use flock when linking in the cross-compile setup!
+    # TODO(evan): refactor cross-compilation such that this code can
+    # be reused.
+    link_flags = '-Wl,--threads --Wl,--thread-count=4'
+
+  # TODO(evan): cache this output.  (But then we'll need to add extra
+  # flags to gyp to flush the cache, yuk!  It's fast enough for now to
+  # just run it every time.)
+