summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/test/backend
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozbuild/mozbuild/test/backend')
-rw-r--r--python/mozbuild/mozbuild/test/backend/__init__.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/common.py253
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/app/moz.build54
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/bar.ini1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/bar.js2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/bar.jsm1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/baz.ini2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/baz.jsm2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/components.manifest2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/foo.css2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/foo.ini1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/foo.js1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/foo.jsm1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/jar.mn11
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/moz.build68
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/prefs.js1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/qux.ini5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/qux.jsm5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/resource1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/resource21
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/build/subdir/bar.js1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/database/bar.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/database/baz.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/database/build/non-unified-compat0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/database/foo.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/database/moz.build14
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/database/qux.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/defines/moz.build9
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/dist-files/install.rdf0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/dist-files/main.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/dist-files/moz.build8
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports-generated/dom1.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports-generated/foo.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports-generated/gfx.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports-generated/moz.build12
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports-generated/mozilla1.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/dom1.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/dom2.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/foo.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/gfx.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/moz.build8
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/mozilla1.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/mozilla2.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/exports/pprio.h0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/bar.xyz0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/foo.xyz0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final_target/both/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final_target/dist-subdir/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final_target/final-target/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final_target/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/final_target/xpi-name/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files-force/foo-data0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-bar.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-foo.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files-force/moz.build14
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files/foo-data0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files/generate-bar.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files/generate-foo.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated-files/moz.build12
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/generated_includes/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/host-defines/moz.build9
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/Cargo.toml13
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/moz.build22
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/host-rust-library/Cargo.toml15
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/host-rust-library/moz.build22
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/foo.h.in1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/ipdl_sources/bar/moz.build16
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/ipdl_sources/foo/moz.build16
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/ipdl_sources/ipdl/moz.build9
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/ipdl_sources/moz.build19
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/jar-manifests/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/moz.build11
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/prog/moz.build11
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/qux1.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo1.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo2.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/real/moz.build14
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/baz1.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/shared/moz.build14
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar1.cc0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar2.cc0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/bar_helper1.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/moz.build8
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/moz.build13
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/static/moz.build12
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/linkage/templates.mozbuild23
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/local_includes/bar/baz/dummy_file_for_nonempty_directory0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/local_includes/foo/dummy_file_for_nonempty_directory0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/local_includes/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/bar.ini0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/foo.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-files/moz.build9
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/en-US/localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/foo-data0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/generate-foo.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/inner/locales/en-US/localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/locales/en-US/localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/moz.build32
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/non-localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/en-US/localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/foo-data0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/generate-foo.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/moz.build22
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/non-localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files/en-US/localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files/foo-data0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files/generate-foo.py0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files/moz.build15
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-generated-files/non-localized-input0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/bar.ini0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/foo.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/localized-pp-files/moz.build8
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/c-library.c2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/c_test_program.c2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/c_simple_program.c2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/c-source.c2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/cxx-library.cpp2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/moz.build10
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/cxx_test_program.cpp2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/cxx_simple_program.cpp2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/moz.build35
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/simple-programs/moz.build3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/program-paths/dist-bin/moz.build4
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/program-paths/dist-subdir/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/program-paths/final-target/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/program-paths/moz.build15
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/program-paths/not-installed/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/bar.res.in0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/cursor.cur0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/desktop1.ttf0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/desktop2.ttf0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/extra.manifest0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/font1.ttf0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/font2.ttf0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/foo.res0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/mobile.ttf0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/moz.build9
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/resources/test.manifest0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/rust-library-features/Cargo.toml15
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/rust-library-features/moz.build20
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/rust-library/Cargo.toml15
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/rust-library/moz.build19
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/rust-programs/code/Cargo.toml10
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/rust-programs/code/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/rust-programs/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/bar.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/bar.s0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/baz.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/foo.asm0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/foo.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/fuga.mm0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/hoge.mm0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/moz.build26
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/qux.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/titi.S0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/sources/toto.S0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/stub0/Makefile.in4
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/stub0/dir1/Makefile.in7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/stub0/dir1/moz.build3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/stub0/dir2/moz.build3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/stub0/dir3/Makefile.in7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/stub0/dir3/moz.build3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/stub0/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/substitute_config_files/Makefile.in0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/substitute_config_files/foo.in1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/substitute_config_files/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/another-file.sjs0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/browser.ini6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/one.txt0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/two.txt0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/test_sub.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/mochitest.ini8
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/support-file.txt0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/test_foo.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest-common.ini1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest.ini2
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_bar.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_foo.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest1.ini4
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest2.ini4
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_bar.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_foo.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/instrumentation.ini1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.ini1
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/moz.build10
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/not_packaged.java0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/test_bar.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/xpcshell.ini3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.ini3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-written/moz.build9
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.ini4
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.js0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/moz.build5
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/src/moz.build12
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/moz.build32
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-one.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-two.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test_config/file.in3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/test_config/moz.build3
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/Makefile.in0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/baz.def0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build11
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.mm0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.c0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.mm0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/bar.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/foo.cpp0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/moz.build9
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/visual-studio/moz.build7
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/xpidl/bar.idl0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/xpidl/config/makefiles/xpidl/Makefile.in0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/xpidl/foo.idl0
-rw-r--r--python/mozbuild/mozbuild/test/backend/data/xpidl/moz.build6
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_build.py265
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_configenvironment.py73
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_database.py91
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_fastermake.py42
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_partialconfigenvironment.py173
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_recursivemake.py1307
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_test_manifest.py94
-rw-r--r--python/mozbuild/mozbuild/test/backend/test_visualstudio.py63
240 files changed, 3467 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/test/backend/__init__.py b/python/mozbuild/mozbuild/test/backend/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/__init__.py
diff --git a/python/mozbuild/mozbuild/test/backend/common.py b/python/mozbuild/mozbuild/test/backend/common.py
new file mode 100644
index 0000000000..07cfa7540f
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/common.py
@@ -0,0 +1,253 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import unittest
+from collections import defaultdict
+from shutil import rmtree
+from tempfile import mkdtemp
+
+import mozpack.path as mozpath
+from mach.logging import LoggingManager
+
+from mozbuild.backend.configenvironment import ConfigEnvironment
+from mozbuild.frontend.emitter import TreeMetadataEmitter
+from mozbuild.frontend.reader import BuildReader
+
+log_manager = LoggingManager()
+log_manager.add_terminal_logging()
+
+
+test_data_path = mozpath.abspath(mozpath.dirname(__file__))
+test_data_path = mozpath.join(test_data_path, "data")
+
+
+CONFIGS = defaultdict(
+ lambda: {
+ "defines": {},
+ "substs": {"OS_TARGET": "WINNT"},
+ },
+ {
+ "binary-components": {
+ "defines": {},
+ "substs": {
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ "COMPILE_ENVIRONMENT": "1",
+ },
+ },
+ "database": {
+ "defines": {},
+ "substs": {
+ "CC": "clang",
+ "CXX": "clang++",
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ },
+ },
+ "rust-library": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "RUST_TARGET": "x86_64-unknown-linux-gnu",
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ },
+ },
+ "host-rust-library": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "RUST_HOST_TARGET": "x86_64-unknown-linux-gnu",
+ "RUST_TARGET": "armv7-linux-androideabi",
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ },
+ },
+ "host-rust-library-features": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "RUST_HOST_TARGET": "x86_64-unknown-linux-gnu",
+ "RUST_TARGET": "armv7-linux-androideabi",
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ },
+ },
+ "rust-library-features": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "RUST_TARGET": "x86_64-unknown-linux-gnu",
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ },
+ },
+ "rust-programs": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "RUST_TARGET": "i686-pc-windows-msvc",
+ "RUST_HOST_TARGET": "i686-pc-windows-msvc",
+ "BIN_SUFFIX": ".exe",
+ "HOST_BIN_SUFFIX": ".exe",
+ },
+ },
+ "test-support-binaries-tracked": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "LIB_SUFFIX": "dll",
+ "BIN_SUFFIX": ".exe",
+ },
+ },
+ "sources": {
+ "defines": {},
+ "substs": {
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ },
+ },
+ "stub0": {
+ "defines": {
+ "MOZ_TRUE_1": "1",
+ "MOZ_TRUE_2": "1",
+ },
+ "substs": {
+ "MOZ_FOO": "foo",
+ "MOZ_BAR": "bar",
+ },
+ },
+ "substitute_config_files": {
+ "defines": {},
+ "substs": {
+ "MOZ_FOO": "foo",
+ "MOZ_BAR": "bar",
+ },
+ },
+ "test_config": {
+ "defines": {
+ "foo": "baz qux",
+ "baz": 1,
+ },
+ "substs": {
+ "foo": "bar baz",
+ },
+ },
+ "visual-studio": {
+ "defines": {},
+ "substs": {
+ "MOZ_APP_NAME": "my_app",
+ },
+ },
+ "prog-lib-c-only": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "LIB_SUFFIX": ".a",
+ "BIN_SUFFIX": "",
+ },
+ },
+ "gn-processor": {
+ "defines": {},
+ "substs": {
+ "BUILD_BACKENDS": [
+ "GnMozbuildWriter",
+ "RecursiveMake",
+ ],
+ "COMPILE_ENVIRONMENT": "1",
+ "STL_FLAGS": [],
+ "RUST_TARGET": "x86_64-unknown-linux-gnu",
+ "LIB_PREFIX": "lib",
+ "LIB_SUFFIX": "a",
+ "OS_TARGET": "Darwin",
+ },
+ },
+ "ipdl_sources": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "LIB_SUFFIX": ".a",
+ "BIN_SUFFIX": "",
+ },
+ },
+ "program-paths": {
+ "defines": {},
+ "substs": {
+ "COMPILE_ENVIRONMENT": "1",
+ "BIN_SUFFIX": ".prog",
+ },
+ },
+ "linkage": {
+ "defines": {},
+ "substs": {
+ "CC_TYPE": "clang",
+ "COMPILE_ENVIRONMENT": "1",
+ "LIB_SUFFIX": "a",
+ "BIN_SUFFIX": ".exe",
+ "DLL_SUFFIX": ".so",
+ "OBJ_SUFFIX": "o",
+ "EXPAND_LIBS_LIST_STYLE": "list",
+ },
+ },
+ },
+)
+
+
+class BackendTester(unittest.TestCase):
+ def setUp(self):
+ self._old_env = dict(os.environ)
+ os.environ.pop("MOZ_OBJDIR", None)
+
+ def tearDown(self):
+ os.environ.clear()
+ os.environ.update(self._old_env)
+
+ def _get_environment(self, name):
+ """Obtain a new instance of a ConfigEnvironment for a known profile.
+
+ A new temporary object directory is created for the environment. The
+ environment is cleaned up automatically when the test finishes.
+ """
+ config = CONFIGS[name]
+ config["substs"]["MOZ_UI_LOCALE"] = "en-US"
+
+ srcdir = mozpath.join(test_data_path, name)
+ config["substs"]["top_srcdir"] = srcdir
+
+ # Create the objdir in the srcdir to ensure that they share the
+ # same drive on Windows.
+ objdir = mkdtemp(dir=srcdir)
+ self.addCleanup(rmtree, objdir)
+
+ return ConfigEnvironment(srcdir, objdir, **config)
+
+ def _emit(self, name, env=None):
+ env = env or self._get_environment(name)
+ reader = BuildReader(env)
+ emitter = TreeMetadataEmitter(env)
+
+ return env, emitter.emit(reader.read_topsrcdir())
+
+ def _consume(self, name, cls, env=None):
+ env, objs = self._emit(name, env=env)
+ backend = cls(env)
+ backend.consume(objs)
+
+ return env
+
+ def _tree_paths(self, topdir, filename):
+ for dirpath, dirnames, filenames in os.walk(topdir):
+ for f in filenames:
+ if f == filename:
+ yield mozpath.relpath(mozpath.join(dirpath, f), topdir)
+
+ def _mozbuild_paths(self, env):
+ return self._tree_paths(env.topsrcdir, "moz.build")
+
+ def _makefile_in_paths(self, env):
+ return self._tree_paths(env.topsrcdir, "Makefile.in")
+
+
+__all__ = ["BackendTester"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/app/moz.build b/python/mozbuild/mozbuild/test/backend/data/build/app/moz.build
new file mode 100644
index 0000000000..27641b2080
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/app/moz.build
@@ -0,0 +1,54 @@
+DIST_SUBDIR = "app"
+
+EXTRA_JS_MODULES += [
+ "../foo.jsm",
+]
+
+EXTRA_JS_MODULES.child += [
+ "../bar.jsm",
+]
+
+EXTRA_PP_JS_MODULES += [
+ "../baz.jsm",
+]
+
+EXTRA_PP_JS_MODULES.child2 += [
+ "../qux.jsm",
+]
+
+FINAL_TARGET_FILES += [
+ "../foo.ini",
+]
+
+FINAL_TARGET_FILES.child += [
+ "../bar.ini",
+]
+
+FINAL_TARGET_PP_FILES += [
+ "../baz.ini",
+ "../foo.css",
+]
+
+FINAL_TARGET_PP_FILES.child2 += [
+ "../qux.ini",
+]
+
+EXTRA_COMPONENTS += [
+ "../components.manifest",
+ "../foo.js",
+]
+
+EXTRA_PP_COMPONENTS += [
+ "../bar.js",
+]
+
+JS_PREFERENCE_FILES += [
+ "../prefs.js",
+]
+
+JAR_MANIFESTS += [
+ "../jar.mn",
+]
+
+DEFINES["FOO"] = "bar"
+DEFINES["BAR"] = True
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/bar.ini b/python/mozbuild/mozbuild/test/backend/data/build/bar.ini
new file mode 100644
index 0000000000..91dcbe1536
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/bar.ini
@@ -0,0 +1 @@
+bar.ini
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/bar.js b/python/mozbuild/mozbuild/test/backend/data/build/bar.js
new file mode 100644
index 0000000000..1a608e8a56
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/bar.js
@@ -0,0 +1,2 @@
+#filter substitution
+bar.js: FOO is @FOO@
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/bar.jsm b/python/mozbuild/mozbuild/test/backend/data/build/bar.jsm
new file mode 100644
index 0000000000..05db2e2f6a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/bar.jsm
@@ -0,0 +1 @@
+bar.jsm
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/baz.ini b/python/mozbuild/mozbuild/test/backend/data/build/baz.ini
new file mode 100644
index 0000000000..975a1e437d
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/baz.ini
@@ -0,0 +1,2 @@
+#filter substitution
+baz.ini: FOO is @FOO@
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/baz.jsm b/python/mozbuild/mozbuild/test/backend/data/build/baz.jsm
new file mode 100644
index 0000000000..f39ed02082
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/baz.jsm
@@ -0,0 +1,2 @@
+#filter substitution
+baz.jsm: FOO is @FOO@
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/components.manifest b/python/mozbuild/mozbuild/test/backend/data/build/components.manifest
new file mode 100644
index 0000000000..b5bb87254c
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/components.manifest
@@ -0,0 +1,2 @@
+component {foo} foo.js
+component {bar} bar.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/foo.css b/python/mozbuild/mozbuild/test/backend/data/build/foo.css
new file mode 100644
index 0000000000..1803d6c572
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/foo.css
@@ -0,0 +1,2 @@
+%filter substitution
+foo.css: FOO is @FOO@
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/foo.ini b/python/mozbuild/mozbuild/test/backend/data/build/foo.ini
new file mode 100644
index 0000000000..c93c9d7658
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/foo.ini
@@ -0,0 +1 @@
+foo.ini
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/foo.js b/python/mozbuild/mozbuild/test/backend/data/build/foo.js
new file mode 100644
index 0000000000..4fa71e2d27
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/foo.js
@@ -0,0 +1 @@
+foo.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/foo.jsm b/python/mozbuild/mozbuild/test/backend/data/build/foo.jsm
new file mode 100644
index 0000000000..d58fd61c16
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/foo.jsm
@@ -0,0 +1 @@
+foo.jsm
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/jar.mn b/python/mozbuild/mozbuild/test/backend/data/build/jar.mn
new file mode 100644
index 0000000000..393055c4ea
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/jar.mn
@@ -0,0 +1,11 @@
+foo.jar:
+% content bar %child/
+% content foo %
+ foo.js
+* foo.css
+ bar.js (subdir/bar.js)
+ qux.js (subdir/bar.js)
+* child/hoge.js (bar.js)
+* child/baz.jsm
+
+% override chrome://foo/bar.svg#hello chrome://bar/bar.svg#hello
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/moz.build b/python/mozbuild/mozbuild/test/backend/data/build/moz.build
new file mode 100644
index 0000000000..700516754d
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/moz.build
@@ -0,0 +1,68 @@
+CONFIGURE_SUBST_FILES += [
+ "/config/autoconf.mk",
+ "/config/emptyvars.mk",
+]
+
+EXTRA_JS_MODULES += [
+ "foo.jsm",
+]
+
+EXTRA_JS_MODULES.child += [
+ "bar.jsm",
+]
+
+EXTRA_PP_JS_MODULES += [
+ "baz.jsm",
+]
+
+EXTRA_PP_JS_MODULES.child2 += [
+ "qux.jsm",
+]
+
+FINAL_TARGET_FILES += [
+ "foo.ini",
+]
+
+FINAL_TARGET_FILES.child += [
+ "bar.ini",
+]
+
+FINAL_TARGET_PP_FILES += [
+ "baz.ini",
+]
+
+FINAL_TARGET_PP_FILES.child2 += [
+ "foo.css",
+ "qux.ini",
+]
+
+EXTRA_COMPONENTS += [
+ "components.manifest",
+ "foo.js",
+]
+
+EXTRA_PP_COMPONENTS += [
+ "bar.js",
+]
+
+JS_PREFERENCE_FILES += [
+ "prefs.js",
+]
+
+RESOURCE_FILES += [
+ "resource",
+]
+
+RESOURCE_FILES.child += [
+ "resource2",
+]
+
+DEFINES["FOO"] = "foo"
+
+JAR_MANIFESTS += [
+ "jar.mn",
+]
+
+DIRS += [
+ "app",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/prefs.js b/python/mozbuild/mozbuild/test/backend/data/build/prefs.js
new file mode 100644
index 0000000000..a030da9fd7
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/prefs.js
@@ -0,0 +1 @@
+prefs.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/qux.ini b/python/mozbuild/mozbuild/test/backend/data/build/qux.ini
new file mode 100644
index 0000000000..3ce157eb6d
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/qux.ini
@@ -0,0 +1,5 @@
+#ifdef BAR
+qux.ini: BAR is defined
+#else
+qux.ini: BAR is not defined
+#endif
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/qux.jsm b/python/mozbuild/mozbuild/test/backend/data/build/qux.jsm
new file mode 100644
index 0000000000..9c5fe28d58
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/qux.jsm
@@ -0,0 +1,5 @@
+#ifdef BAR
+qux.jsm: BAR is defined
+#else
+qux.jsm: BAR is not defined
+#endif
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/resource b/python/mozbuild/mozbuild/test/backend/data/build/resource
new file mode 100644
index 0000000000..91e75c679e
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/resource
@@ -0,0 +1 @@
+resource
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/resource2 b/python/mozbuild/mozbuild/test/backend/data/build/resource2
new file mode 100644
index 0000000000..b7c2700964
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/resource2
@@ -0,0 +1 @@
+resource2
diff --git a/python/mozbuild/mozbuild/test/backend/data/build/subdir/bar.js b/python/mozbuild/mozbuild/test/backend/data/build/subdir/bar.js
new file mode 100644
index 0000000000..80c887a84a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/build/subdir/bar.js
@@ -0,0 +1 @@
+bar.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/database/bar.c b/python/mozbuild/mozbuild/test/backend/data/database/bar.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/database/bar.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/database/baz.cpp b/python/mozbuild/mozbuild/test/backend/data/database/baz.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/database/baz.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/database/build/non-unified-compat b/python/mozbuild/mozbuild/test/backend/data/database/build/non-unified-compat
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/database/build/non-unified-compat
diff --git a/python/mozbuild/mozbuild/test/backend/data/database/foo.c b/python/mozbuild/mozbuild/test/backend/data/database/foo.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/database/foo.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/database/moz.build b/python/mozbuild/mozbuild/test/backend/data/database/moz.build
new file mode 100644
index 0000000000..ebc5d05b5c
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/database/moz.build
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def Library(name):
+ """Template for libraries."""
+ LIBRARY_NAME = name
+
+
+Library("dummy")
+
+SOURCES = ["bar.c", "baz.cpp", "foo.c", "qux.cpp"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/database/qux.cpp b/python/mozbuild/mozbuild/test/backend/data/database/qux.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/database/qux.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/defines/moz.build b/python/mozbuild/mozbuild/test/backend/data/defines/moz.build
new file mode 100644
index 0000000000..b603cac3ff
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/defines/moz.build
@@ -0,0 +1,9 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+value = "xyz"
+DEFINES["FOO"] = True
+DEFINES["BAZ"] = '"ab\'cd"'
+DEFINES["QUX"] = False
+DEFINES["BAR"] = 7
+DEFINES["VALUE"] = value
diff --git a/python/mozbuild/mozbuild/test/backend/data/dist-files/install.rdf b/python/mozbuild/mozbuild/test/backend/data/dist-files/install.rdf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/dist-files/install.rdf
diff --git a/python/mozbuild/mozbuild/test/backend/data/dist-files/main.js b/python/mozbuild/mozbuild/test/backend/data/dist-files/main.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/dist-files/main.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/dist-files/moz.build b/python/mozbuild/mozbuild/test/backend/data/dist-files/moz.build
new file mode 100644
index 0000000000..25961f149f
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/dist-files/moz.build
@@ -0,0 +1,8 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_TARGET_PP_FILES += [
+ "install.rdf",
+ "main.js",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports-generated/dom1.h b/python/mozbuild/mozbuild/test/backend/data/exports-generated/dom1.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports-generated/dom1.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports-generated/foo.h b/python/mozbuild/mozbuild/test/backend/data/exports-generated/foo.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports-generated/foo.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports-generated/gfx.h b/python/mozbuild/mozbuild/test/backend/data/exports-generated/gfx.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports-generated/gfx.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports-generated/moz.build b/python/mozbuild/mozbuild/test/backend/data/exports-generated/moz.build
new file mode 100644
index 0000000000..44c31a3d9c
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports-generated/moz.build
@@ -0,0 +1,12 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+EXPORTS += ["!bar.h", "foo.h"]
+EXPORTS.mozilla += ["!mozilla2.h", "mozilla1.h"]
+EXPORTS.mozilla.dom += ["!dom2.h", "!dom3.h", "dom1.h"]
+EXPORTS.gfx += ["gfx.h"]
+
+GENERATED_FILES += ["bar.h"]
+GENERATED_FILES += ["mozilla2.h"]
+GENERATED_FILES += ["dom2.h"]
+GENERATED_FILES += ["dom3.h"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports-generated/mozilla1.h b/python/mozbuild/mozbuild/test/backend/data/exports-generated/mozilla1.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports-generated/mozilla1.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/dom1.h b/python/mozbuild/mozbuild/test/backend/data/exports/dom1.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/dom1.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/dom2.h b/python/mozbuild/mozbuild/test/backend/data/exports/dom2.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/dom2.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/foo.h b/python/mozbuild/mozbuild/test/backend/data/exports/foo.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/foo.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/gfx.h b/python/mozbuild/mozbuild/test/backend/data/exports/gfx.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/gfx.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/moz.build b/python/mozbuild/mozbuild/test/backend/data/exports/moz.build
new file mode 100644
index 0000000000..371f26f572
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/moz.build
@@ -0,0 +1,8 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+EXPORTS += ["foo.h"]
+EXPORTS.mozilla += ["mozilla1.h", "mozilla2.h"]
+EXPORTS.mozilla.dom += ["dom1.h", "dom2.h"]
+EXPORTS.mozilla.gfx += ["gfx.h"]
+EXPORTS.nspr.private += ["pprio.h"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/mozilla1.h b/python/mozbuild/mozbuild/test/backend/data/exports/mozilla1.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/mozilla1.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/mozilla2.h b/python/mozbuild/mozbuild/test/backend/data/exports/mozilla2.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/mozilla2.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/pprio.h b/python/mozbuild/mozbuild/test/backend/data/exports/pprio.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/exports/pprio.h
diff --git a/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/bar.xyz b/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/bar.xyz
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/bar.xyz
diff --git a/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/foo.xyz b/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/foo.xyz
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/foo.xyz
diff --git a/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/moz.build b/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/moz.build
new file mode 100644
index 0000000000..d665855234
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final-target-files-wildcard/moz.build
@@ -0,0 +1,5 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+FINAL_TARGET_FILES.foo += ["*.xyz"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/final_target/both/moz.build b/python/mozbuild/mozbuild/test/backend/data/final_target/both/moz.build
new file mode 100644
index 0000000000..dfbda9183b
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/both/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+XPI_NAME = "mycrazyxpi"
+DIST_SUBDIR = "asubdir"
diff --git a/python/mozbuild/mozbuild/test/backend/data/final_target/dist-subdir/moz.build b/python/mozbuild/mozbuild/test/backend/data/final_target/dist-subdir/moz.build
new file mode 100644
index 0000000000..e44dd197ad
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/dist-subdir/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_SUBDIR = "asubdir"
diff --git a/python/mozbuild/mozbuild/test/backend/data/final_target/final-target/moz.build b/python/mozbuild/mozbuild/test/backend/data/final_target/final-target/moz.build
new file mode 100644
index 0000000000..e008f94478
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/final-target/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_TARGET = "random-final-target"
diff --git a/python/mozbuild/mozbuild/test/backend/data/final_target/moz.build b/python/mozbuild/mozbuild/test/backend/data/final_target/moz.build
new file mode 100644
index 0000000000..319062b78f
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ["xpi-name", "dist-subdir", "both", "final-target"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/final_target/xpi-name/moz.build b/python/mozbuild/mozbuild/test/backend/data/final_target/xpi-name/moz.build
new file mode 100644
index 0000000000..980810caa3
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/final_target/xpi-name/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+XPI_NAME = "mycrazyxpi"
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files-force/foo-data b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/foo-data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/foo-data
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-bar.py b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-bar.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-bar.py
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-foo.py b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-foo.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/generate-foo.py
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files-force/moz.build b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/moz.build
new file mode 100644
index 0000000000..d86b7b09ea
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files-force/moz.build
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+GENERATED_FILES += ["bar.c", "foo.c", "quux.c"]
+
+bar = GENERATED_FILES["bar.c"]
+bar.script = "generate-bar.py:baz"
+bar.force = True
+
+foo = GENERATED_FILES["foo.c"]
+foo.script = "generate-foo.py"
+foo.inputs = ["foo-data"]
+foo.force = False
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files/foo-data b/python/mozbuild/mozbuild/test/backend/data/generated-files/foo-data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files/foo-data
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files/generate-bar.py b/python/mozbuild/mozbuild/test/backend/data/generated-files/generate-bar.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files/generate-bar.py
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files/generate-foo.py b/python/mozbuild/mozbuild/test/backend/data/generated-files/generate-foo.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files/generate-foo.py
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated-files/moz.build b/python/mozbuild/mozbuild/test/backend/data/generated-files/moz.build
new file mode 100644
index 0000000000..01b444238e
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated-files/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+GENERATED_FILES += ["bar.c", "foo.h", "quux.c"]
+
+bar = GENERATED_FILES["bar.c"]
+bar.script = "generate-bar.py:baz"
+
+foo = GENERATED_FILES["foo.h"]
+foo.script = "generate-foo.py"
+foo.inputs = ["foo-data"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/generated_includes/moz.build b/python/mozbuild/mozbuild/test/backend/data/generated_includes/moz.build
new file mode 100644
index 0000000000..31f9042c0a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/generated_includes/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCAL_INCLUDES += ["!/bar/baz", "!foo"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/host-defines/moz.build b/python/mozbuild/mozbuild/test/backend/data/host-defines/moz.build
new file mode 100644
index 0000000000..f1a632c841
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/host-defines/moz.build
@@ -0,0 +1,9 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+value = "xyz"
+HOST_DEFINES["FOO"] = True
+HOST_DEFINES["BAZ"] = '"ab\'cd"'
+HOST_DEFINES["BAR"] = 7
+HOST_DEFINES["VALUE"] = value
+HOST_DEFINES["QUX"] = False
diff --git a/python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/Cargo.toml b/python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/Cargo.toml
new file mode 100644
index 0000000000..147cb3acb3
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "hostrusttool"
+version = "0.1.0"
+authors = ["The Mozilla Project Developers"]
+
+[lib]
+crate-type = ["staticlib"]
+
+[profile.dev]
+panic = "abort"
+
+[profile.release]
+panic = "abort"
diff --git a/python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/moz.build b/python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/moz.build
new file mode 100644
index 0000000000..96fccf2063
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/host-rust-library-features/moz.build
@@ -0,0 +1,22 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def HostLibrary(name):
+ """Template for libraries."""
+ HOST_LIBRARY_NAME = name
+
+
+@template
+def HostRustLibrary(name, features=None):
+ """Template for Rust libraries."""
+ HostLibrary(name)
+
+ IS_RUST_LIBRARY = True
+
+ if features:
+ HOST_RUST_LIBRARY_FEATURES = features
+
+
+HostRustLibrary("hostrusttool", ["musthave", "cantlivewithout"])
diff --git a/python/mozbuild/mozbuild/test/backend/data/host-rust-library/Cargo.toml b/python/mozbuild/mozbuild/test/backend/data/host-rust-library/Cargo.toml
new file mode 100644
index 0000000000..349664c621
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/host-rust-library/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "hostrusttool"
+version = "0.1.0"
+authors = [
+ "The Mozilla Project Developers",
+]
+
+[lib]
+crate-type = ["staticlib"]
+
+[profile.dev]
+panic = "abort"
+
+[profile.release]
+panic = "abort"
diff --git a/python/mozbuild/mozbuild/test/backend/data/host-rust-library/moz.build b/python/mozbuild/mozbuild/test/backend/data/host-rust-library/moz.build
new file mode 100644
index 0000000000..515f5d1a9f
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/host-rust-library/moz.build
@@ -0,0 +1,22 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def HostLibrary(name):
+ """Template for libraries."""
+ HOST_LIBRARY_NAME = name
+
+
+@template
+def HostRustLibrary(name, features=None):
+ """Template for Rust libraries."""
+ HostLibrary(name)
+
+ IS_RUST_LIBRARY = True
+
+ if features:
+ HOST_RUST_LIBRARY_FEATURES = features
+
+
+HostRustLibrary("hostrusttool")
diff --git a/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/moz.build b/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/moz.build
new file mode 100644
index 0000000000..c38b472911
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+# We want to test recursion into the subdir, so do the real work in 'sub'
+DIRS += ["sub"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/foo.h.in b/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/foo.h.in
new file mode 100644
index 0000000000..da287dfcaa
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/foo.h.in
@@ -0,0 +1 @@
+#define MOZ_FOO @MOZ_FOO@
diff --git a/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/moz.build b/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/moz.build
new file mode 100644
index 0000000000..1420a99a8f
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/install_substitute_config_files/sub/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+CONFIGURE_SUBST_FILES = ["foo.h"]
+
+EXPORTS.out += ["!foo.h"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/bar/moz.build b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/bar/moz.build
new file mode 100644
index 0000000000..f7d1560af3
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/bar/moz.build
@@ -0,0 +1,16 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PREPROCESSED_IPDL_SOURCES += [
+ "bar1.ipdl",
+]
+
+IPDL_SOURCES += [
+ "bar.ipdl",
+ "bar2.ipdlh",
+]
+
+FINAL_LIBRARY = "dummy"
diff --git a/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/foo/moz.build b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/foo/moz.build
new file mode 100644
index 0000000000..02e9f78154
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/foo/moz.build
@@ -0,0 +1,16 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PREPROCESSED_IPDL_SOURCES += [
+ "foo1.ipdl",
+]
+
+IPDL_SOURCES += [
+ "foo.ipdl",
+ "foo2.ipdlh",
+]
+
+FINAL_LIBRARY = "dummy"
diff --git a/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/ipdl/moz.build b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/ipdl/moz.build
new file mode 100644
index 0000000000..066397cb84
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/ipdl/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This file just exists to establish a directory as the IPDL root directory.
+
+FINAL_LIBRARY = "dummy"
diff --git a/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/moz.build b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/moz.build
new file mode 100644
index 0000000000..4f0ddaa10e
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/ipdl_sources/moz.build
@@ -0,0 +1,19 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+@template
+def Library(name):
+ LIBRARY_NAME = name
+
+
+Library("dummy")
+
+DIRS += [
+ "bar",
+ "foo",
+ "ipdl",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/jar-manifests/moz.build b/python/mozbuild/mozbuild/test/backend/data/jar-manifests/moz.build
new file mode 100644
index 0000000000..d988c0ff9b
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/jar-manifests/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+JAR_MANIFESTS += ["jar.mn"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/moz.build
new file mode 100644
index 0000000000..f01a012760
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/moz.build
@@ -0,0 +1,11 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+include("templates.mozbuild")
+
+DIRS += [
+ "real",
+ "shared",
+ "prog",
+ "static",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/prog/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/moz.build
new file mode 100644
index 0000000000..3741f4be09
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/moz.build
@@ -0,0 +1,11 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ["qux"]
+
+Program("MyProgram")
+
+USE_LIBS += [
+ "bar",
+ "baz",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/moz.build
new file mode 100644
index 0000000000..3152de6211
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/moz.build
@@ -0,0 +1,6 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += ["qux1.c"]
+
+SharedLibrary("qux")
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/qux1.c b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/qux1.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/prog/qux/qux1.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo1.c b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo1.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo1.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo2.c b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo2.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/foo2.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/moz.build
new file mode 100644
index 0000000000..a0bd7526e6
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/real/foo/moz.build
@@ -0,0 +1,6 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += ["foo1.c", "foo2.c"]
+
+FINAL_LIBRARY = "foo"
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/real/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/real/moz.build
new file mode 100644
index 0000000000..32f9c1d656
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/real/moz.build
@@ -0,0 +1,14 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += [
+ "foo",
+]
+
+NO_EXPAND_LIBS = True
+
+OS_LIBS += ["-lbaz"]
+
+USE_LIBS += ["static:baz"]
+
+Library("foo")
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/baz1.c b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/baz1.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/baz1.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/moz.build
new file mode 100644
index 0000000000..3299fa28f4
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/baz/moz.build
@@ -0,0 +1,6 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += ["baz1.c"]
+
+FINAL_LIBRARY = "baz"
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/shared/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/moz.build
new file mode 100644
index 0000000000..42d79fe1fd
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/shared/moz.build
@@ -0,0 +1,14 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += [
+ "baz",
+]
+
+STATIC_LIBRARY_NAME = "baz_s"
+FORCE_STATIC_LIB = True
+
+OS_LIBS += ["-lfoo"]
+USE_LIBS += ["qux"]
+
+SharedLibrary("baz")
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar1.cc b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar1.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar1.cc
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar2.cc b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar2.cc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar2.cc
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/bar_helper1.cpp b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/bar_helper1.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/bar_helper1.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/moz.build
new file mode 100644
index 0000000000..12d0fc83fb
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/bar_helper/moz.build
@@ -0,0 +1,8 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += [
+ "bar_helper1.cpp",
+]
+
+FINAL_LIBRARY = "bar"
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/moz.build
new file mode 100644
index 0000000000..d9d75803ed
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/bar/moz.build
@@ -0,0 +1,13 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SOURCES += [
+ "bar1.cc",
+ "bar2.cc",
+]
+
+DIRS += [
+ "bar_helper",
+]
+
+FINAL_LIBRARY = "bar"
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/static/moz.build b/python/mozbuild/mozbuild/test/backend/data/linkage/static/moz.build
new file mode 100644
index 0000000000..37b3d96cc7
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/static/moz.build
@@ -0,0 +1,12 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += [
+ "bar",
+]
+
+USE_LIBS += ["foo"]
+
+OS_LIBS += ["-lbar"]
+
+Library("bar")
diff --git a/python/mozbuild/mozbuild/test/backend/data/linkage/templates.mozbuild b/python/mozbuild/mozbuild/test/backend/data/linkage/templates.mozbuild
new file mode 100644
index 0000000000..1f874060df
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/linkage/templates.mozbuild
@@ -0,0 +1,23 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+@template
+def Library(name):
+ LIBRARY_NAME = name
+
+@template
+def SharedLibrary(name):
+ FORCE_SHARED_LIB = True
+ LIBRARY_NAME = name
+
+@template
+def Binary():
+ # Add -lfoo for testing purposes.
+ OS_LIBS += ['foo']
+
+
+@template
+def Program(name):
+ PROGRAM = name
+
+ Binary() \ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/local_includes/bar/baz/dummy_file_for_nonempty_directory b/python/mozbuild/mozbuild/test/backend/data/local_includes/bar/baz/dummy_file_for_nonempty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/local_includes/bar/baz/dummy_file_for_nonempty_directory
diff --git a/python/mozbuild/mozbuild/test/backend/data/local_includes/foo/dummy_file_for_nonempty_directory b/python/mozbuild/mozbuild/test/backend/data/local_includes/foo/dummy_file_for_nonempty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/local_includes/foo/dummy_file_for_nonempty_directory
diff --git a/python/mozbuild/mozbuild/test/backend/data/local_includes/moz.build b/python/mozbuild/mozbuild/test/backend/data/local_includes/moz.build
new file mode 100644
index 0000000000..1c29ac2ea2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/local_includes/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCAL_INCLUDES += ["/bar/baz", "foo"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/bar.ini b/python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/bar.ini
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/bar.ini
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/foo.js b/python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/foo.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-files/en-US/foo.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-files/moz.build b/python/mozbuild/mozbuild/test/backend/data/localized-files/moz.build
new file mode 100644
index 0000000000..93a97c7b84
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-files/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_FILES += [
+ "en-US/abc/*.abc",
+ "en-US/bar.ini",
+ "en-US/foo.js",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/en-US/localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/en-US/localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/en-US/localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/foo-data b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/foo-data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/foo-data
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/generate-foo.py b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/generate-foo.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/generate-foo.py
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/inner/locales/en-US/localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/inner/locales/en-US/localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/inner/locales/en-US/localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/locales/en-US/localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/locales/en-US/localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/locales/en-US/localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/moz.build b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/moz.build
new file mode 100644
index 0000000000..2b0cf472c9
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/moz.build
@@ -0,0 +1,32 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_GENERATED_FILES += ["foo{AB_CD}.xyz"]
+
+foo = LOCALIZED_GENERATED_FILES["foo{AB_CD}.xyz"]
+foo.script = "generate-foo.py"
+foo.inputs = [
+ "en-US/localized-input",
+ "non-localized-input",
+]
+
+LOCALIZED_GENERATED_FILES += ["bar{AB_rCD}.xyz"]
+
+bar = LOCALIZED_GENERATED_FILES["bar{AB_rCD}.xyz"]
+bar.script = "generate-foo.py"
+bar.inputs = [
+ # Absolute source path.
+ "/inner/locales/en-US/localized-input",
+ "non-localized-input",
+]
+
+LOCALIZED_GENERATED_FILES += ["zot{AB_rCD}.xyz"]
+
+bar = LOCALIZED_GENERATED_FILES["zot{AB_rCD}.xyz"]
+bar.script = "generate-foo.py"
+bar.inputs = [
+ # Relative source path.
+ "locales/en-US/localized-input",
+ "non-localized-input",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/non-localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/non-localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-AB_CD/non-localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/en-US/localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/en-US/localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/en-US/localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/foo-data b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/foo-data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/foo-data
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/generate-foo.py b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/generate-foo.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/generate-foo.py
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/moz.build b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/moz.build
new file mode 100644
index 0000000000..26fb165e06
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/moz.build
@@ -0,0 +1,22 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_GENERATED_FILES += ["foo.xyz"]
+
+foo = LOCALIZED_GENERATED_FILES["foo.xyz"]
+foo.script = "generate-foo.py"
+foo.inputs = [
+ "en-US/localized-input",
+ "non-localized-input",
+]
+
+LOCALIZED_GENERATED_FILES += ["abc.xyz"]
+
+abc = LOCALIZED_GENERATED_FILES["abc.xyz"]
+abc.script = "generate-foo.py"
+abc.inputs = [
+ "en-US/localized-input",
+ "non-localized-input",
+]
+abc.force = True
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/non-localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/non-localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files-force/non-localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/en-US/localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/en-US/localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/en-US/localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/foo-data b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/foo-data
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/foo-data
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/generate-foo.py b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/generate-foo.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/generate-foo.py
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/moz.build b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/moz.build
new file mode 100644
index 0000000000..f44325dfb1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/moz.build
@@ -0,0 +1,15 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_GENERATED_FILES += ["foo.xyz"]
+
+foo = LOCALIZED_GENERATED_FILES["foo.xyz"]
+foo.script = "generate-foo.py"
+foo.inputs = [
+ "en-US/localized-input",
+ "non-localized-input",
+]
+
+# Also check that using it in LOCALIZED_FILES does the right thing.
+LOCALIZED_FILES += ["!foo.xyz"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/non-localized-input b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/non-localized-input
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-generated-files/non-localized-input
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/bar.ini b/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/bar.ini
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/bar.ini
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/foo.js b/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/foo.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/en-US/foo.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/moz.build b/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/moz.build
new file mode 100644
index 0000000000..8cec207128
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/localized-pp-files/moz.build
@@ -0,0 +1,8 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+LOCALIZED_PP_FILES += [
+ "en-US/bar.ini",
+ "en-US/foo.js",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/c-library.c b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/c-library.c
new file mode 100644
index 0000000000..3b09e769db
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/c-library.c
@@ -0,0 +1,2 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/moz.build
new file mode 100644
index 0000000000..8e15d10c43
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-library/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SharedLibrary("c_library")
+
+SOURCES = ["c-library.c"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/c_test_program.c b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/c_test_program.c
new file mode 100644
index 0000000000..3b09e769db
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/c_test_program.c
@@ -0,0 +1,2 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/moz.build
new file mode 100644
index 0000000000..27f2cd3d5d
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-program/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+Program("c_test_program")
+
+SOURCES = ["c_test_program.c"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/c_simple_program.c b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/c_simple_program.c
new file mode 100644
index 0000000000..3b09e769db
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/c_simple_program.c
@@ -0,0 +1,2 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/moz.build
new file mode 100644
index 0000000000..db958d1d1f
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/c-simple-programs/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SimplePrograms(["c_simple_program"], ext=".c")
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/c-source.c b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/c-source.c
new file mode 100644
index 0000000000..3b09e769db
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/c-source.c
@@ -0,0 +1,2 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/cxx-library.cpp b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/cxx-library.cpp
new file mode 100644
index 0000000000..3b09e769db
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/cxx-library.cpp
@@ -0,0 +1,2 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/moz.build
new file mode 100644
index 0000000000..ee75ad0cb9
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-library/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SharedLibrary("cxx-library")
+
+SOURCES = [
+ "c-source.c",
+ "cxx-library.cpp",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/cxx_test_program.cpp b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/cxx_test_program.cpp
new file mode 100644
index 0000000000..3b09e769db
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/cxx_test_program.cpp
@@ -0,0 +1,2 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/moz.build
new file mode 100644
index 0000000000..175f18c88a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-program/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+Program("cxx_test_program")
+
+SOURCES = ["cxx_test_program.cpp"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/cxx_simple_program.cpp b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/cxx_simple_program.cpp
new file mode 100644
index 0000000000..3b09e769db
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/cxx_simple_program.cpp
@@ -0,0 +1,2 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/moz.build
new file mode 100644
index 0000000000..e055370900
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/cxx-simple-programs/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+SimplePrograms(["cxx_simple_program"])
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/moz.build
new file mode 100644
index 0000000000..7f0a6b430b
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/moz.build
@@ -0,0 +1,35 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += [
+ "c-program",
+ "cxx-program",
+ "c-simple-programs",
+ "cxx-simple-programs",
+ "c-library",
+ "cxx-library",
+]
+
+
+@template
+def Program(name):
+ PROGRAM = name
+
+
+@template
+def SimplePrograms(names, ext=".cpp"):
+ SIMPLE_PROGRAMS += names
+ SOURCES += ["%s%s" % (name, ext) for name in names]
+
+
+@template
+def Library(name):
+ LIBRARY_NAME = name
+
+
+@template
+def SharedLibrary(name):
+ Library(name)
+
+ FORCE_SHARED_LIB = True
diff --git a/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/simple-programs/moz.build b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/simple-programs/moz.build
new file mode 100644
index 0000000000..62966a58e1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/prog-lib-c-only/simple-programs/moz.build
@@ -0,0 +1,3 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-bin/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-bin/moz.build
new file mode 100644
index 0000000000..d8b952c014
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-bin/moz.build
@@ -0,0 +1,4 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+Program("dist-bin")
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-subdir/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-subdir/moz.build
new file mode 100644
index 0000000000..fc2f664c01
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-subdir/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_SUBDIR = "foo"
+Program("dist-subdir")
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/final-target/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/final-target/moz.build
new file mode 100644
index 0000000000..a0d5805262
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/final-target/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_TARGET = "final/target"
+Program("final-target")
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/moz.build
new file mode 100644
index 0000000000..d1d087fd45
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/moz.build
@@ -0,0 +1,15 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def Program(name):
+ PROGRAM = name
+
+
+DIRS += [
+ "dist-bin",
+ "dist-subdir",
+ "final-target",
+ "not-installed",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/not-installed/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/not-installed/moz.build
new file mode 100644
index 0000000000..c725ab7326
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/not-installed/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_INSTALL = False
+Program("not-installed")
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/bar.res.in b/python/mozbuild/mozbuild/test/backend/data/resources/bar.res.in
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/bar.res.in
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/cursor.cur b/python/mozbuild/mozbuild/test/backend/data/resources/cursor.cur
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/cursor.cur
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/desktop1.ttf b/python/mozbuild/mozbuild/test/backend/data/resources/desktop1.ttf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/desktop1.ttf
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/desktop2.ttf b/python/mozbuild/mozbuild/test/backend/data/resources/desktop2.ttf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/desktop2.ttf
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/extra.manifest b/python/mozbuild/mozbuild/test/backend/data/resources/extra.manifest
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/extra.manifest
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/font1.ttf b/python/mozbuild/mozbuild/test/backend/data/resources/font1.ttf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/font1.ttf
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/font2.ttf b/python/mozbuild/mozbuild/test/backend/data/resources/font2.ttf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/font2.ttf
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/foo.res b/python/mozbuild/mozbuild/test/backend/data/resources/foo.res
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/foo.res
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/mobile.ttf b/python/mozbuild/mozbuild/test/backend/data/resources/mobile.ttf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/mobile.ttf
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/moz.build b/python/mozbuild/mozbuild/test/backend/data/resources/moz.build
new file mode 100644
index 0000000000..619af26e64
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/moz.build
@@ -0,0 +1,9 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+RESOURCE_FILES += ["bar.res.in", "foo.res"]
+RESOURCE_FILES.cursors += ["cursor.cur"]
+RESOURCE_FILES.fonts += ["font1.ttf", "font2.ttf"]
+RESOURCE_FILES.fonts.desktop += ["desktop1.ttf", "desktop2.ttf"]
+RESOURCE_FILES.fonts.mobile += ["mobile.ttf"]
+RESOURCE_FILES.tests += ["extra.manifest", "test.manifest"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/resources/test.manifest b/python/mozbuild/mozbuild/test/backend/data/resources/test.manifest
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/resources/test.manifest
diff --git a/python/mozbuild/mozbuild/test/backend/data/rust-library-features/Cargo.toml b/python/mozbuild/mozbuild/test/backend/data/rust-library-features/Cargo.toml
new file mode 100644
index 0000000000..0d778b2b0e
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-library-features/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "feature-library"
+version = "0.1.0"
+authors = [
+ "The Mozilla Project Developers",
+]
+
+[lib]
+crate-type = ["staticlib"]
+
+[profile.dev]
+panic = "abort"
+
+[profile.release]
+panic = "abort"
diff --git a/python/mozbuild/mozbuild/test/backend/data/rust-library-features/moz.build b/python/mozbuild/mozbuild/test/backend/data/rust-library-features/moz.build
new file mode 100644
index 0000000000..f17f29b0e7
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-library-features/moz.build
@@ -0,0 +1,20 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def Library(name):
+ """Template for libraries."""
+ LIBRARY_NAME = name
+
+
+@template
+def RustLibrary(name, features):
+ """Template for Rust libraries."""
+ Library(name)
+
+ IS_RUST_LIBRARY = True
+ RUST_LIBRARY_FEATURES = features
+
+
+RustLibrary("feature-library", ["musthave", "cantlivewithout"])
diff --git a/python/mozbuild/mozbuild/test/backend/data/rust-library/Cargo.toml b/python/mozbuild/mozbuild/test/backend/data/rust-library/Cargo.toml
new file mode 100644
index 0000000000..5e9e44632f
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-library/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "test-library"
+version = "0.1.0"
+authors = [
+ "The Mozilla Project Developers",
+]
+
+[lib]
+crate-type = ["staticlib"]
+
+[profile.dev]
+panic = "abort"
+
+[profile.release]
+panic = "abort"
diff --git a/python/mozbuild/mozbuild/test/backend/data/rust-library/moz.build b/python/mozbuild/mozbuild/test/backend/data/rust-library/moz.build
new file mode 100644
index 0000000000..b0f29a1ef5
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-library/moz.build
@@ -0,0 +1,19 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def Library(name):
+ """Template for libraries."""
+ LIBRARY_NAME = name
+
+
+@template
+def RustLibrary(name):
+ """Template for Rust libraries."""
+ Library(name)
+
+ IS_RUST_LIBRARY = True
+
+
+RustLibrary("test-library")
diff --git a/python/mozbuild/mozbuild/test/backend/data/rust-programs/code/Cargo.toml b/python/mozbuild/mozbuild/test/backend/data/rust-programs/code/Cargo.toml
new file mode 100644
index 0000000000..e0d400e070
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-programs/code/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+authors = ["The Mozilla Project Developers"]
+name = "testing"
+version = "0.0.1"
+
+[[bin]]
+name = "target"
+
+[[bin]]
+name = "host"
diff --git a/python/mozbuild/mozbuild/test/backend/data/rust-programs/code/moz.build b/python/mozbuild/mozbuild/test/backend/data/rust-programs/code/moz.build
new file mode 100644
index 0000000000..f0efdb3799
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-programs/code/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+RUST_PROGRAMS += ["target"]
+HOST_RUST_PROGRAMS += ["host"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/rust-programs/moz.build b/python/mozbuild/mozbuild/test/backend/data/rust-programs/moz.build
new file mode 100644
index 0000000000..cb635f6adb
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/rust-programs/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ["code"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/bar.cpp b/python/mozbuild/mozbuild/test/backend/data/sources/bar.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/bar.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/bar.s b/python/mozbuild/mozbuild/test/backend/data/sources/bar.s
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/bar.s
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/baz.c b/python/mozbuild/mozbuild/test/backend/data/sources/baz.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/baz.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/foo.asm b/python/mozbuild/mozbuild/test/backend/data/sources/foo.asm
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/foo.asm
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/foo.cpp b/python/mozbuild/mozbuild/test/backend/data/sources/foo.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/foo.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/fuga.mm b/python/mozbuild/mozbuild/test/backend/data/sources/fuga.mm
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/fuga.mm
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/hoge.mm b/python/mozbuild/mozbuild/test/backend/data/sources/hoge.mm
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/hoge.mm
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/moz.build b/python/mozbuild/mozbuild/test/backend/data/sources/moz.build
new file mode 100644
index 0000000000..40d5a8d38d
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/moz.build
@@ -0,0 +1,26 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def Library(name):
+ """Template for libraries."""
+ LIBRARY_NAME = name
+
+
+Library("dummy")
+
+SOURCES += ["bar.s", "foo.asm"]
+
+HOST_SOURCES += ["bar.cpp", "foo.cpp"]
+HOST_SOURCES += ["baz.c", "qux.c"]
+
+SOURCES += ["baz.c", "qux.c"]
+
+SOURCES += ["fuga.mm", "hoge.mm"]
+
+SOURCES += ["titi.S", "toto.S"]
+
+WASM_SOURCES += ["bar.cpp"]
+WASM_SOURCES += ["baz.c"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/qux.c b/python/mozbuild/mozbuild/test/backend/data/sources/qux.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/qux.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/titi.S b/python/mozbuild/mozbuild/test/backend/data/sources/titi.S
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/titi.S
diff --git a/python/mozbuild/mozbuild/test/backend/data/sources/toto.S b/python/mozbuild/mozbuild/test/backend/data/sources/toto.S
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/sources/toto.S
diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/Makefile.in b/python/mozbuild/mozbuild/test/backend/data/stub0/Makefile.in
new file mode 100644
index 0000000000..02ff0a3f90
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/stub0/Makefile.in
@@ -0,0 +1,4 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FOO := foo
diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/dir1/Makefile.in b/python/mozbuild/mozbuild/test/backend/data/stub0/dir1/Makefile.in
new file mode 100644
index 0000000000..17c147d97a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/stub0/dir1/Makefile.in
@@ -0,0 +1,7 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+include $(DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/dir1/moz.build b/python/mozbuild/mozbuild/test/backend/data/stub0/dir1/moz.build
new file mode 100644
index 0000000000..62966a58e1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/stub0/dir1/moz.build
@@ -0,0 +1,3 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/dir2/moz.build b/python/mozbuild/mozbuild/test/backend/data/stub0/dir2/moz.build
new file mode 100644
index 0000000000..62966a58e1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/stub0/dir2/moz.build
@@ -0,0 +1,3 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/dir3/Makefile.in b/python/mozbuild/mozbuild/test/backend/data/stub0/dir3/Makefile.in
new file mode 100644
index 0000000000..17c147d97a
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/stub0/dir3/Makefile.in
@@ -0,0 +1,7 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+include $(DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/dir3/moz.build b/python/mozbuild/mozbuild/test/backend/data/stub0/dir3/moz.build
new file mode 100644
index 0000000000..62966a58e1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/stub0/dir3/moz.build
@@ -0,0 +1,3 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/python/mozbuild/mozbuild/test/backend/data/stub0/moz.build b/python/mozbuild/mozbuild/test/backend/data/stub0/moz.build
new file mode 100644
index 0000000000..4f6e7cb318
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/stub0/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ["dir1"]
+DIRS += ["dir2"]
+TEST_DIRS += ["dir3"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/Makefile.in b/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/Makefile.in
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/Makefile.in
diff --git a/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/foo.in b/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/foo.in
new file mode 100644
index 0000000000..5331f1f051
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/foo.in
@@ -0,0 +1 @@
+TEST = @MOZ_FOO@
diff --git a/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/moz.build b/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/moz.build
new file mode 100644
index 0000000000..bded13e07d
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/substitute_config_files/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+CONFIGURE_SUBST_FILES = ["foo"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/another-file.sjs b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/another-file.sjs
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/another-file.sjs
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/browser.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/browser.ini
new file mode 100644
index 0000000000..4f1335d6b1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/browser.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+support-files =
+ another-file.sjs
+ data/**
+
+[test_sub.js] \ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/one.txt b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/one.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/one.txt
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/two.txt b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/two.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/data/two.txt
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/test_sub.js b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/test_sub.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/child/test_sub.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/mochitest.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/mochitest.ini
new file mode 100644
index 0000000000..a9860f3de8
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/mochitest.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+support-files =
+ support-file.txt
+ !/child/test_sub.js
+ !/child/another-file.sjs
+ !/child/data/**
+
+[test_foo.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/moz.build
new file mode 100644
index 0000000000..9df54dbc99
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+MOCHITEST_MANIFESTS += ["mochitest.ini"]
+BROWSER_CHROME_MANIFESTS += ["child/browser.ini"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/support-file.txt b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/support-file.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/support-file.txt
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/test_foo.js b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/test_foo.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifest-shared-support/test_foo.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest-common.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest-common.ini
new file mode 100644
index 0000000000..31d07b5af3
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest-common.ini
@@ -0,0 +1 @@
+[test_bar.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest.ini
new file mode 100644
index 0000000000..cf7a3c44bd
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/mochitest.ini
@@ -0,0 +1,2 @@
+[test_foo.js]
+[include:mochitest-common.ini]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/moz.build
new file mode 100644
index 0000000000..8058c0b836
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/moz.build
@@ -0,0 +1,6 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+MOCHITEST_MANIFESTS += [
+ "mochitest.ini",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_bar.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_bar.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_bar.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_foo.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_foo.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-backend-sources/test_foo.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest1.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest1.ini
new file mode 100644
index 0000000000..1f9816a899
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest1.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+support-files = support-file.txt
+
+[test_foo.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest2.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest2.ini
new file mode 100644
index 0000000000..e2a2fc96a7
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/mochitest2.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+support-files = support-file.txt
+
+[test_bar.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/moz.build
new file mode 100644
index 0000000000..a86b934fa1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/moz.build
@@ -0,0 +1,7 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+MOCHITEST_MANIFESTS += [
+ "mochitest1.ini",
+ "mochitest2.ini",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_bar.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_bar.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_bar.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_foo.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_foo.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-duplicate-support-files/test_foo.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/instrumentation.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/instrumentation.ini
new file mode 100644
index 0000000000..03d4f794e2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/instrumentation.ini
@@ -0,0 +1 @@
+[not_packaged.java]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.ini
new file mode 100644
index 0000000000..009b2b2239
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.ini
@@ -0,0 +1 @@
+[mochitest.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/mochitest.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/moz.build
new file mode 100644
index 0000000000..f0496e09d9
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/moz.build
@@ -0,0 +1,10 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+MOCHITEST_MANIFESTS += [
+ "mochitest.ini",
+]
+
+ANDROID_INSTRUMENTATION_MANIFESTS += [
+ "instrumentation.ini",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/not_packaged.java b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/not_packaged.java
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-package-tests/not_packaged.java
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/test_bar.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/test_bar.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/test_bar.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/xpcshell.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/xpcshell.ini
new file mode 100644
index 0000000000..0cddad8ba9
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/dir1/xpcshell.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[test_bar.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.ini
new file mode 100644
index 0000000000..81869e1fa0
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[mochitest.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/mochitest.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/moz.build
new file mode 100644
index 0000000000..42462a3059
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/moz.build
@@ -0,0 +1,9 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+XPCSHELL_TESTS_MANIFESTS += [
+ "dir1/xpcshell.ini",
+ "xpcshell.ini",
+]
+
+MOCHITEST_MANIFESTS += ["mochitest.ini"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.ini b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.ini
new file mode 100644
index 0000000000..f6a5351e94
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+support-files = support/**
+
+[xpcshell.js]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.js b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-manifests-written/xpcshell.js
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/moz.build
new file mode 100644
index 0000000000..eb83fd1826
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ["test", "src"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/src/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/src/moz.build
new file mode 100644
index 0000000000..69cde19c29
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/src/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+
+@template
+def Library(name):
+ """Template for libraries"""
+ LIBRARY_NAME = name
+
+
+Library("foo")
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/moz.build b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/moz.build
new file mode 100644
index 0000000000..a43f4083b3
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/moz.build
@@ -0,0 +1,32 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_TARGET = "_tests/xpcshell/tests/mozbuildtest"
+
+
+@template
+def Library(name):
+ """Template for libraries"""
+ LIBRARY_NAME = name
+
+
+@template
+def SimplePrograms(names, ext=".cpp"):
+ """Template for simple program executables.
+
+ Those have a single source with the same base name as the executable.
+ """
+ SIMPLE_PROGRAMS += names
+ SOURCES += ["%s%s" % (name, ext) for name in names]
+
+
+@template
+def HostLibrary(name):
+ """Template for build tools libraries."""
+ HOST_LIBRARY_NAME = name
+
+
+Library("test-library")
+HostLibrary("host-test-library")
+SimplePrograms(["test-one", "test-two"])
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-one.cpp b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-one.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-one.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-two.cpp b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-two.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test-support-binaries-tracked/test/test-two.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/test_config/file.in b/python/mozbuild/mozbuild/test/backend/data/test_config/file.in
new file mode 100644
index 0000000000..07aa30deb6
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test_config/file.in
@@ -0,0 +1,3 @@
+#ifdef foo
+@foo@
+@bar@
diff --git a/python/mozbuild/mozbuild/test/backend/data/test_config/moz.build b/python/mozbuild/mozbuild/test/backend/data/test_config/moz.build
new file mode 100644
index 0000000000..5cf4c78f90
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/test_config/moz.build
@@ -0,0 +1,3 @@
+CONFIGURE_SUBST_FILES = [
+ "file",
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/Makefile.in b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/Makefile.in
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/Makefile.in
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/baz.def b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/baz.def
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/baz.def
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build
new file mode 100644
index 0000000000..81595d2db3
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DELAYLOAD_DLLS = ["foo.dll", "bar.dll"]
+
+RCFILE = "foo.rc"
+RCINCLUDE = "bar.rc"
+DEFFILE = "baz.def"
+
+WIN32_EXE_LDFLAGS += ["-subsystem:console"]
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.c b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.cpp b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.mm b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.mm
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test1.mm
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.c b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.c
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.cpp b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.mm b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.mm
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/test2.mm
diff --git a/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/bar.cpp b/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/bar.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/bar.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/foo.cpp b/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/foo.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/foo.cpp
diff --git a/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/moz.build b/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/moz.build
new file mode 100644
index 0000000000..ae1fc0c370
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/visual-studio/dir1/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_LIBRARY = "test"
+SOURCES += ["bar.cpp", "foo.cpp"]
+LOCAL_INCLUDES += ["/includeA/foo"]
+DEFINES["DEFINEFOO"] = True
+DEFINES["DEFINEBAR"] = "bar"
diff --git a/python/mozbuild/mozbuild/test/backend/data/visual-studio/moz.build b/python/mozbuild/mozbuild/test/backend/data/visual-studio/moz.build
new file mode 100644
index 0000000000..a0a888fa01
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/visual-studio/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIRS += ["dir1"]
+
+Library("test")
diff --git a/python/mozbuild/mozbuild/test/backend/data/xpidl/bar.idl b/python/mozbuild/mozbuild/test/backend/data/xpidl/bar.idl
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/xpidl/bar.idl
diff --git a/python/mozbuild/mozbuild/test/backend/data/xpidl/config/makefiles/xpidl/Makefile.in b/python/mozbuild/mozbuild/test/backend/data/xpidl/config/makefiles/xpidl/Makefile.in
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/xpidl/config/makefiles/xpidl/Makefile.in
diff --git a/python/mozbuild/mozbuild/test/backend/data/xpidl/foo.idl b/python/mozbuild/mozbuild/test/backend/data/xpidl/foo.idl
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/xpidl/foo.idl
diff --git a/python/mozbuild/mozbuild/test/backend/data/xpidl/moz.build b/python/mozbuild/mozbuild/test/backend/data/xpidl/moz.build
new file mode 100644
index 0000000000..df521ac7c5
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/xpidl/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+XPIDL_MODULE = "my_module"
+XPIDL_SOURCES = ["bar.idl", "foo.idl"]
diff --git a/python/mozbuild/mozbuild/test/backend/test_build.py b/python/mozbuild/mozbuild/test/backend/test_build.py
new file mode 100644
index 0000000000..3287ba5e57
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_build.py
@@ -0,0 +1,265 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import shutil
+import sys
+import unittest
+from contextlib import contextmanager
+from tempfile import mkdtemp
+
+import buildconfig
+import mozpack.path as mozpath
+import six
+from mozfile import which
+from mozpack.files import FileFinder
+from mozunit import main
+
+from mozbuild.backend import get_backend_class
+from mozbuild.backend.configenvironment import ConfigEnvironment
+from mozbuild.backend.fastermake import FasterMakeBackend
+from mozbuild.backend.recursivemake import RecursiveMakeBackend
+from mozbuild.base import MozbuildObject
+from mozbuild.frontend.emitter import TreeMetadataEmitter
+from mozbuild.frontend.reader import BuildReader
+from mozbuild.util import ensureParentDir
+
+
+def make_path():
+ try:
+ return buildconfig.substs["GMAKE"]
+ except KeyError:
+ fetches_dir = os.environ.get("MOZ_FETCHES_DIR")
+ extra_search_dirs = ()
+ if fetches_dir:
+ extra_search_dirs = (os.path.join(fetches_dir, "mozmake"),)
+ # Fallback for when running the test without an objdir.
+ for name in ("gmake", "make", "mozmake", "gnumake", "mingw32-make"):
+ path = which(name, extra_search_dirs=extra_search_dirs)
+ if path:
+ return path
+
+
+BASE_SUBSTS = [
+ ("PYTHON", mozpath.normsep(sys.executable)),
+ ("PYTHON3", mozpath.normsep(sys.executable)),
+ ("MOZ_UI_LOCALE", "en-US"),
+ ("GMAKE", make_path()),
+]
+
+
+class TestBuild(unittest.TestCase):
+ def setUp(self):
+ self._old_env = dict(os.environ)
+ os.environ.pop("MOZCONFIG", None)
+ os.environ.pop("MOZ_OBJDIR", None)
+ os.environ.pop("MOZ_PGO", None)
+
+ def tearDown(self):
+ os.environ.clear()
+ os.environ.update(self._old_env)
+
+ @contextmanager
+ def do_test_backend(self, *backends, **kwargs):
+ # Create the objdir in the srcdir to ensure that they share
+ # the same drive on Windows.
+ topobjdir = mkdtemp(dir=buildconfig.topsrcdir)
+ try:
+ config = ConfigEnvironment(buildconfig.topsrcdir, topobjdir, **kwargs)
+ reader = BuildReader(config)
+ emitter = TreeMetadataEmitter(config)
+ moz_build = mozpath.join(config.topsrcdir, "test.mozbuild")
+ definitions = list(emitter.emit(reader.read_mozbuild(moz_build, config)))
+ for backend in backends:
+ backend(config).consume(definitions)
+
+ yield config
+ except Exception:
+ raise
+ finally:
+ if not os.environ.get("MOZ_NO_CLEANUP"):
+ shutil.rmtree(topobjdir)
+
+ @contextmanager
+ def line_handler(self):
+ lines = []
+
+ def handle_make_line(line):
+ lines.append(line)
+
+ try:
+ yield handle_make_line
+ except Exception:
+ print("\n".join(lines))
+ raise
+
+ if os.environ.get("MOZ_VERBOSE_MAKE"):
+ print("\n".join(lines))
+
+ def test_recursive_make(self):
+ substs = list(BASE_SUBSTS)
+ with self.do_test_backend(RecursiveMakeBackend, substs=substs) as config:
+ build = MozbuildObject(config.topsrcdir, None, None, config.topobjdir)
+ build._config_environment = config
+ overrides = [
+ "install_manifest_depends=",
+ "MOZ_JAR_MAKER_FILE_FORMAT=flat",
+ "TEST_MOZBUILD=1",
+ ]
+ with self.line_handler() as handle_make_line:
+ build._run_make(
+ directory=config.topobjdir,
+ target=overrides,
+ silent=False,
+ line_handler=handle_make_line,
+ )
+
+ self.validate(config)
+
+ def test_faster_recursive_make(self):
+ substs = list(BASE_SUBSTS) + [
+ ("BUILD_BACKENDS", "FasterMake+RecursiveMake"),
+ ]
+ with self.do_test_backend(
+ get_backend_class("FasterMake+RecursiveMake"), substs=substs
+ ) as config:
+ buildid = mozpath.join(config.topobjdir, "config", "buildid")
+ ensureParentDir(buildid)
+ with open(buildid, "w") as fh:
+ fh.write("20100101012345\n")
+
+ build = MozbuildObject(config.topsrcdir, None, None, config.topobjdir)
+ build._config_environment = config
+ overrides = [
+ "install_manifest_depends=",
+ "MOZ_JAR_MAKER_FILE_FORMAT=flat",
+ "TEST_MOZBUILD=1",
+ ]
+ with self.line_handler() as handle_make_line:
+ build._run_make(
+ directory=config.topobjdir,
+ target=overrides,
+ silent=False,
+ line_handler=handle_make_line,
+ )
+
+ self.validate(config)
+
+ def test_faster_make(self):
+ substs = list(BASE_SUBSTS) + [
+ ("MOZ_BUILD_APP", "dummy_app"),
+ ("MOZ_WIDGET_TOOLKIT", "dummy_widget"),
+ ]
+ with self.do_test_backend(
+ RecursiveMakeBackend, FasterMakeBackend, substs=substs
+ ) as config:
+ buildid = mozpath.join(config.topobjdir, "config", "buildid")
+ ensureParentDir(buildid)
+ with open(buildid, "w") as fh:
+ fh.write("20100101012345\n")
+
+ build = MozbuildObject(config.topsrcdir, None, None, config.topobjdir)
+ build._config_environment = config
+ overrides = [
+ "TEST_MOZBUILD=1",
+ ]
+ with self.line_handler() as handle_make_line:
+ build._run_make(
+ directory=mozpath.join(config.topobjdir, "faster"),
+ target=overrides,
+ silent=False,
+ line_handler=handle_make_line,
+ )
+
+ self.validate(config)
+
+ def validate(self, config):
+ self.maxDiff = None
+ test_path = mozpath.join(
+ "$SRCDIR",
+ "python",
+ "mozbuild",
+ "mozbuild",
+ "test",
+ "backend",
+ "data",
+ "build",
+ )
+
+ result = {
+ p: six.ensure_text(f.open().read())
+ for p, f in FileFinder(mozpath.join(config.topobjdir, "dist"))
+ }
+ self.assertTrue(len(result))
+ self.assertEqual(
+ result,
+ {
+ "bin/baz.ini": "baz.ini: FOO is foo\n",
+ "bin/child/bar.ini": "bar.ini\n",
+ "bin/child2/foo.css": "foo.css: FOO is foo\n",
+ "bin/child2/qux.ini": "qux.ini: BAR is not defined\n",
+ "bin/chrome.manifest": "manifest chrome/foo.manifest\n"
+ "manifest components/components.manifest\n",
+ "bin/chrome/foo.manifest": "content bar foo/child/\n"
+ "content foo foo/\n"
+ "override chrome://foo/bar.svg#hello "
+ "chrome://bar/bar.svg#hello\n",
+ "bin/chrome/foo/bar.js": "bar.js\n",
+ "bin/chrome/foo/child/baz.jsm": '//@line 2 "%s/baz.jsm"\nbaz.jsm: FOO is foo\n'
+ % (test_path),
+ "bin/chrome/foo/child/hoge.js": '//@line 2 "%s/bar.js"\nbar.js: FOO is foo\n'
+ % (test_path),
+ "bin/chrome/foo/foo.css": "foo.css: FOO is foo\n",
+ "bin/chrome/foo/foo.js": "foo.js\n",
+ "bin/chrome/foo/qux.js": "bar.js\n",
+ "bin/components/bar.js": '//@line 2 "%s/bar.js"\nbar.js: FOO is foo\n'
+ % (test_path),
+ "bin/components/components.manifest": "component {foo} foo.js\ncomponent {bar} bar.js\n", # NOQA: E501
+ "bin/components/foo.js": "foo.js\n",
+ "bin/defaults/pref/prefs.js": "prefs.js\n",
+ "bin/foo.ini": "foo.ini\n",
+ "bin/modules/baz.jsm": '//@line 2 "%s/baz.jsm"\nbaz.jsm: FOO is foo\n'
+ % (test_path),
+ "bin/modules/child/bar.jsm": "bar.jsm\n",
+ "bin/modules/child2/qux.jsm": '//@line 4 "%s/qux.jsm"\nqux.jsm: BAR is not defined\n' # NOQA: E501
+ % (test_path),
+ "bin/modules/foo.jsm": "foo.jsm\n",
+ "bin/res/resource": "resource\n",
+ "bin/res/child/resource2": "resource2\n",
+ "bin/app/baz.ini": "baz.ini: FOO is bar\n",
+ "bin/app/child/bar.ini": "bar.ini\n",
+ "bin/app/child2/qux.ini": "qux.ini: BAR is defined\n",
+ "bin/app/chrome.manifest": "manifest chrome/foo.manifest\n"
+ "manifest components/components.manifest\n",
+ "bin/app/chrome/foo.manifest": "content bar foo/child/\n"
+ "content foo foo/\n"
+ "override chrome://foo/bar.svg#hello "
+ "chrome://bar/bar.svg#hello\n",
+ "bin/app/chrome/foo/bar.js": "bar.js\n",
+ "bin/app/chrome/foo/child/baz.jsm": '//@line 2 "%s/baz.jsm"\nbaz.jsm: FOO is bar\n'
+ % (test_path),
+ "bin/app/chrome/foo/child/hoge.js": '//@line 2 "%s/bar.js"\nbar.js: FOO is bar\n'
+ % (test_path),
+ "bin/app/chrome/foo/foo.css": "foo.css: FOO is bar\n",
+ "bin/app/chrome/foo/foo.js": "foo.js\n",
+ "bin/app/chrome/foo/qux.js": "bar.js\n",
+ "bin/app/components/bar.js": '//@line 2 "%s/bar.js"\nbar.js: FOO is bar\n'
+ % (test_path),
+ "bin/app/components/components.manifest": "component {foo} foo.js\ncomponent {bar} bar.js\n", # NOQA: E501
+ "bin/app/components/foo.js": "foo.js\n",
+ "bin/app/defaults/preferences/prefs.js": "prefs.js\n",
+ "bin/app/foo.css": "foo.css: FOO is bar\n",
+ "bin/app/foo.ini": "foo.ini\n",
+ "bin/app/modules/baz.jsm": '//@line 2 "%s/baz.jsm"\nbaz.jsm: FOO is bar\n'
+ % (test_path),
+ "bin/app/modules/child/bar.jsm": "bar.jsm\n",
+ "bin/app/modules/child2/qux.jsm": '//@line 2 "%s/qux.jsm"\nqux.jsm: BAR is defined\n' # NOQA: E501
+ % (test_path),
+ "bin/app/modules/foo.jsm": "foo.jsm\n",
+ },
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_configenvironment.py b/python/mozbuild/mozbuild/test/backend/test_configenvironment.py
new file mode 100644
index 0000000000..7900cdd737
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_configenvironment.py
@@ -0,0 +1,73 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import unittest
+
+import mozpack.path as mozpath
+from mozunit import main
+
+import mozbuild.backend.configenvironment as ConfigStatus
+from mozbuild.util import ReadOnlyDict
+
+
+class ConfigEnvironment(ConfigStatus.ConfigEnvironment):
+ def __init__(self, *args, **kwargs):
+ ConfigStatus.ConfigEnvironment.__init__(self, *args, **kwargs)
+ # Be helpful to unit tests
+ if "top_srcdir" not in self.substs:
+ if os.path.isabs(self.topsrcdir):
+ top_srcdir = self.topsrcdir.replace(os.sep, "/")
+ else:
+ top_srcdir = mozpath.relpath(self.topsrcdir, self.topobjdir).replace(
+ os.sep, "/"
+ )
+
+ d = dict(self.substs)
+ d["top_srcdir"] = top_srcdir
+ self.substs = ReadOnlyDict(d)
+
+
+class TestEnvironment(unittest.TestCase):
+ def test_auto_substs(self):
+ """Test the automatically set values of ACDEFINES, ALLSUBSTS
+ and ALLEMPTYSUBSTS.
+ """
+ env = ConfigEnvironment(
+ ".",
+ ".",
+ defines={"foo": "bar", "baz": "qux 42", "abc": "d'e'f"},
+ substs={
+ "FOO": "bar",
+ "FOOBAR": "",
+ "ABC": "def",
+ "bar": "baz qux",
+ "zzz": '"abc def"',
+ "qux": "",
+ },
+ )
+ # Original order of the defines need to be respected in ACDEFINES
+ self.assertEqual(
+ env.substs["ACDEFINES"],
+ """-Dabc='d'\\''e'\\''f' -Dbaz='qux 42' -Dfoo=bar""",
+ )
+ # Likewise for ALLSUBSTS, which also must contain ACDEFINES
+ self.assertEqual(
+ env.substs["ALLSUBSTS"],
+ '''ABC = def
+ACDEFINES = -Dabc='d'\\''e'\\''f' -Dbaz='qux 42' -Dfoo=bar
+FOO = bar
+bar = baz qux
+zzz = "abc def"''',
+ )
+ # ALLEMPTYSUBSTS contains all substs with no value.
+ self.assertEqual(
+ env.substs["ALLEMPTYSUBSTS"],
+ """FOOBAR =
+qux =""",
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_database.py b/python/mozbuild/mozbuild/test/backend/test_database.py
new file mode 100644
index 0000000000..3bc0dfefb1
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_database.py
@@ -0,0 +1,91 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import json
+import os
+
+import six
+from mozunit import main
+
+from mozbuild.backend.clangd import ClangdBackend
+from mozbuild.backend.static_analysis import StaticAnalysisBackend
+from mozbuild.compilation.database import CompileDBBackend
+from mozbuild.test.backend.common import BackendTester
+
+
+class TestCompileDBBackends(BackendTester):
+ def perform_check(self, compile_commands_path, topsrcdir, topobjdir):
+ self.assertTrue(os.path.exists(compile_commands_path))
+ compile_db = json.loads(open(compile_commands_path, "r").read())
+
+ # Verify that we have the same number of items
+ self.assertEqual(len(compile_db), 4)
+
+ expected_db = [
+ {
+ "directory": topobjdir,
+ "command": "clang -o /dev/null -c -ferror-limit=0 {}/bar.c".format(
+ topsrcdir
+ ),
+ "file": "{}/bar.c".format(topsrcdir),
+ },
+ {
+ "directory": topobjdir,
+ "command": "clang -o /dev/null -c -ferror-limit=0 {}/foo.c".format(
+ topsrcdir
+ ),
+ "file": "{}/foo.c".format(topsrcdir),
+ },
+ {
+ "directory": topobjdir,
+ "command": "clang++ -o /dev/null -c -ferror-limit=0 {}/baz.cpp".format(
+ topsrcdir
+ ),
+ "file": "{}/baz.cpp".format(topsrcdir),
+ },
+ {
+ "directory": topobjdir,
+ "command": "clang++ -o /dev/null -c -ferror-limit=0 {}/qux.cpp".format(
+ topsrcdir
+ ),
+ "file": "{}/qux.cpp".format(topsrcdir),
+ },
+ ]
+
+ # Verify item consistency against `expected_db`
+ six.assertCountEqual(self, compile_db, expected_db)
+
+ def test_database(self):
+ """Ensure we can generate a `compile_commands.json` and that is correct."""
+
+ env = self._consume("database", CompileDBBackend)
+ compile_commands_path = os.path.join(env.topobjdir, "compile_commands.json")
+
+ self.perform_check(compile_commands_path, env.topsrcdir, env.topobjdir)
+
+ def test_clangd(self):
+ """Ensure we can generate a `compile_commands.json` and that is correct.
+ in order to be used by ClandBackend"""
+
+ env = self._consume("database", ClangdBackend)
+ compile_commands_path = os.path.join(
+ env.topobjdir, "clangd", "compile_commands.json"
+ )
+
+ self.perform_check(compile_commands_path, env.topsrcdir, env.topobjdir)
+
+ def test_static_analysis(self):
+ """Ensure we can generate a `compile_commands.json` and that is correct.
+ in order to be used by StaticAnalysisBackend"""
+
+ env = self._consume("database", StaticAnalysisBackend)
+ compile_commands_path = os.path.join(
+ env.topobjdir, "static-analysis", "compile_commands.json"
+ )
+
+ self.perform_check(compile_commands_path, env.topsrcdir, env.topobjdir)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_fastermake.py b/python/mozbuild/mozbuild/test/backend/test_fastermake.py
new file mode 100644
index 0000000000..1c9670b091
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_fastermake.py
@@ -0,0 +1,42 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+
+import mozpack.path as mozpath
+from mozpack.copier import FileRegistry
+from mozpack.manifests import InstallManifest
+from mozunit import main
+
+from mozbuild.backend.fastermake import FasterMakeBackend
+from mozbuild.test.backend.common import BackendTester
+
+
+class TestFasterMakeBackend(BackendTester):
+ def test_basic(self):
+ """Ensure the FasterMakeBackend works without error."""
+ env = self._consume("stub0", FasterMakeBackend)
+ self.assertTrue(
+ os.path.exists(mozpath.join(env.topobjdir, "backend.FasterMakeBackend"))
+ )
+ self.assertTrue(
+ os.path.exists(mozpath.join(env.topobjdir, "backend.FasterMakeBackend.in"))
+ )
+
+ def test_final_target_files_wildcard(self):
+ """Ensure that wildcards in FINAL_TARGET_FILES work properly."""
+ env = self._consume("final-target-files-wildcard", FasterMakeBackend)
+ m = InstallManifest(
+ path=mozpath.join(env.topobjdir, "faster", "install_dist_bin")
+ )
+ self.assertEqual(len(m), 1)
+ reg = FileRegistry()
+ m.populate_registry(reg)
+ expected = [("foo/bar.xyz", "bar.xyz"), ("foo/foo.xyz", "foo.xyz")]
+ actual = [(path, mozpath.relpath(f.path, env.topsrcdir)) for (path, f) in reg]
+ self.assertEqual(expected, actual)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_partialconfigenvironment.py b/python/mozbuild/mozbuild/test/backend/test_partialconfigenvironment.py
new file mode 100644
index 0000000000..13b1656981
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_partialconfigenvironment.py
@@ -0,0 +1,173 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import unittest
+from shutil import rmtree
+from tempfile import mkdtemp
+
+import buildconfig
+import mozpack.path as mozpath
+from mozunit import main
+
+from mozbuild.backend.configenvironment import PartialConfigEnvironment
+
+config = {
+ "defines": {
+ "MOZ_FOO": "1",
+ "MOZ_BAR": "2",
+ },
+ "substs": {
+ "MOZ_SUBST_1": "1",
+ "MOZ_SUBST_2": "2",
+ "CPP": "cpp",
+ },
+}
+
+
+class TestPartial(unittest.TestCase):
+ def setUp(self):
+ self._old_env = dict(os.environ)
+
+ def tearDown(self):
+ os.environ.clear()
+ os.environ.update(self._old_env)
+
+ def _objdir(self):
+ objdir = mkdtemp(dir=buildconfig.topsrcdir)
+ self.addCleanup(rmtree, objdir)
+ return objdir
+
+ def test_auto_substs(self):
+ """Test the automatically set values of ACDEFINES, and ALLDEFINES"""
+ env = PartialConfigEnvironment(self._objdir())
+ env.write_vars(config)
+ self.assertEqual(env.substs["ACDEFINES"], "-DMOZ_BAR=2 -DMOZ_FOO=1")
+ self.assertEqual(
+ env.defines["ALLDEFINES"],
+ {
+ "MOZ_BAR": "2",
+ "MOZ_FOO": "1",
+ },
+ )
+
+ def test_remove_subst(self):
+ """Test removing a subst from the config. The file should be overwritten with 'None'"""
+ env = PartialConfigEnvironment(self._objdir())
+ path = mozpath.join(env.topobjdir, "config.statusd", "substs", "MYSUBST")
+ myconfig = config.copy()
+ env.write_vars(myconfig)
+ with self.assertRaises(KeyError):
+ _ = env.substs["MYSUBST"]
+ self.assertFalse(os.path.exists(path))
+
+ myconfig["substs"]["MYSUBST"] = "new"
+ env.write_vars(myconfig)
+
+ self.assertEqual(env.substs["MYSUBST"], "new")
+ self.assertTrue(os.path.exists(path))
+
+ del myconfig["substs"]["MYSUBST"]
+ env.write_vars(myconfig)
+ with self.assertRaises(KeyError):
+ _ = env.substs["MYSUBST"]
+ # Now that the subst is gone, the file still needs to be present so that
+ # make can update dependencies correctly. Overwriting the file with
+ # 'None' is the same as deleting it as far as the
+ # PartialConfigEnvironment is concerned, but make can't track a
+ # dependency on a file that doesn't exist.
+ self.assertTrue(os.path.exists(path))
+
+ def _assert_deps(self, env, deps):
+ deps = sorted(
+ [
+ "$(wildcard %s)" % (mozpath.join(env.topobjdir, "config.statusd", d))
+ for d in deps
+ ]
+ )
+ self.assertEqual(sorted(env.get_dependencies()), deps)
+
+ def test_dependencies(self):
+ """Test getting dependencies on defines and substs."""
+ env = PartialConfigEnvironment(self._objdir())
+ env.write_vars(config)
+ self._assert_deps(env, [])
+
+ self.assertEqual(env.defines["MOZ_FOO"], "1")
+ self._assert_deps(env, ["defines/MOZ_FOO"])
+
+ self.assertEqual(env.defines["MOZ_BAR"], "2")
+ self._assert_deps(env, ["defines/MOZ_FOO", "defines/MOZ_BAR"])
+
+ # Getting a define again shouldn't add a redundant dependency
+ self.assertEqual(env.defines["MOZ_FOO"], "1")
+ self._assert_deps(env, ["defines/MOZ_FOO", "defines/MOZ_BAR"])
+
+ self.assertEqual(env.substs["MOZ_SUBST_1"], "1")
+ self._assert_deps(
+ env, ["defines/MOZ_FOO", "defines/MOZ_BAR", "substs/MOZ_SUBST_1"]
+ )
+
+ with self.assertRaises(KeyError):
+ _ = env.substs["NON_EXISTENT"]
+ self._assert_deps(
+ env,
+ [
+ "defines/MOZ_FOO",
+ "defines/MOZ_BAR",
+ "substs/MOZ_SUBST_1",
+ "substs/NON_EXISTENT",
+ ],
+ )
+ self.assertEqual(env.substs.get("NON_EXISTENT"), None)
+
+ def test_set_subst(self):
+ """Test setting a subst"""
+ env = PartialConfigEnvironment(self._objdir())
+ env.write_vars(config)
+
+ self.assertEqual(env.substs["MOZ_SUBST_1"], "1")
+ env.substs["MOZ_SUBST_1"] = "updated"
+ self.assertEqual(env.substs["MOZ_SUBST_1"], "updated")
+
+ # A new environment should pull the result from the file again.
+ newenv = PartialConfigEnvironment(env.topobjdir)
+ self.assertEqual(newenv.substs["MOZ_SUBST_1"], "1")
+
+ def test_env_override(self):
+ """Test overriding a subst with an environment variable"""
+ env = PartialConfigEnvironment(self._objdir())
+ env.write_vars(config)
+
+ self.assertEqual(env.substs["MOZ_SUBST_1"], "1")
+ self.assertEqual(env.substs["CPP"], "cpp")
+
+ # Reset the environment and set some environment variables.
+ env = PartialConfigEnvironment(env.topobjdir)
+ os.environ["MOZ_SUBST_1"] = "subst 1 environ"
+ os.environ["CPP"] = "cpp environ"
+
+ # The MOZ_SUBST_1 should be overridden by the environment, while CPP is
+ # a special variable and should not.
+ self.assertEqual(env.substs["MOZ_SUBST_1"], "subst 1 environ")
+ self.assertEqual(env.substs["CPP"], "cpp")
+
+ def test_update(self):
+ """Test calling update on the substs or defines pseudo dicts"""
+ env = PartialConfigEnvironment(self._objdir())
+ env.write_vars(config)
+
+ mysubsts = {"NEW": "new"}
+ mysubsts.update(env.substs.iteritems())
+ self.assertEqual(mysubsts["NEW"], "new")
+ self.assertEqual(mysubsts["CPP"], "cpp")
+
+ mydefines = {"DEBUG": "1"}
+ mydefines.update(env.defines.iteritems())
+ self.assertEqual(mydefines["DEBUG"], "1")
+ self.assertEqual(mydefines["MOZ_FOO"], "1")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
new file mode 100644
index 0000000000..acbada060b
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -0,0 +1,1307 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import io
+import os
+import unittest
+
+import mozpack.path as mozpath
+import six
+import six.moves.cPickle as pickle
+from mozpack.manifests import InstallManifest
+from mozunit import main
+
+from mozbuild.backend.recursivemake import RecursiveMakeBackend, RecursiveMakeTraversal
+from mozbuild.backend.test_manifest import TestManifestBackend
+from mozbuild.frontend.emitter import TreeMetadataEmitter
+from mozbuild.frontend.reader import BuildReader
+from mozbuild.test.backend.common import BackendTester
+
+
+class TestRecursiveMakeTraversal(unittest.TestCase):
+ def test_traversal(self):
+ traversal = RecursiveMakeTraversal()
+ traversal.add("", dirs=["A", "B", "C"])
+ traversal.add("", dirs=["D"])
+ traversal.add("A")
+ traversal.add("B", dirs=["E", "F"])
+ traversal.add("C", dirs=["G", "H"])
+ traversal.add("D", dirs=["I", "K"])
+ traversal.add("D", dirs=["J", "L"])
+ traversal.add("E")
+ traversal.add("F")
+ traversal.add("G")
+ traversal.add("H")
+ traversal.add("I", dirs=["M", "N"])
+ traversal.add("J", dirs=["O", "P"])
+ traversal.add("K", dirs=["Q", "R"])
+ traversal.add("L", dirs=["S"])
+ traversal.add("M")
+ traversal.add("N", dirs=["T"])
+ traversal.add("O")
+ traversal.add("P", dirs=["U"])
+ traversal.add("Q")
+ traversal.add("R", dirs=["V"])
+ traversal.add("S", dirs=["W"])
+ traversal.add("T")
+ traversal.add("U")
+ traversal.add("V")
+ traversal.add("W", dirs=["X"])
+ traversal.add("X")
+
+ parallels = set(("G", "H", "I", "J", "O", "P", "Q", "R", "U"))
+
+ def filter(current, subdirs):
+ return (
+ current,
+ [d for d in subdirs.dirs if d in parallels],
+ [d for d in subdirs.dirs if d not in parallels],
+ )
+
+ start, deps = traversal.compute_dependencies(filter)
+ self.assertEqual(start, ("X",))
+ self.maxDiff = None
+ self.assertEqual(
+ deps,
+ {
+ "A": ("",),
+ "B": ("A",),
+ "C": ("F",),
+ "D": ("G", "H"),
+ "E": ("B",),
+ "F": ("E",),
+ "G": ("C",),
+ "H": ("C",),
+ "I": ("D",),
+ "J": ("D",),
+ "K": ("T", "O", "U"),
+ "L": ("Q", "V"),
+ "M": ("I",),
+ "N": ("M",),
+ "O": ("J",),
+ "P": ("J",),
+ "Q": ("K",),
+ "R": ("K",),
+ "S": ("L",),
+ "T": ("N",),
+ "U": ("P",),
+ "V": ("R",),
+ "W": ("S",),
+ "X": ("W",),
+ },
+ )
+
+ self.assertEqual(
+ list(traversal.traverse("", filter)),
+ [
+ "",
+ "A",
+ "B",
+ "E",
+ "F",
+ "C",
+ "G",
+ "H",
+ "D",
+ "I",
+ "M",
+ "N",
+ "T",
+ "J",
+ "O",
+ "P",
+ "U",
+ "K",
+ "Q",
+ "R",
+ "V",
+ "L",
+ "S",
+ "W",
+ "X",
+ ],
+ )
+
+ self.assertEqual(list(traversal.traverse("C", filter)), ["C", "G", "H"])
+
+ def test_traversal_2(self):
+ traversal = RecursiveMakeTraversal()
+ traversal.add("", dirs=["A", "B", "C"])
+ traversal.add("A")
+ traversal.add("B", dirs=["D", "E", "F"])
+ traversal.add("C", dirs=["G", "H", "I"])
+ traversal.add("D")
+ traversal.add("E")
+ traversal.add("F")
+ traversal.add("G")
+ traversal.add("H")
+ traversal.add("I")
+
+ start, deps = traversal.compute_dependencies()
+ self.assertEqual(start, ("I",))
+ self.assertEqual(
+ deps,
+ {
+ "A": ("",),
+ "B": ("A",),
+ "C": ("F",),
+ "D": ("B",),
+ "E": ("D",),
+ "F": ("E",),
+ "G": ("C",),
+ "H": ("G",),
+ "I": ("H",),
+ },
+ )
+
+ def test_traversal_filter(self):
+ traversal = RecursiveMakeTraversal()
+ traversal.add("", dirs=["A", "B", "C"])
+ traversal.add("A")
+ traversal.add("B", dirs=["D", "E", "F"])
+ traversal.add("C", dirs=["G", "H", "I"])
+ traversal.add("D")
+ traversal.add("E")
+ traversal.add("F")
+ traversal.add("G")
+ traversal.add("H")
+ traversal.add("I")
+
+ def filter(current, subdirs):
+ if current == "B":
+ current = None
+ return current, [], subdirs.dirs
+
+ start, deps = traversal.compute_dependencies(filter)
+ self.assertEqual(start, ("I",))
+ self.assertEqual(
+ deps,
+ {
+ "A": ("",),
+ "C": ("F",),
+ "D": ("A",),
+ "E": ("D",),
+ "F": ("E",),
+ "G": ("C",),
+ "H": ("G",),
+ "I": ("H",),
+ },
+ )
+
+ def test_traversal_parallel(self):
+ traversal = RecursiveMakeTraversal()
+ traversal.add("", dirs=["A", "B", "C"])
+ traversal.add("A")
+ traversal.add("B", dirs=["D", "E", "F"])
+ traversal.add("C", dirs=["G", "H", "I"])
+ traversal.add("D")
+ traversal.add("E")
+ traversal.add("F")
+ traversal.add("G")
+ traversal.add("H")
+ traversal.add("I")
+ traversal.add("J")
+
+ def filter(current, subdirs):
+ return current, subdirs.dirs, []
+
+ start, deps = traversal.compute_dependencies(filter)
+ self.assertEqual(start, ("A", "D", "E", "F", "G", "H", "I", "J"))
+ self.assertEqual(
+ deps,
+ {
+ "A": ("",),
+ "B": ("",),
+ "C": ("",),
+ "D": ("B",),
+ "E": ("B",),
+ "F": ("B",),
+ "G": ("C",),
+ "H": ("C",),
+ "I": ("C",),
+ "J": ("",),
+ },
+ )
+
+
+class TestRecursiveMakeBackend(BackendTester):
+ def test_basic(self):
+ """Ensure the RecursiveMakeBackend works without error."""
+ env = self._consume("stub0", RecursiveMakeBackend)
+ self.assertTrue(
+ os.path.exists(mozpath.join(env.topobjdir, "backend.RecursiveMakeBackend"))
+ )
+ self.assertTrue(
+ os.path.exists(
+ mozpath.join(env.topobjdir, "backend.RecursiveMakeBackend.in")
+ )
+ )
+
+ def test_output_files(self):
+ """Ensure proper files are generated."""
+ env = self._consume("stub0", RecursiveMakeBackend)
+
+ expected = ["", "dir1", "dir2"]
+
+ for d in expected:
+ out_makefile = mozpath.join(env.topobjdir, d, "Makefile")
+ out_backend = mozpath.join(env.topobjdir, d, "backend.mk")
+
+ self.assertTrue(os.path.exists(out_makefile))
+ self.assertTrue(os.path.exists(out_backend))
+
+ def test_makefile_conversion(self):
+ """Ensure Makefile.in is converted properly."""
+ env = self._consume("stub0", RecursiveMakeBackend)
+
+ p = mozpath.join(env.topobjdir, "Makefile")
+
+ lines = [
+ l.strip() for l in open(p, "rt").readlines()[1:] if not l.startswith("#")
+ ]
+ self.assertEqual(
+ lines,
+ [
+ "DEPTH := .",
+ "topobjdir := %s" % env.topobjdir,
+ "topsrcdir := %s" % env.topsrcdir,
+ "srcdir := %s" % env.topsrcdir,
+ "srcdir_rel := %s" % mozpath.relpath(env.topsrcdir, env.topobjdir),
+ "relativesrcdir := .",
+ "include $(DEPTH)/config/autoconf.mk",
+ "",
+ "FOO := foo",
+ "",
+ "include $(topsrcdir)/config/recurse.mk",
+ ],
+ )
+
+ def test_missing_makefile_in(self):
+ """Ensure missing Makefile.in results in Makefile creation."""
+ env = self._consume("stub0", RecursiveMakeBackend)
+
+ p = mozpath.join(env.topobjdir, "dir2", "Makefile")
+ self.assertTrue(os.path.exists(p))
+
+ lines = [l.strip() for l in open(p, "rt").readlines()]
+ self.assertEqual(len(lines), 10)
+
+ self.assertTrue(lines[0].startswith("# THIS FILE WAS AUTOMATICALLY"))
+
+ def test_backend_mk(self):
+ """Ensure backend.mk file is written out properly."""
+ env = self._consume("stub0", RecursiveMakeBackend)
+
+ p = mozpath.join(env.topobjdir, "backend.mk")
+
+ lines = [l.strip() for l in open(p, "rt").readlines()[2:]]
+ self.assertEqual(lines, ["DIRS := dir1 dir2"])
+
+ # Make env.substs writable to add ENABLE_TESTS
+ env.substs = dict(env.substs)
+ env.substs["ENABLE_TESTS"] = "1"
+ self._consume("stub0", RecursiveMakeBackend, env=env)
+ p = mozpath.join(env.topobjdir, "backend.mk")
+
+ lines = [l.strip() for l in open(p, "rt").readlines()[2:]]
+ self.assertEqual(lines, ["DIRS := dir1 dir2 dir3"])
+
+ def test_mtime_no_change(self):
+ """Ensure mtime is not updated if file content does not change."""
+
+ env = self._consume("stub0", RecursiveMakeBackend)
+
+ makefile_path = mozpath.join(env.topobjdir, "Makefile")
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ makefile_mtime = os.path.getmtime(makefile_path)
+ backend_mtime = os.path.getmtime(backend_path)
+
+ reader = BuildReader(env)
+ emitter = TreeMetadataEmitter(env)
+ backend = RecursiveMakeBackend(env)
+ backend.consume(emitter.emit(reader.read_topsrcdir()))
+
+ self.assertEqual(os.path.getmtime(makefile_path), makefile_mtime)
+ self.assertEqual(os.path.getmtime(backend_path), backend_mtime)
+
+ def test_substitute_config_files(self):
+ """Ensure substituted config files are produced."""
+ env = self._consume("substitute_config_files", RecursiveMakeBackend)
+
+ p = mozpath.join(env.topobjdir, "foo")
+ self.assertTrue(os.path.exists(p))
+ lines = [l.strip() for l in open(p, "rt").readlines()]
+ self.assertEqual(lines, ["TEST = foo"])
+
+ def test_install_substitute_config_files(self):
+ """Ensure we recurse into the dirs that install substituted config files."""
+ env = self._consume("install_substitute_config_files", RecursiveMakeBackend)
+
+ root_deps_path = mozpath.join(env.topobjdir, "root-deps.mk")
+ lines = [l.strip() for l in open(root_deps_path, "rt").readlines()]
+
+ # Make sure we actually recurse into the sub directory during export to
+ # install the subst file.
+ self.assertTrue(any(l == "recurse_export: sub/export" for l in lines))
+
+ def test_variable_passthru(self):
+ """Ensure variable passthru is written out correctly."""
+ env = self._consume("variable_passthru", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = {
+ "RCFILE": ["RCFILE := $(srcdir)/foo.rc"],
+ "RCINCLUDE": ["RCINCLUDE := $(srcdir)/bar.rc"],
+ "WIN32_EXE_LDFLAGS": ["WIN32_EXE_LDFLAGS += -subsystem:console"],
+ }
+
+ for var, val in expected.items():
+ # print("test_variable_passthru[%s]" % (var))
+ found = [str for str in lines if str.startswith(var)]
+ self.assertEqual(found, val)
+
+ def test_sources(self):
+ """Ensure SOURCES, HOST_SOURCES and WASM_SOURCES are handled properly."""
+ env = self._consume("sources", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = {
+ "ASFILES": ["ASFILES += $(srcdir)/bar.s", "ASFILES += $(srcdir)/foo.asm"],
+ "CMMSRCS": ["CMMSRCS += $(srcdir)/fuga.mm", "CMMSRCS += $(srcdir)/hoge.mm"],
+ "CSRCS": ["CSRCS += $(srcdir)/baz.c", "CSRCS += $(srcdir)/qux.c"],
+ "HOST_CPPSRCS": [
+ "HOST_CPPSRCS += $(srcdir)/bar.cpp",
+ "HOST_CPPSRCS += $(srcdir)/foo.cpp",
+ ],
+ "HOST_CSRCS": [
+ "HOST_CSRCS += $(srcdir)/baz.c",
+ "HOST_CSRCS += $(srcdir)/qux.c",
+ ],
+ "SSRCS": ["SSRCS += $(srcdir)/titi.S", "SSRCS += $(srcdir)/toto.S"],
+ "WASM_CSRCS": ["WASM_CSRCS += $(srcdir)/baz.c"],
+ "WASM_CPPSRCS": ["WASM_CPPSRCS += $(srcdir)/bar.cpp"],
+ }
+
+ for var, val in expected.items():
+ found = [str for str in lines if str.startswith(var)]
+ self.assertEqual(found, val)
+
+ def test_exports(self):
+ """Ensure EXPORTS is handled properly."""
+ env = self._consume("exports", RecursiveMakeBackend)
+
+ # EXPORTS files should appear in the dist_include install manifest.
+ m = InstallManifest(
+ path=mozpath.join(
+ env.topobjdir, "_build_manifests", "install", "dist_include"
+ )
+ )
+ self.assertEqual(len(m), 7)
+ self.assertIn("foo.h", m)
+ self.assertIn("mozilla/mozilla1.h", m)
+ self.assertIn("mozilla/dom/dom2.h", m)
+
+ def test_generated_files(self):
+ """Ensure GENERATED_FILES is handled properly."""
+ env = self._consume("generated-files", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "include $(topsrcdir)/config/AB_rCD.mk",
+ "PRE_COMPILE_TARGETS += $(MDDEPDIR)/bar.c.stub",
+ "bar.c: $(MDDEPDIR)/bar.c.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/bar.c.pp",
+ "$(MDDEPDIR)/bar.c.stub: %s/generate-bar.py" % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,%s/generate-bar.py baz bar.c $(MDDEPDIR)/bar.c.pp $(MDDEPDIR)/bar.c.stub)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ "EXPORT_TARGETS += $(MDDEPDIR)/foo.h.stub",
+ "foo.h: $(MDDEPDIR)/foo.h.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/foo.h.pp",
+ "$(MDDEPDIR)/foo.h.stub: %s/generate-foo.py $(srcdir)/foo-data"
+ % (env.topsrcdir),
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,%s/generate-foo.py main foo.h $(MDDEPDIR)/foo.h.pp $(MDDEPDIR)/foo.h.stub $(srcdir)/foo-data)" # noqa
+ % (env.topsrcdir),
+ "@$(TOUCH) $@",
+ "",
+ ]
+
+ self.maxDiff = None
+ self.assertEqual(lines, expected)
+
+ def test_generated_files_force(self):
+ """Ensure GENERATED_FILES with .force is handled properly."""
+ env = self._consume("generated-files-force", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "include $(topsrcdir)/config/AB_rCD.mk",
+ "PRE_COMPILE_TARGETS += $(MDDEPDIR)/bar.c.stub",
+ "bar.c: $(MDDEPDIR)/bar.c.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/bar.c.pp",
+ "$(MDDEPDIR)/bar.c.stub: %s/generate-bar.py FORCE" % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,%s/generate-bar.py baz bar.c $(MDDEPDIR)/bar.c.pp $(MDDEPDIR)/bar.c.stub)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ "PRE_COMPILE_TARGETS += $(MDDEPDIR)/foo.c.stub",
+ "foo.c: $(MDDEPDIR)/foo.c.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/foo.c.pp",
+ "$(MDDEPDIR)/foo.c.stub: %s/generate-foo.py $(srcdir)/foo-data"
+ % (env.topsrcdir),
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,%s/generate-foo.py main foo.c $(MDDEPDIR)/foo.c.pp $(MDDEPDIR)/foo.c.stub $(srcdir)/foo-data)" # noqa
+ % (env.topsrcdir),
+ "@$(TOUCH) $@",
+ "",
+ ]
+
+ self.maxDiff = None
+ self.assertEqual(lines, expected)
+
+ def test_localized_generated_files(self):
+ """Ensure LOCALIZED_GENERATED_FILES is handled properly."""
+ env = self._consume("localized-generated-files", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "include $(topsrcdir)/config/AB_rCD.mk",
+ "MISC_TARGETS += $(MDDEPDIR)/foo.xyz.stub",
+ "foo.xyz: $(MDDEPDIR)/foo.xyz.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/foo.xyz.pp",
+ "$(MDDEPDIR)/foo.xyz.stub: %s/generate-foo.py $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)" # noqa
+ % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main foo.xyz $(MDDEPDIR)/foo.xyz.pp $(MDDEPDIR)/foo.xyz.stub $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ "LOCALIZED_FILES_0_FILES += foo.xyz",
+ "LOCALIZED_FILES_0_DEST = $(FINAL_TARGET)/",
+ "LOCALIZED_FILES_0_TARGET := misc",
+ "INSTALL_TARGETS += LOCALIZED_FILES_0",
+ ]
+
+ self.maxDiff = None
+ self.assertEqual(lines, expected)
+
+ def test_localized_generated_files_force(self):
+ """Ensure LOCALIZED_GENERATED_FILES with .force is handled properly."""
+ env = self._consume("localized-generated-files-force", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "include $(topsrcdir)/config/AB_rCD.mk",
+ "MISC_TARGETS += $(MDDEPDIR)/foo.xyz.stub",
+ "foo.xyz: $(MDDEPDIR)/foo.xyz.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/foo.xyz.pp",
+ "$(MDDEPDIR)/foo.xyz.stub: %s/generate-foo.py $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)" # noqa
+ % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main foo.xyz $(MDDEPDIR)/foo.xyz.pp $(MDDEPDIR)/foo.xyz.stub $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ "MISC_TARGETS += $(MDDEPDIR)/abc.xyz.stub",
+ "abc.xyz: $(MDDEPDIR)/abc.xyz.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/abc.xyz.pp",
+ "$(MDDEPDIR)/abc.xyz.stub: %s/generate-foo.py $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input FORCE" # noqa
+ % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main abc.xyz $(MDDEPDIR)/abc.xyz.pp $(MDDEPDIR)/abc.xyz.stub $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ ]
+
+ self.maxDiff = None
+ self.assertEqual(lines, expected)
+
+ def test_localized_generated_files_AB_CD(self):
+ """Ensure LOCALIZED_GENERATED_FILES is handled properly
+ when {AB_CD} and {AB_rCD} are used."""
+ env = self._consume("localized-generated-files-AB_CD", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "include $(topsrcdir)/config/AB_rCD.mk",
+ "MISC_TARGETS += $(MDDEPDIR)/foo$(AB_CD).xyz.stub",
+ "foo$(AB_CD).xyz: $(MDDEPDIR)/foo$(AB_CD).xyz.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/foo$(AB_CD).xyz.pp",
+ "$(MDDEPDIR)/foo$(AB_CD).xyz.stub: %s/generate-foo.py $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)" # noqa
+ % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main foo$(AB_CD).xyz $(MDDEPDIR)/foo$(AB_CD).xyz.pp $(MDDEPDIR)/foo$(AB_CD).xyz.stub $(call MERGE_FILE,localized-input) $(srcdir)/non-localized-input)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ "bar$(AB_rCD).xyz: $(MDDEPDIR)/bar$(AB_rCD).xyz.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/bar$(AB_rCD).xyz.pp",
+ "$(MDDEPDIR)/bar$(AB_rCD).xyz.stub: %s/generate-foo.py $(call MERGE_RELATIVE_FILE,localized-input,inner/locales) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)" # noqa
+ % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main bar$(AB_rCD).xyz $(MDDEPDIR)/bar$(AB_rCD).xyz.pp $(MDDEPDIR)/bar$(AB_rCD).xyz.stub $(call MERGE_RELATIVE_FILE,localized-input,inner/locales) $(srcdir)/non-localized-input)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ "zot$(AB_rCD).xyz: $(MDDEPDIR)/zot$(AB_rCD).xyz.stub ;",
+ "EXTRA_MDDEPEND_FILES += $(MDDEPDIR)/zot$(AB_rCD).xyz.pp",
+ "$(MDDEPDIR)/zot$(AB_rCD).xyz.stub: %s/generate-foo.py $(call MERGE_RELATIVE_FILE,localized-input,locales) $(srcdir)/non-localized-input $(if $(IS_LANGUAGE_REPACK),FORCE)" # noqa
+ % env.topsrcdir,
+ "$(REPORT_BUILD)",
+ "$(call py_action,file_generate,--locale=$(AB_CD) %s/generate-foo.py main zot$(AB_rCD).xyz $(MDDEPDIR)/zot$(AB_rCD).xyz.pp $(MDDEPDIR)/zot$(AB_rCD).xyz.stub $(call MERGE_RELATIVE_FILE,localized-input,locales) $(srcdir)/non-localized-input)" # noqa
+ % env.topsrcdir,
+ "@$(TOUCH) $@",
+ "",
+ ]
+
+ self.maxDiff = None
+ self.assertEqual(lines, expected)
+
+ def test_exports_generated(self):
+ """Ensure EXPORTS that are listed in GENERATED_FILES
+ are handled properly."""
+ env = self._consume("exports-generated", RecursiveMakeBackend)
+
+ # EXPORTS files should appear in the dist_include install manifest.
+ m = InstallManifest(
+ path=mozpath.join(
+ env.topobjdir, "_build_manifests", "install", "dist_include"
+ )
+ )
+ self.assertEqual(len(m), 8)
+ self.assertIn("foo.h", m)
+ self.assertIn("mozilla/mozilla1.h", m)
+ self.assertIn("mozilla/dom/dom1.h", m)
+ self.assertIn("gfx/gfx.h", m)
+ self.assertIn("bar.h", m)
+ self.assertIn("mozilla/mozilla2.h", m)
+ self.assertIn("mozilla/dom/dom2.h", m)
+ self.assertIn("mozilla/dom/dom3.h", m)
+ # EXPORTS files that are also GENERATED_FILES should be handled as
+ # INSTALL_TARGETS.
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+ expected = [
+ "include $(topsrcdir)/config/AB_rCD.mk",
+ "dist_include_FILES += bar.h",
+ "dist_include_DEST := $(DEPTH)/dist/include/",
+ "dist_include_TARGET := export",
+ "INSTALL_TARGETS += dist_include",
+ "dist_include_mozilla_FILES += mozilla2.h",
+ "dist_include_mozilla_DEST := $(DEPTH)/dist/include/mozilla",
+ "dist_include_mozilla_TARGET := export",
+ "INSTALL_TARGETS += dist_include_mozilla",
+ "dist_include_mozilla_dom_FILES += dom2.h",
+ "dist_include_mozilla_dom_FILES += dom3.h",
+ "dist_include_mozilla_dom_DEST := $(DEPTH)/dist/include/mozilla/dom",
+ "dist_include_mozilla_dom_TARGET := export",
+ "INSTALL_TARGETS += dist_include_mozilla_dom",
+ ]
+ self.maxDiff = None
+ self.assertEqual(lines, expected)
+
+ def test_resources(self):
+ """Ensure RESOURCE_FILES is handled properly."""
+ env = self._consume("resources", RecursiveMakeBackend)
+
+ # RESOURCE_FILES should appear in the dist_bin install manifest.
+ m = InstallManifest(
+ path=os.path.join(env.topobjdir, "_build_manifests", "install", "dist_bin")
+ )
+ self.assertEqual(len(m), 10)
+ self.assertIn("res/foo.res", m)
+ self.assertIn("res/fonts/font1.ttf", m)
+ self.assertIn("res/fonts/desktop/desktop2.ttf", m)
+
+ self.assertIn("res/bar.res.in", m)
+ self.assertIn("res/tests/test.manifest", m)
+ self.assertIn("res/tests/extra.manifest", m)
+
+ def test_test_manifests_files_written(self):
+ """Ensure test manifests get turned into files."""
+ env = self._consume("test-manifests-written", RecursiveMakeBackend)
+
+ tests_dir = mozpath.join(env.topobjdir, "_tests")
+ m_master = mozpath.join(
+ tests_dir, "testing", "mochitest", "tests", "mochitest.ini"
+ )
+ x_master = mozpath.join(tests_dir, "xpcshell", "xpcshell.ini")
+ self.assertTrue(os.path.exists(m_master))
+ self.assertTrue(os.path.exists(x_master))
+
+ lines = [l.strip() for l in open(x_master, "rt").readlines()]
+ self.assertEqual(
+ lines,
+ [
+ "# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND.",
+ "",
+ "[include:dir1/xpcshell.ini]",
+ "[include:xpcshell.ini]",
+ ],
+ )
+
+ def test_test_manifest_pattern_matches_recorded(self):
+ """Pattern matches in test manifests' support-files should be recorded."""
+ env = self._consume("test-manifests-written", RecursiveMakeBackend)
+ m = InstallManifest(
+ path=mozpath.join(
+ env.topobjdir, "_build_manifests", "install", "_test_files"
+ )
+ )
+
+ # This is not the most robust test in the world, but it gets the job
+ # done.
+ entries = [e for e in m._dests.keys() if "**" in e]
+ self.assertEqual(len(entries), 1)
+ self.assertIn("support/**", entries[0])
+
+ def test_test_manifest_deffered_installs_written(self):
+ """Shared support files are written to their own data file by the backend."""
+ env = self._consume("test-manifest-shared-support", RecursiveMakeBackend)
+
+ # First, read the generated for ini manifest contents.
+ test_files_manifest = mozpath.join(
+ env.topobjdir, "_build_manifests", "install", "_test_files"
+ )
+ m = InstallManifest(path=test_files_manifest)
+
+ # Then, synthesize one from the test-installs.pkl file. This should
+ # allow us to re-create a subset of the above.
+ env = self._consume("test-manifest-shared-support", TestManifestBackend)
+ test_installs_path = mozpath.join(env.topobjdir, "test-installs.pkl")
+
+ with open(test_installs_path, "rb") as fh:
+ test_installs = pickle.load(fh)
+
+ self.assertEqual(
+ set(test_installs.keys()),
+ set(["child/test_sub.js", "child/data/**", "child/another-file.sjs"]),
+ )
+ for key in test_installs.keys():
+ self.assertIn(key, test_installs)
+
+ synthesized_manifest = InstallManifest()
+ for item, installs in test_installs.items():
+ for install_info in installs:
+ if len(install_info) == 3:
+ synthesized_manifest.add_pattern_link(*install_info)
+ if len(install_info) == 2:
+ synthesized_manifest.add_link(*install_info)
+
+ self.assertEqual(len(synthesized_manifest), 3)
+ for item, info in synthesized_manifest._dests.items():
+ self.assertIn(item, m)
+ self.assertEqual(info, m._dests[item])
+
+ def test_xpidl_generation(self):
+ """Ensure xpidl files and directories are written out."""
+ env = self._consume("xpidl", RecursiveMakeBackend)
+
+ # Install manifests should contain entries.
+ install_dir = mozpath.join(env.topobjdir, "_build_manifests", "install")
+ self.assertTrue(os.path.isfile(mozpath.join(install_dir, "xpidl")))
+
+ m = InstallManifest(path=mozpath.join(install_dir, "xpidl"))
+ self.assertIn(".deps/my_module.pp", m)
+
+ m = InstallManifest(path=mozpath.join(install_dir, "xpidl"))
+ self.assertIn("my_module.xpt", m)
+
+ m = InstallManifest(path=mozpath.join(install_dir, "dist_include"))
+ self.assertIn("foo.h", m)
+
+ p = mozpath.join(env.topobjdir, "config/makefiles/xpidl")
+ self.assertTrue(os.path.isdir(p))
+
+ self.assertTrue(os.path.isfile(mozpath.join(p, "Makefile")))
+
+ def test_test_support_files_tracked(self):
+ env = self._consume("test-support-binaries-tracked", RecursiveMakeBackend)
+ m = InstallManifest(
+ path=mozpath.join(env.topobjdir, "_build_manifests", "install", "_tests")
+ )
+ self.assertEqual(len(m), 4)
+ self.assertIn("xpcshell/tests/mozbuildtest/test-library.dll", m)
+ self.assertIn("xpcshell/tests/mozbuildtest/test-one.exe", m)
+ self.assertIn("xpcshell/tests/mozbuildtest/test-two.exe", m)
+ self.assertIn("xpcshell/tests/mozbuildtest/host-test-library.dll", m)
+
+ def test_old_install_manifest_deleted(self):
+ # Simulate an install manifest from a previous backend version. Ensure
+ # it is deleted.
+ env = self._get_environment("stub0")
+ purge_dir = mozpath.join(env.topobjdir, "_build_manifests", "install")
+ manifest_path = mozpath.join(purge_dir, "old_manifest")
+ os.makedirs(purge_dir)
+ m = InstallManifest()
+ m.write(path=manifest_path)
+ with open(
+ mozpath.join(env.topobjdir, "backend.RecursiveMakeBackend"), "w"
+ ) as f:
+ f.write("%s\n" % manifest_path)
+
+ self.assertTrue(os.path.exists(manifest_path))
+ self._consume("stub0", RecursiveMakeBackend, env)
+ self.assertFalse(os.path.exists(manifest_path))
+
+ def test_install_manifests_written(self):
+ env, objs = self._emit("stub0")
+ backend = RecursiveMakeBackend(env)
+
+ m = InstallManifest()
+ backend._install_manifests["testing"] = m
+ m.add_link(__file__, "self")
+ backend.consume(objs)
+
+ man_dir = mozpath.join(env.topobjdir, "_build_manifests", "install")
+ self.assertTrue(os.path.isdir(man_dir))
+
+ expected = ["testing"]
+ for e in expected:
+ full = mozpath.join(man_dir, e)
+ self.assertTrue(os.path.exists(full))
+
+ m2 = InstallManifest(path=full)
+ self.assertEqual(m, m2)
+
+ def test_ipdl_sources(self):
+ """Test that PREPROCESSED_IPDL_SOURCES and IPDL_SOURCES are written to
+ ipdlsrcs.mk correctly."""
+ env = self._get_environment("ipdl_sources")
+
+ # Use the ipdl directory as the IPDL root for testing.
+ ipdl_root = mozpath.join(env.topobjdir, "ipdl")
+
+ # Make substs writable so we can set the value of IPDL_ROOT to reflect
+ # the correct objdir.
+ env.substs = dict(env.substs)
+ env.substs["IPDL_ROOT"] = ipdl_root
+
+ self._consume("ipdl_sources", RecursiveMakeBackend, env)
+
+ manifest_path = mozpath.join(ipdl_root, "ipdlsrcs.mk")
+ lines = [l.strip() for l in open(manifest_path, "rt").readlines()]
+
+ # Handle Windows paths correctly
+ topsrcdir = mozpath.normsep(env.topsrcdir)
+
+ expected = [
+ "ALL_IPDLSRCS := bar1.ipdl foo1.ipdl %s/bar/bar.ipdl %s/bar/bar2.ipdlh %s/foo/foo.ipdl %s/foo/foo2.ipdlh" # noqa
+ % tuple([topsrcdir] * 4),
+ "IPDLDIRS := %s %s/bar %s/foo" % (ipdl_root, topsrcdir, topsrcdir),
+ ]
+
+ found = [str for str in lines if str.startswith(("ALL_IPDLSRCS", "IPDLDIRS"))]
+ self.assertEqual(found, expected)
+
+ # Check that each directory declares the generated relevant .cpp files
+ # to be built in CPPSRCS.
+ # ENABLE_UNIFIED_BUILD defaults to False without mozilla-central's
+ # moz.configure so we don't see unified sources here.
+ for dir, expected in (
+ (".", []),
+ ("ipdl", []),
+ (
+ "bar",
+ [
+ "CPPSRCS += "
+ + " ".join(
+ f"{ipdl_root}/{f}"
+ for f in [
+ "bar.cpp",
+ "bar1.cpp",
+ "bar1Child.cpp",
+ "bar1Parent.cpp",
+ "bar2.cpp",
+ "barChild.cpp",
+ "barParent.cpp",
+ ]
+ )
+ ],
+ ),
+ (
+ "foo",
+ [
+ "CPPSRCS += "
+ + " ".join(
+ f"{ipdl_root}/{f}"
+ for f in [
+ "foo.cpp",
+ "foo1.cpp",
+ "foo1Child.cpp",
+ "foo1Parent.cpp",
+ "foo2.cpp",
+ "fooChild.cpp",
+ "fooParent.cpp",
+ ]
+ )
+ ],
+ ),
+ ):
+ backend_path = mozpath.join(env.topobjdir, dir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()]
+
+ found = [str for str in lines if str.startswith("CPPSRCS")]
+ self.assertEqual(found, expected)
+
+ def test_defines(self):
+ """Test that DEFINES are written to backend.mk correctly."""
+ env = self._consume("defines", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ var = "DEFINES"
+ defines = [val for val in lines if val.startswith(var)]
+
+ expected = ["DEFINES += -DFOO '-DBAZ=\"ab'\\''cd\"' -UQUX -DBAR=7 -DVALUE=xyz"]
+ self.assertEqual(defines, expected)
+
+ def test_local_includes(self):
+ """Test that LOCAL_INCLUDES are written to backend.mk correctly."""
+ env = self._consume("local_includes", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "LOCAL_INCLUDES += -I$(srcdir)/bar/baz",
+ "LOCAL_INCLUDES += -I$(srcdir)/foo",
+ ]
+
+ found = [str for str in lines if str.startswith("LOCAL_INCLUDES")]
+ self.assertEqual(found, expected)
+
+ def test_generated_includes(self):
+ """Test that GENERATED_INCLUDES are written to backend.mk correctly."""
+ env = self._consume("generated_includes", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "LOCAL_INCLUDES += -I$(CURDIR)/bar/baz",
+ "LOCAL_INCLUDES += -I$(CURDIR)/foo",
+ ]
+
+ found = [str for str in lines if str.startswith("LOCAL_INCLUDES")]
+ self.assertEqual(found, expected)
+
+ def test_rust_library(self):
+ """Test that a Rust library is written to backend.mk correctly."""
+ env = self._consume("rust-library", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [
+ l.strip()
+ for l in open(backend_path, "rt").readlines()[2:]
+ # Strip out computed flags, they're a PITA to test.
+ if not l.startswith("COMPUTED_")
+ ]
+
+ expected = [
+ "RUST_LIBRARY_FILE := %s/x86_64-unknown-linux-gnu/release/libtest_library.a"
+ % env.topobjdir, # noqa
+ "CARGO_FILE := $(srcdir)/Cargo.toml",
+ "CARGO_TARGET_DIR := %s" % env.topobjdir,
+ ]
+
+ self.assertEqual(lines, expected)
+
+ def test_host_rust_library(self):
+ """Test that a Rust library is written to backend.mk correctly."""
+ env = self._consume("host-rust-library", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [
+ l.strip()
+ for l in open(backend_path, "rt").readlines()[2:]
+ # Strip out computed flags, they're a PITA to test.
+ if not l.startswith("COMPUTED_")
+ ]
+
+ expected = [
+ "HOST_RUST_LIBRARY_FILE := %s/x86_64-unknown-linux-gnu/release/libhostrusttool.a"
+ % env.topobjdir, # noqa
+ "CARGO_FILE := $(srcdir)/Cargo.toml",
+ "CARGO_TARGET_DIR := %s" % env.topobjdir,
+ ]
+
+ self.assertEqual(lines, expected)
+
+ def test_host_rust_library_with_features(self):
+ """Test that a host Rust library with features is written to backend.mk correctly."""
+ env = self._consume("host-rust-library-features", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [
+ l.strip()
+ for l in open(backend_path, "rt").readlines()[2:]
+ # Strip out computed flags, they're a PITA to test.
+ if not l.startswith("COMPUTED_")
+ ]
+
+ expected = [
+ "HOST_RUST_LIBRARY_FILE := %s/x86_64-unknown-linux-gnu/release/libhostrusttool.a"
+ % env.topobjdir, # noqa
+ "CARGO_FILE := $(srcdir)/Cargo.toml",
+ "CARGO_TARGET_DIR := %s" % env.topobjdir,
+ "HOST_RUST_LIBRARY_FEATURES := musthave cantlivewithout",
+ ]
+
+ self.assertEqual(lines, expected)
+
+ def test_rust_library_with_features(self):
+ """Test that a Rust library with features is written to backend.mk correctly."""
+ env = self._consume("rust-library-features", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [
+ l.strip()
+ for l in open(backend_path, "rt").readlines()[2:]
+ # Strip out computed flags, they're a PITA to test.
+ if not l.startswith("COMPUTED_")
+ ]
+
+ expected = [
+ "RUST_LIBRARY_FILE := %s/x86_64-unknown-linux-gnu/release/libfeature_library.a"
+ % env.topobjdir, # noqa
+ "CARGO_FILE := $(srcdir)/Cargo.toml",
+ "CARGO_TARGET_DIR := %s" % env.topobjdir,
+ "RUST_LIBRARY_FEATURES := musthave cantlivewithout",
+ ]
+
+ self.assertEqual(lines, expected)
+
+ def test_rust_programs(self):
+ """Test that `{HOST_,}RUST_PROGRAMS` are written to backend.mk correctly."""
+ env = self._consume("rust-programs", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "code/backend.mk")
+ lines = [
+ l.strip()
+ for l in open(backend_path, "rt").readlines()[2:]
+ # Strip out computed flags, they're a PITA to test.
+ if not l.startswith("COMPUTED_")
+ ]
+
+ expected = [
+ "CARGO_FILE := %s/code/Cargo.toml" % env.topsrcdir,
+ "CARGO_TARGET_DIR := %s" % env.topobjdir,
+ "RUST_PROGRAMS += $(DEPTH)/i686-pc-windows-msvc/release/target.exe",
+ "RUST_CARGO_PROGRAMS += target",
+ "HOST_RUST_PROGRAMS += $(DEPTH)/i686-pc-windows-msvc/release/host.exe",
+ "HOST_RUST_CARGO_PROGRAMS += host",
+ ]
+
+ self.assertEqual(lines, expected)
+
+ root_deps_path = mozpath.join(env.topobjdir, "root-deps.mk")
+ lines = [l.strip() for l in open(root_deps_path, "rt").readlines()]
+
+ self.assertTrue(
+ any(l == "recurse_compile: code/host code/target" for l in lines)
+ )
+
+ def test_final_target(self):
+ """Test that FINAL_TARGET is written to backend.mk correctly."""
+ env = self._consume("final_target", RecursiveMakeBackend)
+
+ final_target_rule = "FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)" # noqa
+ expected = dict()
+ expected[env.topobjdir] = []
+ expected[mozpath.join(env.topobjdir, "both")] = [
+ "XPI_NAME = mycrazyxpi",
+ "DIST_SUBDIR = asubdir",
+ final_target_rule,
+ ]
+ expected[mozpath.join(env.topobjdir, "dist-subdir")] = [
+ "DIST_SUBDIR = asubdir",
+ final_target_rule,
+ ]
+ expected[mozpath.join(env.topobjdir, "xpi-name")] = [
+ "XPI_NAME = mycrazyxpi",
+ final_target_rule,
+ ]
+ expected[mozpath.join(env.topobjdir, "final-target")] = [
+ "FINAL_TARGET = $(DEPTH)/random-final-target"
+ ]
+ for key, expected_rules in six.iteritems(expected):
+ backend_path = mozpath.join(key, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+ found = [
+ str
+ for str in lines
+ if str.startswith("FINAL_TARGET")
+ or str.startswith("XPI_NAME")
+ or str.startswith("DIST_SUBDIR")
+ ]
+ self.assertEqual(found, expected_rules)
+
+ def test_final_target_pp_files(self):
+ """Test that FINAL_TARGET_PP_FILES is written to backend.mk correctly."""
+ env = self._consume("dist-files", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "DIST_FILES_0 += $(srcdir)/install.rdf",
+ "DIST_FILES_0 += $(srcdir)/main.js",
+ "DIST_FILES_0_PATH := $(DEPTH)/dist/bin/",
+ "DIST_FILES_0_TARGET := misc",
+ "PP_TARGETS += DIST_FILES_0",
+ ]
+
+ found = [str for str in lines if "DIST_FILES" in str]
+ self.assertEqual(found, expected)
+
+ def test_localized_files(self):
+ """Test that LOCALIZED_FILES is written to backend.mk correctly."""
+ env = self._consume("localized-files", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "LOCALIZED_FILES_0_FILES += $(wildcard $(LOCALE_SRCDIR)/abc/*.abc)",
+ "LOCALIZED_FILES_0_FILES += $(call MERGE_FILE,bar.ini)",
+ "LOCALIZED_FILES_0_FILES += $(call MERGE_FILE,foo.js)",
+ "LOCALIZED_FILES_0_DEST = $(FINAL_TARGET)/",
+ "LOCALIZED_FILES_0_TARGET := misc",
+ "INSTALL_TARGETS += LOCALIZED_FILES_0",
+ ]
+
+ found = [str for str in lines if "LOCALIZED_FILES" in str]
+ self.assertEqual(found, expected)
+
+ def test_localized_pp_files(self):
+ """Test that LOCALIZED_PP_FILES is written to backend.mk correctly."""
+ env = self._consume("localized-pp-files", RecursiveMakeBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.mk")
+ lines = [l.strip() for l in open(backend_path, "rt").readlines()[2:]]
+
+ expected = [
+ "LOCALIZED_PP_FILES_0 += $(call MERGE_FILE,bar.ini)",
+ "LOCALIZED_PP_FILES_0 += $(call MERGE_FILE,foo.js)",
+ "LOCALIZED_PP_FILES_0_PATH = $(FINAL_TARGET)/",
+ "LOCALIZED_PP_FILES_0_TARGET := misc",
+ "LOCALIZED_PP_FILES_0_FLAGS := --silence-missing-directive-warnings",
+ "PP_TARGETS += LOCALIZED_PP_FILES_0",
+ ]
+
+ found = [str for str in lines if "LOCALIZED_PP_FILES" in str]
+ self.assertEqual(found, expected)
+
+ def test_config(self):
+ """Test that CONFIGURE_SUBST_FILES are properly handled."""
+ env = self._consume("test_config", RecursiveMakeBackend)
+
+ self.assertEqual(
+ open(os.path.join(env.topobjdir, "file"), "r").readlines(),
+ ["#ifdef foo\n", "bar baz\n", "@bar@\n"],
+ )
+
+ def test_prog_lib_c_only(self):
+ """Test that C-only binary artifacts are marked as such."""
+ env = self._consume("prog-lib-c-only", RecursiveMakeBackend)
+
+ # PROGRAM C-onlyness.
+ with open(os.path.join(env.topobjdir, "c-program", "backend.mk"), "r") as fh:
+ lines = fh.readlines()
+ lines = [line.rstrip() for line in lines]
+
+ self.assertIn("PROG_IS_C_ONLY_c_test_program := 1", lines)
+
+ with open(os.path.join(env.topobjdir, "cxx-program", "backend.mk"), "r") as fh:
+ lines = fh.readlines()
+ lines = [line.rstrip() for line in lines]
+
+ # Test for only the absence of the variable, not the precise
+ # form of the variable assignment.
+ for line in lines:
+ self.assertNotIn("PROG_IS_C_ONLY_cxx_test_program", line)
+
+ # SIMPLE_PROGRAMS C-onlyness.
+ with open(
+ os.path.join(env.topobjdir, "c-simple-programs", "backend.mk"), "r"
+ ) as fh:
+ lines = fh.readlines()
+ lines = [line.rstrip() for line in lines]
+
+ self.assertIn("PROG_IS_C_ONLY_c_simple_program := 1", lines)
+
+ with open(
+ os.path.join(env.topobjdir, "cxx-simple-programs", "backend.mk"), "r"
+ ) as fh:
+ lines = fh.readlines()
+ lines = [line.rstrip() for line in lines]
+
+ for line in lines:
+ self.assertNotIn("PROG_IS_C_ONLY_cxx_simple_program", line)
+
+ # Libraries C-onlyness.
+ with open(os.path.join(env.topobjdir, "c-library", "backend.mk"), "r") as fh:
+ lines = fh.readlines()
+ lines = [line.rstrip() for line in lines]
+
+ self.assertIn("LIB_IS_C_ONLY := 1", lines)
+
+ with open(os.path.join(env.topobjdir, "cxx-library", "backend.mk"), "r") as fh:
+ lines = fh.readlines()
+ lines = [line.rstrip() for line in lines]
+
+ for line in lines:
+ self.assertNotIn("LIB_IS_C_ONLY", line)
+
+ def test_linkage(self):
+ env = self._consume("linkage", RecursiveMakeBackend)
+ expected_linkage = {
+ "prog": {
+ "SHARED_LIBS": ["qux/qux.so", "../shared/baz.so"],
+ "STATIC_LIBS": ["../real/foo.a"],
+ "OS_LIBS": ["-lfoo", "-lbaz", "-lbar"],
+ },
+ "shared": {
+ "OS_LIBS": ["-lfoo"],
+ "SHARED_LIBS": ["../prog/qux/qux.so"],
+ "STATIC_LIBS": [],
+ },
+ "static": {
+ "STATIC_LIBS": ["../real/foo.a"],
+ "OS_LIBS": ["-lbar"],
+ "SHARED_LIBS": ["../prog/qux/qux.so"],
+ },
+ "real": {
+ "STATIC_LIBS": [],
+ "SHARED_LIBS": ["../prog/qux/qux.so"],
+ "OS_LIBS": ["-lbaz"],
+ },
+ }
+ actual_linkage = {}
+ for name in expected_linkage.keys():
+ with open(os.path.join(env.topobjdir, name, "backend.mk"), "r") as fh:
+ actual_linkage[name] = [line.rstrip() for line in fh.readlines()]
+ for name in expected_linkage:
+ for var in expected_linkage[name]:
+ for val in expected_linkage[name][var]:
+ val = os.path.normpath(val)
+ line = "%s += %s" % (var, val)
+ self.assertIn(line, actual_linkage[name])
+ actual_linkage[name].remove(line)
+ for line in actual_linkage[name]:
+ self.assertNotIn("%s +=" % var, line)
+
+ def test_list_files(self):
+ env = self._consume("linkage", RecursiveMakeBackend)
+ expected_list_files = {
+ "prog/MyProgram_exe.list": [
+ "../static/bar/bar1.o",
+ "../static/bar/bar2.o",
+ "../static/bar/bar_helper/bar_helper1.o",
+ ],
+ "shared/baz_so.list": ["baz/baz1.o"],
+ }
+ actual_list_files = {}
+ for name in expected_list_files.keys():
+ with open(os.path.join(env.topobjdir, name), "r") as fh:
+ actual_list_files[name] = [line.rstrip() for line in fh.readlines()]
+ for name in expected_list_files:
+ self.assertEqual(
+ actual_list_files[name],
+ [os.path.normpath(f) for f in expected_list_files[name]],
+ )
+
+ # We don't produce a list file for a shared library composed only of
+ # object files in its directory, but instead list them in a variable.
+ with open(os.path.join(env.topobjdir, "prog", "qux", "backend.mk"), "r") as fh:
+ lines = [line.rstrip() for line in fh.readlines()]
+
+ self.assertIn("qux.so_OBJS := qux1.o", lines)
+
+ def test_jar_manifests(self):
+ env = self._consume("jar-manifests", RecursiveMakeBackend)
+
+ with open(os.path.join(env.topobjdir, "backend.mk"), "r") as fh:
+ lines = fh.readlines()
+
+ lines = [line.rstrip() for line in lines]
+
+ self.assertIn("JAR_MANIFEST := %s/jar.mn" % env.topsrcdir, lines)
+
+ def test_test_manifests_duplicate_support_files(self):
+ """Ensure duplicate support-files in test manifests work."""
+ env = self._consume(
+ "test-manifests-duplicate-support-files", RecursiveMakeBackend
+ )
+
+ p = os.path.join(env.topobjdir, "_build_manifests", "install", "_test_files")
+ m = InstallManifest(p)
+ self.assertIn("testing/mochitest/tests/support-file.txt", m)
+
+ def test_install_manifests_package_tests(self):
+ """Ensure test suites honor package_tests=False."""
+ env = self._consume("test-manifests-package-tests", RecursiveMakeBackend)
+
+ man_dir = mozpath.join(env.topobjdir, "_build_manifests", "install")
+ self.assertTrue(os.path.isdir(man_dir))
+
+ full = mozpath.join(man_dir, "_test_files")
+ self.assertTrue(os.path.exists(full))
+
+ m = InstallManifest(path=full)
+
+ # Only mochitest.js should be in the install manifest.
+ self.assertTrue("testing/mochitest/tests/mochitest.js" in m)
+
+ # The path is odd here because we do not normalize at test manifest
+ # processing time. This is a fragile test because there's currently no
+ # way to iterate the manifest.
+ self.assertFalse("instrumentation/./not_packaged.java" in m)
+
+ def test_program_paths(self):
+ """PROGRAMs with various moz.build settings that change the destination should produce
+ the expected paths in backend.mk."""
+ env = self._consume("program-paths", RecursiveMakeBackend)
+
+ expected = [
+ ("dist-bin", "$(DEPTH)/dist/bin/dist-bin.prog"),
+ ("dist-subdir", "$(DEPTH)/dist/bin/foo/dist-subdir.prog"),
+ ("final-target", "$(DEPTH)/final/target/final-target.prog"),
+ ("not-installed", "not-installed.prog"),
+ ]
+ prefix = "PROGRAM = "
+ for (subdir, expected_program) in expected:
+ with io.open(os.path.join(env.topobjdir, subdir, "backend.mk"), "r") as fh:
+ lines = fh.readlines()
+ program = [
+ line.rstrip().split(prefix, 1)[1]
+ for line in lines
+ if line.startswith(prefix)
+ ][0]
+ self.assertEqual(program, expected_program)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_test_manifest.py b/python/mozbuild/mozbuild/test/backend/test_test_manifest.py
new file mode 100644
index 0000000000..fadf65e447
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_test_manifest.py
@@ -0,0 +1,94 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+
+import mozpack.path as mozpath
+import six.moves.cPickle as pickle
+from mozunit import main
+
+from mozbuild.backend.test_manifest import TestManifestBackend
+from mozbuild.test.backend.common import BackendTester
+
+
+class TestTestManifestBackend(BackendTester):
+ def test_all_tests_metadata_file_written(self):
+ """Ensure all-tests.pkl is generated."""
+ env = self._consume("test-manifests-written", TestManifestBackend)
+
+ all_tests_path = mozpath.join(env.topobjdir, "all-tests.pkl")
+ self.assertTrue(os.path.exists(all_tests_path))
+
+ with open(all_tests_path, "rb") as fh:
+ o = pickle.load(fh)
+
+ self.assertIn("xpcshell.js", o)
+ self.assertIn("dir1/test_bar.js", o)
+
+ self.assertEqual(len(o["xpcshell.js"]), 1)
+
+ def test_test_installs_metadata_file_written(self):
+ """Ensure test-installs.pkl is generated."""
+ env = self._consume("test-manifest-shared-support", TestManifestBackend)
+ all_tests_path = mozpath.join(env.topobjdir, "all-tests.pkl")
+ self.assertTrue(os.path.exists(all_tests_path))
+ test_installs_path = mozpath.join(env.topobjdir, "test-installs.pkl")
+
+ with open(test_installs_path, "rb") as fh:
+ test_installs = pickle.load(fh)
+
+ self.assertEqual(
+ set(test_installs.keys()),
+ set(["child/test_sub.js", "child/data/**", "child/another-file.sjs"]),
+ )
+
+ for key in test_installs.keys():
+ self.assertIn(key, test_installs)
+
+ def test_test_defaults_metadata_file_written(self):
+ """Ensure test-defaults.pkl is generated."""
+ env = self._consume("test-manifests-written", TestManifestBackend)
+
+ test_defaults_path = mozpath.join(env.topobjdir, "test-defaults.pkl")
+ self.assertTrue(os.path.exists(test_defaults_path))
+
+ with open(test_defaults_path, "rb") as fh:
+ o = {mozpath.normpath(k): v for k, v in pickle.load(fh).items()}
+
+ self.assertEqual(
+ set(mozpath.relpath(k, env.topsrcdir) for k in o.keys()),
+ set(["dir1/xpcshell.ini", "xpcshell.ini", "mochitest.ini"]),
+ )
+
+ manifest_path = mozpath.join(env.topsrcdir, "xpcshell.ini")
+ self.assertIn("here", o[manifest_path])
+ self.assertIn("support-files", o[manifest_path])
+
+ def test_test_manifest_sources(self):
+ """Ensure that backend sources are generated correctly."""
+ env = self._consume("test-manifests-backend-sources", TestManifestBackend)
+
+ backend_path = mozpath.join(env.topobjdir, "backend.TestManifestBackend.in")
+ self.assertTrue(os.path.exists(backend_path))
+
+ status_path = mozpath.join(env.topobjdir, "config.status")
+
+ with open(backend_path, "r") as fh:
+ sources = set(source.strip() for source in fh)
+
+ self.assertEqual(
+ sources,
+ set(
+ [
+ mozpath.join(env.topsrcdir, "mochitest.ini"),
+ mozpath.join(env.topsrcdir, "mochitest-common.ini"),
+ mozpath.join(env.topsrcdir, "moz.build"),
+ status_path,
+ ]
+ ),
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python/mozbuild/mozbuild/test/backend/test_visualstudio.py b/python/mozbuild/mozbuild/test/backend/test_visualstudio.py
new file mode 100644
index 0000000000..14cccb484b
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/test_visualstudio.py
@@ -0,0 +1,63 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import unittest
+from xml.dom.minidom import parse
+
+from mozunit import main
+
+from mozbuild.backend.visualstudio import VisualStudioBackend
+from mozbuild.test.backend.common import BackendTester
+
+
+class TestVisualStudioBackend(BackendTester):
+ @unittest.skip("Failing inconsistently in automation.")
+ def test_basic(self):
+ """Ensure we can consume our stub project."""
+
+ env = self._consume("visual-studio", VisualStudioBackend)
+
+ msvc = os.path.join(env.topobjdir, "msvc")
+ self.assertTrue(os.path.isdir(msvc))
+
+ self.assertTrue(os.path.isfile(os.path.join(msvc, "mozilla.sln")))
+ self.assertTrue(os.path.isfile(os.path.join(msvc, "mozilla.props")))
+ self.assertTrue(os.path.isfile(os.path.join(msvc, "mach.bat")))
+ self.assertTrue(os.path.isfile(os.path.join(msvc, "binary_my_app.vcxproj")))
+ self.assertTrue(os.path.isfile(os.path.join(msvc, "target_full.vcxproj")))
+ self.assertTrue(os.path.isfile(os.path.join(msvc, "library_dir1.vcxproj")))
+ self.assertTrue(os.path.isfile(os.path.join(msvc, "library_dir1.vcxproj.user")))
+
+ d = parse(os.path.join(msvc, "library_dir1.vcxproj"))
+ self.assertEqual(d.documentElement.tagName, "Project")
+ els = d.getElementsByTagName("ClCompile")
+ self.assertEqual(len(els), 2)
+
+ # mozilla-config.h should be explicitly listed as an include.
+ els = d.getElementsByTagName("NMakeForcedIncludes")
+ self.assertEqual(len(els), 1)
+ self.assertEqual(
+ els[0].firstChild.nodeValue, "$(TopObjDir)\\dist\\include\\mozilla-config.h"
+ )
+
+ # LOCAL_INCLUDES get added to the include search path.
+ els = d.getElementsByTagName("NMakeIncludeSearchPath")
+ self.assertEqual(len(els), 1)
+ includes = els[0].firstChild.nodeValue.split(";")
+ self.assertIn(os.path.normpath("$(TopSrcDir)/includeA/foo"), includes)
+ self.assertIn(os.path.normpath("$(TopSrcDir)/dir1"), includes)
+ self.assertIn(os.path.normpath("$(TopObjDir)/dir1"), includes)
+ self.assertIn(os.path.normpath("$(TopObjDir)\\dist\\include"), includes)
+
+ # DEFINES get added to the project.
+ els = d.getElementsByTagName("NMakePreprocessorDefinitions")
+ self.assertEqual(len(els), 1)
+ defines = els[0].firstChild.nodeValue.split(";")
+ self.assertIn("DEFINEFOO", defines)
+ self.assertIn("DEFINEBAR=bar", defines)
+
+
+if __name__ == "__main__":
+ main()