summaryrefslogtreecommitdiffstats
path: root/test cases
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--test cases/cmake/1 basic/main.cpp10
-rw-r--r--test cases/cmake/1 basic/meson.build14
-rw-r--r--test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt20
-rw-r--r--test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp15
-rw-r--r--test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp18
-rw-r--r--test cases/cmake/1 basic/subprojects/cmMod/cpp_pch.hpp2
-rw-r--r--test cases/cmake/10 header only/main.cpp16
-rw-r--r--test cases/cmake/10 header only/meson.build12
-rw-r--r--test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt12
-rw-r--r--test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp24
-rw-r--r--test cases/cmake/11 cmake_module_path/cmake/FindSomethingLikePython.cmake9
-rw-r--r--test cases/cmake/11 cmake_module_path/meson.build25
-rw-r--r--test cases/cmake/11 cmake_module_path/subprojects/cmMod/CMakeLists.txt15
-rw-r--r--test cases/cmake/11 cmake_module_path/subprojects/cmMod/gen.py9
-rw-r--r--test cases/cmake/12 generator expressions/main.cpp10
-rw-r--r--test cases/cmake/12 generator expressions/meson.build12
-rw-r--r--test cases/cmake/12 generator expressions/subprojects/cmMod/CMakeLists.txt32
-rw-r--r--test cases/cmake/12 generator expressions/subprojects/cmMod/include/cmMod.hpp63
-rw-r--r--test cases/cmake/12 generator expressions/test.json5
-rw-r--r--test cases/cmake/13 system includes/main.cpp10
-rw-r--r--test cases/cmake/13 system includes/meson.build18
-rw-r--r--test cases/cmake/13 system includes/subprojects/cmMod/CMakeLists.txt15
-rw-r--r--test cases/cmake/13 system includes/subprojects/cmMod/cmMod.cpp12
-rw-r--r--test cases/cmake/13 system includes/subprojects/cmMod/cmMod.hpp13
-rw-r--r--test cases/cmake/13 system includes/subprojects/cmMod/sysInc/triggerWarn.hpp14
-rw-r--r--test cases/cmake/14 fortran threads/meson.build12
-rw-r--r--test cases/cmake/15 object library advanced/main.cpp11
-rw-r--r--test cases/cmake/15 object library advanced/meson.build17
-rw-r--r--test cases/cmake/15 object library advanced/subprojects/cmObjLib/CMakeLists.txt18
-rw-r--r--test cases/cmake/15 object library advanced/subprojects/cmObjLib/genC.cpp31
-rw-r--r--test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.cpp9
-rw-r--r--test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.hpp16
-rw-r--r--test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.cpp6
-rw-r--r--test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.hpp16
-rw-r--r--test cases/cmake/16 threads/main.cpp9
-rw-r--r--test cases/cmake/16 threads/meson.build12
-rw-r--r--test cases/cmake/16 threads/meson_options.txt1
-rw-r--r--test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt15
-rw-r--r--test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp15
-rw-r--r--test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp21
-rw-r--r--test cases/cmake/16 threads/subprojects/cmMod/main.cpp9
-rw-r--r--test cases/cmake/16 threads/test.json11
-rw-r--r--test cases/cmake/17 include path order/main.cpp10
-rw-r--r--test cases/cmake/17 include path order/meson.build9
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/CMakeLists.txt34
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/cmMod.cpp11
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incA/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incB/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incC/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incD/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incE/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incF/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incG/cmMod.hpp14
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incH/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incI/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incJ/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incL/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incM/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incN/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incO/cmMod.hpp4
-rw-r--r--test cases/cmake/17 include path order/subprojects/cmMod/incP/cmMod.hpp4
-rw-r--r--test cases/cmake/18 skip include files/main.cpp10
-rw-r--r--test cases/cmake/18 skip include files/meson.build9
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/CMakeLists.txt15
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.cpp10
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.hpp16
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/CMakeLists.txt30
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc1.cpp7
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc2.cpp7
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc3.cpp7
-rw-r--r--test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc4.cpp7
-rw-r--r--test cases/cmake/19 advanced options/main.cpp18
-rw-r--r--test cases/cmake/19 advanced options/meson.build29
-rw-r--r--test cases/cmake/19 advanced options/subprojects/cmOpts/CMakeLists.txt18
-rw-r--r--test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.cpp31
-rw-r--r--test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.hpp14
-rw-r--r--test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.cpp25
-rw-r--r--test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.hpp3
-rw-r--r--test cases/cmake/19 advanced options/subprojects/cmOpts/main.cpp10
-rw-r--r--test cases/cmake/19 advanced options/test.json5
-rw-r--r--test cases/cmake/2 advanced/main.cpp15
-rw-r--r--test cases/cmake/2 advanced/meson.build27
-rw-r--r--test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt38
-rw-r--r--test cases/cmake/2 advanced/subprojects/cmMod/config.h.in3
-rw-r--r--test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.cpp26
-rw-r--r--test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.hpp13
-rw-r--r--test cases/cmake/2 advanced/subprojects/cmMod/main.cpp11
-rw-r--r--test cases/cmake/2 advanced/test.json5
-rw-r--r--test cases/cmake/20 cmake file/foolib.cmake.in1
-rw-r--r--test cases/cmake/20 cmake file/meson.build12
-rw-r--r--test cases/cmake/20 cmake file/test.json5
-rw-r--r--test cases/cmake/21 shared module/meson.build13
-rw-r--r--test cases/cmake/21 shared module/prog.c108
-rw-r--r--test cases/cmake/21 shared module/runtime.c19
-rw-r--r--test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt7
-rw-r--r--test cases/cmake/21 shared module/subprojects/cmMod/module/module.c96
-rw-r--r--test cases/cmake/21 shared module/subprojects/cmMod/module/module.h3
-rw-r--r--test cases/cmake/22 cmake module/cmake_project/CMakeLists.txt4
-rw-r--r--test cases/cmake/22 cmake module/meson.build31
-rw-r--r--test cases/cmake/22 cmake module/projectConfig.cmake.in4
-rw-r--r--test cases/cmake/22 cmake module/test.json6
-rw-r--r--test cases/cmake/23 cmake toolchain/CMakeToolchain.cmake1
-rw-r--r--test cases/cmake/23 cmake toolchain/meson.build13
-rw-r--r--test cases/cmake/23 cmake toolchain/nativefile.ini.in9
-rw-r--r--test cases/cmake/23 cmake toolchain/subprojects/cmMod/CMakeLists.txt15
-rw-r--r--test cases/cmake/23 cmake toolchain/subprojects/cmModFortran/CMakeLists.txt19
-rw-r--r--test cases/cmake/24 mixing languages/main.c5
-rw-r--r--test cases/cmake/24 mixing languages/meson.build13
-rw-r--r--test cases/cmake/24 mixing languages/subprojects/cmTest/CMakeLists.txt8
-rw-r--r--test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.c13
-rw-r--r--test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.h3
-rw-r--r--test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.m7
-rw-r--r--test cases/cmake/25 assembler/main.c18
-rw-r--r--test cases/cmake/25 assembler/meson.build9
-rw-r--r--test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt45
-rw-r--r--test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c8
-rw-r--r--test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s4
-rw-r--r--test cases/cmake/3 advanced no dep/main.cpp15
-rw-r--r--test cases/cmake/3 advanced no dep/meson.build19
-rw-r--r--test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt26
-rw-r--r--test cases/cmake/3 advanced no dep/subprojects/cmMod/config.h.in3
-rw-r--r--test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.cpp16
-rw-r--r--test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.hpp13
-rw-r--r--test cases/cmake/3 advanced no dep/subprojects/cmMod/main.cpp10
-rw-r--r--test cases/cmake/3 advanced no dep/test.json8
-rw-r--r--test cases/cmake/4 code gen/main.cpp8
-rw-r--r--test cases/cmake/4 code gen/meson.build24
-rw-r--r--test cases/cmake/4 code gen/subprojects/cmCodeGen/CMakeLists.txt6
-rw-r--r--test cases/cmake/4 code gen/subprojects/cmCodeGen/main.cpp21
-rw-r--r--test cases/cmake/4 code gen/test.hpp5
-rw-r--r--test cases/cmake/5 object library/main.cpp11
-rw-r--r--test cases/cmake/5 object library/meson.build21
-rw-r--r--test cases/cmake/5 object library/subprojects/cmObjLib/CMakeLists.txt11
-rw-r--r--test cases/cmake/5 object library/subprojects/cmObjLib/libA.cpp5
-rw-r--r--test cases/cmake/5 object library/subprojects/cmObjLib/libA.hpp16
-rw-r--r--test cases/cmake/5 object library/subprojects/cmObjLib/libB.cpp6
-rw-r--r--test cases/cmake/5 object library/subprojects/cmObjLib/libB.hpp16
-rw-r--r--test cases/cmake/6 object library no dep/main.cpp11
-rw-r--r--test cases/cmake/6 object library no dep/meson.build13
-rw-r--r--test cases/cmake/6 object library no dep/subprojects/cmObjLib/CMakeLists.txt6
-rw-r--r--test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.cpp5
-rw-r--r--test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.hpp16
-rw-r--r--test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.cpp5
-rw-r--r--test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.hpp16
-rw-r--r--test cases/cmake/7 cmake options/meson.build3
-rw-r--r--test cases/cmake/7 cmake options/subprojects/cmOpts/CMakeLists.txt10
-rw-r--r--test cases/cmake/7 cmake options/test.json12
-rw-r--r--test cases/cmake/8 custom command/main.cpp11
-rw-r--r--test cases/cmake/8 custom command/meson.build16
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/CMakeLists.txt163
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/args_test.cpp18
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cmMod.cpp24
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cmMod.hpp14
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cp.cpp22
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.cpp.am5
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.hpp.am5
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyInc.hpp.am3
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.cpp.am5
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.hpp.am5
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyTest.cpp9
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/CMakeLists.txt7
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest.hpp5
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest2.hpp3
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest3.hpp3
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest4.hpp3
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest5.hpp3
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/genMain.cpp40
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/macro_name.cpp20
-rw-r--r--test cases/cmake/8 custom command/subprojects/cmMod/mycpy/.gitkeep1
-rw-r--r--test cases/cmake/9 disabled subproject/meson.build6
-rw-r--r--test cases/common/1 trivial/meson.build29
-rw-r--r--test cases/common/1 trivial/trivial.c6
-rw-r--r--test cases/common/10 man install/bar.21
-rw-r--r--test cases/common/10 man install/baz.1.in6
-rw-r--r--test cases/common/10 man install/foo.11
-rw-r--r--test cases/common/10 man install/foo.fr.11
-rw-r--r--test cases/common/10 man install/meson.build14
-rw-r--r--test cases/common/10 man install/test.json10
-rw-r--r--test cases/common/10 man install/vanishing/meson.build1
-rw-r--r--test cases/common/10 man install/vanishing/vanishing.11
-rw-r--r--test cases/common/10 man install/vanishing/vanishing.21
-rw-r--r--test cases/common/100 postconf with args/meson.build10
-rw-r--r--test cases/common/100 postconf with args/postconf.py18
-rw-r--r--test cases/common/100 postconf with args/prog.c5
-rw-r--r--test cases/common/100 postconf with args/raw.dat1
-rw-r--r--test cases/common/101 testframework options/meson.build8
-rw-r--r--test cases/common/101 testframework options/meson_options.txt3
-rw-r--r--test cases/common/101 testframework options/test.json10
-rw-r--r--test cases/common/102 extract same name/lib.c3
-rw-r--r--test cases/common/102 extract same name/main.c6
-rw-r--r--test cases/common/102 extract same name/meson.build19
-rw-r--r--test cases/common/102 extract same name/src/lib.c3
-rw-r--r--test cases/common/103 has header symbol/meson.build40
-rw-r--r--test cases/common/104 has arg/meson.build60
-rwxr-xr-xtest cases/common/105 generatorcustom/catter.py14
-rwxr-xr-xtest cases/common/105 generatorcustom/gen-resx.py9
-rw-r--r--test cases/common/105 generatorcustom/gen.c35
-rwxr-xr-xtest cases/common/105 generatorcustom/gen.py13
-rw-r--r--test cases/common/105 generatorcustom/host.c9
-rw-r--r--test cases/common/105 generatorcustom/main.c8
-rw-r--r--test cases/common/105 generatorcustom/meson.build44
-rw-r--r--test cases/common/105 generatorcustom/res1.txt1
-rw-r--r--test cases/common/105 generatorcustom/res2.txt1
-rw-r--r--test cases/common/106 multiple dir configure file/meson.build11
-rw-r--r--test cases/common/106 multiple dir configure file/subdir/foo.txt0
-rw-r--r--test cases/common/106 multiple dir configure file/subdir/meson.build11
-rw-r--r--test cases/common/106 multiple dir configure file/subdir/someinput.in0
-rw-r--r--test cases/common/107 spaces backslash/asm output/meson.build1
-rw-r--r--test cases/common/107 spaces backslash/comparer-end-notstring.c20
-rw-r--r--test cases/common/107 spaces backslash/comparer-end.c16
-rw-r--r--test cases/common/107 spaces backslash/comparer.c16
-rw-r--r--test cases/common/107 spaces backslash/include/comparer.h4
-rw-r--r--test cases/common/107 spaces backslash/meson.build28
-rw-r--r--test cases/common/108 ternary/meson.build12
-rw-r--r--test cases/common/109 custom target capture/data_source.txt1
-rw-r--r--test cases/common/109 custom target capture/meson.build24
-rwxr-xr-xtest cases/common/109 custom target capture/my_compiler.py14
-rw-r--r--test cases/common/109 custom target capture/test.json5
-rw-r--r--test cases/common/11 subdir/meson.build2
-rw-r--r--test cases/common/11 subdir/subdir/meson.build2
-rw-r--r--test cases/common/11 subdir/subdir/prog.c1
-rwxr-xr-xtest cases/common/110 allgenerate/converter.py8
-rw-r--r--test cases/common/110 allgenerate/foobar.cpp.in6
-rw-r--r--test cases/common/110 allgenerate/meson.build20
-rw-r--r--test cases/common/111 pathjoin/meson.build27
-rw-r--r--test cases/common/112 subdir subproject/meson.build2
-rw-r--r--test cases/common/112 subdir subproject/prog/meson.build5
-rw-r--r--test cases/common/112 subdir subproject/prog/prog.c5
-rw-r--r--test cases/common/112 subdir subproject/subprojects/sub/meson.build3
-rw-r--r--test cases/common/112 subdir subproject/subprojects/sub/sub.c5
-rw-r--r--test cases/common/112 subdir subproject/subprojects/sub/sub.h6
-rw-r--r--test cases/common/113 interpreter copy mutable var on assignment/meson.build19
-rw-r--r--test cases/common/114 skip/meson.build3
-rw-r--r--test cases/common/115 subproject project arguments/exe.c27
-rw-r--r--test cases/common/115 subproject project arguments/exe.cpp27
-rw-r--r--test cases/common/115 subproject project arguments/meson.build17
-rw-r--r--test cases/common/115 subproject project arguments/subprojects/subexe/meson.build13
-rw-r--r--test cases/common/115 subproject project arguments/subprojects/subexe/subexe.c27
-rw-r--r--test cases/common/116 test skip/meson.build4
-rw-r--r--test cases/common/116 test skip/test_skip.c3
-rw-r--r--test cases/common/117 shared module/meson.build40
-rw-r--r--test cases/common/117 shared module/module.c96
-rw-r--r--test cases/common/117 shared module/nosyms.c4
-rw-r--r--test cases/common/117 shared module/prog.c103
-rw-r--r--test cases/common/117 shared module/runtime.c19
-rw-r--r--test cases/common/117 shared module/test.json7
-rw-r--r--test cases/common/118 llvm ir and assembly/main.c13
-rw-r--r--test cases/common/118 llvm ir and assembly/main.cpp15
-rw-r--r--test cases/common/118 llvm ir and assembly/meson.build79
-rw-r--r--test cases/common/118 llvm ir and assembly/square-aarch64.S29
-rw-r--r--test cases/common/118 llvm ir and assembly/square-arm.S29
-rw-r--r--test cases/common/118 llvm ir and assembly/square-x86.S36
-rw-r--r--test cases/common/118 llvm ir and assembly/square-x86_64.S37
-rw-r--r--test cases/common/118 llvm ir and assembly/square.ll4
-rw-r--r--test cases/common/118 llvm ir and assembly/symbol-underscore.h5
-rw-r--r--test cases/common/119 cpp and asm/meson.build33
-rw-r--r--test cases/common/119 cpp and asm/retval-arm.S11
-rw-r--r--test cases/common/119 cpp and asm/retval-x86.S11
-rw-r--r--test cases/common/119 cpp and asm/retval-x86_64.S11
-rw-r--r--test cases/common/119 cpp and asm/symbol-underscore.h5
-rw-r--r--test cases/common/119 cpp and asm/trivial.cc16
-rw-r--r--test cases/common/12 data/datafile.dat1
-rw-r--r--test cases/common/12 data/etcfile.dat1
-rw-r--r--test cases/common/12 data/fileobject_datafile.dat1
-rw-r--r--test cases/common/12 data/meson.build24
-rw-r--r--test cases/common/12 data/runscript.sh3
-rw-r--r--test cases/common/12 data/somefile.txt0
-rw-r--r--test cases/common/12 data/test.json15
-rw-r--r--test cases/common/12 data/to_be_renamed_1.txt0
-rw-r--r--test cases/common/12 data/to_be_renamed_3.txt0
-rw-r--r--test cases/common/12 data/to_be_renamed_4.txt0
-rw-r--r--test cases/common/12 data/vanishing/meson.build1
-rw-r--r--test cases/common/12 data/vanishing/to_be_renamed_2.txt0
-rw-r--r--test cases/common/12 data/vanishing/vanishing.dat1
-rw-r--r--test cases/common/12 data/vanishing/vanishing2.dat4
-rw-r--r--test cases/common/120 extract all shared library/extractor.h6
-rw-r--r--test cases/common/120 extract all shared library/four.c5
-rw-r--r--test cases/common/120 extract all shared library/func1234.def5
-rw-r--r--test cases/common/120 extract all shared library/meson.build15
-rw-r--r--test cases/common/120 extract all shared library/one.c5
-rw-r--r--test cases/common/120 extract all shared library/prog.c10
-rw-r--r--test cases/common/120 extract all shared library/three.c5
-rw-r--r--test cases/common/120 extract all shared library/two.c5
-rw-r--r--test cases/common/121 object only target/meson.build51
-rwxr-xr-xtest cases/common/121 object only target/obj_generator.py20
-rw-r--r--test cases/common/121 object only target/objdir/meson.build27
-rw-r--r--test cases/common/121 object only target/objdir/source4.c3
-rw-r--r--test cases/common/121 object only target/objdir/source5.c3
-rw-r--r--test cases/common/121 object only target/objdir/source6.c3
-rw-r--r--test cases/common/121 object only target/prog.c11
-rw-r--r--test cases/common/121 object only target/source.c3
-rw-r--r--test cases/common/121 object only target/source2.c3
-rw-r--r--test cases/common/121 object only target/source2.def2
-rw-r--r--test cases/common/121 object only target/source3.c3
-rw-r--r--test cases/common/121 object only target/test.json6
-rw-r--r--test cases/common/122 no buildincdir/include/header.h3
-rw-r--r--test cases/common/122 no buildincdir/meson.build14
-rw-r--r--test cases/common/122 no buildincdir/prog.c5
-rw-r--r--test cases/common/123 custom target directory install/docgen.py15
-rw-r--r--test cases/common/123 custom target directory install/meson.build9
-rw-r--r--test cases/common/123 custom target directory install/test.json7
-rw-r--r--test cases/common/124 dependency file generation/main .c3
-rw-r--r--test cases/common/124 dependency file generation/meson.build14
-rw-r--r--test cases/common/125 configure file in generator/inc/confdata.in1
-rw-r--r--test cases/common/125 configure file in generator/inc/meson.build6
-rw-r--r--test cases/common/125 configure file in generator/meson.build4
-rwxr-xr-xtest cases/common/125 configure file in generator/src/gen.py13
-rw-r--r--test cases/common/125 configure file in generator/src/main.c17
-rw-r--r--test cases/common/125 configure file in generator/src/meson.build7
-rw-r--r--test cases/common/125 configure file in generator/src/source1
-rw-r--r--test cases/common/126 generated llvm ir/copyfile.py6
-rw-r--r--test cases/common/126 generated llvm ir/main.c13
-rw-r--r--test cases/common/126 generated llvm ir/meson.build28
-rw-r--r--test cases/common/126 generated llvm ir/square.ll.in4
-rw-r--r--test cases/common/127 generated assembly/copyfile.py6
-rw-r--r--test cases/common/127 generated assembly/empty.c0
-rw-r--r--test cases/common/127 generated assembly/main.c16
-rw-r--r--test cases/common/127 generated assembly/meson.build66
-rw-r--r--test cases/common/127 generated assembly/square-arm.S.in13
-rw-r--r--test cases/common/127 generated assembly/square-x86.S.in34
-rw-r--r--test cases/common/127 generated assembly/square-x86_64.S.in38
-rw-r--r--test cases/common/127 generated assembly/square.def2
-rw-r--r--test cases/common/127 generated assembly/symbol-underscore.h5
-rw-r--r--test cases/common/128 build by default targets in tests/main.c3
-rw-r--r--test cases/common/128 build by default targets in tests/meson.build23
-rw-r--r--test cases/common/128 build by default targets in tests/write_file.py6
-rw-r--r--test cases/common/129 build by default/checkexists.py10
-rw-r--r--test cases/common/129 build by default/foo.c6
-rw-r--r--test cases/common/129 build by default/meson.build44
-rw-r--r--test cases/common/129 build by default/mygen.py8
-rw-r--r--test cases/common/129 build by default/source.txt1
-rw-r--r--test cases/common/13 pch/c/meson.build14
-rw-r--r--test cases/common/13 pch/c/pch/prog.h6
-rw-r--r--test cases/common/13 pch/c/prog.c9
-rw-r--r--test cases/common/13 pch/cpp/meson.build1
-rw-r--r--test cases/common/13 pch/cpp/pch/prog.hh1
-rw-r--r--test cases/common/13 pch/cpp/prog.cc11
-rw-r--r--test cases/common/13 pch/generated/gen_custom.py5
-rw-r--r--test cases/common/13 pch/generated/gen_generator.py7
-rw-r--r--test cases/common/13 pch/generated/generated_generator.in1
-rw-r--r--test cases/common/13 pch/generated/meson.build22
-rw-r--r--test cases/common/13 pch/generated/pch/prog.h2
-rw-r--r--test cases/common/13 pch/generated/prog.c5
-rw-r--r--test cases/common/13 pch/linkwhole/lib1.c4
-rw-r--r--test cases/common/13 pch/linkwhole/lib2.c6
-rw-r--r--test cases/common/13 pch/linkwhole/main.c9
-rw-r--r--test cases/common/13 pch/linkwhole/meson.build8
-rw-r--r--test cases/common/13 pch/linkwhole/pch1/pch_one.h4
-rw-r--r--test cases/common/13 pch/linkwhole/pch2/pch_two.h4
-rw-r--r--test cases/common/13 pch/meson.build26
-rw-r--r--test cases/common/13 pch/mixed/func.c7
-rw-r--r--test cases/common/13 pch/mixed/main.cc10
-rw-r--r--test cases/common/13 pch/mixed/meson.build14
-rw-r--r--test cases/common/13 pch/mixed/pch/func.h1
-rw-r--r--test cases/common/13 pch/mixed/pch/main.h1
-rw-r--r--test cases/common/13 pch/userDefined/meson.build10
-rw-r--r--test cases/common/13 pch/userDefined/pch/pch.c5
-rw-r--r--test cases/common/13 pch/userDefined/pch/pch.h1
-rw-r--r--test cases/common/13 pch/userDefined/prog.c8
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h1
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/meson.build15
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/pch/prog.h1
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/prog.c9
-rw-r--r--test cases/common/13 pch/withIncludeFile/meson.build18
-rw-r--r--test cases/common/13 pch/withIncludeFile/pch/prog.h6
-rw-r--r--test cases/common/13 pch/withIncludeFile/prog.c10
-rw-r--r--test cases/common/130 include order/ctsub/copyfile.py6
-rw-r--r--test cases/common/130 include order/ctsub/emptyfile.c0
-rw-r--r--test cases/common/130 include order/ctsub/main.h1
-rw-r--r--test cases/common/130 include order/ctsub/meson.build9
-rw-r--r--test cases/common/130 include order/inc1/hdr.h1
-rw-r--r--test cases/common/130 include order/inc2/hdr.h1
-rw-r--r--test cases/common/130 include order/meson.build36
-rw-r--r--test cases/common/130 include order/ordertest.c10
-rw-r--r--test cases/common/130 include order/sub1/main.h1
-rw-r--r--test cases/common/130 include order/sub1/meson.build4
-rw-r--r--test cases/common/130 include order/sub1/some.c6
-rw-r--r--test cases/common/130 include order/sub1/some.h10
-rw-r--r--test cases/common/130 include order/sub2/main.h1
-rw-r--r--test cases/common/130 include order/sub2/meson.build2
-rw-r--r--test cases/common/130 include order/sub3/main.h1
-rw-r--r--test cases/common/130 include order/sub3/meson.build1
-rw-r--r--test cases/common/130 include order/sub4/main.c8
-rw-r--r--test cases/common/130 include order/sub4/main.h3
-rw-r--r--test cases/common/130 include order/sub4/meson.build6
-rw-r--r--test cases/common/131 override options/four.c9
-rw-r--r--test cases/common/131 override options/meson.build6
-rw-r--r--test cases/common/131 override options/one.c3
-rw-r--r--test cases/common/131 override options/three.c7
-rw-r--r--test cases/common/131 override options/two.c6
-rw-r--r--test cases/common/132 get define/concat.h24
-rw-r--r--test cases/common/132 get define/meson.build111
-rw-r--r--test cases/common/132 get define/meson_options.txt1
-rw-r--r--test cases/common/133 c cpp and asm/main.c8
-rw-r--r--test cases/common/133 c cpp and asm/main.cpp11
-rw-r--r--test cases/common/133 c cpp and asm/meson.build23
-rw-r--r--test cases/common/133 c cpp and asm/retval-arm.S11
-rw-r--r--test cases/common/133 c cpp and asm/retval-x86.S12
-rw-r--r--test cases/common/133 c cpp and asm/retval-x86_64.S11
-rw-r--r--test cases/common/133 c cpp and asm/somelib.c3
-rw-r--r--test cases/common/133 c cpp and asm/symbol-underscore.h5
-rw-r--r--test cases/common/134 compute int/config.h.in4
-rw-r--r--test cases/common/134 compute int/foobar.h6
-rw-r--r--test cases/common/134 compute int/meson.build46
-rw-r--r--test cases/common/134 compute int/prog.c.in25
-rw-r--r--test cases/common/135 custom target object output/meson.build16
-rw-r--r--test cases/common/135 custom target object output/obj_generator.py18
-rw-r--r--test cases/common/135 custom target object output/objdir/meson.build5
-rw-r--r--test cases/common/135 custom target object output/objdir/source.c3
-rw-r--r--test cases/common/135 custom target object output/progdir/meson.build1
-rw-r--r--test cases/common/135 custom target object output/progdir/prog.c5
-rw-r--r--test cases/common/136 empty build file/meson.build2
-rw-r--r--test cases/common/136 empty build file/subdir/meson.build0
-rw-r--r--test cases/common/137 whole archive/exe/meson.build1
-rw-r--r--test cases/common/137 whole archive/exe2/meson.build1
-rw-r--r--test cases/common/137 whole archive/exe3/meson.build1
-rw-r--r--test cases/common/137 whole archive/exe4/meson.build1
-rw-r--r--test cases/common/137 whole archive/func1.c7
-rw-r--r--test cases/common/137 whole archive/func2.c7
-rw-r--r--test cases/common/137 whole archive/meson.build49
-rw-r--r--test cases/common/137 whole archive/mylib.h21
-rw-r--r--test cases/common/137 whole archive/prog.c5
-rw-r--r--test cases/common/137 whole archive/sh_func2_dep_func1/meson.build4
-rw-r--r--test cases/common/137 whole archive/sh_func2_linked_func1/meson.build3
-rw-r--r--test cases/common/137 whole archive/sh_func2_transdep_func1/meson.build6
-rw-r--r--test cases/common/137 whole archive/sh_only_link_whole/meson.build1
-rw-r--r--test cases/common/137 whole archive/st_func1/meson.build1
-rw-r--r--test cases/common/137 whole archive/st_func2/meson.build1
-rw-r--r--test cases/common/138 C and CPP link/dummy.c0
-rw-r--r--test cases/common/138 C and CPP link/foo.c19
-rw-r--r--test cases/common/138 C and CPP link/foo.cpp34
-rw-r--r--test cases/common/138 C and CPP link/foo.h16
-rw-r--r--test cases/common/138 C and CPP link/foo.hpp24
-rw-r--r--test cases/common/138 C and CPP link/foobar.c27
-rw-r--r--test cases/common/138 C and CPP link/foobar.h16
-rw-r--r--test cases/common/138 C and CPP link/meson.build133
-rw-r--r--test cases/common/138 C and CPP link/sub.c19
-rw-r--r--test cases/common/138 C and CPP link/sub.h16
-rw-r--r--test cases/common/139 mesonintrospect from scripts/check_env.py28
-rw-r--r--test cases/common/139 mesonintrospect from scripts/check_introspection.py18
-rw-r--r--test cases/common/139 mesonintrospect from scripts/meson.build14
-rw-r--r--test cases/common/14 configure file/basename.py28
-rw-r--r--test cases/common/14 configure file/check_file.py34
-rw-r--r--test cases/common/14 configure file/check_inputs.py14
-rw-r--r--test cases/common/14 configure file/config.h1
-rw-r--r--test cases/common/14 configure file/config.h.in5
-rw-r--r--test cases/common/14 configure file/config4a.h.in2
-rw-r--r--test cases/common/14 configure file/config4b.h.in2
-rw-r--r--test cases/common/14 configure file/config5.h.in1
-rw-r--r--test cases/common/14 configure file/config6.h.in19
-rw-r--r--test cases/common/14 configure file/config7.h.in16
-rw-r--r--test cases/common/14 configure file/config8.h.in3
-rw-r--r--test cases/common/14 configure file/depfile0
-rw-r--r--test cases/common/14 configure file/differentafterbasename1.in0
-rw-r--r--test cases/common/14 configure file/differentafterbasename2.in0
-rw-r--r--test cases/common/14 configure file/dummy.dat0
-rw-r--r--test cases/common/14 configure file/dumpprog.c52
-rw-r--r--test cases/common/14 configure file/file_contains.py22
-rwxr-xr-xtest cases/common/14 configure file/generator-deps.py19
-rwxr-xr-xtest cases/common/14 configure file/generator-without-input-file.py14
-rwxr-xr-xtest cases/common/14 configure file/generator.py17
-rw-r--r--test cases/common/14 configure file/invalid-utf8.bin.inbin0 -> 10 bytes
-rw-r--r--test cases/common/14 configure file/meson.build330
-rw-r--r--test cases/common/14 configure file/nosubst-nocopy1.txt.in1
-rw-r--r--test cases/common/14 configure file/nosubst-nocopy2.txt.in1
-rw-r--r--test cases/common/14 configure file/prog.c17
-rw-r--r--test cases/common/14 configure file/prog2.c5
-rw-r--r--test cases/common/14 configure file/prog4.c6
-rw-r--r--test cases/common/14 configure file/prog5.c6
-rw-r--r--test cases/common/14 configure file/prog6.c11
-rw-r--r--test cases/common/14 configure file/prog7.c10
-rw-r--r--test cases/common/14 configure file/prog9.c18
-rw-r--r--test cases/common/14 configure file/sameafterbasename.in0
-rw-r--r--test cases/common/14 configure file/sameafterbasename.in20
-rw-r--r--test cases/common/14 configure file/subdir/meson.build38
-rw-r--r--test cases/common/14 configure file/test.json9
-rw-r--r--test cases/common/14 configure file/test.py.in4
-rw-r--r--test cases/common/14 configure file/touch.py16
-rwxr-xr-xtest cases/common/140 custom target multiple outputs/generator.py14
-rw-r--r--test cases/common/140 custom target multiple outputs/meson.build44
-rw-r--r--test cases/common/140 custom target multiple outputs/test.json10
-rw-r--r--test cases/common/141 special characters/.editorconfig2
-rw-r--r--test cases/common/141 special characters/arg-char-test.c11
-rw-r--r--test cases/common/141 special characters/arg-string-test.c13
-rw-r--r--test cases/common/141 special characters/arg-unquoted-test.c18
-rw-r--r--test cases/common/141 special characters/check_quoting.py28
-rw-r--r--test cases/common/141 special characters/meson.build75
-rw-r--r--test cases/common/141 special characters/test.json6
-rw-r--r--test cases/common/142 nested links/meson.build8
-rw-r--r--test cases/common/142 nested links/xephyr.c3
-rw-r--r--test cases/common/143 list of file sources/foo1
-rw-r--r--test cases/common/143 list of file sources/gen.py7
-rw-r--r--test cases/common/143 list of file sources/meson.build12
-rw-r--r--test cases/common/144 link depends custom target/foo.c15
-rwxr-xr-xtest cases/common/144 link depends custom target/make_file.py5
-rw-r--r--test cases/common/144 link depends custom target/meson.build14
-rw-r--r--test cases/common/145 recursive linking/3rdorderdeps/lib.c.in8
-rw-r--r--test cases/common/145 recursive linking/3rdorderdeps/main.c.in16
-rw-r--r--test cases/common/145 recursive linking/3rdorderdeps/meson.build49
-rw-r--r--test cases/common/145 recursive linking/circular/lib1.c6
-rw-r--r--test cases/common/145 recursive linking/circular/lib2.c6
-rw-r--r--test cases/common/145 recursive linking/circular/lib3.c6
-rw-r--r--test cases/common/145 recursive linking/circular/main.c28
-rw-r--r--test cases/common/145 recursive linking/circular/meson.build5
-rw-r--r--test cases/common/145 recursive linking/circular/prop1.c3
-rw-r--r--test cases/common/145 recursive linking/circular/prop2.c3
-rw-r--r--test cases/common/145 recursive linking/circular/prop3.c3
-rw-r--r--test cases/common/145 recursive linking/edge-cases/libsto.c8
-rw-r--r--test cases/common/145 recursive linking/edge-cases/meson.build9
-rw-r--r--test cases/common/145 recursive linking/edge-cases/shstmain.c16
-rw-r--r--test cases/common/145 recursive linking/edge-cases/stobuilt.c7
-rw-r--r--test cases/common/145 recursive linking/edge-cases/stomain.c16
-rw-r--r--test cases/common/145 recursive linking/lib.h17
-rw-r--r--test cases/common/145 recursive linking/main.c46
-rw-r--r--test cases/common/145 recursive linking/meson.build29
-rw-r--r--test cases/common/145 recursive linking/shnodep/lib.c6
-rw-r--r--test cases/common/145 recursive linking/shnodep/meson.build1
-rw-r--r--test cases/common/145 recursive linking/shshdep/lib.c8
-rw-r--r--test cases/common/145 recursive linking/shshdep/meson.build1
-rw-r--r--test cases/common/145 recursive linking/shstdep/lib.c8
-rw-r--r--test cases/common/145 recursive linking/shstdep/meson.build1
-rw-r--r--test cases/common/145 recursive linking/stnodep/lib.c6
-rw-r--r--test cases/common/145 recursive linking/stnodep/meson.build2
-rw-r--r--test cases/common/145 recursive linking/stshdep/lib.c8
-rw-r--r--test cases/common/145 recursive linking/stshdep/meson.build2
-rw-r--r--test cases/common/145 recursive linking/ststdep/lib.c8
-rw-r--r--test cases/common/145 recursive linking/ststdep/meson.build2
-rw-r--r--test cases/common/146 library at root/lib.c6
-rw-r--r--test cases/common/146 library at root/main/main.c5
-rw-r--r--test cases/common/146 library at root/main/meson.build2
-rw-r--r--test cases/common/146 library at root/meson.build3
-rw-r--r--test cases/common/147 simd/fallback.c8
-rw-r--r--test cases/common/147 simd/include/simdheader.h3
-rw-r--r--test cases/common/147 simd/meson.build43
-rw-r--r--test cases/common/147 simd/simd_avx.c49
-rw-r--r--test cases/common/147 simd/simd_avx2.c42
-rw-r--r--test cases/common/147 simd/simd_mmx.c67
-rw-r--r--test cases/common/147 simd/simd_neon.c20
-rw-r--r--test cases/common/147 simd/simd_sse.c29
-rw-r--r--test cases/common/147 simd/simd_sse2.c36
-rw-r--r--test cases/common/147 simd/simd_sse3.c38
-rw-r--r--test cases/common/147 simd/simd_sse41.c40
-rw-r--r--test cases/common/147 simd/simd_sse42.c43
-rw-r--r--test cases/common/147 simd/simd_ssse3.c48
-rw-r--r--test cases/common/147 simd/simdchecker.c143
-rw-r--r--test cases/common/147 simd/simdfuncs.h75
-rw-r--r--test cases/common/148 shared module resolving symbol in executable/meson.build25
-rw-r--r--test cases/common/148 shared module resolving symbol in executable/module.c16
-rw-r--r--test cases/common/148 shared module resolving symbol in executable/prog.c61
-rw-r--r--test cases/common/149 dotinclude/dotproc.c10
-rw-r--r--test cases/common/149 dotinclude/meson.build4
-rw-r--r--test cases/common/149 dotinclude/stdio.h6
-rw-r--r--test cases/common/15 if/meson.build72
-rw-r--r--test cases/common/15 if/prog.c1
-rw-r--r--test cases/common/150 reserved targets/all/meson.build1
-rw-r--r--test cases/common/150 reserved targets/benchmark/meson.build1
-rw-r--r--test cases/common/150 reserved targets/clean-ctlist/meson.build1
-rw-r--r--test cases/common/150 reserved targets/clean-gcda/meson.build1
-rw-r--r--test cases/common/150 reserved targets/clean-gcno/meson.build1
-rw-r--r--test cases/common/150 reserved targets/clean/meson.build1
-rw-r--r--test cases/common/150 reserved targets/coverage-html/meson.build1
-rw-r--r--test cases/common/150 reserved targets/coverage-sonarqube/meson.build1
-rw-r--r--test cases/common/150 reserved targets/coverage-text/meson.build1
-rw-r--r--test cases/common/150 reserved targets/coverage-xml/meson.build1
-rw-r--r--test cases/common/150 reserved targets/coverage/meson.build1
-rw-r--r--test cases/common/150 reserved targets/dist/meson.build1
-rw-r--r--test cases/common/150 reserved targets/distcheck/meson.build1
-rw-r--r--test cases/common/150 reserved targets/install/meson.build1
-rw-r--r--test cases/common/150 reserved targets/meson.build34
-rw-r--r--test cases/common/150 reserved targets/phony/meson.build1
-rw-r--r--test cases/common/150 reserved targets/reconfigure/meson.build1
-rw-r--r--test cases/common/150 reserved targets/runtarget/echo.py6
-rw-r--r--test cases/common/150 reserved targets/runtarget/meson.build2
-rw-r--r--test cases/common/150 reserved targets/scan-build/meson.build1
-rw-r--r--test cases/common/150 reserved targets/test.c3
-rw-r--r--test cases/common/150 reserved targets/test/meson.build1
-rw-r--r--test cases/common/150 reserved targets/uninstall/meson.build1
-rw-r--r--test cases/common/151 duplicate source names/dir1/file.c16
-rw-r--r--test cases/common/151 duplicate source names/dir1/meson.build1
-rw-r--r--test cases/common/151 duplicate source names/dir2/dir1/file.c1
-rw-r--r--test cases/common/151 duplicate source names/dir2/file.c1
-rw-r--r--test cases/common/151 duplicate source names/dir2/meson.build1
-rw-r--r--test cases/common/151 duplicate source names/dir3/dir1/file.c1
-rw-r--r--test cases/common/151 duplicate source names/dir3/file.c1
-rw-r--r--test cases/common/151 duplicate source names/dir3/meson.build1
-rw-r--r--test cases/common/151 duplicate source names/meson.build19
-rw-r--r--test cases/common/152 index customtarget/check_args.py18
-rw-r--r--test cases/common/152 index customtarget/gen_sources.py49
-rw-r--r--test cases/common/152 index customtarget/lib.c20
-rw-r--r--test cases/common/152 index customtarget/meson.build80
-rw-r--r--test cases/common/152 index customtarget/subdir/foo.c22
-rw-r--r--test cases/common/152 index customtarget/subdir/meson.build19
-rw-r--r--test cases/common/153 wrap file should not failed/meson.build23
-rw-r--r--test cases/common/153 wrap file should not failed/src/meson.build6
-rw-r--r--test cases/common/153 wrap file should not failed/src/subprojects/foo/prog2.c7
-rw-r--r--test cases/common/153 wrap file should not failed/src/subprojects/prog.c7
-rw-r--r--test cases/common/153 wrap file should not failed/src/test.c9
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/.gitignore3
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/bar-1.0/bar.c3
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/bar-1.0/meson.build2
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/bar.wrap8
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/foo.c3
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/meson.build2
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/.meson-subproject-wrap-hash.txt1
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/foo.c7
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/meson.build2
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo-1.0/foo.c3
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo-1.0/meson.build2
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/foo.wrap11
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0-patch.tar.xzbin0 -> 244 bytes
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0.tar.xzbin0 -> 196 bytes
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8-8-wrap.zip1
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8.tar.gz1
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0-patch.tar.xzbin0 -> 244 bytes
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0.tar.xzbin0 -> 200 bytes
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/foo-1.0/meson.build2
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch33
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch21
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch21
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/patchdir.wrap9
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap14
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/foo.c3
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/meson.build2
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/zlib.wrap10
-rw-r--r--test cases/common/154 includedir subproj/meson.build9
-rw-r--r--test cases/common/154 includedir subproj/prog.c3
-rw-r--r--test cases/common/154 includedir subproj/subprojects/inctest/include/incfile.h2
-rw-r--r--test cases/common/154 includedir subproj/subprojects/inctest/meson.build13
-rw-r--r--test cases/common/155 subproject dir name collision/a.c13
-rw-r--r--test cases/common/155 subproject dir name collision/custom_subproject_dir/B/b.c20
-rw-r--r--test cases/common/155 subproject dir name collision/custom_subproject_dir/B/meson.build4
-rw-r--r--test cases/common/155 subproject dir name collision/custom_subproject_dir/C/c.c14
-rw-r--r--test cases/common/155 subproject dir name collision/custom_subproject_dir/C/meson.build3
-rw-r--r--test cases/common/155 subproject dir name collision/meson.build12
-rw-r--r--test cases/common/155 subproject dir name collision/other_subdir/custom_subproject_dir/other.c19
-rw-r--r--test cases/common/155 subproject dir name collision/other_subdir/meson.build1
-rw-r--r--test cases/common/156 config tool variable/meson.build31
-rw-r--r--test cases/common/157 custom target subdir depend files/copyfile.py6
-rw-r--r--test cases/common/157 custom target subdir depend files/meson.build7
-rw-r--r--test cases/common/157 custom target subdir depend files/subdir/dep.dat1
-rw-r--r--test cases/common/157 custom target subdir depend files/subdir/foo.c.in6
-rw-r--r--test cases/common/157 custom target subdir depend files/subdir/meson.build6
-rw-r--r--test cases/common/158 disabler/meson.build153
-rw-r--r--test cases/common/159 array option/meson.build17
-rw-r--r--test cases/common/159 array option/meson_options.txt19
-rw-r--r--test cases/common/16 comparison/meson.build146
-rw-r--r--test cases/common/16 comparison/prog.c1
-rw-r--r--test cases/common/160 custom target template substitution/checkcopy.py9
-rw-r--r--test cases/common/160 custom target template substitution/foo.c.in6
-rw-r--r--test cases/common/160 custom target template substitution/meson.build17
-rw-r--r--test cases/common/161 not-found dependency/meson.build14
-rw-r--r--test cases/common/161 not-found dependency/sub/meson.build1
-rw-r--r--test cases/common/161 not-found dependency/subprojects/trivial/meson.build3
-rw-r--r--test cases/common/161 not-found dependency/subprojects/trivial/trivial.c3
-rw-r--r--test cases/common/161 not-found dependency/testlib.c0
-rw-r--r--test cases/common/162 subdir if_found/meson.build11
-rw-r--r--test cases/common/162 subdir if_found/subdir/meson.build1
-rw-r--r--test cases/common/163 default options prefix dependent defaults/meson.build1
-rw-r--r--test cases/common/164 dependency factory/meson.build66
-rw-r--r--test cases/common/165 get project license/bar.c6
-rw-r--r--test cases/common/165 get project license/meson.build8
-rw-r--r--test cases/common/166 yield/meson.build7
-rw-r--r--test cases/common/166 yield/meson_options.txt3
-rw-r--r--test cases/common/166 yield/subprojects/sub/meson.build5
-rw-r--r--test cases/common/166 yield/subprojects/sub/meson_options.txt3
-rw-r--r--test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/a.c14
-rw-r--r--test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/meson.build4
-rw-r--r--test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/var/subprojects/wrap_files_might_be_here1
-rw-r--r--test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/b.c14
-rw-r--r--test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/meson.build4
-rw-r--r--test cases/common/167 subproject nested subproject dirs/meson.build11
-rw-r--r--test cases/common/167 subproject nested subproject dirs/prog.c5
-rw-r--r--test cases/common/168 preserve gendir/base.inp1
-rw-r--r--test cases/common/168 preserve gendir/com/mesonbuild/subbie.inp1
-rwxr-xr-xtest cases/common/168 preserve gendir/genprog.py46
-rw-r--r--test cases/common/168 preserve gendir/meson.build13
-rw-r--r--test cases/common/168 preserve gendir/testprog.c6
-rw-r--r--test cases/common/169 source in dep/bar.cpp5
-rw-r--r--test cases/common/169 source in dep/foo.c3
-rw-r--r--test cases/common/169 source in dep/generated/funname1
-rwxr-xr-xtest cases/common/169 source in dep/generated/genheader.py17
-rw-r--r--test cases/common/169 source in dep/generated/main.c5
-rw-r--r--test cases/common/169 source in dep/generated/meson.build12
-rw-r--r--test cases/common/169 source in dep/meson.build8
-rw-r--r--test cases/common/17 array/func.c1
-rw-r--r--test cases/common/17 array/meson.build8
-rw-r--r--test cases/common/17 array/prog.c3
-rw-r--r--test cases/common/170 generator link whole/export.h18
-rwxr-xr-xtest cases/common/170 generator link whole/generator.py30
-rw-r--r--test cases/common/170 generator link whole/main.c11
-rw-r--r--test cases/common/170 generator link whole/meson.build62
-rw-r--r--test cases/common/170 generator link whole/meson_test_function.tmpl0
-rw-r--r--test cases/common/170 generator link whole/pull_meson_test_function.c6
-rw-r--r--test cases/common/171 initial c_args/meson.build7
-rw-r--r--test cases/common/171 initial c_args/test.json8
-rw-r--r--test cases/common/172 identical target name in subproject flat layout/foo.c1
-rw-r--r--test cases/common/172 identical target name in subproject flat layout/main.c16
-rw-r--r--test cases/common/172 identical target name in subproject flat layout/meson.build15
-rw-r--r--test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/foo.c1
-rw-r--r--test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/meson.build3
-rw-r--r--test cases/common/173 as-needed/config.h14
-rw-r--r--test cases/common/173 as-needed/libA.cpp7
-rw-r--r--test cases/common/173 as-needed/libA.h5
-rw-r--r--test cases/common/173 as-needed/libB.cpp19
-rw-r--r--test cases/common/173 as-needed/main.cpp7
-rw-r--r--test cases/common/173 as-needed/meson.build13
-rw-r--r--test cases/common/174 ndebug if-release enabled/main.c15
-rw-r--r--test cases/common/174 ndebug if-release enabled/meson.build7
-rw-r--r--test cases/common/175 ndebug if-release disabled/main.c7
-rw-r--r--test cases/common/175 ndebug if-release disabled/meson.build7
-rw-r--r--test cases/common/176 subproject version/meson.build9
-rw-r--r--test cases/common/176 subproject version/subprojects/a/meson.build5
-rw-r--r--test cases/common/177 subdir_done/meson.build11
-rw-r--r--test cases/common/178 bothlibraries/dummy.py8
-rw-r--r--test cases/common/178 bothlibraries/foo.cpp11
-rw-r--r--test cases/common/178 bothlibraries/libfile.c7
-rw-r--r--test cases/common/178 bothlibraries/main.c8
-rw-r--r--test cases/common/178 bothlibraries/main2.c9
-rw-r--r--test cases/common/178 bothlibraries/meson.build62
-rw-r--r--test cases/common/178 bothlibraries/mylib.h13
-rw-r--r--test cases/common/179 escape and unicode/file.c.in5
-rw-r--r--test cases/common/179 escape and unicode/file.py10
-rw-r--r--test cases/common/179 escape and unicode/find.py9
-rw-r--r--test cases/common/179 escape and unicode/fun.c3
-rw-r--r--test cases/common/179 escape and unicode/main.c12
-rw-r--r--test cases/common/179 escape and unicode/meson.build38
-rw-r--r--test cases/common/18 includedir/include/func.h6
-rw-r--r--test cases/common/18 includedir/meson.build4
-rw-r--r--test cases/common/18 includedir/src/func.c5
-rw-r--r--test cases/common/18 includedir/src/meson.build5
-rw-r--r--test cases/common/18 includedir/src/prog.c5
-rw-r--r--test cases/common/180 has link arg/meson.build47
-rw-r--r--test cases/common/181 same target name flat layout/foo.c1
-rw-r--r--test cases/common/181 same target name flat layout/main.c16
-rw-r--r--test cases/common/181 same target name flat layout/meson.build15
-rw-r--r--test cases/common/181 same target name flat layout/subdir/foo.c1
-rw-r--r--test cases/common/181 same target name flat layout/subdir/meson.build1
-rw-r--r--test cases/common/182 find override/meson.build25
-rw-r--r--test cases/common/182 find override/otherdir/main.c5
-rw-r--r--test cases/common/182 find override/otherdir/main2.c5
-rw-r--r--test cases/common/182 find override/otherdir/meson.build30
-rw-r--r--test cases/common/182 find override/otherdir/source.desc1
-rw-r--r--test cases/common/182 find override/otherdir/source2.desc1
-rwxr-xr-xtest cases/common/182 find override/subdir/converter.py15
-rwxr-xr-xtest cases/common/182 find override/subdir/gencodegen.py.in15
-rw-r--r--test cases/common/182 find override/subdir/meson.build14
-rw-r--r--test cases/common/182 find override/subprojects/sub.wrap5
-rw-r--r--test cases/common/182 find override/subprojects/sub/meson.build4
-rw-r--r--test cases/common/183 partial dependency/declare_dependency/headers/foo.c16
-rw-r--r--test cases/common/183 partial dependency/declare_dependency/headers/foo.h16
-rw-r--r--test cases/common/183 partial dependency/declare_dependency/main.c25
-rw-r--r--test cases/common/183 partial dependency/declare_dependency/meson.build32
-rw-r--r--test cases/common/183 partial dependency/declare_dependency/other.c20
-rw-r--r--test cases/common/183 partial dependency/meson.build17
-rw-r--r--test cases/common/184 openmp/main.c16
-rw-r--r--test cases/common/184 openmp/main.cpp16
-rw-r--r--test cases/common/184 openmp/main.f909
-rw-r--r--test cases/common/184 openmp/meson.build58
-rw-r--r--test cases/common/185 same target name/file.c3
-rw-r--r--test cases/common/185 same target name/meson.build4
-rw-r--r--test cases/common/185 same target name/sub/file2.c3
-rw-r--r--test cases/common/185 same target name/sub/meson.build1
-rwxr-xr-xtest cases/common/186 test depends/gen.py13
-rw-r--r--test cases/common/186 test depends/main.c1
-rw-r--r--test cases/common/186 test depends/meson.build26
-rwxr-xr-xtest cases/common/186 test depends/test.py20
-rw-r--r--test cases/common/187 args flattening/meson.build25
-rw-r--r--test cases/common/188 dict/meson.build82
-rw-r--r--test cases/common/188 dict/prog.c8
-rw-r--r--test cases/common/189 check header/meson.build48
-rw-r--r--test cases/common/189 check header/ouagadougou.h1
-rw-r--r--test cases/common/19 header in file list/header.h1
-rw-r--r--test cases/common/19 header in file list/meson.build14
-rw-r--r--test cases/common/19 header in file list/prog.c3
-rw-r--r--test cases/common/190 install_mode/config.h.in5
-rw-r--r--test cases/common/190 install_mode/data_source.txt1
-rw-r--r--test cases/common/190 install_mode/foo.11
-rw-r--r--test cases/common/190 install_mode/meson.build60
-rw-r--r--test cases/common/190 install_mode/rootdir.h3
-rw-r--r--test cases/common/190 install_mode/runscript.sh3
-rw-r--r--test cases/common/190 install_mode/stat.c1
-rw-r--r--test cases/common/190 install_mode/sub1/second.dat1
-rw-r--r--test cases/common/190 install_mode/sub2/stub0
-rw-r--r--test cases/common/190 install_mode/test.json22
-rw-r--r--test cases/common/190 install_mode/trivial.c6
-rw-r--r--test cases/common/191 subproject array version/meson.build3
-rw-r--r--test cases/common/191 subproject array version/subprojects/foo/meson.build1
-rw-r--r--test cases/common/192 feature option/meson.build62
-rw-r--r--test cases/common/192 feature option/meson_options.txt3
-rw-r--r--test cases/common/193 feature option disabled/meson.build23
-rw-r--r--test cases/common/193 feature option disabled/meson_options.txt3
-rw-r--r--test cases/common/194 static threads/lib1.c13
-rw-r--r--test cases/common/194 static threads/lib2.c5
-rw-r--r--test cases/common/194 static threads/meson.build13
-rw-r--r--test cases/common/194 static threads/prog.c6
-rw-r--r--test cases/common/195 generator in subdir/com/mesonbuild/genprog.py46
-rw-r--r--test cases/common/195 generator in subdir/com/mesonbuild/meson.build10
-rw-r--r--test cases/common/195 generator in subdir/com/mesonbuild/subbie.inp1
-rw-r--r--test cases/common/195 generator in subdir/com/mesonbuild/testprog.c5
-rw-r--r--test cases/common/195 generator in subdir/meson.build3
-rw-r--r--test cases/common/196 subproject with features/meson.build17
-rw-r--r--test cases/common/196 subproject with features/meson_options.txt3
-rw-r--r--test cases/common/196 subproject with features/nothing.c4
-rw-r--r--test cases/common/196 subproject with features/subprojects/auto_sub_with_missing_dep/meson.build3
-rw-r--r--test cases/common/196 subproject with features/subprojects/disabled_sub/lib/meson.build3
-rw-r--r--test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.c5
-rw-r--r--test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.h6
-rw-r--r--test cases/common/196 subproject with features/subprojects/disabled_sub/meson.build3
-rw-r--r--test cases/common/196 subproject with features/subprojects/sub/lib/meson.build2
-rw-r--r--test cases/common/196 subproject with features/subprojects/sub/lib/sub.c5
-rw-r--r--test cases/common/196 subproject with features/subprojects/sub/lib/sub.h6
-rw-r--r--test cases/common/196 subproject with features/subprojects/sub/meson.build3
-rw-r--r--test cases/common/197 function attributes/meson.build119
-rw-r--r--test cases/common/197 function attributes/meson_options.txt7
-rw-r--r--test cases/common/197 function attributes/test.json10
-rw-r--r--test cases/common/198 broken subproject/meson.build2
-rw-r--r--test cases/common/198 broken subproject/subprojects/broken/broken.c1
-rw-r--r--test cases/common/198 broken subproject/subprojects/broken/meson.build4
-rw-r--r--test cases/common/199 argument syntax/meson.build19
-rw-r--r--test cases/common/2 cpp/VERSIONFILE1
-rw-r--r--test cases/common/2 cpp/cpp.C6
-rw-r--r--test cases/common/2 cpp/meson.build41
-rw-r--r--test cases/common/2 cpp/something.txt1
-rw-r--r--test cases/common/2 cpp/trivial.cc6
-rw-r--r--test cases/common/20 global arg/meson.build16
-rw-r--r--test cases/common/20 global arg/prog.c43
-rw-r--r--test cases/common/20 global arg/prog.cc15
-rw-r--r--test cases/common/200 install name_prefix name_suffix/libfile.c14
-rw-r--r--test cases/common/200 install name_prefix name_suffix/meson.build13
-rw-r--r--test cases/common/200 install name_prefix name_suffix/test.json19
-rw-r--r--test cases/common/201 kwarg entry/inc/prog.h3
-rw-r--r--test cases/common/201 kwarg entry/meson.build7
-rw-r--r--test cases/common/201 kwarg entry/prog.c7
-rw-r--r--test cases/common/201 kwarg entry/test.json6
-rw-r--r--test cases/common/202 custom target build by default/docgen.py12
-rw-r--r--test cases/common/202 custom target build by default/meson.build10
-rw-r--r--test cases/common/202 custom target build by default/test.json5
-rw-r--r--test cases/common/203 find_library and headers/foo.h1
-rw-r--r--test cases/common/203 find_library and headers/meson.build23
-rw-r--r--test cases/common/204 line continuation/meson.build17
-rw-r--r--test cases/common/205 native file path override/main.cpp5
-rw-r--r--test cases/common/205 native file path override/meson.build7
-rw-r--r--test cases/common/205 native file path override/nativefile.ini2
-rw-r--r--test cases/common/205 native file path override/test.json6
-rw-r--r--test cases/common/206 tap tests/cat.c26
-rw-r--r--test cases/common/206 tap tests/issue7515.txt27
-rw-r--r--test cases/common/206 tap tests/meson.build14
-rw-r--r--test cases/common/206 tap tests/tester.c10
-rw-r--r--test cases/common/207 warning level 0/main.cpp12
-rw-r--r--test cases/common/207 warning level 0/meson.build3
-rwxr-xr-xtest cases/common/208 link custom/custom_stlib.py81
-rw-r--r--test cases/common/208 link custom/custom_target.c6
-rw-r--r--test cases/common/208 link custom/custom_target.py6
-rw-r--r--test cases/common/208 link custom/dummy.c1
-rw-r--r--test cases/common/208 link custom/lib.c7
-rw-r--r--test cases/common/208 link custom/meson.build86
-rw-r--r--test cases/common/208 link custom/outerlib.c3
-rw-r--r--test cases/common/208 link custom/prog.c6
-rw-r--r--test cases/common/209 link custom_i single from multiple/generate_conflicting_stlibs.py90
-rw-r--r--test cases/common/209 link custom_i single from multiple/meson.build42
-rw-r--r--test cases/common/209 link custom_i single from multiple/prog.c5
-rw-r--r--test cases/common/21 target arg/func.c9
-rw-r--r--test cases/common/21 target arg/func2.c9
-rw-r--r--test cases/common/21 target arg/meson.build9
-rw-r--r--test cases/common/21 target arg/prog.cc13
-rw-r--r--test cases/common/21 target arg/prog2.cc13
-rw-r--r--test cases/common/210 link custom_i multiple from multiple/generate_stlibs.py92
-rw-r--r--test cases/common/210 link custom_i multiple from multiple/meson.build42
-rw-r--r--test cases/common/210 link custom_i multiple from multiple/prog.c8
-rw-r--r--test cases/common/211 dependency get_variable method/meson.build67
-rw-r--r--test cases/common/211 dependency get_variable method/test.json9
-rw-r--r--test cases/common/212 source set configuration_data/a.c8
-rw-r--r--test cases/common/212 source set configuration_data/all.h9
-rw-r--r--test cases/common/212 source set configuration_data/f.c7
-rw-r--r--test cases/common/212 source set configuration_data/g.c6
-rw-r--r--test cases/common/212 source set configuration_data/meson.build54
-rw-r--r--test cases/common/212 source set configuration_data/nope.c3
-rw-r--r--test cases/common/212 source set configuration_data/subdir/b.c13
-rw-r--r--test cases/common/212 source set configuration_data/subdir/meson.build1
-rw-r--r--test cases/common/213 source set dictionary/a.c8
-rw-r--r--test cases/common/213 source set dictionary/all.h9
-rw-r--r--test cases/common/213 source set dictionary/f.c7
-rw-r--r--test cases/common/213 source set dictionary/g.c6
-rw-r--r--test cases/common/213 source set dictionary/meson.build56
-rw-r--r--test cases/common/213 source set dictionary/nope.c3
-rw-r--r--test cases/common/213 source set dictionary/subdir/b.c13
-rw-r--r--test cases/common/213 source set dictionary/subdir/meson.build1
-rw-r--r--test cases/common/214 source set custom target/a.c7
-rw-r--r--test cases/common/214 source set custom target/all.h2
-rw-r--r--test cases/common/214 source set custom target/cp.py5
-rw-r--r--test cases/common/214 source set custom target/f.c5
-rw-r--r--test cases/common/214 source set custom target/g.c5
-rw-r--r--test cases/common/214 source set custom target/meson.build28
-rw-r--r--test cases/common/215 source set realistic example/boards/arm/aarch64.cc8
-rw-r--r--test cases/common/215 source set realistic example/boards/arm/arm.cc10
-rw-r--r--test cases/common/215 source set realistic example/boards/arm/arm.h12
-rw-r--r--test cases/common/215 source set realistic example/boards/arm/arm32.cc8
-rw-r--r--test cases/common/215 source set realistic example/boards/arm/versatilepb.cc16
-rw-r--r--test cases/common/215 source set realistic example/boards/arm/virt.cc16
-rw-r--r--test cases/common/215 source set realistic example/boards/arm/xlnx_zcu102.cc16
-rw-r--r--test cases/common/215 source set realistic example/boards/meson.build7
-rw-r--r--test cases/common/215 source set realistic example/boards/x86/pc.cc26
-rw-r--r--test cases/common/215 source set realistic example/common.h41
-rw-r--r--test cases/common/215 source set realistic example/config/aarch645
-rw-r--r--test cases/common/215 source set realistic example/config/arm3
-rw-r--r--test cases/common/215 source set realistic example/config/x864
-rw-r--r--test cases/common/215 source set realistic example/devices/meson.build3
-rw-r--r--test cases/common/215 source set realistic example/devices/virtio-mmio.cc16
-rw-r--r--test cases/common/215 source set realistic example/devices/virtio-pci.cc16
-rw-r--r--test cases/common/215 source set realistic example/devices/virtio.cc6
-rw-r--r--test cases/common/215 source set realistic example/devices/virtio.h10
-rw-r--r--test cases/common/215 source set realistic example/dummy.cpp0
-rw-r--r--test cases/common/215 source set realistic example/main.cc32
-rw-r--r--test cases/common/215 source set realistic example/meson.build53
-rw-r--r--test cases/common/215 source set realistic example/not-found.cc8
-rw-r--r--test cases/common/215 source set realistic example/was-found.cc7
-rw-r--r--test cases/common/215 source set realistic example/zlib.cc15
-rw-r--r--test cases/common/216 custom target input extracted objects/check_object.py17
-rw-r--r--test cases/common/216 custom target input extracted objects/libdir/gen.py6
-rw-r--r--test cases/common/216 custom target input extracted objects/libdir/meson.build21
-rw-r--r--test cases/common/216 custom target input extracted objects/libdir/source.c3
-rw-r--r--test cases/common/216 custom target input extracted objects/meson.build48
-rw-r--r--test cases/common/217 test priorities/meson.build22
-rw-r--r--test cases/common/217 test priorities/testprog.py5
-rw-r--r--test cases/common/218 include_dir dot/meson.build8
-rw-r--r--test cases/common/218 include_dir dot/rone.h1
-rw-r--r--test cases/common/218 include_dir dot/src/main.c5
-rw-r--r--test cases/common/218 include_dir dot/src/meson.build6
-rw-r--r--test cases/common/218 include_dir dot/src/rone.c3
-rw-r--r--test cases/common/219 include_type dependency/main.cpp8
-rw-r--r--test cases/common/219 include_type dependency/meson.build44
-rw-r--r--test cases/common/219 include_type dependency/pch/test.hpp1
-rw-r--r--test cases/common/219 include_type dependency/subprojects/subDep/meson.build3
-rw-r--r--test cases/common/22 object extraction/check-obj.py21
-rw-r--r--test cases/common/22 object extraction/create-source.py3
-rw-r--r--test cases/common/22 object extraction/header.h1
-rw-r--r--test cases/common/22 object extraction/lib.c3
-rw-r--r--test cases/common/22 object extraction/lib2.c3
-rw-r--r--test cases/common/22 object extraction/main.c5
-rw-r--r--test cases/common/22 object extraction/meson.build50
-rw-r--r--test cases/common/22 object extraction/src/lib.c3
-rw-r--r--test cases/common/220 fs module/meson.build144
-rw-r--r--test cases/common/220 fs module/subdir/meson.build6
-rw-r--r--test cases/common/220 fs module/subdir/subdirfile.txt1
-rw-r--r--test cases/common/220 fs module/subprojects/subbie/meson.build11
-rw-r--r--test cases/common/220 fs module/subprojects/subbie/subprojectfile.txt1
-rw-r--r--test cases/common/220 fs module/subprojects/subbie/subsub/meson.build3
-rw-r--r--test cases/common/220 fs module/subprojects/subbie/subsub/subsubfile.txt1
-rw-r--r--test cases/common/221 zlib/meson.build23
-rw-r--r--test cases/common/222 native prop/crossfile.ini4
-rw-r--r--test cases/common/222 native prop/meson.build49
-rw-r--r--test cases/common/222 native prop/nativefile.ini3
-rw-r--r--test cases/common/223 persubproject options/foo.c5
-rw-r--r--test cases/common/223 persubproject options/main.cpp3
-rw-r--r--test cases/common/223 persubproject options/meson.build20
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub1/foo.c8
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub1/meson.build10
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub2/foo.c9
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub2/foo.cpp10
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub2/meson.build16
-rw-r--r--test cases/common/223 persubproject options/test.json7
-rw-r--r--test cases/common/224 arithmetic operators/meson.build8
-rw-r--r--test cases/common/225 link language/c_linkage.cpp5
-rw-r--r--test cases/common/225 link language/c_linkage.h10
-rw-r--r--test cases/common/225 link language/lib.cpp5
-rw-r--r--test cases/common/225 link language/main.c5
-rw-r--r--test cases/common/225 link language/meson.build18
-rw-r--r--test cases/common/226 link depends indexed custom target/check_arch.py32
-rw-r--r--test cases/common/226 link depends indexed custom target/foo.c15
-rw-r--r--test cases/common/226 link depends indexed custom target/make_file.py8
-rw-r--r--test cases/common/226 link depends indexed custom target/meson.build20
-rwxr-xr-xtest cases/common/227 very long commmand line/codegen.py7
-rw-r--r--test cases/common/227 very long commmand line/main.c1
-rw-r--r--test cases/common/227 very long commmand line/meson.build49
-rwxr-xr-xtest cases/common/227 very long commmand line/name_gen.py23
-rw-r--r--test cases/common/228 custom_target source/a0
-rw-r--r--test cases/common/228 custom_target source/meson.build5
-rw-r--r--test cases/common/228 custom_target source/x.py5
-rw-r--r--test cases/common/229 disabler array addition/meson.build9
-rw-r--r--test cases/common/229 disabler array addition/test.c1
-rw-r--r--test cases/common/23 endian/meson.build7
-rw-r--r--test cases/common/23 endian/prog.c24
-rw-r--r--test cases/common/230 external project/app.c6
-rw-r--r--test cases/common/230 external project/func.c6
-rw-r--r--test cases/common/230 external project/func.h1
-rwxr-xr-xtest cases/common/230 external project/libfoo/configure44
-rw-r--r--test cases/common/230 external project/libfoo/libfoo.c8
-rw-r--r--test cases/common/230 external project/libfoo/libfoo.h3
-rw-r--r--test cases/common/230 external project/libfoo/meson.build23
-rw-r--r--test cases/common/230 external project/meson.build27
-rw-r--r--test cases/common/230 external project/test.json7
-rw-r--r--test cases/common/231 subdir files/meson.build3
-rw-r--r--test cases/common/231 subdir files/subdir/meson.build1
-rw-r--r--test cases/common/231 subdir files/subdir/prog.c1
-rw-r--r--test cases/common/232 dependency allow_fallback/meson.build12
-rw-r--r--test cases/common/232 dependency allow_fallback/subprojects/foob/meson.build2
-rw-r--r--test cases/common/232 dependency allow_fallback/subprojects/foob3/meson.build2
-rw-r--r--test cases/common/233 wrap case/meson.build6
-rw-r--r--test cases/common/233 wrap case/prog.c13
-rw-r--r--test cases/common/233 wrap case/subprojects/up_down.wrap5
-rw-r--r--test cases/common/233 wrap case/subprojects/up_down/meson.build3
-rw-r--r--test cases/common/233 wrap case/subprojects/up_down/up_down.h3
-rw-r--r--test cases/common/234 get_file_contents/.gitattributes1
-rw-r--r--test cases/common/234 get_file_contents/VERSION1
-rw-r--r--test cases/common/234 get_file_contents/meson.build21
-rw-r--r--test cases/common/234 get_file_contents/other/meson.build3
-rw-r--r--test cases/common/234 get_file_contents/utf-16-textbin0 -> 150 bytes
-rw-r--r--test cases/common/235 invalid standard overriden to valid/main.c3
-rw-r--r--test cases/common/235 invalid standard overriden to valid/meson.build8
-rw-r--r--test cases/common/235 invalid standard overriden to valid/test.json9
-rw-r--r--test cases/common/236 proper args splitting/main.c11
-rw-r--r--test cases/common/236 proper args splitting/meson.build9
-rw-r--r--test cases/common/236 proper args splitting/test.json9
-rw-r--r--test cases/common/237 fstrings/meson.build7
-rw-r--r--test cases/common/238 dependency include_type inconsistency/bar/meson.build5
-rw-r--r--test cases/common/238 dependency include_type inconsistency/meson.build5
-rw-r--r--test cases/common/238 dependency include_type inconsistency/subprojects/baz.wrap3
-rw-r--r--test cases/common/238 dependency include_type inconsistency/subprojects/baz/meson.build3
-rw-r--r--test cases/common/238 dependency include_type inconsistency/subprojects/foo.wrap3
-rw-r--r--test cases/common/238 dependency include_type inconsistency/subprojects/foo/meson.build9
-rw-r--r--test cases/common/239 includedir violation/meson.build11
-rw-r--r--test cases/common/239 includedir violation/subprojects/sub/include/placeholder.h3
-rw-r--r--test cases/common/239 includedir violation/subprojects/sub/meson.build3
-rw-r--r--test cases/common/239 includedir violation/test.json9
-rw-r--r--test cases/common/24 library versions/lib.c14
-rw-r--r--test cases/common/24 library versions/meson.build9
-rw-r--r--test cases/common/24 library versions/subdir/meson.build8
-rw-r--r--test cases/common/24 library versions/test.json7
-rw-r--r--test cases/common/240 dependency native host == build/meson.build18
-rw-r--r--test cases/common/240 dependency native host == build/test.json14
-rw-r--r--test cases/common/241 set and get variable/meson.build71
-rw-r--r--test cases/common/241 set and get variable/test1.txt0
-rw-r--r--test cases/common/241 set and get variable/test2.txt0
-rw-r--r--test cases/common/242 custom target feed/data_source.txt1
-rw-r--r--test cases/common/242 custom target feed/meson.build24
-rwxr-xr-xtest cases/common/242 custom target feed/my_compiler.py14
-rw-r--r--test cases/common/242 custom target feed/test.json5
-rw-r--r--test cases/common/243 escape++/meson.build4
-rw-r--r--test cases/common/243 escape++/test.c3
-rw-r--r--test cases/common/244 variable scope/meson.build15
-rw-r--r--test cases/common/245 custom target index source/code_source.c6
-rw-r--r--test cases/common/245 custom target index source/copyfile.py6
-rw-r--r--test cases/common/245 custom target index source/copyfile2.py7
-rw-r--r--test cases/common/245 custom target index source/header_source.h1
-rw-r--r--test cases/common/245 custom target index source/main.c8
-rw-r--r--test cases/common/245 custom target index source/meson.build51
-rw-r--r--test cases/common/246 dependency fallbacks/meson.build10
-rw-r--r--test cases/common/246 dependency fallbacks/subprojects/png/meson.build3
-rw-r--r--test cases/common/247 deprecated option/meson.build20
-rw-r--r--test cases/common/247 deprecated option/meson_options.txt23
-rw-r--r--test cases/common/247 deprecated option/test.json29
-rw-r--r--test cases/common/248 install_emptydir/meson.build4
-rw-r--r--test cases/common/248 install_emptydir/test.json7
-rw-r--r--test cases/common/249 install_symlink/datafile.dat1
-rw-r--r--test cases/common/249 install_symlink/meson.build9
-rw-r--r--test cases/common/249 install_symlink/test.json7
-rw-r--r--test cases/common/25 config subdir/include/config.h.in6
-rw-r--r--test cases/common/25 config subdir/include/meson.build4
-rw-r--r--test cases/common/25 config subdir/meson.build6
-rw-r--r--test cases/common/25 config subdir/src/meson.build2
-rw-r--r--test cases/common/25 config subdir/src/prog.c5
-rw-r--r--test cases/common/250 system include dir/lib/lib.hpp4
-rw-r--r--test cases/common/250 system include dir/main.cpp3
-rw-r--r--test cases/common/250 system include dir/meson.build13
-rw-r--r--test cases/common/251 add_project_dependencies/inc/lib.h2
-rw-r--r--test cases/common/251 add_project_dependencies/lib.c14
-rw-r--r--test cases/common/251 add_project_dependencies/main.c5
-rw-r--r--test cases/common/251 add_project_dependencies/meson.build22
-rw-r--r--test cases/common/252 install data structured/dir1/bad0
-rw-r--r--test cases/common/252 install data structured/dir1/file10
-rw-r--r--test cases/common/252 install data structured/dir1/file20
-rw-r--r--test cases/common/252 install data structured/dir1/file30
-rw-r--r--test cases/common/252 install data structured/dir2/bad0
-rw-r--r--test cases/common/252 install data structured/dir2/file10
-rw-r--r--test cases/common/252 install data structured/dir2/file20
-rw-r--r--test cases/common/252 install data structured/dir2/file30
-rw-r--r--test cases/common/252 install data structured/dir3/bad0
-rw-r--r--test cases/common/252 install data structured/dir3/file10
-rw-r--r--test cases/common/252 install data structured/dir3/file20
-rw-r--r--test cases/common/252 install data structured/dir3/file30
-rw-r--r--test cases/common/252 install data structured/meson.build16
-rw-r--r--test cases/common/252 install data structured/pysrc/__init__.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/bad.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/bar.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/foo.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/meson.build11
-rw-r--r--test cases/common/252 install data structured/pysrc/submod/__init__.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/submod/bad.py1
-rw-r--r--test cases/common/252 install data structured/pysrc/submod/baz.py1
-rw-r--r--test cases/common/252 install data structured/test.json18
-rw-r--r--test cases/common/253 subproject dependency variables/meson.build18
-rw-r--r--test cases/common/253 subproject dependency variables/subprojects/subfiles/foo.c1
-rw-r--r--test cases/common/253 subproject dependency variables/subprojects/subfiles/meson.build29
-rw-r--r--test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir/foo.c1
-rw-r--r--test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir2/foo.c1
-rw-r--r--test cases/common/253 subproject dependency variables/test.json8
-rw-r--r--test cases/common/254 long output/dumper.c17
-rw-r--r--test cases/common/254 long output/meson.build5
-rw-r--r--test cases/common/255 module warnings/meson.build9
-rw-r--r--test cases/common/255 module warnings/test.json16
-rw-r--r--test cases/common/256 subproject extracted objects/foo.c11
-rw-r--r--test cases/common/256 subproject extracted objects/meson.build5
-rw-r--r--test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.cpp6
-rw-r--r--test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.h12
-rw-r--r--test cases/common/256 subproject extracted objects/subprojects/myobjects/meson.build3
-rw-r--r--test cases/common/256 subproject extracted objects/test.json5
-rw-r--r--test cases/common/257 generated header dep/foo.c1
-rw-r--r--test cases/common/257 generated header dep/meson.build22
-rw-r--r--test cases/common/258 subsubproject inplace/meson.build3
-rw-r--r--test cases/common/258 subsubproject inplace/subprojects/sub/meson.build3
-rw-r--r--test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub-1.0/meson.build1
-rw-r--r--test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub.wrap2
-rw-r--r--test cases/common/258 subsubproject inplace/subprojects/subsub.wrap2
-rw-r--r--test cases/common/259 preprocess/bar.c3
-rw-r--r--test cases/common/259 preprocess/foo.c1
-rw-r--r--test cases/common/259 preprocess/foo.h2
-rw-r--r--test cases/common/259 preprocess/meson.build15
-rw-r--r--test cases/common/259 preprocess/src/file.map.in3
-rw-r--r--test cases/common/259 preprocess/src/meson.build3
-rw-r--r--test cases/common/26 find program/meson.build39
-rw-r--r--test cases/common/26 find program/print-version-with-prefix.py8
-rw-r--r--test cases/common/26 find program/print-version.py8
-rw-r--r--test cases/common/26 find program/scripts/test_subdir.py3
-rw-r--r--test cases/common/26 find program/source.in3
-rw-r--r--test cases/common/27 multiline string/meson.build37
-rw-r--r--test cases/common/28 try compile/invalid.c2
-rw-r--r--test cases/common/28 try compile/meson.build27
-rw-r--r--test cases/common/28 try compile/valid.c2
-rw-r--r--test cases/common/29 compiler id/meson.build15
-rw-r--r--test cases/common/3 static/libfile.c3
-rw-r--r--test cases/common/3 static/libfile2.c3
-rw-r--r--test cases/common/3 static/meson.build14
-rw-r--r--test cases/common/3 static/meson_options.txt1
-rw-r--r--test cases/common/30 sizeof/config.h.in2
-rw-r--r--test cases/common/30 sizeof/meson.build33
-rw-r--r--test cases/common/30 sizeof/prog.c.in15
-rw-r--r--test cases/common/31 define10/config.h.in2
-rw-r--r--test cases/common/31 define10/meson.build12
-rw-r--r--test cases/common/31 define10/prog.c13
-rw-r--r--test cases/common/32 has header/meson.build54
-rw-r--r--test cases/common/32 has header/ouagadougou.h1
-rw-r--r--test cases/common/33 run program/check-env.py5
-rw-r--r--test cases/common/33 run program/get-version.py3
-rw-r--r--test cases/common/33 run program/meson.build85
-rw-r--r--test cases/common/33 run program/scripts/hello.bat2
-rwxr-xr-xtest cases/common/33 run program/scripts/hello.sh3
-rw-r--r--test cases/common/34 logic ops/meson.build95
-rw-r--r--test cases/common/35 string operations/meson.build127
-rw-r--r--test cases/common/36 has function/meson.build116
-rw-r--r--test cases/common/37 has member/meson.build21
-rw-r--r--test cases/common/38 alignment/meson.build31
-rw-r--r--test cases/common/39 library chain/main.c5
-rw-r--r--test cases/common/39 library chain/meson.build5
-rw-r--r--test cases/common/39 library chain/subdir/lib1.c17
-rw-r--r--test cases/common/39 library chain/subdir/meson.build4
-rw-r--r--test cases/common/39 library chain/subdir/subdir2/lib2.c14
-rw-r--r--test cases/common/39 library chain/subdir/subdir2/meson.build1
-rw-r--r--test cases/common/39 library chain/subdir/subdir3/lib3.c14
-rw-r--r--test cases/common/39 library chain/subdir/subdir3/meson.build1
-rw-r--r--test cases/common/39 library chain/test.json6
-rw-r--r--test cases/common/4 shared/libfile.c14
-rw-r--r--test cases/common/4 shared/meson.build13
-rw-r--r--test cases/common/40 options/meson.build45
-rw-r--r--test cases/common/40 options/meson_options.txt9
-rw-r--r--test cases/common/41 test args/cmd_args.c18
-rw-r--r--test cases/common/41 test args/copyfile.py6
-rw-r--r--test cases/common/41 test args/env2vars.c23
-rw-r--r--test cases/common/41 test args/envvars.c23
-rw-r--r--test cases/common/41 test args/meson.build35
-rw-r--r--test cases/common/41 test args/tester.c34
-rwxr-xr-xtest cases/common/41 test args/tester.py11
-rw-r--r--test cases/common/41 test args/testfile.txt1
-rw-r--r--test cases/common/42 subproject/meson.build28
-rw-r--r--test cases/common/42 subproject/subprojects/sublib/include/subdefs.h21
-rw-r--r--test cases/common/42 subproject/subprojects/sublib/meson.build19
-rw-r--r--test cases/common/42 subproject/subprojects/sublib/simpletest.c5
-rw-r--r--test cases/common/42 subproject/subprojects/sublib/sublib.c5
-rw-r--r--test cases/common/42 subproject/test.json7
-rw-r--r--test cases/common/42 subproject/user.c16
-rw-r--r--test cases/common/43 subproject options/meson.build7
-rw-r--r--test cases/common/43 subproject options/meson_options.txt1
-rw-r--r--test cases/common/43 subproject options/subprojects/subproject/meson.build5
-rw-r--r--test cases/common/43 subproject options/subprojects/subproject/meson_options.txt1
-rw-r--r--test cases/common/44 pkgconfig-gen/answer.c3
-rw-r--r--test cases/common/44 pkgconfig-gen/dependencies/custom.c3
-rw-r--r--test cases/common/44 pkgconfig-gen/dependencies/dummy.c3
-rw-r--r--test cases/common/44 pkgconfig-gen/dependencies/exposed.c3
-rw-r--r--test cases/common/44 pkgconfig-gen/dependencies/internal.c3
-rw-r--r--test cases/common/44 pkgconfig-gen/dependencies/main.c10
-rw-r--r--test cases/common/44 pkgconfig-gen/dependencies/meson.build62
-rw-r--r--test cases/common/44 pkgconfig-gen/foo.c7
-rw-r--r--test cases/common/44 pkgconfig-gen/meson.build178
-rw-r--r--test cases/common/44 pkgconfig-gen/simple.c5
-rw-r--r--test cases/common/44 pkgconfig-gen/simple.h6
-rw-r--r--test cases/common/44 pkgconfig-gen/simple5.c6
-rw-r--r--test cases/common/44 pkgconfig-gen/test.json33
-rw-r--r--test cases/common/45 custom install dirs/datafile.cat1
-rw-r--r--test cases/common/45 custom install dirs/meson.build11
-rw-r--r--test cases/common/45 custom install dirs/prog.11
-rw-r--r--test cases/common/45 custom install dirs/prog.c3
-rw-r--r--test cases/common/45 custom install dirs/sample.h6
-rw-r--r--test cases/common/45 custom install dirs/subdir/datafile.dog1
-rw-r--r--test cases/common/45 custom install dirs/test.json16
-rw-r--r--test cases/common/46 subproject subproject/meson.build11
-rw-r--r--test cases/common/46 subproject subproject/prog.c5
-rw-r--r--test cases/common/46 subproject subproject/subprojects/a/a.c14
-rw-r--r--test cases/common/46 subproject subproject/subprojects/a/meson.build4
-rw-r--r--test cases/common/46 subproject subproject/subprojects/b/b.c14
-rw-r--r--test cases/common/46 subproject subproject/subprojects/b/meson.build3
-rw-r--r--test cases/common/46 subproject subproject/subprojects/c/meson.build3
-rw-r--r--test cases/common/47 same file name/d1/file.c1
-rw-r--r--test cases/common/47 same file name/d2/file.c1
-rw-r--r--test cases/common/47 same file name/meson.build3
-rw-r--r--test cases/common/47 same file name/prog.c6
-rw-r--r--test cases/common/48 file grabber/a.c1
-rw-r--r--test cases/common/48 file grabber/b.c1
-rw-r--r--test cases/common/48 file grabber/c.c1
-rw-r--r--test cases/common/48 file grabber/grabber.bat5
-rwxr-xr-xtest cases/common/48 file grabber/grabber.sh5
-rw-r--r--test cases/common/48 file grabber/grabber2.bat5
-rw-r--r--test cases/common/48 file grabber/meson.build35
-rw-r--r--test cases/common/48 file grabber/prog.c7
-rw-r--r--test cases/common/48 file grabber/subdir/meson.build5
-rw-r--r--test cases/common/48 file grabber/subdir/suba.c1
-rw-r--r--test cases/common/48 file grabber/subdir/subb.c1
-rw-r--r--test cases/common/48 file grabber/subdir/subc.c1
-rw-r--r--test cases/common/48 file grabber/subdir/subprog.c7
-rw-r--r--test cases/common/49 custom target/data_source.txt1
-rwxr-xr-xtest cases/common/49 custom target/depfile/dep.py15
-rw-r--r--test cases/common/49 custom target/depfile/meson.build7
-rw-r--r--test cases/common/49 custom target/meson.build73
-rwxr-xr-xtest cases/common/49 custom target/my_compiler.py22
-rw-r--r--test cases/common/49 custom target/test.json5
-rw-r--r--test cases/common/5 linkstatic/libfile.c3
-rw-r--r--test cases/common/5 linkstatic/libfile2.c3
-rw-r--r--test cases/common/5 linkstatic/libfile3.c3
-rw-r--r--test cases/common/5 linkstatic/libfile4.c3
-rw-r--r--test cases/common/5 linkstatic/main.c5
-rw-r--r--test cases/common/5 linkstatic/meson.build6
-rw-r--r--test cases/common/50 custom target chain/data_source.txt1
-rw-r--r--test cases/common/50 custom target chain/meson.build34
-rwxr-xr-xtest cases/common/50 custom target chain/my_compiler.py15
-rwxr-xr-xtest cases/common/50 custom target chain/my_compiler2.py15
-rw-r--r--test cases/common/50 custom target chain/test.json6
-rw-r--r--test cases/common/50 custom target chain/usetarget/meson.build8
-rw-r--r--test cases/common/50 custom target chain/usetarget/myexe.c6
-rwxr-xr-xtest cases/common/50 custom target chain/usetarget/subcomp.py7
-rw-r--r--test cases/common/51 run target/.clang-format1
-rw-r--r--test cases/common/51 run target/.clang-tidy0
-rw-r--r--test cases/common/51 run target/check-env.py28
-rwxr-xr-xtest cases/common/51 run target/check_exists.py7
-rwxr-xr-xtest cases/common/51 run target/configure.in3
-rw-r--r--test cases/common/51 run target/converter.py6
-rwxr-xr-xtest cases/common/51 run target/fakeburner.py15
-rw-r--r--test cases/common/51 run target/helloprinter.c11
-rw-r--r--test cases/common/51 run target/meson.build112
-rw-r--r--test cases/common/51 run target/subdir/textprinter.py3
-rw-r--r--test cases/common/52 object generator/meson.build34
-rwxr-xr-xtest cases/common/52 object generator/obj_generator.py18
-rw-r--r--test cases/common/52 object generator/prog.c7
-rw-r--r--test cases/common/52 object generator/source.c3
-rw-r--r--test cases/common/52 object generator/source2.c3
-rw-r--r--test cases/common/52 object generator/source3.c3
-rwxr-xr-xtest cases/common/53 install script/customtarget.py19
-rw-r--r--test cases/common/53 install script/meson.build45
-rwxr-xr-xtest cases/common/53 install script/myinstall.py31
-rw-r--r--test cases/common/53 install script/prog.c14
-rw-r--r--test cases/common/53 install script/src/a file.txt0
-rw-r--r--test cases/common/53 install script/src/foo.c10
-rw-r--r--test cases/common/53 install script/src/meson.build5
-rw-r--r--test cases/common/53 install script/src/myinstall.py14
-rw-r--r--test cases/common/53 install script/test.json15
-rwxr-xr-xtest cases/common/54 custom target source output/generator.py16
-rw-r--r--test cases/common/54 custom target source output/main.c5
-rw-r--r--test cases/common/54 custom target source output/meson.build9
-rw-r--r--test cases/common/55 exe static shared/meson.build15
-rw-r--r--test cases/common/55 exe static shared/prog.c10
-rw-r--r--test cases/common/55 exe static shared/shlib2.c8
-rw-r--r--test cases/common/55 exe static shared/stat.c7
-rw-r--r--test cases/common/55 exe static shared/stat2.c3
-rw-r--r--test cases/common/55 exe static shared/subdir/exports.h12
-rw-r--r--test cases/common/55 exe static shared/subdir/meson.build1
-rw-r--r--test cases/common/55 exe static shared/subdir/shlib.c5
-rw-r--r--test cases/common/56 array methods/a.txt0
-rw-r--r--test cases/common/56 array methods/b.txt0
-rw-r--r--test cases/common/56 array methods/c.txt0
-rw-r--r--test cases/common/56 array methods/meson.build70
-rw-r--r--test cases/common/57 custom header generator/input.def1
-rw-r--r--test cases/common/57 custom header generator/makeheader.py12
-rw-r--r--test cases/common/57 custom header generator/meson.build21
-rw-r--r--test cases/common/57 custom header generator/prog.c5
-rw-r--r--test cases/common/57 custom header generator/somefile.txt0
-rw-r--r--test cases/common/58 multiple generators/data2.dat1
-rw-r--r--test cases/common/58 multiple generators/main.cpp6
-rw-r--r--test cases/common/58 multiple generators/meson.build13
-rwxr-xr-xtest cases/common/58 multiple generators/mygen.py22
-rw-r--r--test cases/common/58 multiple generators/subdir/data.dat1
-rw-r--r--test cases/common/58 multiple generators/subdir/meson.build4
-rw-r--r--test cases/common/59 install subdir/meson.build21
-rw-r--r--test cases/common/59 install subdir/nested_elided/sub/dircheck/ninth.dat1
-rw-r--r--test cases/common/59 install subdir/nested_elided/sub/eighth.dat1
-rw-r--r--test cases/common/59 install subdir/sub/sub1/third.dat1
-rw-r--r--test cases/common/59 install subdir/sub1/second.dat1
-rw-r--r--test cases/common/59 install subdir/sub2/dircheck/excluded-three.dat0
-rw-r--r--test cases/common/59 install subdir/sub2/excluded-three.dat0
-rw-r--r--test cases/common/59 install subdir/sub2/excluded/two.dat0
-rw-r--r--test cases/common/59 install subdir/sub2/one.dat0
-rw-r--r--test cases/common/59 install subdir/sub_elided/dircheck/fifth.dat1
-rw-r--r--test cases/common/59 install subdir/sub_elided/fourth.dat1
-rw-r--r--test cases/common/59 install subdir/subdir/meson.build5
-rw-r--r--test cases/common/59 install subdir/subdir/sub1/data1.dat1
-rw-r--r--test cases/common/59 install subdir/subdir/sub1/sub2/data2.dat1
-rw-r--r--test cases/common/59 install subdir/subdir/sub_elided/dircheck/seventh.dat1
-rw-r--r--test cases/common/59 install subdir/subdir/sub_elided/sixth.dat1
-rw-r--r--test cases/common/59 install subdir/test.json17
-rw-r--r--test cases/common/6 linkshared/cpplib.cpp6
-rw-r--r--test cases/common/6 linkshared/cpplib.h12
-rw-r--r--test cases/common/6 linkshared/cppmain.cpp5
-rw-r--r--test cases/common/6 linkshared/libfile.c14
-rw-r--r--test cases/common/6 linkshared/main.c11
-rw-r--r--test cases/common/6 linkshared/meson.build12
-rw-r--r--test cases/common/6 linkshared/test.json6
-rw-r--r--test cases/common/60 foreach/meson.build53
-rw-r--r--test cases/common/60 foreach/prog1.c6
-rw-r--r--test cases/common/60 foreach/prog2.c6
-rw-r--r--test cases/common/60 foreach/prog3.c6
-rw-r--r--test cases/common/60 foreach/test.json10
-rw-r--r--test cases/common/61 number arithmetic/meson.build76
-rw-r--r--test cases/common/62 string arithmetic/meson.build49
-rw-r--r--test cases/common/62 string arithmetic/test.json7
-rw-r--r--test cases/common/63 array arithmetic/meson.build15
-rw-r--r--test cases/common/64 arithmetic bidmas/meson.build15
-rw-r--r--test cases/common/65 build always/main.c7
-rw-r--r--test cases/common/65 build always/meson.build14
-rw-r--r--test cases/common/65 build always/version.c.in3
-rw-r--r--test cases/common/65 build always/version.h3
-rwxr-xr-xtest cases/common/65 build always/version_gen.py29
-rw-r--r--test cases/common/66 vcstag/meson.build42
-rw-r--r--test cases/common/66 vcstag/tagprog.c8
-rw-r--r--test cases/common/66 vcstag/vcstag.c.in1
-rwxr-xr-xtest cases/common/66 vcstag/version.py3
-rw-r--r--test cases/common/67 modules/meson.build14
-rw-r--r--test cases/common/67 modules/meson_options.txt6
-rw-r--r--test cases/common/68 should fail/failing.c3
-rw-r--r--test cases/common/68 should fail/meson.build4
-rw-r--r--test cases/common/69 configure file in custom target/inc/confdata.in1
-rw-r--r--test cases/common/69 configure file in custom target/inc/meson.build6
-rw-r--r--test cases/common/69 configure file in custom target/meson.build4
-rw-r--r--test cases/common/69 configure file in custom target/src/meson.build20
-rw-r--r--test cases/common/69 configure file in custom target/src/mycompiler.py9
-rw-r--r--test cases/common/7 mixed/func.c4
-rw-r--r--test cases/common/7 mixed/main.cc7
-rw-r--r--test cases/common/7 mixed/meson.build3
-rw-r--r--test cases/common/70 external test program/meson.build3
-rwxr-xr-xtest cases/common/70 external test program/mytest.py10
-rwxr-xr-xtest cases/common/71 ctarget dependency/gen1.py12
-rwxr-xr-xtest cases/common/71 ctarget dependency/gen2.py10
-rw-r--r--test cases/common/71 ctarget dependency/input.dat1
-rw-r--r--test cases/common/71 ctarget dependency/meson.build20
-rw-r--r--test cases/common/72 shared subproject/a.c13
-rw-r--r--test cases/common/72 shared subproject/meson.build10
-rw-r--r--test cases/common/72 shared subproject/subprojects/B/b.c21
-rw-r--r--test cases/common/72 shared subproject/subprojects/B/meson.build4
-rw-r--r--test cases/common/72 shared subproject/subprojects/C/c.c14
-rw-r--r--test cases/common/72 shared subproject/subprojects/C/meson.build3
-rw-r--r--test cases/common/73 shared subproject 2/a.c13
-rw-r--r--test cases/common/73 shared subproject 2/meson.build13
-rw-r--r--test cases/common/73 shared subproject 2/subprojects/B/b.c20
-rw-r--r--test cases/common/73 shared subproject 2/subprojects/B/meson.build4
-rw-r--r--test cases/common/73 shared subproject 2/subprojects/C/c.c14
-rw-r--r--test cases/common/73 shared subproject 2/subprojects/C/meson.build3
-rw-r--r--test cases/common/74 file object/lib.c3
-rw-r--r--test cases/common/74 file object/meson.build8
-rw-r--r--test cases/common/74 file object/prog.c13
-rw-r--r--test cases/common/74 file object/subdir1/lib.c3
-rw-r--r--test cases/common/74 file object/subdir1/meson.build7
-rw-r--r--test cases/common/74 file object/subdir1/prog.c13
-rw-r--r--test cases/common/74 file object/subdir2/lib.c3
-rw-r--r--test cases/common/74 file object/subdir2/meson.build7
-rw-r--r--test cases/common/74 file object/subdir2/prog.c13
-rw-r--r--test cases/common/75 custom subproject dir/a.c13
-rw-r--r--test cases/common/75 custom subproject dir/custom_subproject_dir/B/b.c20
-rw-r--r--test cases/common/75 custom subproject dir/custom_subproject_dir/B/meson.build4
-rw-r--r--test cases/common/75 custom subproject dir/custom_subproject_dir/C/c.c14
-rw-r--r--test cases/common/75 custom subproject dir/custom_subproject_dir/C/meson.build3
-rw-r--r--test cases/common/75 custom subproject dir/meson.build10
-rw-r--r--test cases/common/76 has type/meson.build13
-rw-r--r--test cases/common/77 extract from nested subdir/meson.build8
-rw-r--r--test cases/common/77 extract from nested subdir/src/first/lib_first.c3
-rw-r--r--test cases/common/77 extract from nested subdir/src/first/meson.build1
-rw-r--r--test cases/common/77 extract from nested subdir/src/meson.build1
-rw-r--r--test cases/common/77 extract from nested subdir/tst/first/exe_first.c5
-rw-r--r--test cases/common/77 extract from nested subdir/tst/first/meson.build4
-rw-r--r--test cases/common/77 extract from nested subdir/tst/meson.build1
-rw-r--r--test cases/common/78 internal dependency/meson.build4
-rw-r--r--test cases/common/78 internal dependency/proj1/include/proj1.h5
-rw-r--r--test cases/common/78 internal dependency/proj1/meson.build11
-rw-r--r--test cases/common/78 internal dependency/proj1/proj1f1.c6
-rw-r--r--test cases/common/78 internal dependency/proj1/proj1f2.c6
-rw-r--r--test cases/common/78 internal dependency/proj1/proj1f3.c6
-rw-r--r--test cases/common/78 internal dependency/src/main.c10
-rw-r--r--test cases/common/78 internal dependency/src/meson.build2
-rw-r--r--test cases/common/79 same basename/exe1.c5
-rw-r--r--test cases/common/79 same basename/exe2.c5
-rw-r--r--test cases/common/79 same basename/lib.c22
-rw-r--r--test cases/common/79 same basename/meson.build14
-rw-r--r--test cases/common/79 same basename/sharedsub/meson.build1
-rw-r--r--test cases/common/79 same basename/staticsub/meson.build3
-rwxr-xr-xtest cases/common/8 install/gendir.py8
-rw-r--r--test cases/common/8 install/meson.build10
-rw-r--r--test cases/common/8 install/prog.c3
-rw-r--r--test cases/common/8 install/stat.c1
-rw-r--r--test cases/common/8 install/test.json9
-rw-r--r--test cases/common/80 declare dep/entity/entity.h4
-rw-r--r--test cases/common/80 declare dep/entity/entity1.c9
-rw-r--r--test cases/common/80 declare dep/entity/entity2.c5
-rw-r--r--test cases/common/80 declare dep/entity/meson.build10
-rw-r--r--test cases/common/80 declare dep/main.c18
-rw-r--r--test cases/common/80 declare dep/meson.build24
-rw-r--r--test cases/common/81 extract all/extractor.h6
-rw-r--r--test cases/common/81 extract all/four.c5
-rw-r--r--test cases/common/81 extract all/meson.build13
-rw-r--r--test cases/common/81 extract all/one.c5
-rw-r--r--test cases/common/81 extract all/prog.c10
-rw-r--r--test cases/common/81 extract all/three.c5
-rw-r--r--test cases/common/81 extract all/two.c5
-rw-r--r--test cases/common/82 add language/meson.build10
-rw-r--r--test cases/common/82 add language/prog.c6
-rw-r--r--test cases/common/82 add language/prog.cc6
-rw-r--r--test cases/common/83 identical target name in subproject/bar.c6
-rw-r--r--test cases/common/83 identical target name in subproject/meson.build9
-rw-r--r--test cases/common/83 identical target name in subproject/subprojects/foo/bar.c6
-rw-r--r--test cases/common/83 identical target name in subproject/subprojects/foo/meson.build7
-rw-r--r--test cases/common/83 identical target name in subproject/subprojects/foo/true.py4
-rw-r--r--test cases/common/83 identical target name in subproject/true.py4
-rw-r--r--test cases/common/84 plusassign/meson.build70
-rw-r--r--test cases/common/85 skip subdir/meson.build3
-rw-r--r--test cases/common/85 skip subdir/subdir1/meson.build1
-rw-r--r--test cases/common/85 skip subdir/subdir1/subdir2/meson.build1
-rw-r--r--test cases/common/86 private include/meson.build4
-rwxr-xr-xtest cases/common/86 private include/stlib/compiler.py32
-rw-r--r--test cases/common/86 private include/stlib/foo1.def0
-rw-r--r--test cases/common/86 private include/stlib/foo2.def0
-rw-r--r--test cases/common/86 private include/stlib/meson.build12
-rw-r--r--test cases/common/86 private include/user/libuser.c6
-rw-r--r--test cases/common/86 private include/user/meson.build5
-rw-r--r--test cases/common/87 default options/meson.build33
-rw-r--r--test cases/common/87 default options/subprojects/sub1/meson.build3
-rw-r--r--test cases/common/87 default options/subprojects/sub1/meson_options.txt1
-rw-r--r--test cases/common/88 dep fallback/gensrc.py6
-rw-r--r--test cases/common/88 dep fallback/meson.build38
-rw-r--r--test cases/common/88 dep fallback/subprojects/boblib/bob.c8
-rw-r--r--test cases/common/88 dep fallback/subprojects/boblib/bob.h6
-rw-r--r--test cases/common/88 dep fallback/subprojects/boblib/genbob.py6
-rw-r--r--test cases/common/88 dep fallback/subprojects/boblib/meson.build18
-rw-r--r--test cases/common/88 dep fallback/subprojects/dummylib/meson.build4
-rw-r--r--test cases/common/88 dep fallback/tester.c14
-rw-r--r--test cases/common/89 default library/ef.cpp8
-rw-r--r--test cases/common/89 default library/ef.h22
-rw-r--r--test cases/common/89 default library/eftest.cpp14
-rw-r--r--test cases/common/89 default library/meson.build10
-rw-r--r--test cases/common/9 header install/child/childdir.h3
-rw-r--r--test cases/common/9 header install/meson.build12
-rw-r--r--test cases/common/9 header install/rootdir.h3
-rw-r--r--test cases/common/9 header install/sub/fileheader.h3
-rw-r--r--test cases/common/9 header install/sub/meson.build1
-rw-r--r--test cases/common/9 header install/subdir.h3
-rw-r--r--test cases/common/9 header install/test.json10
-rw-r--r--test cases/common/9 header install/vanishing_subdir/meson.build1
-rw-r--r--test cases/common/9 header install/vanishing_subdir/vanished.h5
-rw-r--r--test cases/common/90 gen extra/meson.build40
-rw-r--r--test cases/common/90 gen extra/name.dat1
-rw-r--r--test cases/common/90 gen extra/name.l3
-rw-r--r--test cases/common/90 gen extra/plain.c5
-rwxr-xr-xtest cases/common/90 gen extra/srcgen.py27
-rw-r--r--test cases/common/90 gen extra/srcgen2.py32
-rw-r--r--test cases/common/90 gen extra/srcgen3.py15
-rw-r--r--test cases/common/90 gen extra/upper.c5
-rw-r--r--test cases/common/91 benchmark/delayer.c20
-rw-r--r--test cases/common/91 benchmark/meson.build4
-rw-r--r--test cases/common/92 test workdir/meson.build8
-rw-r--r--test cases/common/92 test workdir/opener.c12
-rwxr-xr-xtest cases/common/92 test workdir/subdir/checker.py5
-rw-r--r--test cases/common/92 test workdir/subdir/meson.build4
-rw-r--r--test cases/common/93 suites/exe1.c6
-rw-r--r--test cases/common/93 suites/exe2.c6
-rw-r--r--test cases/common/93 suites/meson.build9
-rw-r--r--test cases/common/93 suites/subprojects/sub/meson.build7
-rw-r--r--test cases/common/93 suites/subprojects/sub/sub1.c6
-rw-r--r--test cases/common/93 suites/subprojects/sub/sub2.c6
-rw-r--r--test cases/common/94 threads/meson.build21
-rw-r--r--test cases/common/94 threads/threadprog.c46
-rw-r--r--test cases/common/94 threads/threadprog.cpp43
-rw-r--r--test cases/common/95 manygen/depuser.c8
-rw-r--r--test cases/common/95 manygen/meson.build14
-rw-r--r--test cases/common/95 manygen/subdir/funcinfo.def1
-rwxr-xr-xtest cases/common/95 manygen/subdir/manygen.py82
-rw-r--r--test cases/common/95 manygen/subdir/meson.build26
-rw-r--r--test cases/common/96 stringdef/meson.build3
-rw-r--r--test cases/common/96 stringdef/stringdef.c10
-rw-r--r--test cases/common/97 find program path/meson.build22
-rwxr-xr-xtest cases/common/97 find program path/program.py3
-rw-r--r--test cases/common/98 subproject subdir/meson.build94
-rw-r--r--test cases/common/98 subproject subdir/prog.c5
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub/lib/meson.build3
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub/lib/sub.c5
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub/lib/sub.h6
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub/meson.build2
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_implicit.wrap6
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_implicit/meson.build13
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_implicit/meson_options.txt1
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/foo.h1
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/meson.build7
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/packagefiles/subsubsub-1.0.zipbin0 -> 455 bytes
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/subsubsub.wrap4
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_novar/meson.build4
-rw-r--r--test cases/common/98 subproject subdir/subprojects/sub_static/meson.build8
-rw-r--r--test cases/common/98 subproject subdir/test.json5
-rw-r--r--test cases/common/99 postconf/meson.build5
-rw-r--r--test cases/common/99 postconf/postconf.py16
-rw-r--r--test cases/common/99 postconf/prog.c5
-rw-r--r--test cases/common/99 postconf/raw.dat1
-rw-r--r--test cases/csharp/1 basic/meson.build4
-rw-r--r--test cases/csharp/1 basic/prog.cs8
-rw-r--r--test cases/csharp/1 basic/test.json6
-rw-r--r--test cases/csharp/1 basic/text.cs7
-rw-r--r--test cases/csharp/2 library/helper.cs7
-rw-r--r--test cases/csharp/2 library/meson.build15
-rw-r--r--test cases/csharp/2 library/prog.cs8
-rw-r--r--test cases/csharp/2 library/test.json9
-rw-r--r--test cases/csharp/3 resource/TestRes.resx31
-rw-r--r--test cases/csharp/3 resource/meson.build6
-rw-r--r--test cases/csharp/3 resource/resprog.cs13
-rw-r--r--test cases/csharp/4 external dep/hello.txt1
-rw-r--r--test cases/csharp/4 external dep/meson.build9
-rw-r--r--test cases/csharp/4 external dep/prog.cs8
-rw-r--r--test cases/csharp/4 external dep/test.json5
-rw-r--r--test cases/cuda/1 simple/meson.build4
-rw-r--r--test cases/cuda/1 simple/prog.cu29
-rw-r--r--test cases/cuda/10 cuda dependency/c/meson.build2
-rw-r--r--test cases/cuda/10 cuda dependency/c/prog.c19
-rw-r--r--test cases/cuda/10 cuda dependency/cpp/meson.build2
-rw-r--r--test cases/cuda/10 cuda dependency/cpp/prog.cc19
-rw-r--r--test cases/cuda/10 cuda dependency/meson.build6
-rw-r--r--test cases/cuda/10 cuda dependency/modules/meson.build2
-rw-r--r--test cases/cuda/10 cuda dependency/modules/prog.cc33
-rw-r--r--test cases/cuda/10 cuda dependency/version_reqs/meson.build2
-rw-r--r--test cases/cuda/10 cuda dependency/version_reqs/prog.cc28
-rw-r--r--test cases/cuda/11 cuda dependency (nvcc)/meson.build4
-rw-r--r--test cases/cuda/11 cuda dependency (nvcc)/modules/meson.build2
-rw-r--r--test cases/cuda/11 cuda dependency (nvcc)/modules/prog.cu33
-rw-r--r--test cases/cuda/11 cuda dependency (nvcc)/version_reqs/meson.build2
-rw-r--r--test cases/cuda/11 cuda dependency (nvcc)/version_reqs/prog.cu29
-rw-r--r--test cases/cuda/12 cuda dependency (mixed)/kernel.cu8
-rw-r--r--test cases/cuda/12 cuda dependency (mixed)/meson.build4
-rw-r--r--test cases/cuda/12 cuda dependency (mixed)/prog.cpp37
-rw-r--r--test cases/cuda/13 cuda compiler setting/meson.build4
-rw-r--r--test cases/cuda/13 cuda compiler setting/nativefile.ini3
-rw-r--r--test cases/cuda/13 cuda compiler setting/prog.cu29
-rw-r--r--test cases/cuda/14 cuda has header symbol/meson.build26
-rw-r--r--test cases/cuda/15 sanitizer/meson.build4
-rw-r--r--test cases/cuda/15 sanitizer/prog.cu29
-rw-r--r--test cases/cuda/16 multistd/lib.cu3
-rw-r--r--test cases/cuda/16 multistd/main.cu21
-rw-r--r--test cases/cuda/16 multistd/meson.build13
-rw-r--r--test cases/cuda/2 split/lib.cu12
-rw-r--r--test cases/cuda/2 split/main.cpp7
-rw-r--r--test cases/cuda/2 split/meson.build6
-rw-r--r--test cases/cuda/2 split/static/lib.cu12
-rw-r--r--test cases/cuda/2 split/static/libsta.cu12
-rw-r--r--test cases/cuda/2 split/static/main_static.cpp7
-rw-r--r--test cases/cuda/2 split/static/meson.build4
-rw-r--r--test cases/cuda/3 cudamodule/meson.build69
-rw-r--r--test cases/cuda/3 cudamodule/prog.cu29
-rw-r--r--test cases/cuda/4 shared/main.cu20
-rw-r--r--test cases/cuda/4 shared/meson.build6
-rw-r--r--test cases/cuda/4 shared/shared/kernels.cu13
-rw-r--r--test cases/cuda/4 shared/shared/kernels.h86
-rw-r--r--test cases/cuda/4 shared/shared/meson.build7
-rw-r--r--test cases/cuda/5 threads/main.cu20
-rw-r--r--test cases/cuda/5 threads/meson.build7
-rw-r--r--test cases/cuda/5 threads/shared/kernels.cu13
-rw-r--r--test cases/cuda/5 threads/shared/kernels.h86
-rw-r--r--test cases/cuda/5 threads/shared/meson.build5
-rw-r--r--test cases/cuda/6 std/main.cu20
-rw-r--r--test cases/cuda/6 std/meson.build4
-rw-r--r--test cases/cuda/7 static vs runtime/main.cu20
-rw-r--r--test cases/cuda/7 static vs runtime/meson.build4
-rw-r--r--test cases/cuda/8 release/main.cu24
-rw-r--r--test cases/cuda/8 release/meson.build10
-rw-r--r--test cases/cuda/9 optimize for space/main.cu20
-rw-r--r--test cases/cuda/9 optimize for space/meson.build4
-rwxr-xr-xtest cases/cython/1 basic/cytest.py19
-rw-r--r--test cases/cython/1 basic/libdir/cstorer.pxd9
-rw-r--r--test cases/cython/1 basic/libdir/meson.build8
-rw-r--r--test cases/cython/1 basic/libdir/storer.c24
-rw-r--r--test cases/cython/1 basic/libdir/storer.h16
-rw-r--r--test cases/cython/1 basic/libdir/storer.pyx16
-rw-r--r--test cases/cython/1 basic/meson.build20
-rw-r--r--test cases/cython/1 basic/test.json10
-rw-r--r--test cases/cython/2 generated sources/configure.pyx.in2
-rw-r--r--test cases/cython/2 generated sources/g.in2
-rw-r--r--test cases/cython/2 generated sources/gen.py14
-rwxr-xr-xtest cases/cython/2 generated sources/generator.py12
-rw-r--r--test cases/cython/2 generated sources/includestuff.pyx1
-rw-r--r--test cases/cython/2 generated sources/libdir/gen.py14
-rw-r--r--test cases/cython/2 generated sources/libdir/meson.build10
-rw-r--r--test cases/cython/2 generated sources/meson.build105
-rw-r--r--test cases/cython/2 generated sources/simpleinclude.pyx1
-rw-r--r--test cases/cython/2 generated sources/simplestuff.pxi2
-rw-r--r--test cases/cython/2 generated sources/stuff.pxi.in2
-rw-r--r--test cases/cython/2 generated sources/test.py13
-rw-r--r--test cases/cython/3 cython_args/cythonargs.pyx5
-rw-r--r--test cases/cython/3 cython_args/meson.build30
-rw-r--r--test cases/cython/3 cython_args/test.py3
-rw-r--r--test cases/d/1 simple/app.d8
-rw-r--r--test cases/d/1 simple/meson.build4
-rw-r--r--test cases/d/1 simple/test.json6
-rw-r--r--test cases/d/1 simple/utils.d8
-rw-r--r--test cases/d/10 d cpp/cppmain.cpp18
-rw-r--r--test cases/d/10 d cpp/dmain.d5
-rw-r--r--test cases/d/10 d cpp/libfile.cpp5
-rw-r--r--test cases/d/10 d cpp/libfile.d5
-rw-r--r--test cases/d/10 d cpp/meson.build13
-rw-r--r--test cases/d/11 dub/.gitignore1
-rw-r--r--test cases/d/11 dub/meson.build23
-rw-r--r--test cases/d/11 dub/test.d14
-rw-r--r--test cases/d/12 root include directory/meson.build7
-rw-r--r--test cases/d/12 root include directory/some/dlang/code.d7
-rw-r--r--test cases/d/12 root include directory/some/dlang/meson.build8
-rw-r--r--test cases/d/12 root include directory/some/meson.build1
-rw-r--r--test cases/d/13 declare dep/meson.build13
-rw-r--r--test cases/d/13 declare dep/test.d15
-rw-r--r--test cases/d/13 declare dep/views/test.txt1
-rw-r--r--test cases/d/14 dub with deps/meson.build34
-rw-r--r--test cases/d/14 dub with deps/test.d59
-rw-r--r--test cases/d/15 compiler run checks/meson.build50
-rw-r--r--test cases/d/15 compiler run checks/test_sizeof.d17
-rw-r--r--test cases/d/16 code generation/exe.d9
-rw-r--r--test cases/d/16 code generation/generator.d13
-rw-r--r--test cases/d/16 code generation/input.txt1
-rw-r--r--test cases/d/16 code generation/meson.build18
-rw-r--r--test cases/d/2 static library/app.d8
-rw-r--r--test cases/d/2 static library/libstuff.d9
-rw-r--r--test cases/d/2 static library/meson.build5
-rw-r--r--test cases/d/2 static library/test.json7
-rw-r--r--test cases/d/3 shared library/app.d8
-rw-r--r--test cases/d/3 shared library/libstuff.d14
-rw-r--r--test cases/d/3 shared library/libstuff.di3
-rw-r--r--test cases/d/3 shared library/lld-test.py20
-rw-r--r--test cases/d/3 shared library/meson.build26
-rw-r--r--test cases/d/3 shared library/sub/libstuff.d14
-rw-r--r--test cases/d/3 shared library/sub/meson.build1
-rw-r--r--test cases/d/3 shared library/test.json11
-rw-r--r--test cases/d/4 library versions/lib.d16
-rw-r--r--test cases/d/4 library versions/meson.build25
-rw-r--r--test cases/d/4 library versions/test.json25
-rw-r--r--test cases/d/5 mixed/app.d8
-rw-r--r--test cases/d/5 mixed/libstuff.c18
-rw-r--r--test cases/d/5 mixed/meson.build9
-rw-r--r--test cases/d/5 mixed/test.json13
-rw-r--r--test cases/d/6 unittest/app.d38
-rw-r--r--test cases/d/6 unittest/meson.build8
-rw-r--r--test cases/d/6 unittest/second_unit.d10
-rw-r--r--test cases/d/6 unittest/test.json6
-rw-r--r--test cases/d/7 multilib/app.d9
-rw-r--r--test cases/d/7 multilib/meson.build24
-rw-r--r--test cases/d/7 multilib/say1.d15
-rw-r--r--test cases/d/7 multilib/say1.di1
-rw-r--r--test cases/d/7 multilib/say2.d15
-rw-r--r--test cases/d/7 multilib/say2.di1
-rw-r--r--test cases/d/7 multilib/test.json18
-rw-r--r--test cases/d/8 has multi arguments/meson.build8
-rw-r--r--test cases/d/9 features/app.d82
-rw-r--r--test cases/d/9 features/data/food.txt6
-rw-r--r--test cases/d/9 features/data/people.txt5
-rw-r--r--test cases/d/9 features/extra.d9
-rw-r--r--test cases/d/9 features/meson.build106
-rw-r--r--test cases/failing build/1 vala c werror/meson.build10
-rw-r--r--test cases/failing build/1 vala c werror/prog.vala7
-rw-r--r--test cases/failing build/1 vala c werror/unused-var.c8
-rw-r--r--test cases/failing build/2 hidden symbol/bob.c5
-rw-r--r--test cases/failing build/2 hidden symbol/bob.h3
-rw-r--r--test cases/failing build/2 hidden symbol/bobuser.c5
-rw-r--r--test cases/failing build/2 hidden symbol/meson.build11
-rw-r--r--test cases/failing build/3 pch disabled/c/meson.build2
-rw-r--r--test cases/failing build/3 pch disabled/c/pch/prog.h1
-rw-r--r--test cases/failing build/3 pch disabled/c/pch/prog_pch.c5
-rw-r--r--test cases/failing build/3 pch disabled/c/prog.c9
-rw-r--r--test cases/failing build/3 pch disabled/meson.build5
-rw-r--r--test cases/failing build/4 cmake subproject isolation/incDir/fileA.hpp3
-rw-r--r--test cases/failing build/4 cmake subproject isolation/main.cpp10
-rw-r--r--test cases/failing build/4 cmake subproject isolation/meson.build17
-rw-r--r--test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/CMakeLists.txt10
-rw-r--r--test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.cpp12
-rw-r--r--test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.hpp14
-rw-r--r--test cases/failing build/4 cmake subproject isolation/test.json5
-rw-r--r--test cases/failing build/5 failed pickled/false.py4
-rw-r--r--test cases/failing build/5 failed pickled/meson.build7
-rw-r--r--test cases/failing test/1 trivial/main.c3
-rw-r--r--test cases/failing test/1 trivial/meson.build3
-rw-r--r--test cases/failing test/2 signal/main.c6
-rw-r--r--test cases/failing test/2 signal/meson.build7
-rw-r--r--test cases/failing test/3 ambiguous/main.c6
-rw-r--r--test cases/failing test/3 ambiguous/meson.build10
-rwxr-xr-xtest cases/failing test/3 ambiguous/test_runner.sh7
-rw-r--r--test cases/failing test/4 hard error/main.c3
-rw-r--r--test cases/failing test/4 hard error/meson.build4
-rw-r--r--test cases/failing test/5 tap tests/meson.build9
-rw-r--r--test cases/failing test/5 tap tests/tester.c10
-rw-r--r--test cases/failing test/5 tap tests/tester_with_status.c8
-rw-r--r--test cases/failing test/6 xpass/meson.build4
-rw-r--r--test cases/failing test/6 xpass/xpass.c1
-rw-r--r--test cases/failing/1 project not first/meson.build4
-rw-r--r--test cases/failing/1 project not first/prog.c1
-rw-r--r--test cases/failing/1 project not first/test.json7
-rw-r--r--test cases/failing/10 out of bounds/meson.build4
-rw-r--r--test cases/failing/10 out of bounds/test.json7
-rw-r--r--test cases/failing/100 no glib-compile-resources/meson.build8
-rw-r--r--test cases/failing/100 no glib-compile-resources/test.json7
-rw-r--r--test cases/failing/100 no glib-compile-resources/trivial.gresource.xml3
-rw-r--r--test cases/failing/101 number in combo/meson.build1
-rw-r--r--test cases/failing/101 number in combo/nativefile.ini2
-rw-r--r--test cases/failing/101 number in combo/test.json5
-rw-r--r--test cases/failing/102 bool in combo/meson.build1
-rw-r--r--test cases/failing/102 bool in combo/meson_options.txt5
-rw-r--r--test cases/failing/102 bool in combo/nativefile.ini2
-rw-r--r--test cases/failing/102 bool in combo/test.json5
-rw-r--r--test cases/failing/103 compiler no lang/meson.build2
-rw-r--r--test cases/failing/103 compiler no lang/test.json7
-rw-r--r--test cases/failing/104 no fallback/meson.build2
-rw-r--r--test cases/failing/104 no fallback/subprojects/foob/meson.build2
-rw-r--r--test cases/failing/104 no fallback/test.json8
-rw-r--r--test cases/failing/105 feature require/meson.build2
-rw-r--r--test cases/failing/105 feature require/meson_options.txt1
-rw-r--r--test cases/failing/105 feature require/test.json8
-rw-r--r--test cases/failing/106 feature require.bis/meson.build2
-rw-r--r--test cases/failing/106 feature require.bis/meson_options.txt1
-rw-r--r--test cases/failing/106 feature require.bis/test.json8
-rw-r--r--test cases/failing/107 no build get_external_property/meson.build3
-rw-r--r--test cases/failing/107 no build get_external_property/test.json7
-rw-r--r--test cases/failing/108 enter subdir twice/meson.build3
-rw-r--r--test cases/failing/108 enter subdir twice/sub/meson.build1
-rw-r--r--test cases/failing/108 enter subdir twice/test.json7
-rw-r--r--test cases/failing/109 invalid fstring/109 invalid fstring/meson.build4
-rw-r--r--test cases/failing/109 invalid fstring/109 invalid fstring/test.json7
-rw-r--r--test cases/failing/109 invalid fstring/meson.build3
-rw-r--r--test cases/failing/109 invalid fstring/test.json7
-rw-r--r--test cases/failing/11 object arithmetic/meson.build3
-rw-r--r--test cases/failing/11 object arithmetic/test.json8
-rw-r--r--test cases/failing/110 compiler argument checking/meson.build4
-rw-r--r--test cases/failing/110 compiler argument checking/test.json7
-rw-r--r--test cases/failing/111 empty fallback/meson.build6
-rw-r--r--test cases/failing/111 empty fallback/subprojects/foo/meson.build3
-rw-r--r--test cases/failing/111 empty fallback/test.json8
-rw-r--r--test cases/failing/112 cmake executable dependency/meson.build9
-rw-r--r--test cases/failing/112 cmake executable dependency/subprojects/cmlib/CMakeLists.txt5
-rw-r--r--test cases/failing/112 cmake executable dependency/subprojects/cmlib/main.c3
-rw-r--r--test cases/failing/112 cmake executable dependency/test.json10
-rw-r--r--test cases/failing/113 allow_fallback with fallback/meson.build3
-rw-r--r--test cases/failing/113 allow_fallback with fallback/test.json8
-rw-r--r--test cases/failing/114 nonsensical bindgen/meson.build20
-rw-r--r--test cases/failing/114 nonsensical bindgen/src/header.h8
-rw-r--r--test cases/failing/114 nonsensical bindgen/src/source.c8
-rw-r--r--test cases/failing/114 nonsensical bindgen/test.json8
-rw-r--r--test cases/failing/115 run_target in test/meson.build7
-rw-r--r--test cases/failing/115 run_target in test/test.json8
-rw-r--r--test cases/failing/115 run_target in test/trivial.c6
-rw-r--r--test cases/failing/116 run_target in add_install_script/meson.build7
-rw-r--r--test cases/failing/116 run_target in add_install_script/test.json8
-rw-r--r--test cases/failing/116 run_target in add_install_script/trivial.c11
-rw-r--r--test cases/failing/117 pathsep in install_symlink/meson.build3
-rw-r--r--test cases/failing/117 pathsep in install_symlink/test.json7
-rw-r--r--test cases/failing/118 subproject version conflict/meson.build4
-rw-r--r--test cases/failing/118 subproject version conflict/subprojects/A/meson.build4
-rw-r--r--test cases/failing/118 subproject version conflict/subprojects/B/meson.build3
-rw-r--r--test cases/failing/118 subproject version conflict/test.json7
-rw-r--r--test cases/failing/119 structured source empty string/main.rs0
-rw-r--r--test cases/failing/119 structured source empty string/meson.build13
-rw-r--r--test cases/failing/119 structured source empty string/test.json7
-rw-r--r--test cases/failing/12 string arithmetic/meson.build3
-rw-r--r--test cases/failing/12 string arithmetic/test.json7
-rw-r--r--test cases/failing/120 structured_sources conflicts/main.rs0
-rw-r--r--test cases/failing/120 structured_sources conflicts/meson.build17
-rw-r--r--test cases/failing/120 structured_sources conflicts/test.json7
-rw-r--r--test cases/failing/121 missing compiler/meson.build3
-rw-r--r--test cases/failing/121 missing compiler/subprojects/sub/main.c1
-rw-r--r--test cases/failing/121 missing compiler/subprojects/sub/meson.build4
-rw-r--r--test cases/failing/121 missing compiler/test.json7
-rw-r--r--test cases/failing/122 cmake subproject error/meson.build8
-rw-r--r--test cases/failing/122 cmake subproject error/subprojects/cmlib/CMakeLists.txt5
-rw-r--r--test cases/failing/122 cmake subproject error/test.json10
-rw-r--r--test cases/failing/123 pkgconfig not relocatable outside prefix/meson.build22
-rw-r--r--test cases/failing/123 pkgconfig not relocatable outside prefix/test.json8
-rw-r--r--test cases/failing/124 subproject sandbox violation/meson.build34
-rw-r--r--test cases/failing/124 subproject sandbox violation/meson_options.txt1
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj1/file.txt0
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj1/meson.build4
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj1/nested/meson.build5
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj2/file.txt0
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj2/meson.build7
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj2/nested/meson.build0
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj3/file.txt0
-rw-r--r--test cases/failing/124 subproject sandbox violation/subprojects/subproj3/meson.build3
-rw-r--r--test cases/failing/124 subproject sandbox violation/test.json16
-rw-r--r--test cases/failing/125 override and add_project_dependency/inc/lib.h2
-rw-r--r--test cases/failing/125 override and add_project_dependency/lib.c3
-rw-r--r--test cases/failing/125 override and add_project_dependency/meson.build8
-rw-r--r--test cases/failing/125 override and add_project_dependency/subprojects/a/meson.build10
-rw-r--r--test cases/failing/125 override and add_project_dependency/subprojects/a/prog.c6
-rw-r--r--test cases/failing/125 override and add_project_dependency/test.json7
-rw-r--r--test cases/failing/126 targets before add_project_dependency/inc/lib.h2
-rw-r--r--test cases/failing/126 targets before add_project_dependency/lib.c3
-rw-r--r--test cases/failing/126 targets before add_project_dependency/meson.build5
-rw-r--r--test cases/failing/126 targets before add_project_dependency/test.json7
-rw-r--r--test cases/failing/127 extract from unity/meson.build4
-rw-r--r--test cases/failing/127 extract from unity/src1.c3
-rw-r--r--test cases/failing/127 extract from unity/src2.c3
-rw-r--r--test cases/failing/127 extract from unity/test.json7
-rw-r--r--test cases/failing/128 subproject object as a dependency/main.c1
-rw-r--r--test cases/failing/128 subproject object as a dependency/meson.build4
-rw-r--r--test cases/failing/128 subproject object as a dependency/subprojects/sub/meson.build1
-rw-r--r--test cases/failing/128 subproject object as a dependency/test.json7
-rw-r--r--test cases/failing/129 generator host binary/exe.c1
-rw-r--r--test cases/failing/129 generator host binary/lib.in1
-rw-r--r--test cases/failing/129 generator host binary/meson.build14
-rw-r--r--test cases/failing/129 generator host binary/test.json5
-rw-r--r--test cases/failing/13 array arithmetic/meson.build3
-rw-r--r--test cases/failing/13 array arithmetic/test.json7
-rw-r--r--test cases/failing/14 invalid option name/meson.build1
-rw-r--r--test cases/failing/14 invalid option name/meson_options.txt1
-rw-r--r--test cases/failing/14 invalid option name/test.json7
-rw-r--r--test cases/failing/15 kwarg before arg/meson.build3
-rw-r--r--test cases/failing/15 kwarg before arg/prog.c1
-rw-r--r--test cases/failing/15 kwarg before arg/test.json7
-rw-r--r--test cases/failing/16 extract from subproject/main.c5
-rw-r--r--test cases/failing/16 extract from subproject/meson.build9
-rw-r--r--test cases/failing/16 extract from subproject/subprojects/sub_project/meson.build3
-rw-r--r--test cases/failing/16 extract from subproject/subprojects/sub_project/sub_lib.c3
-rw-r--r--test cases/failing/16 extract from subproject/test.json7
-rw-r--r--test cases/failing/17 same target/file.c1
-rw-r--r--test cases/failing/17 same target/meson.build4
-rw-r--r--test cases/failing/17 same target/test.json7
-rw-r--r--test cases/failing/18 wrong plusassign/meson.build3
-rw-r--r--test cases/failing/18 wrong plusassign/test.json7
-rw-r--r--test cases/failing/19 target clash/clash.c6
-rw-r--r--test cases/failing/19 target clash/meson.build15
-rw-r--r--test cases/failing/19 target clash/test.json7
-rw-r--r--test cases/failing/2 missing file/meson.build3
-rw-r--r--test cases/failing/2 missing file/test.json7
-rw-r--r--test cases/failing/20 version/meson.build1
-rw-r--r--test cases/failing/20 version/test.json8
-rw-r--r--test cases/failing/21 subver/meson.build3
-rw-r--r--test cases/failing/21 subver/subprojects/foo/meson.build1
-rw-r--r--test cases/failing/21 subver/test.json7
-rw-r--r--test cases/failing/22 assert/meson.build3
-rw-r--r--test cases/failing/22 assert/test.json7
-rw-r--r--test cases/failing/23 rel testdir/meson.build4
-rw-r--r--test cases/failing/23 rel testdir/simple.c3
-rw-r--r--test cases/failing/23 rel testdir/test.json7
-rw-r--r--test cases/failing/24 int conversion/meson.build3
-rw-r--r--test cases/failing/24 int conversion/test.json7
-rw-r--r--test cases/failing/25 badlang/meson.build3
-rw-r--r--test cases/failing/25 badlang/test.json7
-rw-r--r--test cases/failing/26 output subdir/foo.in1
-rw-r--r--test cases/failing/26 output subdir/meson.build5
-rw-r--r--test cases/failing/26 output subdir/subdir/dummy.txt1
-rw-r--r--test cases/failing/26 output subdir/test.json7
-rw-r--r--test cases/failing/27 noprog use/meson.build9
-rw-r--r--test cases/failing/27 noprog use/test.json7
-rw-r--r--test cases/failing/28 no crossprop/meson.build3
-rw-r--r--test cases/failing/28 no crossprop/test.json7
-rw-r--r--test cases/failing/29 nested ternary/meson.build3
-rw-r--r--test cases/failing/29 nested ternary/test.json7
-rw-r--r--test cases/failing/3 missing subdir/meson.build3
-rw-r--r--test cases/failing/3 missing subdir/test.json9
-rw-r--r--test cases/failing/30 invalid man extension/foo.a10
-rw-r--r--test cases/failing/30 invalid man extension/meson.build2
-rw-r--r--test cases/failing/30 invalid man extension/test.json7
-rw-r--r--test cases/failing/31 no man extension/foo0
-rw-r--r--test cases/failing/31 no man extension/meson.build2
-rw-r--r--test cases/failing/31 no man extension/test.json7
-rw-r--r--test cases/failing/32 exe static shared/meson.build11
-rw-r--r--test cases/failing/32 exe static shared/prog.c10
-rw-r--r--test cases/failing/32 exe static shared/shlib2.c16
-rw-r--r--test cases/failing/32 exe static shared/stat.c3
-rw-r--r--test cases/failing/32 exe static shared/test.json7
-rw-r--r--test cases/failing/33 non-root subproject/meson.build3
-rw-r--r--test cases/failing/33 non-root subproject/some/meson.build1
-rw-r--r--test cases/failing/33 non-root subproject/test.json7
-rw-r--r--test cases/failing/34 dependency not-required then required/meson.build4
-rw-r--r--test cases/failing/34 dependency not-required then required/test.json8
-rw-r--r--test cases/failing/35 project argument after target/exe.c3
-rw-r--r--test cases/failing/35 project argument after target/meson.build7
-rw-r--r--test cases/failing/35 project argument after target/test.json7
-rw-r--r--test cases/failing/36 pkgconfig dependency impossible conditions/meson.build7
-rw-r--r--test cases/failing/36 pkgconfig dependency impossible conditions/test.json7
-rw-r--r--test cases/failing/37 has function external dependency/meson.build8
-rw-r--r--test cases/failing/37 has function external dependency/mylib.c1
-rw-r--r--test cases/failing/37 has function external dependency/test.json7
-rw-r--r--test cases/failing/38 prefix absolute/meson.build2
-rw-r--r--test cases/failing/38 prefix absolute/test.json11
-rw-r--r--test cases/failing/39 kwarg assign/dummy.c3
-rw-r--r--test cases/failing/39 kwarg assign/meson.build3
-rw-r--r--test cases/failing/39 kwarg assign/prog.c3
-rw-r--r--test cases/failing/39 kwarg assign/test.json7
-rw-r--r--test cases/failing/4 missing meson.build/meson.build3
-rw-r--r--test cases/failing/4 missing meson.build/subdir/dummy.txt1
-rw-r--r--test cases/failing/4 missing meson.build/test.json9
-rw-r--r--test cases/failing/40 custom target plainname many inputs/1.txt1
-rw-r--r--test cases/failing/40 custom target plainname many inputs/2.txt1
-rw-r--r--test cases/failing/40 custom target plainname many inputs/catfiles.py9
-rw-r--r--test cases/failing/40 custom target plainname many inputs/meson.build8
-rw-r--r--test cases/failing/40 custom target plainname many inputs/test.json7
-rwxr-xr-xtest cases/failing/41 custom target outputs not matching install_dirs/generator.py16
-rw-r--r--test cases/failing/41 custom target outputs not matching install_dirs/meson.build13
-rw-r--r--test cases/failing/41 custom target outputs not matching install_dirs/test.json33
-rw-r--r--test cases/failing/42 project name colon/meson.build1
-rw-r--r--test cases/failing/42 project name colon/test.json7
-rw-r--r--test cases/failing/43 abs subdir/bob/meson.build2
-rw-r--r--test cases/failing/43 abs subdir/meson.build5
-rw-r--r--test cases/failing/43 abs subdir/test.json7
-rw-r--r--test cases/failing/44 abspath to srcdir/meson.build3
-rw-r--r--test cases/failing/44 abspath to srcdir/test.json7
-rw-r--r--test cases/failing/45 pkgconfig variables reserved/meson.build16
-rw-r--r--test cases/failing/45 pkgconfig variables reserved/simple.c5
-rw-r--r--test cases/failing/45 pkgconfig variables reserved/simple.h6
-rw-r--r--test cases/failing/45 pkgconfig variables reserved/test.json7
-rw-r--r--test cases/failing/46 pkgconfig variables zero length/meson.build16
-rw-r--r--test cases/failing/46 pkgconfig variables zero length/simple.c5
-rw-r--r--test cases/failing/46 pkgconfig variables zero length/simple.h6
-rw-r--r--test cases/failing/46 pkgconfig variables zero length/test.json7
-rw-r--r--test cases/failing/47 pkgconfig variables zero length value/meson.build16
-rw-r--r--test cases/failing/47 pkgconfig variables zero length value/simple.c5
-rw-r--r--test cases/failing/47 pkgconfig variables zero length value/simple.h6
-rw-r--r--test cases/failing/47 pkgconfig variables zero length value/test.json7
-rw-r--r--test cases/failing/48 pkgconfig variables not key value/meson.build16
-rw-r--r--test cases/failing/48 pkgconfig variables not key value/simple.c5
-rw-r--r--test cases/failing/48 pkgconfig variables not key value/simple.h6
-rw-r--r--test cases/failing/48 pkgconfig variables not key value/test.json7
-rw-r--r--test cases/failing/49 executable comparison/meson.build6
-rw-r--r--test cases/failing/49 executable comparison/prog.c1
-rw-r--r--test cases/failing/49 executable comparison/test.json8
-rw-r--r--test cases/failing/5 misplaced option/meson.build3
-rw-r--r--test cases/failing/5 misplaced option/test.json7
-rw-r--r--test cases/failing/50 inconsistent comparison/meson.build7
-rw-r--r--test cases/failing/50 inconsistent comparison/test.json7
-rw-r--r--test cases/failing/51 slashname/meson.build11
-rw-r--r--test cases/failing/51 slashname/sub/meson.build1
-rw-r--r--test cases/failing/51 slashname/sub/prog.c6
-rw-r--r--test cases/failing/51 slashname/test.json7
-rw-r--r--test cases/failing/52 reserved meson prefix/meson-foo/meson.build0
-rw-r--r--test cases/failing/52 reserved meson prefix/meson.build3
-rw-r--r--test cases/failing/52 reserved meson prefix/test.json7
-rw-r--r--test cases/failing/53 wrong shared crate type/foo.rs0
-rw-r--r--test cases/failing/53 wrong shared crate type/meson.build7
-rw-r--r--test cases/failing/53 wrong shared crate type/test.json7
-rw-r--r--test cases/failing/54 wrong static crate type/foo.rs0
-rw-r--r--test cases/failing/54 wrong static crate type/meson.build7
-rw-r--r--test cases/failing/54 wrong static crate type/test.json7
-rw-r--r--test cases/failing/55 or on new line/meson.build7
-rw-r--r--test cases/failing/55 or on new line/meson_options.txt1
-rw-r--r--test cases/failing/55 or on new line/test.json7
-rw-r--r--test cases/failing/56 link with executable/meson.build4
-rw-r--r--test cases/failing/56 link with executable/module.c4
-rw-r--r--test cases/failing/56 link with executable/prog.c5
-rw-r--r--test cases/failing/56 link with executable/test.json7
-rw-r--r--test cases/failing/57 assign custom target index/meson.build24
-rw-r--r--test cases/failing/57 assign custom target index/test.json7
-rw-r--r--test cases/failing/58 getoption prefix/meson.build5
-rw-r--r--test cases/failing/58 getoption prefix/subprojects/abc/meson.build1
-rw-r--r--test cases/failing/58 getoption prefix/subprojects/abc/meson_options.txt1
-rw-r--r--test cases/failing/58 getoption prefix/test.json7
-rw-r--r--test cases/failing/59 bad option argument/meson.build3
-rw-r--r--test cases/failing/59 bad option argument/meson_options.txt1
-rw-r--r--test cases/failing/59 bad option argument/test.json7
-rw-r--r--test cases/failing/6 missing incdir/meson.build3
-rw-r--r--test cases/failing/6 missing incdir/test.json7
-rw-r--r--test cases/failing/60 subproj filegrab/meson.build5
-rw-r--r--test cases/failing/60 subproj filegrab/prog.c1
-rw-r--r--test cases/failing/60 subproj filegrab/subprojects/a/meson.build3
-rw-r--r--test cases/failing/60 subproj filegrab/test.json7
-rw-r--r--test cases/failing/61 grab subproj/meson.build7
-rw-r--r--test cases/failing/61 grab subproj/subprojects/foo/meson.build3
-rw-r--r--test cases/failing/61 grab subproj/subprojects/foo/sub.c6
-rw-r--r--test cases/failing/61 grab subproj/test.json7
-rw-r--r--test cases/failing/62 grab sibling/meson.build3
-rw-r--r--test cases/failing/62 grab sibling/subprojects/a/meson.build3
-rw-r--r--test cases/failing/62 grab sibling/subprojects/b/meson.build3
-rw-r--r--test cases/failing/62 grab sibling/subprojects/b/sneaky.c6
-rw-r--r--test cases/failing/62 grab sibling/test.json7
-rw-r--r--test cases/failing/63 string as link target/meson.build2
-rw-r--r--test cases/failing/63 string as link target/prog.c1
-rw-r--r--test cases/failing/63 string as link target/test.json7
-rw-r--r--test cases/failing/64 dependency not-found and required/meson.build2
-rw-r--r--test cases/failing/64 dependency not-found and required/test.json7
-rw-r--r--test cases/failing/65 subproj different versions/main.c9
-rw-r--r--test cases/failing/65 subproj different versions/meson.build9
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/a/a.c5
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/a/a.h1
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/a/meson.build11
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/b/b.c5
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/b/b.h1
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/b/meson.build11
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/c/c.h3
-rw-r--r--test cases/failing/65 subproj different versions/subprojects/c/meson.build5
-rw-r--r--test cases/failing/65 subproj different versions/test.json7
-rw-r--r--test cases/failing/66 wrong boost module/meson.build9
-rw-r--r--test cases/failing/66 wrong boost module/test.json7
-rw-r--r--test cases/failing/67 install_data rename bad size/file1.txt0
-rw-r--r--test cases/failing/67 install_data rename bad size/file2.txt0
-rw-r--r--test cases/failing/67 install_data rename bad size/meson.build3
-rw-r--r--test cases/failing/67 install_data rename bad size/test.json7
-rw-r--r--test cases/failing/68 skip only subdir/meson.build8
-rw-r--r--test cases/failing/68 skip only subdir/subdir/meson.build3
-rw-r--r--test cases/failing/68 skip only subdir/test.json7
-rw-r--r--test cases/failing/69 dual override/meson.build5
-rw-r--r--test cases/failing/69 dual override/overrides.py4
-rw-r--r--test cases/failing/69 dual override/test.json7
-rw-r--r--test cases/failing/7 go to subproject/meson.build3
-rw-r--r--test cases/failing/7 go to subproject/subprojects/meson.build1
-rw-r--r--test cases/failing/7 go to subproject/test.json7
-rw-r--r--test cases/failing/70 override used/meson.build5
-rwxr-xr-xtest cases/failing/70 override used/other.py3
-rwxr-xr-xtest cases/failing/70 override used/something.py3
-rw-r--r--test cases/failing/70 override used/test.json7
-rw-r--r--test cases/failing/71 run_command unclean exit/meson.build4
-rwxr-xr-xtest cases/failing/71 run_command unclean exit/returncode.py4
-rw-r--r--test cases/failing/71 run_command unclean exit/test.json8
-rw-r--r--test cases/failing/72 int literal leading zero/meson.build5
-rw-r--r--test cases/failing/72 int literal leading zero/test.json8
-rw-r--r--test cases/failing/73 configuration immutable/input0
-rw-r--r--test cases/failing/73 configuration immutable/meson.build12
-rw-r--r--test cases/failing/73 configuration immutable/test.json7
-rw-r--r--test cases/failing/74 link with shared module on osx/meson.build8
-rw-r--r--test cases/failing/74 link with shared module on osx/module.c3
-rw-r--r--test cases/failing/74 link with shared module on osx/prog.c4
-rw-r--r--test cases/failing/74 link with shared module on osx/test.json7
-rw-r--r--test cases/failing/75 non ascii in ascii encoded configure file/config9.h.in1
-rw-r--r--test cases/failing/75 non ascii in ascii encoded configure file/meson.build10
-rw-r--r--test cases/failing/75 non ascii in ascii encoded configure file/test.json8
-rw-r--r--test cases/failing/76 subproj dependency not-found and required/meson.build2
-rw-r--r--test cases/failing/76 subproj dependency not-found and required/test.json7
-rw-r--r--test cases/failing/77 unfound run/meson.build4
-rw-r--r--test cases/failing/77 unfound run/test.json7
-rw-r--r--test cases/failing/78 framework dependency with version/meson.build8
-rw-r--r--test cases/failing/78 framework dependency with version/test.json7
-rw-r--r--test cases/failing/79 override exe config/foo.c3
-rw-r--r--test cases/failing/79 override exe config/meson.build6
-rw-r--r--test cases/failing/79 override exe config/test.json7
-rw-r--r--test cases/failing/8 recursive/meson.build3
-rw-r--r--test cases/failing/8 recursive/subprojects/a/meson.build3
-rw-r--r--test cases/failing/8 recursive/subprojects/b/meson.build3
-rw-r--r--test cases/failing/8 recursive/test.json7
-rw-r--r--test cases/failing/80 gl dependency with version/meson.build9
-rw-r--r--test cases/failing/80 gl dependency with version/test.json7
-rw-r--r--test cases/failing/81 threads dependency with version/meson.build3
-rw-r--r--test cases/failing/81 threads dependency with version/test.json7
-rw-r--r--test cases/failing/82 gtest dependency with version/meson.build8
-rw-r--r--test cases/failing/82 gtest dependency with version/test.json7
-rw-r--r--test cases/failing/83 dub libray/meson.build11
-rw-r--r--test cases/failing/83 dub libray/test.json7
-rw-r--r--test cases/failing/84 dub executable/meson.build11
-rw-r--r--test cases/failing/84 dub executable/test.json7
-rw-r--r--test cases/failing/85 dub compiler/meson.build17
-rw-r--r--test cases/failing/85 dub compiler/test.json19
-rw-r--r--test cases/failing/86 subproj not-found dep/meson.build2
-rw-r--r--test cases/failing/86 subproj not-found dep/subprojects/somesubproj/meson.build3
-rw-r--r--test cases/failing/86 subproj not-found dep/test.json7
-rw-r--r--test cases/failing/87 invalid configure file/input0
-rw-r--r--test cases/failing/87 invalid configure file/meson.build9
-rw-r--r--test cases/failing/87 invalid configure file/test.json7
-rw-r--r--test cases/failing/88 kwarg dupe/meson.build6
-rw-r--r--test cases/failing/88 kwarg dupe/prog.c6
-rw-r--r--test cases/failing/88 kwarg dupe/test.json7
-rw-r--r--test cases/failing/89 missing pch file/meson.build3
-rw-r--r--test cases/failing/89 missing pch file/prog.c3
-rw-r--r--test cases/failing/89 missing pch file/test.json8
-rw-r--r--test cases/failing/9 missing extra file/meson.build3
-rw-r--r--test cases/failing/9 missing extra file/prog.c3
-rw-r--r--test cases/failing/9 missing extra file/test.json7
-rw-r--r--test cases/failing/90 pch source different folder/include/pch.h0
-rw-r--r--test cases/failing/90 pch source different folder/meson.build5
-rw-r--r--test cases/failing/90 pch source different folder/prog.c1
-rw-r--r--test cases/failing/90 pch source different folder/src/pch.c0
-rw-r--r--test cases/failing/90 pch source different folder/test.json7
-rw-r--r--test cases/failing/91 unknown config tool/meson.build2
-rw-r--r--test cases/failing/91 unknown config tool/test.json7
-rw-r--r--test cases/failing/92 custom target install data/Info.plist.cpp1
-rw-r--r--test cases/failing/92 custom target install data/meson.build11
-rw-r--r--test cases/failing/92 custom target install data/preproc.py13
-rw-r--r--test cases/failing/92 custom target install data/test.json7
-rw-r--r--test cases/failing/93 add dict non string key/meson.build9
-rw-r--r--test cases/failing/93 add dict non string key/test.json7
-rw-r--r--test cases/failing/94 add dict duplicate keys/meson.build9
-rw-r--r--test cases/failing/94 add dict duplicate keys/test.json7
-rw-r--r--test cases/failing/95 no host get_external_property/meson.build3
-rw-r--r--test cases/failing/95 no host get_external_property/test.json7
-rw-r--r--test cases/failing/96 no native compiler/main.c3
-rw-r--r--test cases/failing/96 no native compiler/meson.build12
-rw-r--r--test cases/failing/96 no native compiler/test.json7
-rw-r--r--test cases/failing/97 subdir parse error/meson.build2
-rw-r--r--test cases/failing/97 subdir parse error/subdir/meson.build1
-rw-r--r--test cases/failing/97 subdir parse error/test.json7
-rw-r--r--test cases/failing/98 invalid option file/meson.build1
-rw-r--r--test cases/failing/98 invalid option file/meson_options.txt1
-rw-r--r--test cases/failing/98 invalid option file/test.json7
-rw-r--r--test cases/failing/99 no lang/main.c3
-rw-r--r--test cases/failing/99 no lang/meson.build2
-rw-r--r--test cases/failing/99 no lang/test.json7
-rw-r--r--test cases/fortran/1 basic/meson.build13
-rw-r--r--test cases/fortran/1 basic/simple.f903
-rw-r--r--test cases/fortran/10 find library/gzip.f9032
-rw-r--r--test cases/fortran/10 find library/main.f9038
-rw-r--r--test cases/fortran/10 find library/meson.build13
-rw-r--r--test cases/fortran/11 compiles links runs/meson.build17
-rw-r--r--test cases/fortran/12 submodule/a1.f9026
-rw-r--r--test cases/fortran/12 submodule/a2.f9010
-rw-r--r--test cases/fortran/12 submodule/a3.f9013
-rw-r--r--test cases/fortran/12 submodule/child.f9013
-rw-r--r--test cases/fortran/12 submodule/meson.build13
-rw-r--r--test cases/fortran/12 submodule/parent.f9026
-rw-r--r--test cases/fortran/13 coarray/main.f9010
-rw-r--r--test cases/fortran/13 coarray/meson.build24
-rw-r--r--test cases/fortran/14 fortran links c/clib.c7
-rw-r--r--test cases/fortran/14 fortran links c/clib.def2
-rw-r--r--test cases/fortran/14 fortran links c/f_call_c.f9011
-rw-r--r--test cases/fortran/14 fortran links c/meson.build17
-rw-r--r--test cases/fortran/15 include/inc1.f905
-rw-r--r--test cases/fortran/15 include/inc2.f902
-rw-r--r--test cases/fortran/15 include/include_hierarchy.f909
-rw-r--r--test cases/fortran/15 include/include_syntax.f9025
-rw-r--r--test cases/fortran/15 include/meson.build19
-rw-r--r--test cases/fortran/15 include/subprojects/cmake_inc/CMakeLists.txt4
-rw-r--r--test cases/fortran/15 include/subprojects/cmake_inc/main.f909
-rw-r--r--test cases/fortran/15 include/subprojects/cmake_inc/thousand.f901
-rw-r--r--test cases/fortran/15 include/timestwo.f902
-rw-r--r--test cases/fortran/16 openmp/main.f9018
-rw-r--r--test cases/fortran/16 openmp/meson.build34
-rw-r--r--test cases/fortran/17 add_languages/meson.build5
-rw-r--r--test cases/fortran/18 first_arg/main.f903
-rw-r--r--test cases/fortran/18 first_arg/meson.build46
-rw-r--r--test cases/fortran/19 fortran_std/legacy.f8
-rw-r--r--test cases/fortran/19 fortran_std/meson.build27
-rw-r--r--test cases/fortran/19 fortran_std/std2003.f9037
-rw-r--r--test cases/fortran/19 fortran_std/std2008.f9033
-rw-r--r--test cases/fortran/19 fortran_std/std2018.f9035
-rw-r--r--test cases/fortran/19 fortran_std/std95.f9014
-rw-r--r--test cases/fortran/2 modules/comment_mod.f906
-rw-r--r--test cases/fortran/2 modules/meson.build9
-rw-r--r--test cases/fortran/2 modules/mymod.F908
-rw-r--r--test cases/fortran/2 modules/prog.f9011
-rw-r--r--test cases/fortran/20 buildtype/main.f902
-rw-r--r--test cases/fortran/20 buildtype/meson.build5
-rw-r--r--test cases/fortran/21 install static/main.f905
-rw-r--r--test cases/fortran/21 install static/main_lib.f9016
-rw-r--r--test cases/fortran/21 install static/meson.build20
-rw-r--r--test cases/fortran/21 install static/subprojects/static_hello/meson.build12
-rw-r--r--test cases/fortran/21 install static/subprojects/static_hello/static_hello.f9017
-rw-r--r--test cases/fortran/21 install static/test.json10
-rw-r--r--test cases/fortran/3 module procedure/meson.build5
-rw-r--r--test cases/fortran/3 module procedure/use_syntax.f9031
-rw-r--r--test cases/fortran/4 self dependency/meson.build8
-rw-r--r--test cases/fortran/4 self dependency/selfdep.f9018
-rw-r--r--test cases/fortran/4 self dependency/src/selfdep_mod.f906
-rw-r--r--test cases/fortran/4 self dependency/subprojects/sub1/main.f906
-rw-r--r--test cases/fortran/4 self dependency/subprojects/sub1/meson.build3
-rw-r--r--test cases/fortran/5 static/main.f906
-rw-r--r--test cases/fortran/5 static/meson.build6
-rw-r--r--test cases/fortran/5 static/static_hello.f9017
-rw-r--r--test cases/fortran/6 dynamic/dynamic.f9017
-rw-r--r--test cases/fortran/6 dynamic/main.f906
-rw-r--r--test cases/fortran/6 dynamic/meson.build13
-rw-r--r--test cases/fortran/7 generated/meson.build39
-rw-r--r--test cases/fortran/7 generated/mod1.fpp6
-rw-r--r--test cases/fortran/7 generated/mod2.fpp7
-rw-r--r--test cases/fortran/7 generated/mod3.f906
-rw-r--r--test cases/fortran/7 generated/prog.f908
-rw-r--r--test cases/fortran/8 module names/meson.build6
-rw-r--r--test cases/fortran/8 module names/mod1.f906
-rw-r--r--test cases/fortran/8 module names/mod2.f906
-rw-r--r--test cases/fortran/8 module names/test.f909
-rw-r--r--test cases/fortran/9 cpp/fortran.f11
-rw-r--r--test cases/fortran/9 cpp/main.c8
-rw-r--r--test cases/fortran/9 cpp/main.cpp8
-rw-r--r--test cases/fortran/9 cpp/meson.build29
-rw-r--r--test cases/fpga/1 simple/meson.build8
-rw-r--r--test cases/fpga/1 simple/spin.pcf6
-rw-r--r--test cases/fpga/1 simple/spin.v32
-rw-r--r--test cases/frameworks/1 boost/extralib.cpp27
-rw-r--r--test cases/frameworks/1 boost/linkexe.cc18
-rw-r--r--test cases/frameworks/1 boost/meson.build74
-rw-r--r--test cases/frameworks/1 boost/meson_options.txt1
-rw-r--r--test cases/frameworks/1 boost/nomod.cpp18
-rw-r--r--test cases/frameworks/1 boost/partial_dep/foo.cpp20
-rw-r--r--test cases/frameworks/1 boost/partial_dep/foo.hpp27
-rw-r--r--test cases/frameworks/1 boost/partial_dep/main.cpp27
-rw-r--r--test cases/frameworks/1 boost/partial_dep/meson.build31
-rw-r--r--test cases/frameworks/1 boost/python_module.cpp22
-rw-r--r--test cases/frameworks/1 boost/test.json22
-rw-r--r--test cases/frameworks/1 boost/test_python_module.py27
-rw-r--r--test cases/frameworks/1 boost/unit_test.cpp9
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar-docs.sgml41
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar1/baz.jpg0
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar1/baz.png.in0
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml41
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt15
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types4
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build15
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar2/foobar-docs.sgml41
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar2/meson.build13
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar3/foobar-docs.sgml41
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar3/meson.build6
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar4/foobar-docs.sgml41
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/foobar4/meson.build7
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/meson.build10
-rw-r--r--test cases/frameworks/10 gtk-doc/doc/version.xml.in1
-rw-r--r--test cases/frameworks/10 gtk-doc/foo.c30
-rw-r--r--test cases/frameworks/10 gtk-doc/include/foo-version.h.in29
-rw-r--r--test cases/frameworks/10 gtk-doc/include/foo.h33
-rw-r--r--test cases/frameworks/10 gtk-doc/include/generate-enums-docbook.py63
-rw-r--r--test cases/frameworks/10 gtk-doc/include/meson.build17
-rw-r--r--test cases/frameworks/10 gtk-doc/meson.build45
-rw-r--r--test cases/frameworks/10 gtk-doc/test.json64
-rw-r--r--test cases/frameworks/11 gir subproject/gir/meson-subsample.c124
-rw-r--r--test cases/frameworks/11 gir subproject/gir/meson-subsample.h21
-rw-r--r--test cases/frameworks/11 gir subproject/gir/meson.build40
-rw-r--r--test cases/frameworks/11 gir subproject/gir/prog.c12
-rwxr-xr-xtest cases/frameworks/11 gir subproject/gir/prog.py6
-rw-r--r--test cases/frameworks/11 gir subproject/meson.build20
-rw-r--r--test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.c127
-rw-r--r--test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.h26
-rw-r--r--test cases/frameworks/11 gir subproject/subprojects/mesongir/meson.build31
-rw-r--r--test cases/frameworks/11 gir subproject/test.json13
-rw-r--r--test cases/frameworks/12 multiple gir/gir/meson-subsample.c124
-rw-r--r--test cases/frameworks/12 multiple gir/gir/meson-subsample.h17
-rw-r--r--test cases/frameworks/12 multiple gir/gir/meson.build31
-rw-r--r--test cases/frameworks/12 multiple gir/gir/prog.c12
-rw-r--r--test cases/frameworks/12 multiple gir/meson.build12
-rw-r--r--test cases/frameworks/12 multiple gir/mesongir/meson-sample.c126
-rw-r--r--test cases/frameworks/12 multiple gir/mesongir/meson-sample.h.in22
-rw-r--r--test cases/frameworks/12 multiple gir/mesongir/meson.build39
-rw-r--r--test cases/frameworks/12 multiple gir/test.json17
-rw-r--r--test cases/frameworks/13 yelp/help/C/index.page8
-rw-r--r--test cases/frameworks/13 yelp/help/C/index2.page8
-rw-r--r--test cases/frameworks/13 yelp/help/C/index3.page8
-rw-r--r--test cases/frameworks/13 yelp/help/C/media/test.txt1
-rw-r--r--test cases/frameworks/13 yelp/help/LINGUAS2
-rw-r--r--test cases/frameworks/13 yelp/help/de/de.po13
-rw-r--r--test cases/frameworks/13 yelp/help/es/es.po13
-rw-r--r--test cases/frameworks/13 yelp/help/es/media/test.txt1
-rw-r--r--test cases/frameworks/13 yelp/help/meson.build21
-rw-r--r--test cases/frameworks/13 yelp/meson.build8
-rw-r--r--test cases/frameworks/13 yelp/test.json23
-rw-r--r--test cases/frameworks/14 doxygen/doc/Doxyfile.in2473
-rw-r--r--test cases/frameworks/14 doxygen/doc/meson.build16
-rw-r--r--test cases/frameworks/14 doxygen/include/comedian.h17
-rw-r--r--test cases/frameworks/14 doxygen/include/spede.h35
-rw-r--r--test cases/frameworks/14 doxygen/meson.build27
-rw-r--r--test cases/frameworks/14 doxygen/src/spede.cpp49
-rw-r--r--test cases/frameworks/14 doxygen/test.json6
-rw-r--r--test cases/frameworks/15 llvm/meson.build51
-rw-r--r--test cases/frameworks/15 llvm/meson_options.txt10
-rw-r--r--test cases/frameworks/15 llvm/sum.c76
-rw-r--r--test cases/frameworks/15 llvm/test.json18
-rw-r--r--test cases/frameworks/16 sdl2/meson.build13
-rw-r--r--test cases/frameworks/16 sdl2/meson_options.txt6
-rw-r--r--test cases/frameworks/16 sdl2/sdl2prog.c33
-rw-r--r--test cases/frameworks/16 sdl2/test.json14
-rw-r--r--test cases/frameworks/17 mpi/main.c27
-rw-r--r--test cases/frameworks/17 mpi/main.cpp12
-rw-r--r--test cases/frameworks/17 mpi/main.f9030
-rw-r--r--test cases/frameworks/17 mpi/meson.build52
-rw-r--r--test cases/frameworks/17 mpi/meson_options.txt6
-rw-r--r--test cases/frameworks/17 mpi/test.json17
-rw-r--r--test cases/frameworks/18 vulkan/meson.build13
-rw-r--r--test cases/frameworks/18 vulkan/test.json3
-rw-r--r--test cases/frameworks/18 vulkan/vulkanprog.c26
-rw-r--r--test cases/frameworks/19 pcap/meson.build22
-rw-r--r--test cases/frameworks/19 pcap/pcap_prog.c15
-rw-r--r--test cases/frameworks/19 pcap/test.json3
-rw-r--r--test cases/frameworks/2 gtest/meson.build14
-rw-r--r--test cases/frameworks/2 gtest/test.cc9
-rw-r--r--test cases/frameworks/2 gtest/test.json3
-rw-r--r--test cases/frameworks/2 gtest/test_nomain.cc14
-rw-r--r--test cases/frameworks/20 cups/cups_prog.c8
-rw-r--r--test cases/frameworks/20 cups/meson.build21
-rw-r--r--test cases/frameworks/20 cups/test.json3
-rw-r--r--test cases/frameworks/21 libwmf/libwmf_prog.c8
-rw-r--r--test cases/frameworks/21 libwmf/meson.build27
-rw-r--r--test cases/frameworks/21 libwmf/test.json3
-rw-r--r--test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c6
-rw-r--r--test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h6
-rw-r--r--test cases/frameworks/22 gir link order/fake-gthread/meson.build12
-rw-r--r--test cases/frameworks/22 gir link order/get-prgname/get-prgname.c8
-rw-r--r--test cases/frameworks/22 gir link order/get-prgname/get-prgname.h6
-rw-r--r--test cases/frameworks/22 gir link order/get-prgname/meson.build13
-rw-r--r--test cases/frameworks/22 gir link order/meson-sample.c48
-rw-r--r--test cases/frameworks/22 gir link order/meson-sample.h17
-rw-r--r--test cases/frameworks/22 gir link order/meson.build41
-rw-r--r--test cases/frameworks/22 gir link order/test.json3
-rw-r--r--test cases/frameworks/23 hotdoc/doc/index.md1
-rw-r--r--test cases/frameworks/23 hotdoc/doc/meson.build19
-rw-r--r--test cases/frameworks/23 hotdoc/doc/sitemap.txt2
-rw-r--r--test cases/frameworks/23 hotdoc/meson.build14
-rw-r--r--test cases/frameworks/23 hotdoc/test.json9
-rw-r--r--test cases/frameworks/24 libgcrypt/libgcrypt_prog.c8
-rw-r--r--test cases/frameworks/24 libgcrypt/meson.build23
-rw-r--r--test cases/frameworks/24 libgcrypt/test.json3
-rw-r--r--test cases/frameworks/25 hdf5/main.c30
-rw-r--r--test cases/frameworks/25 hdf5/main.cpp29
-rw-r--r--test cases/frameworks/25 hdf5/main.f9017
-rw-r--r--test cases/frameworks/25 hdf5/meson.build47
-rw-r--r--test cases/frameworks/25 hdf5/meson_options.txt6
-rw-r--r--test cases/frameworks/25 hdf5/test.json11
-rw-r--r--test cases/frameworks/26 netcdf/main.c14
-rw-r--r--test cases/frameworks/26 netcdf/main.cpp15
-rw-r--r--test cases/frameworks/26 netcdf/main.f9019
-rw-r--r--test cases/frameworks/26 netcdf/meson.build36
-rw-r--r--test cases/frameworks/26 netcdf/test.json3
-rw-r--r--test cases/frameworks/27 gpgme/gpgme_prog.c8
-rw-r--r--test cases/frameworks/27 gpgme/meson.build27
-rw-r--r--test cases/frameworks/27 gpgme/test.json3
-rw-r--r--test cases/frameworks/28 gir link order 2/meson-sample.c42
-rw-r--r--test cases/frameworks/28 gir link order 2/meson-sample.h17
-rw-r--r--test cases/frameworks/28 gir link order 2/meson.build35
-rw-r--r--test cases/frameworks/28 gir link order 2/samelibname/dummy.c0
-rw-r--r--test cases/frameworks/28 gir link order 2/samelibname/meson.build5
-rw-r--r--test cases/frameworks/28 gir link order 2/test.json3
-rw-r--r--test cases/frameworks/29 blocks/main.c6
-rw-r--r--test cases/frameworks/29 blocks/meson.build12
-rw-r--r--test cases/frameworks/29 blocks/test.json3
-rw-r--r--test cases/frameworks/3 gmock/gmocktest.cc27
-rw-r--r--test cases/frameworks/3 gmock/meson.build16
-rw-r--r--test cases/frameworks/3 gmock/test.json3
-rw-r--r--test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake220
-rw-r--r--test cases/frameworks/30 scalapack/main.c34
-rw-r--r--test cases/frameworks/30 scalapack/main.f9025
-rw-r--r--test cases/frameworks/30 scalapack/meson.build26
-rw-r--r--test cases/frameworks/30 scalapack/test.json3
-rw-r--r--test cases/frameworks/31 curses/main.c7
-rw-r--r--test cases/frameworks/31 curses/meson.build13
-rw-r--r--test cases/frameworks/31 curses/meson_options.txt6
-rw-r--r--test cases/frameworks/31 curses/test.json12
-rw-r--r--test cases/frameworks/32 boost root/boost/include/boost/version.hpp3
-rw-r--r--test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib0
-rw-r--r--test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib0
-rw-r--r--test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.00
-rw-r--r--test cases/frameworks/32 boost root/meson.build6
-rw-r--r--test cases/frameworks/32 boost root/nativefile.ini.in2
-rw-r--r--test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp3
-rw-r--r--test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib0
-rw-r--r--test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib0
-rw-r--r--test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.00
-rw-r--r--test cases/frameworks/33 boost split root/meson.build6
-rw-r--r--test cases/frameworks/33 boost split root/nativefile.ini.in3
-rw-r--r--test cases/frameworks/34 gir static lib/meson.build18
-rw-r--r--test cases/frameworks/34 gir static lib/statichelper/meson-sample.c126
-rw-r--r--test cases/frameworks/34 gir static lib/statichelper/meson-sample.h.in22
-rw-r--r--test cases/frameworks/34 gir static lib/statichelper/meson.build22
-rw-r--r--test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.c124
-rw-r--r--test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.h17
-rw-r--r--test cases/frameworks/34 gir static lib/subdir/gir/meson.build28
-rw-r--r--test cases/frameworks/34 gir static lib/subdir/gir/prog.c12
-rw-r--r--test cases/frameworks/34 gir static lib/test.json9
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x32-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x64-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/libboost_python.so.0.3.00
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/include/boost/version.hpp3
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x32-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x64-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/libboost_regex.so.0.3.00
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/include/boost/version.hpp3
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x32-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x64-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x32-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x64-0_3.lib0
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/lib/libboost_python.so.0.3.00
-rw-r--r--test cases/frameworks/35 boost symlinks/boost/lib/libboost_regex.so.0.3.00
-rw-r--r--test cases/frameworks/35 boost symlinks/meson.build6
-rw-r--r--test cases/frameworks/35 boost symlinks/nativefile.ini.in2
-rw-r--r--test cases/frameworks/4 qt/main.cpp55
-rw-r--r--test cases/frameworks/4 qt/mainWindow.cpp8
-rw-r--r--test cases/frameworks/4 qt/mainWindow.h20
-rw-r--r--test cases/frameworks/4 qt/mainWindow.ui54
-rw-r--r--test cases/frameworks/4 qt/manualinclude.cpp26
-rw-r--r--test cases/frameworks/4 qt/manualinclude.h22
-rw-r--r--test cases/frameworks/4 qt/meson.build158
-rw-r--r--test cases/frameworks/4 qt/meson_options.txt2
-rw-r--r--test cases/frameworks/4 qt/plugin/plugin.cpp12
-rw-r--r--test cases/frameworks/4 qt/plugin/plugin.h14
-rw-r--r--test cases/frameworks/4 qt/plugin/plugin.json3
-rw-r--r--test cases/frameworks/4 qt/pluginInterface/plugin_if.h21
-rw-r--r--test cases/frameworks/4 qt/q5core.cpp28
-rw-r--r--test cases/frameworks/4 qt/qt4_lang.qrc6
-rw-r--r--test cases/frameworks/4 qt/qt4core_fr.ts12
-rw-r--r--test cases/frameworks/4 qt/qt4embedded_fr.ts12
-rw-r--r--test cases/frameworks/4 qt/qt5_lang.qrc6
-rw-r--r--test cases/frameworks/4 qt/qt5core_fr.ts12
-rw-r--r--test cases/frameworks/4 qt/qt5embedded_fr.ts12
-rw-r--r--test cases/frameworks/4 qt/qt6_lang.qrc6
-rw-r--r--test cases/frameworks/4 qt/qt6core_fr.ts12
-rw-r--r--test cases/frameworks/4 qt/qt6embedded_fr.ts12
-rw-r--r--test cases/frameworks/4 qt/qtinterface.cpp8
-rw-r--r--test cases/frameworks/4 qt/stuff.qrc6
-rw-r--r--test cases/frameworks/4 qt/stuff2.qrc6
-rw-r--r--test cases/frameworks/4 qt/subfolder/generator.py6
-rw-r--r--test cases/frameworks/4 qt/subfolder/main.cpp29
-rw-r--r--test cases/frameworks/4 qt/subfolder/meson.build32
-rw-r--r--test cases/frameworks/4 qt/subfolder/resources/stuff3.qrc6
-rw-r--r--test cases/frameworks/4 qt/subfolder/resources/stuff4.qrc.in8
-rw-r--r--test cases/frameworks/4 qt/subfolder/resources/thing.pngbin0 -> 40303 bytes
-rw-r--r--test cases/frameworks/4 qt/test.json12
-rw-r--r--test cases/frameworks/4 qt/thing.pngbin0 -> 40303 bytes
-rw-r--r--test cases/frameworks/4 qt/thing2.pngbin0 -> 40303 bytes
-rw-r--r--test cases/frameworks/5 protocol buffers/asubdir/defs.proto5
-rw-r--r--test cases/frameworks/5 protocol buffers/asubdir/main.cpp9
-rw-r--r--test cases/frameworks/5 protocol buffers/asubdir/meson.build8
-rw-r--r--test cases/frameworks/5 protocol buffers/defs.proto5
-rw-r--r--test cases/frameworks/5 protocol buffers/main.cpp9
-rw-r--r--test cases/frameworks/5 protocol buffers/meson.build22
-rw-r--r--test cases/frameworks/5 protocol buffers/sidedir/meson.build7
-rw-r--r--test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp16
-rw-r--r--test cases/frameworks/5 protocol buffers/test.json3
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto7
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto10
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/meson.build13
-rw-r--r--test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp16
-rw-r--r--test cases/frameworks/6 gettext/data/data3/meson.build9
-rw-r--r--test cases/frameworks/6 gettext/data/data3/test.desktop.in5
-rw-r--r--test cases/frameworks/6 gettext/data/meson.build59
-rw-r--r--test cases/frameworks/6 gettext/data/test.desktop.in5
-rw-r--r--test cases/frameworks/6 gettext/data/test2.desktop.in5
-rw-r--r--test cases/frameworks/6 gettext/data/test5.desktop.in.in5
-rw-r--r--test cases/frameworks/6 gettext/data/test6.desktop.in.in5
-rw-r--r--test cases/frameworks/6 gettext/data2/meson.build10
-rw-r--r--test cases/frameworks/6 gettext/data2/test.desktop.in5
-rw-r--r--test cases/frameworks/6 gettext/data3/com.mesonbuild.test.intlprog.metainfo.xml33
-rw-r--r--test cases/frameworks/6 gettext/data3/meson.build33
-rw-r--r--test cases/frameworks/6 gettext/data3/metainfo.its33
-rwxr-xr-xtest cases/frameworks/6 gettext/data3/verify.py13
-rw-r--r--test cases/frameworks/6 gettext/generated/desktopgenerator.py13
-rw-r--r--test cases/frameworks/6 gettext/generated/meson.build16
-rw-r--r--test cases/frameworks/6 gettext/generated/something.desktop.in.in15
-rw-r--r--test cases/frameworks/6 gettext/meson.build27
-rw-r--r--test cases/frameworks/6 gettext/meson_options.txt1
-rw-r--r--test cases/frameworks/6 gettext/po/LINGUAS3
-rw-r--r--test cases/frameworks/6 gettext/po/POTFILES2
-rw-r--r--test cases/frameworks/6 gettext/po/de.po26
-rw-r--r--test cases/frameworks/6 gettext/po/fi.po22
-rw-r--r--test cases/frameworks/6 gettext/po/intltest.pot38
-rw-r--r--test cases/frameworks/6 gettext/po/meson.build4
-rw-r--r--test cases/frameworks/6 gettext/po/ru.po34
-rw-r--r--test cases/frameworks/6 gettext/src/intlmain.c17
-rw-r--r--test cases/frameworks/6 gettext/src/meson.build2
-rw-r--r--test cases/frameworks/6 gettext/test.json26
-rw-r--r--test cases/frameworks/7 gnome/copyfile.py6
-rw-r--r--test cases/frameworks/7 gnome/gdbus/data/com.example.Sample.xml14
-rw-r--r--test cases/frameworks/7 gnome/gdbus/gdbusprog.c8
-rw-r--r--test cases/frameworks/7 gnome/gdbus/meson.build95
-rw-r--r--test cases/frameworks/7 gnome/genmarshal/main.c.in102
-rw-r--r--test cases/frameworks/7 gnome/genmarshal/marshaller.list3
-rw-r--r--test cases/frameworks/7 gnome/genmarshal/meson.build54
-rwxr-xr-xtest cases/frameworks/7 gnome/gir/copy.py18
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep1.c56
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep1.h23
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c124
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h21
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build22
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.c124
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.h21
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build22
-rw-r--r--test cases/frameworks/7 gnome/gir/dep1/meson.build31
-rw-r--r--test cases/frameworks/7 gnome/gir/meson-sample.c121
-rw-r--r--test cases/frameworks/7 gnome/gir/meson-sample.h24
-rw-r--r--test cases/frameworks/7 gnome/gir/meson-sample2.c45
-rw-r--r--test cases/frameworks/7 gnome/gir/meson-sample2.h21
-rw-r--r--test cases/frameworks/7 gnome/gir/meson.build60
-rw-r--r--test cases/frameworks/7 gnome/gir/prog.c35
-rwxr-xr-xtest cases/frameworks/7 gnome/gir/prog.py11
-rw-r--r--test cases/frameworks/7 gnome/meson.build63
-rw-r--r--test cases/frameworks/7 gnome/mkenums/enums.c.in41
-rw-r--r--test cases/frameworks/7 gnome/mkenums/enums.h.in24
-rw-r--r--test cases/frameworks/7 gnome/mkenums/enums2.c.in41
-rw-r--r--test cases/frameworks/7 gnome/mkenums/enums2.h.in24
-rw-r--r--test cases/frameworks/7 gnome/mkenums/main.c30
-rw-r--r--test cases/frameworks/7 gnome/mkenums/main4.c35
-rw-r--r--test cases/frameworks/7 gnome/mkenums/main5.c35
-rw-r--r--test cases/frameworks/7 gnome/mkenums/meson-decls.h2
-rw-r--r--test cases/frameworks/7 gnome/mkenums/meson-sample.h20
-rw-r--r--test cases/frameworks/7 gnome/mkenums/meson.build164
-rw-r--r--test cases/frameworks/7 gnome/resources-data/meson.build18
-rw-r--r--test cases/frameworks/7 gnome/resources-data/res1.txt1
-rw-r--r--test cases/frameworks/7 gnome/resources-data/res3.txt.in1
-rw-r--r--test cases/frameworks/7 gnome/resources-data/subdir/meson.build8
-rw-r--r--test cases/frameworks/7 gnome/resources-data/subdir/res2.txt1
-rw-r--r--test cases/frameworks/7 gnome/resources-data/subdir/res4.txt.in1
-rw-r--r--test cases/frameworks/7 gnome/resources/generated-main.c26
-rw-r--r--test cases/frameworks/7 gnome/resources/generated.gresource.xml9
-rw-r--r--test cases/frameworks/7 gnome/resources/generated/meson.build4
-rw-r--r--test cases/frameworks/7 gnome/resources/meson.build72
-rw-r--r--test cases/frameworks/7 gnome/resources/myresource.gresource.xml9
-rw-r--r--test cases/frameworks/7 gnome/resources/res3.txt1
-rw-r--r--test cases/frameworks/7 gnome/resources/resources.py10
-rw-r--r--test cases/frameworks/7 gnome/resources/simple-main.c27
-rw-r--r--test cases/frameworks/7 gnome/resources/simple.gresource.xml7
-rw-r--r--test cases/frameworks/7 gnome/schemas/com.github.meson.gschema.xml12
-rw-r--r--test cases/frameworks/7 gnome/schemas/meson.build7
-rw-r--r--test cases/frameworks/7 gnome/schemas/schemaprog.c47
-rw-r--r--test cases/frameworks/7 gnome/test.json40
-rw-r--r--test cases/frameworks/8 flex/lexer.l13
-rw-r--r--test cases/frameworks/8 flex/meson.build36
-rw-r--r--test cases/frameworks/8 flex/parser.y11
-rw-r--r--test cases/frameworks/8 flex/prog.c30
-rw-r--r--test cases/frameworks/8 flex/test.json3
-rw-r--r--test cases/frameworks/8 flex/test.txt1
-rw-r--r--test cases/frameworks/8 flex/testfile1
-rw-r--r--test cases/frameworks/9 wxwidgets/mainwin.h23
-rw-r--r--test cases/frameworks/9 wxwidgets/meson.build19
-rw-r--r--test cases/frameworks/9 wxwidgets/wxprog.cpp56
-rw-r--r--test cases/frameworks/9 wxwidgets/wxstc.cpp6
-rw-r--r--test cases/java/1 basic/com/mesonbuild/Simple.java7
-rw-r--r--test cases/java/1 basic/meson.build11
-rw-r--r--test cases/java/1 basic/test.json5
-rw-r--r--test cases/java/10 resources/meson.build7
-rw-r--r--test cases/java/10 resources/src/com/mesonbuild/Resources.java26
-rw-r--r--test cases/java/10 resources/src/meson.build13
-rw-r--r--test cases/java/10 resources/src/resources/resource1.txt1
-rw-r--r--test cases/java/10 resources/src/resources/subdir/resource2.txt1
-rw-r--r--test cases/java/2 subdir/meson.build3
-rw-r--r--test cases/java/2 subdir/sub/com/mesonbuild/Simple.java8
-rw-r--r--test cases/java/2 subdir/sub/com/mesonbuild/TextPrinter.java14
-rw-r--r--test cases/java/2 subdir/sub/meson.build5
-rw-r--r--test cases/java/3 args/com/mesonbuild/Simple.java7
-rw-r--r--test cases/java/3 args/meson.build8
-rw-r--r--test cases/java/4 inner class/com/mesonbuild/Simple.java15
-rw-r--r--test cases/java/4 inner class/meson.build5
-rw-r--r--test cases/java/5 includedirs/com/mesonbuild/Simple.java8
-rw-r--r--test cases/java/5 includedirs/com/mesonbuild/TextPrinter.java14
-rw-r--r--test cases/java/5 includedirs/meson.build14
-rw-r--r--test cases/java/6 codegen/com/mesonbuild/Config.java.in5
-rw-r--r--test cases/java/6 codegen/com/mesonbuild/Simple.java12
-rw-r--r--test cases/java/6 codegen/com/mesonbuild/TextPrinter.java14
-rw-r--r--test cases/java/6 codegen/com/mesonbuild/meson.build6
-rw-r--r--test cases/java/6 codegen/meson.build15
-rw-r--r--test cases/java/7 linking/com/mesonbuild/Linking.java9
-rw-r--r--test cases/java/7 linking/meson.build8
-rw-r--r--test cases/java/7 linking/sub/com/mesonbuild/SimpleLib.java7
-rw-r--r--test cases/java/7 linking/sub/meson.build2
-rw-r--r--test cases/java/8 codegen custom target/com/mesonbuild/Config.java.in5
-rw-r--r--test cases/java/8 codegen custom target/com/mesonbuild/Simple.java12
-rw-r--r--test cases/java/8 codegen custom target/com/mesonbuild/TextPrinter.java14
-rw-r--r--test cases/java/8 codegen custom target/com/mesonbuild/meson.build8
-rw-r--r--test cases/java/8 codegen custom target/meson.build15
-rw-r--r--test cases/java/9 jni/lib/com_mesonbuild_JniTest.c9
-rw-r--r--test cases/java/9 jni/lib/meson.build18
-rw-r--r--test cases/java/9 jni/lib/native.c11
-rw-r--r--test cases/java/9 jni/meson.build38
-rw-r--r--test cases/java/9 jni/src/com/mesonbuild/Configured.java.in5
-rw-r--r--test cases/java/9 jni/src/com/mesonbuild/JniTest.java15
-rw-r--r--test cases/java/9 jni/src/com/mesonbuild/meson.build11
-rw-r--r--test cases/java/9 jni/src/meson.build9
-rw-r--r--test cases/keyval/1 basic/.config3
-rw-r--r--test cases/keyval/1 basic/meson.build18
-rw-r--r--test cases/keyval/1 basic/test.json7
-rw-r--r--test cases/keyval/2 subdir/.config2
-rw-r--r--test cases/keyval/2 subdir/dir/meson.build12
-rw-r--r--test cases/keyval/2 subdir/meson.build4
-rw-r--r--test cases/keyval/3 load_config files/dir/config2
-rw-r--r--test cases/keyval/3 load_config files/dir/meson.build12
-rw-r--r--test cases/keyval/3 load_config files/meson.build4
-rw-r--r--test cases/keyval/4 load_config builddir/config2
-rw-r--r--test cases/keyval/4 load_config builddir/meson.build14
-rw-r--r--test cases/linuxlike/1 pkg-config/incdir/myinc.h3
-rw-r--r--test cases/linuxlike/1 pkg-config/meson.build53
-rw-r--r--test cases/linuxlike/1 pkg-config/prog-checkver.c15
-rw-r--r--test cases/linuxlike/1 pkg-config/prog.c8
-rw-r--r--test cases/linuxlike/10 large file support/meson.build16
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c3
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build2
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build3
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c11
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build16
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/main.c9
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/meson.build9
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.c5
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.h1
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/a/meson.build11
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.c11
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.h1
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/b/meson.build17
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/c/c.h3
-rw-r--r--test cases/linuxlike/12 subprojects in subprojects/subprojects/c/meson.build5
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake/FindImportedOldStyle.cmake5
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake/FindImportedTarget.cmake15
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake56
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake_fake1/cmMesonTestF1Config.cmake11
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake_fake2/cmMesonTestF2Config.cmake9
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake_fake3/bin/.gitkeep0
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake_fake3/lib/cmake/cmMesonTestF3/cmMesonTestF3Config.cmake9
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonTestDep/cmMesonTestDepConfig.cmake9
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfig.cmake9
-rw-r--r--test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfigVersion.cmake12
-rw-r--r--test cases/linuxlike/13 cmake dependency/incdir/myinc.h3
-rw-r--r--test cases/linuxlike/13 cmake dependency/meson.build101
-rw-r--r--test cases/linuxlike/13 cmake dependency/prog-checkver.c15
-rw-r--r--test cases/linuxlike/13 cmake dependency/prog.c8
-rw-r--r--test cases/linuxlike/13 cmake dependency/test.json14
-rw-r--r--test cases/linuxlike/13 cmake dependency/testFlagSet.c18
-rw-r--r--test cases/linuxlike/14 static dynamic linkage/main.c7
-rw-r--r--test cases/linuxlike/14 static dynamic linkage/meson.build36
-rwxr-xr-xtest cases/linuxlike/14 static dynamic linkage/verify_static.py29
-rw-r--r--test cases/linuxlike/15 ld binary/meson.build4
-rw-r--r--test cases/linuxlike/2 external library/meson.build43
-rw-r--r--test cases/linuxlike/2 external library/prog.c8
-rw-r--r--test cases/linuxlike/3 linker script/bob.c9
-rw-r--r--test cases/linuxlike/3 linker script/bob.h6
-rw-r--r--test cases/linuxlike/3 linker script/bob.map6
-rw-r--r--test cases/linuxlike/3 linker script/bob.map.in6
-rw-r--r--test cases/linuxlike/3 linker script/copy.py5
-rw-r--r--test cases/linuxlike/3 linker script/meson.build62
-rw-r--r--test cases/linuxlike/3 linker script/prog.c5
-rw-r--r--test cases/linuxlike/3 linker script/sub/foo.map6
-rw-r--r--test cases/linuxlike/3 linker script/sub/meson.build6
-rw-r--r--test cases/linuxlike/4 extdep static lib/lib.c8
-rw-r--r--test cases/linuxlike/4 extdep static lib/meson.build10
-rw-r--r--test cases/linuxlike/4 extdep static lib/prog.c5
-rw-r--r--test cases/linuxlike/5 dependency versions/meson.build122
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/fakezlib/meson.build3
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c0
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build11
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c0
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build8
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c0
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build9
-rw-r--r--test cases/linuxlike/6 subdir include order/meson.build12
-rw-r--r--test cases/linuxlike/6 subdir include order/prog.c7
-rw-r--r--test cases/linuxlike/6 subdir include order/subdir/glib.h1
-rw-r--r--test cases/linuxlike/7 library versions/exe.orig.c8
-rw-r--r--test cases/linuxlike/7 library versions/lib.c3
-rw-r--r--test cases/linuxlike/7 library versions/meson.build55
-rw-r--r--test cases/linuxlike/7 library versions/test.json14
-rw-r--r--test cases/linuxlike/8 subproject library install/meson.build10
-rw-r--r--test cases/linuxlike/8 subproject library install/subprojects/sublib/include/subdefs.h21
-rw-r--r--test cases/linuxlike/8 subproject library install/subprojects/sublib/meson.build10
-rw-r--r--test cases/linuxlike/8 subproject library install/subprojects/sublib/sublib.c5
-rw-r--r--test cases/linuxlike/8 subproject library install/test.json7
-rw-r--r--test cases/linuxlike/9 compiler checks with dependencies/meson.build36
-rw-r--r--test cases/nasm/1 configure file/hello.asm27
-rw-r--r--test cases/nasm/1 configure file/meson.build55
-rw-r--r--test cases/nasm/2 asm language/hello.asm31
-rw-r--r--test cases/nasm/2 asm language/meson.build57
-rw-r--r--test cases/native/1 trivial/meson.build9
-rw-r--r--test cases/native/1 trivial/trivial.c6
-rw-r--r--test cases/native/2 global arg/meson.build14
-rw-r--r--test cases/native/2 global arg/prog.c43
-rw-r--r--test cases/native/2 global arg/prog.cc15
-rwxr-xr-xtest cases/native/3 pipeline/depends/copyrunner.py7
-rw-r--r--test cases/native/3 pipeline/depends/filecopier.c23
-rw-r--r--test cases/native/3 pipeline/depends/libsrc.c.in3
-rw-r--r--test cases/native/3 pipeline/depends/meson.build11
-rw-r--r--test cases/native/3 pipeline/depends/prog.c5
-rw-r--r--test cases/native/3 pipeline/input_src.dat1
-rw-r--r--test cases/native/3 pipeline/meson.build23
-rw-r--r--test cases/native/3 pipeline/prog.c5
-rw-r--r--test cases/native/3 pipeline/src/input_src.dat1
-rw-r--r--test cases/native/3 pipeline/src/meson.build12
-rw-r--r--test cases/native/3 pipeline/src/prog.c9
-rw-r--r--test cases/native/3 pipeline/src/srcgen.c40
-rw-r--r--test cases/native/3 pipeline/srcgen.c69
-rw-r--r--test cases/native/4 tryrun/error.c3
-rw-r--r--test cases/native/4 tryrun/meson.build78
-rw-r--r--test cases/native/4 tryrun/no_compile.c1
-rw-r--r--test cases/native/4 tryrun/ok.c7
-rw-r--r--test cases/native/5 install script/file.txt0
-rw-r--r--test cases/native/5 install script/meson.build12
-rw-r--r--test cases/native/5 install script/src/exe.c27
-rw-r--r--test cases/native/5 install script/src/meson.build1
-rw-r--r--test cases/native/5 install script/test.json8
-rwxr-xr-xtest cases/native/5 install script/wrap.py6
-rw-r--r--test cases/native/6 add language/meson.build3
-rw-r--r--test cases/native/6 add language/prog.cc6
-rw-r--r--test cases/native/7 selfbuilt custom/checkarg.cpp6
-rw-r--r--test cases/native/7 selfbuilt custom/data.dat1
-rw-r--r--test cases/native/7 selfbuilt custom/mainprog.cpp5
-rw-r--r--test cases/native/7 selfbuilt custom/meson.build39
-rw-r--r--test cases/native/7 selfbuilt custom/tool.cpp34
-rw-r--r--test cases/native/8 external program shebang parsing/input.txt1
-rw-r--r--test cases/native/8 external program shebang parsing/main.c72
-rw-r--r--test cases/native/8 external program shebang parsing/meson.build21
-rw-r--r--test cases/native/8 external program shebang parsing/script.int.in2
-rw-r--r--test cases/native/9 override with exe/main2.input0
-rw-r--r--test cases/native/9 override with exe/meson.build21
-rw-r--r--test cases/native/9 override with exe/subprojects/sub/foobar.c13
-rw-r--r--test cases/native/9 override with exe/subprojects/sub/meson.build3
-rw-r--r--test cases/objc/1 simple/meson.build4
-rw-r--r--test cases/objc/1 simple/prog.m5
-rw-r--r--test cases/objc/2 nsstring/meson.build20
-rw-r--r--test cases/objc/2 nsstring/stringprog.m9
-rw-r--r--test cases/objc/3 objc args/meson.build4
-rw-r--r--test cases/objc/3 objc args/prog.m11
-rw-r--r--test cases/objc/4 c++ project objc subproject/master.cpp11
-rw-r--r--test cases/objc/4 c++ project objc subproject/meson.build6
-rw-r--r--test cases/objc/4 c++ project objc subproject/subprojects/foo/foo.m4
-rw-r--r--test cases/objc/4 c++ project objc subproject/subprojects/foo/meson.build5
-rw-r--r--test cases/objcpp/1 simple/meson.build4
-rw-r--r--test cases/objcpp/1 simple/prog.mm8
-rw-r--r--test cases/objcpp/2 objc++ args/meson.build4
-rw-r--r--test cases/objcpp/2 objc++ args/prog.mm16
-rw-r--r--test cases/osx/1 basic/main.c5
-rw-r--r--test cases/osx/1 basic/meson.build3
-rw-r--r--test cases/osx/2 library versions/CMakeLists.txt29
-rw-r--r--test cases/osx/2 library versions/exe.orig.c7
-rw-r--r--test cases/osx/2 library versions/lib.c3
-rw-r--r--test cases/osx/2 library versions/meson.build81
-rw-r--r--test cases/osx/2 library versions/require_pkgconfig.py9
-rw-r--r--test cases/osx/2 library versions/test.json12
-rw-r--r--test cases/osx/3 has function xcode8/meson.build30
-rw-r--r--test cases/osx/4 framework/meson.build32
-rw-r--r--test cases/osx/4 framework/prog.c3
-rw-r--r--test cases/osx/4 framework/stat.c1
-rw-r--r--test cases/osx/4 framework/test.json6
-rw-r--r--test cases/osx/4 framework/xcode-frameworks.pngbin0 -> 421385 bytes
-rw-r--r--test cases/osx/5 extra frameworks/meson.build10
-rw-r--r--test cases/osx/5 extra frameworks/prog.c3
-rw-r--r--test cases/osx/5 extra frameworks/stat.c1
-rw-r--r--test cases/osx/5 extra frameworks/test.json6
-rw-r--r--test cases/osx/6 multiframework/main.m5
-rw-r--r--test cases/osx/6 multiframework/meson.build13
-rw-r--r--test cases/osx/7 bitcode/libbar.mm6
-rw-r--r--test cases/osx/7 bitcode/libfile.c5
-rw-r--r--test cases/osx/7 bitcode/libfoo.m6
-rw-r--r--test cases/osx/7 bitcode/meson.build11
-rw-r--r--test cases/osx/7 bitcode/vis.h6
-rw-r--r--test cases/osx/8 pie/main.c5
-rw-r--r--test cases/osx/8 pie/meson.build3
-rw-r--r--test cases/python/1 basic/gluon/__init__.py0
-rw-r--r--test cases/python/1 basic/gluon/gluonator.py2
-rw-r--r--test cases/python/1 basic/meson.build27
-rwxr-xr-xtest cases/python/1 basic/prog.py8
-rw-r--r--test cases/python/1 basic/subdir/meson.build4
-rwxr-xr-xtest cases/python/1 basic/subdir/subprog.py11
-rwxr-xr-xtest cases/python/2 extmodule/blaster.py.in11
-rw-r--r--test cases/python/2 extmodule/ext/meson.build9
-rw-r--r--test cases/python/2 extmodule/ext/nested/meson.build15
-rw-r--r--test cases/python/2 extmodule/ext/tachyon_module.c49
-rw-r--r--test cases/python/2 extmodule/ext/wrongdir/meson.build6
-rw-r--r--test cases/python/2 extmodule/meson.build50
-rw-r--r--test cases/python/2 extmodule/test.json13
-rwxr-xr-xtest cases/python/3 cython/cytest.py19
-rw-r--r--test cases/python/3 cython/libdir/cstorer.pxd9
-rw-r--r--test cases/python/3 cython/libdir/meson.build11
-rw-r--r--test cases/python/3 cython/libdir/storer.c24
-rw-r--r--test cases/python/3 cython/libdir/storer.h8
-rw-r--r--test cases/python/3 cython/libdir/storer.pyx16
-rw-r--r--test cases/python/3 cython/meson.build26
-rw-r--r--test cases/python/4 custom target depends extmodule/blaster.py30
-rw-r--r--test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c8
-rw-r--r--test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h6
-rw-r--r--test cases/python/4 custom target depends extmodule/ext/lib/meson.build4
-rw-r--r--test cases/python/4 custom target depends extmodule/ext/meson.build6
-rw-r--r--test cases/python/4 custom target depends extmodule/ext/tachyon_module.c51
-rw-r--r--test cases/python/4 custom target depends extmodule/meson.build45
-rw-r--r--test cases/python/5 modules kwarg/meson.build7
-rw-r--r--test cases/python/6 failing subproject/meson.build5
-rw-r--r--test cases/python/6 failing subproject/subprojects/bar/meson.build4
-rw-r--r--test cases/python/7 install path/meson.build20
-rw-r--r--test cases/python/7 install path/structured/alpha/one.py0
-rw-r--r--test cases/python/7 install path/structured/alpha/three.py0
-rw-r--r--test cases/python/7 install path/structured/alpha/two.py0
-rw-r--r--test cases/python/7 install path/structured/beta/one.py0
-rw-r--r--test cases/python/7 install path/structured/meson.build9
-rw-r--r--test cases/python/7 install path/structured/one.py0
-rw-r--r--test cases/python/7 install path/structured/two.py0
-rw-r--r--test cases/python/7 install path/test.json18
-rw-r--r--test cases/python/7 install path/test.py0
-rwxr-xr-xtest cases/python/8 different python versions/blaster.py14
-rw-r--r--test cases/python/8 different python versions/ext/meson.build6
-rw-r--r--test cases/python/8 different python versions/ext/tachyon_module.c59
-rw-r--r--test cases/python/8 different python versions/meson.build34
-rw-r--r--test cases/python/8 different python versions/meson_options.txt4
-rw-r--r--test cases/python/8 different python versions/test.json13
-rw-r--r--test cases/python3/1 basic/gluon/__init__.py0
-rw-r--r--test cases/python3/1 basic/gluon/gluonator.py2
-rw-r--r--test cases/python3/1 basic/meson.build34
-rwxr-xr-xtest cases/python3/1 basic/prog.py9
-rw-r--r--test cases/python3/1 basic/subdir/meson.build4
-rwxr-xr-xtest cases/python3/1 basic/subdir/subprog.py12
-rwxr-xr-xtest cases/python3/2 extmodule/blaster.py14
-rw-r--r--test cases/python3/2 extmodule/ext/meson.build6
-rw-r--r--test cases/python3/2 extmodule/ext/tachyon_module.c49
-rw-r--r--test cases/python3/2 extmodule/meson.build37
-rwxr-xr-xtest cases/python3/3 cython/cytest.py23
-rw-r--r--test cases/python3/3 cython/libdir/cstorer.pxd9
-rw-r--r--test cases/python3/3 cython/libdir/meson.build12
-rw-r--r--test cases/python3/3 cython/libdir/storer.c24
-rw-r--r--test cases/python3/3 cython/libdir/storer.h8
-rw-r--r--test cases/python3/3 cython/libdir/storer.pyx16
-rw-r--r--test cases/python3/3 cython/meson.build26
-rw-r--r--test cases/python3/4 custom target depends extmodule/blaster.py32
-rw-r--r--test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c8
-rw-r--r--test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h6
-rw-r--r--test cases/python3/4 custom target depends extmodule/ext/lib/meson.build4
-rw-r--r--test cases/python3/4 custom target depends extmodule/ext/meson.build6
-rw-r--r--test cases/python3/4 custom target depends extmodule/ext/tachyon_module.c51
-rw-r--r--test cases/python3/4 custom target depends extmodule/meson.build41
-rw-r--r--test cases/rewrite/1 basic/addSrc.json94
-rw-r--r--test cases/rewrite/1 basic/addTgt.json9
-rw-r--r--test cases/rewrite/1 basic/info.json57
-rw-r--r--test cases/rewrite/1 basic/meson.build19
-rw-r--r--test cases/rewrite/1 basic/rmSrc.json88
-rw-r--r--test cases/rewrite/1 basic/rmTgt.json17
-rw-r--r--test cases/rewrite/2 subdirs/addSrc.json13
-rw-r--r--test cases/rewrite/2 subdirs/addTgt.json10
-rw-r--r--test cases/rewrite/2 subdirs/info.json12
-rw-r--r--test cases/rewrite/2 subdirs/meson.build4
-rw-r--r--test cases/rewrite/2 subdirs/rmTgt.json7
-rw-r--r--test cases/rewrite/2 subdirs/sub1/meson.build1
-rw-r--r--test cases/rewrite/2 subdirs/sub2/meson.build1
-rw-r--r--test cases/rewrite/3 kwargs/add.json38
-rw-r--r--test cases/rewrite/3 kwargs/defopts_delete.json18
-rw-r--r--test cases/rewrite/3 kwargs/defopts_set.json24
-rw-r--r--test cases/rewrite/3 kwargs/delete.json20
-rw-r--r--test cases/rewrite/3 kwargs/info.json20
-rw-r--r--test cases/rewrite/3 kwargs/meson.build7
-rw-r--r--test cases/rewrite/3 kwargs/remove.json38
-rw-r--r--test cases/rewrite/3 kwargs/remove_regex.json29
-rw-r--r--test cases/rewrite/3 kwargs/set.json34
-rw-r--r--test cases/rewrite/4 same name targets/addSrc.json8
-rw-r--r--test cases/rewrite/4 same name targets/info.json12
-rw-r--r--test cases/rewrite/4 same name targets/meson.build6
-rw-r--r--test cases/rewrite/4 same name targets/sub1/meson.build3
-rw-r--r--test cases/rewrite/5 sorting/meson.build33
-rw-r--r--test cases/rewrite/6 extra_files/addExtraFiles.json111
-rw-r--r--test cases/rewrite/6 extra_files/info.json57
-rw-r--r--test cases/rewrite/6 extra_files/meson.build21
-rw-r--r--test cases/rewrite/6 extra_files/rmExtraFiles.json93
-rw-r--r--test cases/rust/1 basic/clippy.toml1
-rw-r--r--test cases/rust/1 basic/meson.build9
-rw-r--r--test cases/rust/1 basic/prog.rs4
-rw-r--r--test cases/rust/1 basic/subdir/meson.build2
-rw-r--r--test cases/rust/1 basic/subdir/prog.rs3
-rw-r--r--test cases/rust/1 basic/test.json8
-rw-r--r--test cases/rust/10 language stds/2015.rs3
-rw-r--r--test cases/rust/10 language stds/2018.rs9
-rw-r--r--test cases/rust/10 language stds/meson.build18
-rw-r--r--test cases/rust/11 generated main/gen.py20
-rw-r--r--test cases/rust/11 generated main/generated_lib_main.rs5
-rw-r--r--test cases/rust/11 generated main/meson.build21
-rw-r--r--test cases/rust/11 generated main/sub/meson.build13
-rw-r--r--test cases/rust/12 bindgen/dependencies/clib2.c5
-rw-r--r--test cases/rust/12 bindgen/dependencies/external_dep.h8
-rw-r--r--test cases/rust/12 bindgen/dependencies/internal_dep.h6
-rw-r--r--test cases/rust/12 bindgen/dependencies/internal_main.rs16
-rw-r--r--test cases/rust/12 bindgen/dependencies/meson.build43
-rw-r--r--test cases/rust/12 bindgen/include/other.h6
-rw-r--r--test cases/rust/12 bindgen/meson.build83
-rw-r--r--test cases/rust/12 bindgen/src/gen_header.py19
-rw-r--r--test cases/rust/12 bindgen/src/header.h8
-rw-r--r--test cases/rust/12 bindgen/src/main.rs14
-rw-r--r--test cases/rust/12 bindgen/src/main2.rs15
-rw-r--r--test cases/rust/12 bindgen/src/source.c8
-rw-r--r--test cases/rust/12 bindgen/sub/meson.build39
-rw-r--r--test cases/rust/12 bindgen/test.json7
-rw-r--r--test cases/rust/13 external c dependencies/c_accessing_zlib.c10
-rw-r--r--test cases/rust/13 external c dependencies/meson.build23
-rw-r--r--test cases/rust/13 external c dependencies/meson_options.txt2
-rw-r--r--test cases/rust/13 external c dependencies/prog.rs9
-rw-r--r--test cases/rust/13 external c dependencies/test.json18
-rw-r--r--test cases/rust/14 external libm/meson.build24
-rw-r--r--test cases/rust/14 external libm/meson_options.txt2
-rw-r--r--test cases/rust/14 external libm/prog.rs5
-rw-r--r--test cases/rust/14 external libm/rs_math.rs12
-rw-r--r--test cases/rust/14 external libm/test.json10
-rw-r--r--test cases/rust/15 polyglot sharedlib/adder.c18
-rw-r--r--test cases/rust/15 polyglot sharedlib/adder.h34
-rw-r--r--test cases/rust/15 polyglot sharedlib/adder.rs9
-rw-r--r--test cases/rust/15 polyglot sharedlib/addertest.c12
-rw-r--r--test cases/rust/15 polyglot sharedlib/meson.build20
-rw-r--r--test cases/rust/16 internal c dependencies/lib.c6
-rw-r--r--test cases/rust/16 internal c dependencies/lib.h22
-rw-r--r--test cases/rust/16 internal c dependencies/main.rs9
-rw-r--r--test cases/rust/16 internal c dependencies/meson.build14
-rwxr-xr-xtest cases/rust/16 internal c dependencies/test.py25
-rw-r--r--test cases/rust/17 staticlib link staticlib/branch.rs4
-rw-r--r--test cases/rust/17 staticlib link staticlib/leaf.rs1
-rw-r--r--test cases/rust/17 staticlib link staticlib/meson.build8
-rw-r--r--test cases/rust/17 staticlib link staticlib/prog.c7
-rw-r--r--test cases/rust/17 staticlib link staticlib/test.json7
-rw-r--r--test cases/rust/18 proc-macro/meson.build19
-rw-r--r--test cases/rust/18 proc-macro/proc.rs7
-rw-r--r--test cases/rust/18 proc-macro/use.rs8
-rwxr-xr-xtest cases/rust/19 structured sources/gen.py20
-rw-r--r--test cases/rust/19 structured sources/main-gen-copy.rs5
-rw-r--r--test cases/rust/19 structured sources/meson.build58
-rwxr-xr-xtest cases/rust/19 structured sources/no_copy_test.py18
-rw-r--r--test cases/rust/19 structured sources/priv.rs3
-rw-r--r--test cases/rust/19 structured sources/src/foo.rs.in4
-rw-r--r--test cases/rust/19 structured sources/src/main.rs5
-rw-r--r--test cases/rust/19 structured sources/src2/foo/mod.rs4
-rw-r--r--test cases/rust/19 structured sources/src2/main-unique.rs5
-rw-r--r--test cases/rust/19 structured sources/src2/meson.build4
-rw-r--r--test cases/rust/2 sharedlib/meson.build17
-rw-r--r--test cases/rust/2 sharedlib/prog.rs3
-rw-r--r--test cases/rust/2 sharedlib/stuff.rs11
-rw-r--r--test cases/rust/2 sharedlib/test.json10
-rw-r--r--test cases/rust/2 sharedlib/value.c3
-rw-r--r--test cases/rust/3 staticlib/meson.build7
-rw-r--r--test cases/rust/3 staticlib/other.rs5
-rw-r--r--test cases/rust/3 staticlib/prog.rs5
-rw-r--r--test cases/rust/3 staticlib/stuff.rs14
-rw-r--r--test cases/rust/3 staticlib/test.json7
-rw-r--r--test cases/rust/3 staticlib/value.c5
-rw-r--r--test cases/rust/4 polyglot/meson.build9
-rw-r--r--test cases/rust/4 polyglot/prog.c8
-rw-r--r--test cases/rust/4 polyglot/stuff.rs6
-rw-r--r--test cases/rust/4 polyglot/test.json10
-rw-r--r--test cases/rust/5 polyglot static/clib.c12
-rw-r--r--test cases/rust/5 polyglot static/meson.build18
-rw-r--r--test cases/rust/5 polyglot static/prog.c7
-rw-r--r--test cases/rust/5 polyglot static/stuff.rs6
-rw-r--r--test cases/rust/5 polyglot static/test.json7
-rw-r--r--test cases/rust/6 named staticlib/meson.build5
-rw-r--r--test cases/rust/6 named staticlib/prog.rs3
-rw-r--r--test cases/rust/6 named staticlib/stuff.rs1
-rw-r--r--test cases/rust/6 named staticlib/test.json7
-rw-r--r--test cases/rust/7 private crate collision/meson.build5
-rw-r--r--test cases/rust/7 private crate collision/prog.rs3
-rw-r--r--test cases/rust/7 private crate collision/rand.rs4
-rw-r--r--test cases/rust/7 private crate collision/test.json7
-rw-r--r--test cases/rust/8 many files/foo.rs3
-rw-r--r--test cases/rust/8 many files/main.rs5
-rw-r--r--test cases/rust/8 many files/meson.build3
-rw-r--r--test cases/rust/9 unit tests/meson.build43
-rw-r--r--test cases/rust/9 unit tests/test.rs24
-rw-r--r--test cases/rust/9 unit tests/test2.rs11
-rw-r--r--test cases/swift/1 exe/main.swift1
-rw-r--r--test cases/swift/1 exe/meson.build3
-rw-r--r--test cases/swift/2 multifile/libfile.swift3
-rw-r--r--test cases/swift/2 multifile/main.swift5
-rw-r--r--test cases/swift/2 multifile/meson.build3
-rw-r--r--test cases/swift/3 library/exe/main.swift7
-rw-r--r--test cases/swift/3 library/exe/meson.build2
-rw-r--r--test cases/swift/3 library/lib/datasource.swift3
-rw-r--r--test cases/swift/3 library/lib/meson.build1
-rw-r--r--test cases/swift/3 library/lib/othersource.swift3
-rw-r--r--test cases/swift/3 library/meson.build4
-rw-r--r--test cases/swift/4 generate/gen/main.swift18
-rw-r--r--test cases/swift/4 generate/gen/meson.build6
-rw-r--r--test cases/swift/4 generate/meson.build4
-rw-r--r--test cases/swift/4 generate/user/main.swift3
-rw-r--r--test cases/swift/4 generate/user/meson.build2
-rw-r--r--test cases/swift/5 mixed/main.swift3
-rw-r--r--test cases/swift/5 mixed/meson.build6
-rw-r--r--test cases/swift/5 mixed/mylib.c5
-rw-r--r--test cases/swift/5 mixed/mylib.h3
-rw-r--r--test cases/swift/6 modulemap/main.swift5
-rw-r--r--test cases/swift/6 modulemap/meson.build8
-rw-r--r--test cases/swift/6 modulemap/module.modulemap5
-rw-r--r--test cases/swift/6 modulemap/mylib.c5
-rw-r--r--test cases/swift/6 modulemap/mylib.h3
-rw-r--r--test cases/swift/7 modulemap subdir/main.swift5
-rw-r--r--test cases/swift/7 modulemap subdir/meson.build6
-rw-r--r--test cases/swift/7 modulemap subdir/mylib/meson.build4
-rw-r--r--test cases/swift/7 modulemap subdir/mylib/module.modulemap5
-rw-r--r--test cases/swift/7 modulemap subdir/mylib/mylib.c5
-rw-r--r--test cases/swift/7 modulemap subdir/mylib/mylib.h3
-rw-r--r--test cases/unit/1 soname/CMakeLists.txt26
-rw-r--r--test cases/unit/1 soname/main.c5
-rw-r--r--test cases/unit/1 soname/meson.build35
-rw-r--r--test cases/unit/1 soname/versioned.c3
-rw-r--r--test cases/unit/10 build_rpath/meson.build16
-rw-r--r--test cases/unit/10 build_rpath/prog.c5
-rw-r--r--test cases/unit/10 build_rpath/prog.cc8
-rw-r--r--test cases/unit/10 build_rpath/sub/meson.build1
-rw-r--r--test cases/unit/10 build_rpath/sub/stuff.c3
-rwxr-xr-xtest cases/unit/100 relative find program/foo.py3
-rw-r--r--test cases/unit/100 relative find program/meson.build3
-rw-r--r--test cases/unit/100 relative find program/subdir/meson.build2
-rw-r--r--test cases/unit/101 rlib linkage/lib2.rs5
-rw-r--r--test cases/unit/101 rlib linkage/main.rs5
-rw-r--r--test cases/unit/101 rlib linkage/meson.build22
-rw-r--r--test cases/unit/102 python without pkgconfig/meson.build4
-rw-r--r--test cases/unit/103 strip/lib.c3
-rw-r--r--test cases/unit/103 strip/meson.build3
-rw-r--r--test cases/unit/104 debug function/meson.build4
-rw-r--r--test cases/unit/105 pkgconfig relocatable with absolute path/meson.build15
-rw-r--r--test cases/unit/106 subproject symlink/cp.py6
-rw-r--r--test cases/unit/106 subproject symlink/main.c6
-rw-r--r--test cases/unit/106 subproject symlink/meson.build15
-rw-r--r--test cases/unit/106 subproject symlink/symlinked_subproject/datadir/datafile1
-rw-r--r--test cases/unit/106 subproject symlink/symlinked_subproject/datadir/meson.build1
-rw-r--r--test cases/unit/106 subproject symlink/symlinked_subproject/meson.build10
-rw-r--r--test cases/unit/106 subproject symlink/symlinked_subproject/src.c4
-rw-r--r--test cases/unit/107 new subproject on reconfigure/meson.build3
-rw-r--r--test cases/unit/107 new subproject on reconfigure/meson_options.txt1
-rw-r--r--test cases/unit/107 new subproject on reconfigure/subprojects/foo/foo.c2
-rw-r--r--test cases/unit/107 new subproject on reconfigure/subprojects/foo/meson.build8
-rw-r--r--test cases/unit/108 configure same noop/meson.build1
-rw-r--r--test cases/unit/108 configure same noop/meson_options.txt5
-rw-r--r--test cases/unit/109 freeze/freeze.c21
-rw-r--r--test cases/unit/109 freeze/meson.build4
-rw-r--r--test cases/unit/11 cross prog/meson.build16
-rwxr-xr-xtest cases/unit/11 cross prog/some_cross_tool.py4
-rwxr-xr-xtest cases/unit/11 cross prog/sometool.py4
-rw-r--r--test cases/unit/110 classpath/com/mesonbuild/Simple.java7
-rw-r--r--test cases/unit/110 classpath/meson.build14
-rw-r--r--test cases/unit/12 promote/meson.build4
-rw-r--r--test cases/unit/12 promote/subprojects/s1/meson.build7
-rw-r--r--test cases/unit/12 promote/subprojects/s1/s1.c6
-rw-r--r--test cases/unit/12 promote/subprojects/s1/subprojects/s3/meson.build3
-rw-r--r--test cases/unit/12 promote/subprojects/s1/subprojects/s3/s3.c3
-rw-r--r--test cases/unit/12 promote/subprojects/s1/subprojects/scommon/meson.build3
-rw-r--r--test cases/unit/12 promote/subprojects/s1/subprojects/scommon/scommon_broken.c1
-rw-r--r--test cases/unit/12 promote/subprojects/s2/meson.build5
-rw-r--r--test cases/unit/12 promote/subprojects/s2/s2.c6
-rw-r--r--test cases/unit/12 promote/subprojects/s2/subprojects/athing.wrap1
-rw-r--r--test cases/unit/12 promote/subprojects/s2/subprojects/scommon/meson.build3
-rw-r--r--test cases/unit/12 promote/subprojects/s2/subprojects/scommon/scommon_ok.c3
-rw-r--r--test cases/unit/13 reconfigure/meson.build5
-rw-r--r--test cases/unit/14 testsetup selection/main.c3
-rw-r--r--test cases/unit/14 testsetup selection/meson.build10
-rw-r--r--test cases/unit/14 testsetup selection/subprojects/bar/bar.c3
-rw-r--r--test cases/unit/14 testsetup selection/subprojects/bar/meson.build6
-rw-r--r--test cases/unit/14 testsetup selection/subprojects/foo/foo.c3
-rw-r--r--test cases/unit/14 testsetup selection/subprojects/foo/meson.build4
-rw-r--r--test cases/unit/15 prebuilt object/cp.py5
-rw-r--r--test cases/unit/15 prebuilt object/main.c5
-rw-r--r--test cases/unit/15 prebuilt object/meson.build40
-rw-r--r--test cases/unit/15 prebuilt object/source.c8
-rw-r--r--test cases/unit/16 prebuilt static/libdir/best.c3
-rw-r--r--test cases/unit/16 prebuilt static/libdir/best.h3
-rw-r--r--test cases/unit/16 prebuilt static/libdir/meson.build5
-rw-r--r--test cases/unit/16 prebuilt static/main.c7
-rw-r--r--test cases/unit/16 prebuilt static/meson.build5
-rw-r--r--test cases/unit/17 prebuilt shared/alexandria.c6
-rw-r--r--test cases/unit/17 prebuilt shared/alexandria.h20
-rw-r--r--test cases/unit/17 prebuilt shared/another_visitor.c10
-rw-r--r--test cases/unit/17 prebuilt shared/meson.build38
-rw-r--r--test cases/unit/17 prebuilt shared/meson_options.txt1
-rw-r--r--test cases/unit/17 prebuilt shared/patron.c9
-rw-r--r--test cases/unit/17 prebuilt shared/rejected.c8
-rw-r--r--test cases/unit/17 prebuilt shared/rejected.h6
-rw-r--r--test cases/unit/17 prebuilt shared/rejected_main.c6
-rw-r--r--test cases/unit/18 pkgconfig static/foo.c8
-rw-r--r--test cases/unit/18 pkgconfig static/foo.pc.in11
-rw-r--r--test cases/unit/18 pkgconfig static/include/foo.h3
-rw-r--r--test cases/unit/18 pkgconfig static/main.c14
-rw-r--r--test cases/unit/18 pkgconfig static/meson.build37
-rw-r--r--test cases/unit/19 array option/meson.build15
-rw-r--r--test cases/unit/19 array option/meson_options.txt20
-rw-r--r--test cases/unit/2 testsetups/buggy.c14
-rwxr-xr-xtest cases/unit/2 testsetups/envcheck.py5
-rw-r--r--test cases/unit/2 testsetups/impl.c5
-rw-r--r--test cases/unit/2 testsetups/impl.h3
-rw-r--r--test cases/unit/2 testsetups/meson.build33
-rw-r--r--test cases/unit/20 subproj dep variables/meson.build16
-rw-r--r--test cases/unit/20 subproj dep variables/subprojects/failingsubproj/meson.build3
-rw-r--r--test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/meson.build3
-rw-r--r--test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/subprojects/subsubproject.wrap1
-rw-r--r--test cases/unit/20 subproj dep variables/subprojects/somesubproj/meson.build3
-rw-r--r--test cases/unit/21 exit status/meson.build2
-rw-r--r--test cases/unit/22 warning location/a.c0
-rw-r--r--test cases/unit/22 warning location/b.c0
-rw-r--r--test cases/unit/22 warning location/conf.in1
-rw-r--r--test cases/unit/22 warning location/main.c0
-rw-r--r--test cases/unit/22 warning location/meson.build11
-rw-r--r--test cases/unit/22 warning location/sub/c.c0
-rw-r--r--test cases/unit/22 warning location/sub/d.c0
-rw-r--r--test cases/unit/22 warning location/sub/meson.build4
-rw-r--r--test cases/unit/22 warning location/sub/sub.c0
-rw-r--r--test cases/unit/23 unfound pkgconfig/meson.build15
-rw-r--r--test cases/unit/23 unfound pkgconfig/some.c3
-rw-r--r--test cases/unit/24 compiler run_command/meson.build10
-rw-r--r--test cases/unit/25 non-permitted kwargs/meson.build5
-rw-r--r--test cases/unit/26 install umask/datafile.cat1
-rw-r--r--test cases/unit/26 install umask/meson.build7
-rw-r--r--test cases/unit/26 install umask/myinstall.py17
-rw-r--r--test cases/unit/26 install umask/prog.11
-rw-r--r--test cases/unit/26 install umask/prog.c3
-rw-r--r--test cases/unit/26 install umask/sample.h6
-rw-r--r--test cases/unit/26 install umask/subdir/datafile.dog1
-rwxr-xr-xtest cases/unit/26 install umask/subdir/sayhello2
-rw-r--r--test cases/unit/27 pkgconfig usage/dependee/meson.build6
-rw-r--r--test cases/unit/27 pkgconfig usage/dependee/pkguser.c6
-rw-r--r--test cases/unit/27 pkgconfig usage/dependency/meson.build24
-rw-r--r--test cases/unit/27 pkgconfig usage/dependency/pkgdep.c7
-rw-r--r--test cases/unit/27 pkgconfig usage/dependency/pkgdep.h3
-rw-r--r--test cases/unit/27 pkgconfig usage/dependency/privatelib.c3
-rw-r--r--test cases/unit/28 ndebug if-release/main.c11
-rw-r--r--test cases/unit/28 ndebug if-release/meson.build3
-rw-r--r--test cases/unit/29 guessed linker dependencies/exe/app.c6
-rw-r--r--test cases/unit/29 guessed linker dependencies/exe/meson.build7
-rw-r--r--test cases/unit/29 guessed linker dependencies/lib/lib.c20
-rw-r--r--test cases/unit/29 guessed linker dependencies/lib/meson.build11
-rw-r--r--test cases/unit/29 guessed linker dependencies/lib/meson_options.txt1
-rw-r--r--test cases/unit/3 subproject defaults/meson.build10
-rw-r--r--test cases/unit/3 subproject defaults/meson_options.txt3
-rw-r--r--test cases/unit/3 subproject defaults/subprojects/foob/meson.build11
-rw-r--r--test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt5
-rw-r--r--test cases/unit/30 shared_mod linking/libfile.c14
-rw-r--r--test cases/unit/30 shared_mod linking/main.c11
-rw-r--r--test cases/unit/30 shared_mod linking/meson.build5
-rw-r--r--test cases/unit/31 forcefallback/meson.build9
-rw-r--r--test cases/unit/31 forcefallback/subprojects/notzlib/meson.build7
-rw-r--r--test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.c6
-rw-r--r--test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.h18
-rw-r--r--test cases/unit/31 forcefallback/test_not_zlib.c8
-rw-r--r--test cases/unit/32 pkgconfig use libraries/app/app.c6
-rw-r--r--test cases/unit/32 pkgconfig use libraries/app/meson.build5
-rw-r--r--test cases/unit/32 pkgconfig use libraries/lib/liba.c2
-rw-r--r--test cases/unit/32 pkgconfig use libraries/lib/libb.c5
-rw-r--r--test cases/unit/32 pkgconfig use libraries/lib/meson.build14
-rw-r--r--test cases/unit/33 cross file overrides always args/meson.build3
-rw-r--r--test cases/unit/33 cross file overrides always args/test.c8
-rw-r--r--test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt19
-rw-r--r--test cases/unit/34 command line/meson.build9
-rw-r--r--test cases/unit/34 command line/meson_options.txt2
-rw-r--r--test cases/unit/34 command line/subprojects/subp/meson.build3
-rw-r--r--test cases/unit/34 command line/subprojects/subp/meson_options.txt1
-rw-r--r--test cases/unit/35 dist script/meson.build10
-rw-r--r--test cases/unit/35 dist script/prog.c7
-rwxr-xr-xtest cases/unit/35 dist script/replacer.py16
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/dist-script.py12
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/meson.build11
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/meson_options.txt1
-rw-r--r--test cases/unit/35 dist script/subprojects/sub/prog.c1
-rw-r--r--test cases/unit/36 exe_wrapper behaviour/broken-cross.txt20
-rw-r--r--test cases/unit/36 exe_wrapper behaviour/meson.build19
-rw-r--r--test cases/unit/36 exe_wrapper behaviour/meson_options.txt2
-rw-r--r--test cases/unit/36 exe_wrapper behaviour/prog.c17
-rw-r--r--test cases/unit/37 mixed command line args/meson.build1
-rw-r--r--test cases/unit/37 mixed command line args/meson_options.txt10
-rw-r--r--test cases/unit/38 pkgconfig format/meson.build18
-rw-r--r--test cases/unit/38 pkgconfig format/somelib.c7
-rw-r--r--test cases/unit/38 pkgconfig format/someret.c3
-rw-r--r--test cases/unit/39 external, internal library rpath/built library/bar.c7
-rw-r--r--test cases/unit/39 external, internal library rpath/built library/meson.build26
-rw-r--r--test cases/unit/39 external, internal library rpath/built library/meson_options.txt1
-rw-r--r--test cases/unit/39 external, internal library rpath/built library/prog.c7
-rw-r--r--test cases/unit/39 external, internal library rpath/external library/bar.c6
-rw-r--r--test cases/unit/39 external, internal library rpath/external library/faa.c4
-rw-r--r--test cases/unit/39 external, internal library rpath/external library/foo.c4
-rw-r--r--test cases/unit/39 external, internal library rpath/external library/meson.build22
-rw-r--r--test cases/unit/4 suite selection/failing_test.c1
-rw-r--r--test cases/unit/4 suite selection/meson.build17
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjfail/failing_test.c1
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjfail/meson.build9
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjmix/failing_test.c1
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjmix/meson.build9
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjmix/successful_test.c1
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build9
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjsucc/successful_test.c1
-rw-r--r--test cases/unit/4 suite selection/successful_test.c1
-rw-r--r--test cases/unit/40 featurenew subprojects/meson.build7
-rw-r--r--test cases/unit/40 featurenew subprojects/subprojects/bar/meson.build3
-rw-r--r--test cases/unit/40 featurenew subprojects/subprojects/baz/meson.build3
-rw-r--r--test cases/unit/40 featurenew subprojects/subprojects/foo/meson.build3
-rw-r--r--test cases/unit/41 rpath order/meson.build11
-rw-r--r--test cases/unit/41 rpath order/myexe.c3
-rw-r--r--test cases/unit/41 rpath order/subprojects/sub1/lib.c0
-rw-r--r--test cases/unit/41 rpath order/subprojects/sub1/meson.build5
-rw-r--r--test cases/unit/41 rpath order/subprojects/sub2/lib.c0
-rw-r--r--test cases/unit/41 rpath order/subprojects/sub2/meson.build5
-rw-r--r--test cases/unit/42 dep order/lib1.c0
-rw-r--r--test cases/unit/42 dep order/lib2.c0
-rw-r--r--test cases/unit/42 dep order/meson.build8
-rw-r--r--test cases/unit/42 dep order/myexe.c3
-rw-r--r--test cases/unit/43 promote wrap/meson.build4
-rw-r--r--test cases/unit/43 promote wrap/subprojects/s1/meson.build1
-rw-r--r--test cases/unit/43 promote wrap/subprojects/s1/subprojects/ambiguous/meson.build1
-rw-r--r--test cases/unit/43 promote wrap/subprojects/s2/meson.build1
-rw-r--r--test cases/unit/43 promote wrap/subprojects/s2/subprojects/ambiguous.wrap2
-rw-r--r--test cases/unit/44 vscpp17/main.cpp29
-rw-r--r--test cases/unit/44 vscpp17/meson.build4
-rwxr-xr-xtest cases/unit/45 native dep pkgconfig var/cross_pkgconfig.py12
-rw-r--r--test cases/unit/45 native dep pkgconfig var/cross_pkgconfig/dep_tester.pc5
-rw-r--r--test cases/unit/45 native dep pkgconfig var/meson.build15
-rw-r--r--test cases/unit/45 native dep pkgconfig var/meson_options.txt6
-rw-r--r--test cases/unit/45 native dep pkgconfig var/native_pkgconfig/dep_tester.pc5
-rw-r--r--test cases/unit/46 native file binary/meson.build21
-rw-r--r--test cases/unit/46 native file binary/meson_options.txt5
-rw-r--r--test cases/unit/47 reconfigure/main.c4
-rw-r--r--test cases/unit/47 reconfigure/meson.build11
-rw-r--r--test cases/unit/47 reconfigure/meson_options.txt4
-rw-r--r--test cases/unit/47 reconfigure/subprojects/sub1/meson.build3
-rw-r--r--test cases/unit/48 testsetup default/envcheck.py11
-rw-r--r--test cases/unit/48 testsetup default/meson.build23
-rw-r--r--test cases/unit/49 pkgconfig csharp library/meson.build10
-rw-r--r--test cases/unit/49 pkgconfig csharp library/somelib.cs12
-rw-r--r--test cases/unit/5 compiler detection/compiler wrapper.py6
-rw-r--r--test cases/unit/5 compiler detection/meson.build8
-rw-r--r--test cases/unit/5 compiler detection/trivial.c6
-rw-r--r--test cases/unit/5 compiler detection/trivial.cc6
-rw-r--r--test cases/unit/5 compiler detection/trivial.m5
-rw-r--r--test cases/unit/5 compiler detection/trivial.mm8
-rw-r--r--test cases/unit/50 noncross options/meson.build14
-rw-r--r--test cases/unit/50 noncross options/prog.c1
-rw-r--r--test cases/unit/50 noncross options/ylib.pc13
-rw-r--r--test cases/unit/51 ldflagdedup/bob.c5
-rw-r--r--test cases/unit/51 ldflagdedup/meson.build12
-rw-r--r--test cases/unit/51 ldflagdedup/prog.c7
-rw-r--r--test cases/unit/52 pkgconfig static link order/dummy.c0
-rw-r--r--test cases/unit/52 pkgconfig static link order/meson.build11
-rw-r--r--test cases/unit/53 clang-format/.clang-format5
-rw-r--r--test cases/unit/53 clang-format/dummydir.h/dummy.dat1
-rw-r--r--test cases/unit/53 clang-format/header_expected_h3
-rw-r--r--test cases/unit/53 clang-format/header_orig_h9
-rw-r--r--test cases/unit/53 clang-format/meson.build3
-rw-r--r--test cases/unit/53 clang-format/prog_expected_c6
-rw-r--r--test cases/unit/53 clang-format/prog_orig_c20
-rw-r--r--test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson.build9
-rw-r--r--test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson_options.txt1
-rw-r--r--test cases/unit/55 dedup compiler libs/app/app.c13
-rw-r--r--test cases/unit/55 dedup compiler libs/app/meson.build2
-rw-r--r--test cases/unit/55 dedup compiler libs/liba/liba.c18
-rw-r--r--test cases/unit/55 dedup compiler libs/liba/liba.h8
-rw-r--r--test cases/unit/55 dedup compiler libs/liba/meson.build8
-rw-r--r--test cases/unit/55 dedup compiler libs/libb/libb.c7
-rw-r--r--test cases/unit/55 dedup compiler libs/libb/libb.h6
-rw-r--r--test cases/unit/55 dedup compiler libs/libb/meson.build6
-rw-r--r--test cases/unit/55 dedup compiler libs/meson.build7
-rw-r--r--test cases/unit/56 introspection/cp.py5
-rw-r--r--test cases/unit/56 introspection/meson.build72
-rw-r--r--test cases/unit/56 introspection/meson_options.txt2
-rw-r--r--test cases/unit/56 introspection/sharedlib/meson.build2
-rw-r--r--test cases/unit/56 introspection/sharedlib/shared.cpp9
-rw-r--r--test cases/unit/56 introspection/sharedlib/shared.hpp10
-rw-r--r--test cases/unit/56 introspection/staticlib/meson.build3
-rw-r--r--test cases/unit/56 introspection/staticlib/static.c5
-rw-r--r--test cases/unit/56 introspection/staticlib/static.h11
-rw-r--r--test cases/unit/56 introspection/t1.cpp13
-rw-r--r--test cases/unit/56 introspection/t2.cpp8
-rw-r--r--test cases/unit/56 introspection/t3.cpp16
-rw-r--r--test cases/unit/57 pkg_config_path option/build_extra_path/totally_made_up_dep.pc7
-rw-r--r--test cases/unit/57 pkg_config_path option/host_extra_path/totally_made_up_dep.pc7
-rw-r--r--test cases/unit/57 pkg_config_path option/meson.build7
-rw-r--r--test cases/unit/58 introspect buildoptions/c_compiler.py3
-rw-r--r--test cases/unit/58 introspect buildoptions/main.c6
-rw-r--r--test cases/unit/58 introspect buildoptions/meson.build18
-rw-r--r--test cases/unit/58 introspect buildoptions/meson_options.txt2
-rw-r--r--test cases/unit/58 introspect buildoptions/subprojects/evilFile.txt0
-rw-r--r--test cases/unit/58 introspect buildoptions/subprojects/projectA/meson.build3
-rw-r--r--test cases/unit/58 introspect buildoptions/subprojects/projectA/meson_options.txt1
-rw-r--r--test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson.build9
-rw-r--r--test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson_options.txt1
-rw-r--r--test cases/unit/59 native file override/crossfile16
-rw-r--r--test cases/unit/59 native file override/crossfile24
-rw-r--r--test cases/unit/59 native file override/meson.build10
-rw-r--r--test cases/unit/59 native file override/meson_options.txt13
-rw-r--r--test cases/unit/59 native file override/nativefile16
-rw-r--r--test cases/unit/6 std override/meson.build10
-rw-r--r--test cases/unit/6 std override/prog11.cpp6
-rw-r--r--test cases/unit/6 std override/prog98.cpp6
-rw-r--r--test cases/unit/6 std override/progp.cpp6
-rwxr-xr-xtest cases/unit/60 identity cross/build_wrapper.py11
-rwxr-xr-xtest cases/unit/60 identity cross/host_wrapper.py11
-rw-r--r--test cases/unit/60 identity cross/meson.build15
-rw-r--r--test cases/unit/60 identity cross/stuff.h27
-rw-r--r--test cases/unit/61 pkgconfig relative paths/pkgconfig/librelativepath.pc9
-rw-r--r--test cases/unit/62 cmake_prefix_path/meson.build4
-rw-r--r--test cases/unit/62 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake4
-rw-r--r--test cases/unit/63 cmake parser/meson.build19
-rw-r--r--test cases/unit/63 cmake parser/prefix/lib/cmake/mesontest/mesontest-config.cmake63
-rw-r--r--test cases/unit/64 alias target/main.c3
-rw-r--r--test cases/unit/64 alias target/meson.build17
-rw-r--r--test cases/unit/64 alias target/subdir/meson.build6
-rw-r--r--test cases/unit/65 static archive stripping/app/appA.c4
-rw-r--r--test cases/unit/65 static archive stripping/app/appB.c4
-rw-r--r--test cases/unit/65 static archive stripping/app/meson.build7
-rw-r--r--test cases/unit/65 static archive stripping/lib/libA.c5
-rw-r--r--test cases/unit/65 static archive stripping/lib/libA.h1
-rw-r--r--test cases/unit/65 static archive stripping/lib/libB.c5
-rw-r--r--test cases/unit/65 static archive stripping/lib/libB.h1
-rw-r--r--test cases/unit/65 static archive stripping/lib/meson.build23
-rw-r--r--test cases/unit/66 static link/lib/func1.c9
-rw-r--r--test cases/unit/66 static link/lib/func10.c4
-rw-r--r--test cases/unit/66 static link/lib/func11.c6
-rw-r--r--test cases/unit/66 static link/lib/func12.c7
-rw-r--r--test cases/unit/66 static link/lib/func14.c4
-rw-r--r--test cases/unit/66 static link/lib/func15.c6
-rw-r--r--test cases/unit/66 static link/lib/func16.c6
-rw-r--r--test cases/unit/66 static link/lib/func17.c4
-rw-r--r--test cases/unit/66 static link/lib/func18.c6
-rw-r--r--test cases/unit/66 static link/lib/func19.c7
-rw-r--r--test cases/unit/66 static link/lib/func2.c6
-rw-r--r--test cases/unit/66 static link/lib/func3.c4
-rw-r--r--test cases/unit/66 static link/lib/func4.c6
-rw-r--r--test cases/unit/66 static link/lib/func5.c4
-rw-r--r--test cases/unit/66 static link/lib/func6.c6
-rw-r--r--test cases/unit/66 static link/lib/func7.c4
-rw-r--r--test cases/unit/66 static link/lib/func8.c6
-rw-r--r--test cases/unit/66 static link/lib/func9.c6
-rw-r--r--test cases/unit/66 static link/lib/meson.build80
-rw-r--r--test cases/unit/66 static link/meson.build32
-rw-r--r--test cases/unit/66 static link/test1.c7
-rw-r--r--test cases/unit/66 static link/test2.c6
-rw-r--r--test cases/unit/66 static link/test3.c6
-rw-r--r--test cases/unit/66 static link/test4.c6
-rw-r--r--test cases/unit/66 static link/test5.c6
-rw-r--r--test cases/unit/67 test env value/meson.build10
-rwxr-xr-xtest cases/unit/67 test env value/test.py6
-rw-r--r--test cases/unit/68 clang-tidy/.clang-tidy1
-rw-r--r--test cases/unit/68 clang-tidy/cttest.cpp7
-rw-r--r--test cases/unit/68 clang-tidy/dummydir.h/dummy.dat1
-rw-r--r--test cases/unit/68 clang-tidy/meson.build3
-rw-r--r--test cases/unit/69 cross/crossfile.in5
-rw-r--r--test cases/unit/69 cross/meson.build16
-rw-r--r--test cases/unit/69 cross/meson_options.txt1
-rw-r--r--test cases/unit/7 run installed/foo/foo.c3
-rw-r--r--test cases/unit/7 run installed/foo/meson.build6
-rw-r--r--test cases/unit/7 run installed/meson.build8
-rw-r--r--test cases/unit/7 run installed/prog.c5
-rwxr-xr-xtest cases/unit/70 cross test passed/exewrapper.py24
-rw-r--r--test cases/unit/70 cross test passed/meson.build19
-rw-r--r--test cases/unit/70 cross test passed/meson_options.txt5
-rw-r--r--test cases/unit/70 cross test passed/script.py7
-rw-r--r--test cases/unit/70 cross test passed/src/main.c6
-rw-r--r--test cases/unit/71 summary/meson.build24
-rw-r--r--test cases/unit/71 summary/meson_options.txt1
-rw-r--r--test cases/unit/71 summary/subprojects/sub/meson.build4
-rw-r--r--test cases/unit/71 summary/subprojects/sub2/meson.build6
-rw-r--r--test cases/unit/71 summary/subprojects/sub2/subprojects/subsub/meson.build3
-rw-r--r--test cases/unit/72 wrap file url/meson.build4
-rw-r--r--test cases/unit/72 wrap file url/subprojects/foo-patch.tar.xzbin0 -> 228 bytes
-rw-r--r--test cases/unit/72 wrap file url/subprojects/foo.tar.xzbin0 -> 216 bytes
-rw-r--r--test cases/unit/73 dep files/foo.c0
-rw-r--r--test cases/unit/73 dep files/meson.build16
-rw-r--r--test cases/unit/74 pkgconfig prefixes/client/client.c8
-rw-r--r--test cases/unit/74 pkgconfig prefixes/client/meson.build3
-rw-r--r--test cases/unit/74 pkgconfig prefixes/val1/meson.build5
-rw-r--r--test cases/unit/74 pkgconfig prefixes/val1/val1.c3
-rw-r--r--test cases/unit/74 pkgconfig prefixes/val1/val1.h1
-rw-r--r--test cases/unit/74 pkgconfig prefixes/val2/meson.build8
-rw-r--r--test cases/unit/74 pkgconfig prefixes/val2/val2.c4
-rw-r--r--test cases/unit/74 pkgconfig prefixes/val2/val2.h1
-rw-r--r--test cases/unit/75 subdir libdir/meson.build2
-rw-r--r--test cases/unit/75 subdir libdir/subprojects/flub/meson.build1
-rw-r--r--test cases/unit/76 as link whole/bar.c6
-rw-r--r--test cases/unit/76 as link whole/foo.c6
-rw-r--r--test cases/unit/76 as link whole/meson.build11
-rw-r--r--test cases/unit/77 nostdlib/meson.build14
-rw-r--r--test cases/unit/77 nostdlib/prog.c7
-rw-r--r--test cases/unit/77 nostdlib/subprojects/mylibc/libc.c35
-rw-r--r--test cases/unit/77 nostdlib/subprojects/mylibc/meson.build13
-rw-r--r--test cases/unit/77 nostdlib/subprojects/mylibc/stdio.h5
-rw-r--r--test cases/unit/77 nostdlib/subprojects/mylibc/stubstart.s8
-rw-r--r--test cases/unit/78 user options for subproject/.gitignore1
-rw-r--r--test cases/unit/78 user options for subproject/75 user options for subproject/.gitignore1
-rw-r--r--test cases/unit/78 user options for subproject/75 user options for subproject/meson.build3
-rw-r--r--test cases/unit/78 user options for subproject/subprojects/sub/meson.build45
-rw-r--r--test cases/unit/78 user options for subproject/subprojects/sub/meson_options.txt9
-rw-r--r--test cases/unit/79 global-rpath/meson.build3
-rw-r--r--test cases/unit/79 global-rpath/rpathified.cpp6
-rw-r--r--test cases/unit/79 global-rpath/yonder/meson.build5
-rw-r--r--test cases/unit/79 global-rpath/yonder/yonder.cpp3
-rw-r--r--test cases/unit/79 global-rpath/yonder/yonder.h1
-rw-r--r--test cases/unit/8 -L -l order/first.pc13
-rw-r--r--test cases/unit/8 -L -l order/meson.build6
-rw-r--r--test cases/unit/8 -L -l order/prog.c5
-rw-r--r--test cases/unit/8 -L -l order/second.pc13
-rw-r--r--test cases/unit/80 wrap-git/meson.build4
-rw-r--r--test cases/unit/80 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build3
-rw-r--r--test cases/unit/80 wrap-git/subprojects/wrap_git_upstream/main.c4
-rw-r--r--test cases/unit/81 meson version compare/meson.build19
-rw-r--r--test cases/unit/81 meson version compare/subprojects/foo/meson.build8
-rw-r--r--test cases/unit/82 cross only introspect/meson.build2
-rw-r--r--test cases/unit/83 change option choices/meson.build1
-rw-r--r--test cases/unit/83 change option choices/meson_options.1.txt13
-rw-r--r--test cases/unit/83 change option choices/meson_options.2.txt13
-rw-r--r--test cases/unit/84 nested subproject regenerate depends/main.c3
-rw-r--r--test cases/unit/84 nested subproject regenerate depends/meson.build10
-rw-r--r--test cases/unit/84 nested subproject regenerate depends/subprojects/sub1/meson.build4
-rw-r--r--test cases/unit/84 nested subproject regenerate depends/subprojects/sub2/CMakeLists.txt1
-rw-r--r--test cases/unit/85 cpp modules/gcc/main.cpp7
-rw-r--r--test cases/unit/85 cpp modules/gcc/meson.build19
-rw-r--r--test cases/unit/85 cpp modules/gcc/src0.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src1.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src2.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src3.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src4.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src5.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src6.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src7.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src8.cxx7
-rw-r--r--test cases/unit/85 cpp modules/gcc/src9.cxx5
-rw-r--r--test cases/unit/85 cpp modules/meson.build11
-rw-r--r--test cases/unit/85 cpp modules/vs/main.cpp7
-rw-r--r--test cases/unit/85 cpp modules/vs/meson.build15
-rw-r--r--test cases/unit/85 cpp modules/vs/src0.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src1.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src2.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src3.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src4.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src5.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src6.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src7.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src8.ixx7
-rw-r--r--test cases/unit/85 cpp modules/vs/src9.ixx5
-rw-r--r--test cases/unit/86 prelinking/file1.c14
-rw-r--r--test cases/unit/86 prelinking/file2.c9
-rw-r--r--test cases/unit/86 prelinking/file3.c9
-rw-r--r--test cases/unit/86 prelinking/file4.c9
-rw-r--r--test cases/unit/86 prelinking/main.c10
-rw-r--r--test cases/unit/86 prelinking/meson.build7
-rw-r--r--test cases/unit/86 prelinking/private_header.h11
-rw-r--r--test cases/unit/86 prelinking/public_header.h3
-rw-r--r--test cases/unit/87 run native test/main.c17
-rw-r--r--test cases/unit/87 run native test/meson.build6
-rw-r--r--test cases/unit/88 multiple envvars/meson.build4
-rw-r--r--test cases/unit/88 multiple envvars/prog.c18
-rw-r--r--test cases/unit/88 multiple envvars/prog.cpp18
-rw-r--r--test cases/unit/89 pkgconfig build rpath order/dummy.pc7
-rw-r--r--test cases/unit/89 pkgconfig build rpath order/meson.build20
-rw-r--r--test cases/unit/89 pkgconfig build rpath order/prog.c5
-rw-r--r--test cases/unit/89 pkgconfig build rpath order/prog.cc8
-rw-r--r--test cases/unit/89 pkgconfig build rpath order/sub/meson.build1
-rw-r--r--test cases/unit/89 pkgconfig build rpath order/sub/stuff.c3
-rw-r--r--test cases/unit/9 d dedup/meson.build5
-rw-r--r--test cases/unit/9 d dedup/prog.c14
-rw-r--r--test cases/unit/90 devenv/main.c14
-rw-r--r--test cases/unit/90 devenv/meson.build17
-rw-r--r--test cases/unit/90 devenv/subprojects/sub/foo.c10
-rw-r--r--test cases/unit/90 devenv/subprojects/sub/meson.build6
-rwxr-xr-xtest cases/unit/90 devenv/test-devenv.py8
-rw-r--r--test cases/unit/91 install skip subprojects/foo.c4
-rw-r--r--test cases/unit/91 install skip subprojects/foo.dat1
-rw-r--r--test cases/unit/91 install skip subprojects/foo.h1
-rw-r--r--test cases/unit/91 install skip subprojects/foo/foofile0
-rw-r--r--test cases/unit/91 install skip subprojects/meson.build8
-rw-r--r--test cases/unit/91 install skip subprojects/subprojects/bar/bar.c4
-rw-r--r--test cases/unit/91 install skip subprojects/subprojects/bar/bar.dat1
-rw-r--r--test cases/unit/91 install skip subprojects/subprojects/bar/bar.h1
-rw-r--r--test cases/unit/91 install skip subprojects/subprojects/bar/bar/barfile1
-rw-r--r--test cases/unit/91 install skip subprojects/subprojects/bar/meson.build6
-rw-r--r--test cases/unit/92 new subproject in configured project/meson.build7
-rw-r--r--test cases/unit/92 new subproject in configured project/meson_options.txt3
-rw-r--r--test cases/unit/92 new subproject in configured project/subprojects/sub/foo.c6
-rw-r--r--test cases/unit/92 new subproject in configured project/subprojects/sub/meson.build7
-rw-r--r--test cases/unit/93 clangformat/.clang-format4
-rw-r--r--test cases/unit/93 clangformat/.clang-format-ignore3
-rw-r--r--test cases/unit/93 clangformat/.clang-format-include3
-rw-r--r--test cases/unit/93 clangformat/meson.build1
-rw-r--r--test cases/unit/93 clangformat/not-included/badformat.cpp2
-rw-r--r--test cases/unit/93 clangformat/src/badformat.c2
-rw-r--r--test cases/unit/93 clangformat/src/badformat.cpp2
-rw-r--r--test cases/unit/94 custominc/easytogrepfor/genh.py7
-rw-r--r--test cases/unit/94 custominc/easytogrepfor/meson.build3
-rw-r--r--test cases/unit/94 custominc/helper.c5
-rw-r--r--test cases/unit/94 custominc/meson.build9
-rw-r--r--test cases/unit/94 custominc/prog.c9
-rw-r--r--test cases/unit/94 custominc/prog2.c10
-rw-r--r--test cases/unit/95 implicit force fallback/meson.build8
-rw-r--r--test cases/unit/95 implicit force fallback/subprojects/something/meson.build3
-rw-r--r--test cases/unit/96 compiler.links file arg/meson.build11
-rw-r--r--test cases/unit/96 compiler.links file arg/test.c1
-rw-r--r--test cases/unit/97 link full name/.gitignore5
-rw-r--r--test cases/unit/97 link full name/libtestprovider/meson.build20
-rw-r--r--test cases/unit/97 link full name/libtestprovider/provider.c12
-rw-r--r--test cases/unit/97 link full name/proguser/meson.build11
-rw-r--r--test cases/unit/97 link full name/proguser/receiver.c18
-rw-r--r--test cases/unit/98 install all targets/bar-custom.txt0
-rw-r--r--test cases/unit/98 install all targets/bar-devel.h0
-rw-r--r--test cases/unit/98 install all targets/bar-notag.txt0
-rw-r--r--test cases/unit/98 install all targets/custom_files/data.txt1
-rw-r--r--test cases/unit/98 install all targets/foo.in0
-rw-r--r--test cases/unit/98 install all targets/foo1-devel.h0
-rw-r--r--test cases/unit/98 install all targets/lib.c9
-rw-r--r--test cases/unit/98 install all targets/main.c3
-rw-r--r--test cases/unit/98 install all targets/meson.build108
-rw-r--r--test cases/unit/98 install all targets/script.py7
-rw-r--r--test cases/unit/98 install all targets/subdir/bar2-devel.h0
-rw-r--r--test cases/unit/98 install all targets/subdir/foo2.in0
-rw-r--r--test cases/unit/98 install all targets/subdir/foo3-devel.h0
-rw-r--r--test cases/unit/98 install all targets/subdir/lib.c9
-rw-r--r--test cases/unit/98 install all targets/subdir/main.c3
-rw-r--r--test cases/unit/98 install all targets/subdir/meson.build21
-rw-r--r--test cases/unit/98 install all targets/subdir/script.py7
-rw-r--r--test cases/unit/99 custom target name/file.txt.in0
-rw-r--r--test cases/unit/99 custom target name/meson.build14
-rw-r--r--test cases/unit/99 custom target name/subdir/meson.build9
-rw-r--r--test cases/vala/1 basic/meson.build7
-rw-r--r--test cases/vala/1 basic/prog.vala7
-rw-r--r--test cases/vala/10 mixed sources/c/foo.c5
-rw-r--r--test cases/vala/10 mixed sources/c/meson.build5
-rw-r--r--test cases/vala/10 mixed sources/c/writec.py12
-rw-r--r--test cases/vala/10 mixed sources/meson.build7
-rw-r--r--test cases/vala/10 mixed sources/vala/bar.vala5
-rw-r--r--test cases/vala/11 generated vapi/libbar/bar.c29
-rw-r--r--test cases/vala/11 generated vapi/libbar/bar.h9
-rw-r--r--test cases/vala/11 generated vapi/libbar/meson.build32
-rw-r--r--test cases/vala/11 generated vapi/libfoo/foo.c28
-rw-r--r--test cases/vala/11 generated vapi/libfoo/foo.h9
-rw-r--r--test cases/vala/11 generated vapi/libfoo/foo.metadata1
-rw-r--r--test cases/vala/11 generated vapi/libfoo/meson.build42
-rw-r--r--test cases/vala/11 generated vapi/main.vala9
-rw-r--r--test cases/vala/11 generated vapi/meson.build13
-rw-r--r--test cases/vala/11 generated vapi/test.json13
-rw-r--r--test cases/vala/12 custom output/bar.vala0
-rw-r--r--test cases/vala/12 custom output/foo.vala0
-rw-r--r--test cases/vala/12 custom output/meson.build13
-rw-r--r--test cases/vala/13 find library/meson.build9
-rw-r--r--test cases/vala/13 find library/test.vala6
-rw-r--r--test cases/vala/14 target glib version and gresources/gres/meson.build3
-rw-r--r--test cases/vala/14 target glib version and gresources/gres/test-resources.xml6
-rw-r--r--test cases/vala/14 target glib version and gresources/gres/test.ui19
-rw-r--r--test cases/vala/14 target glib version and gresources/meson.build12
-rw-r--r--test cases/vala/14 target glib version and gresources/test.vala37
-rw-r--r--test cases/vala/15 static vapi in source tree/meson.build13
-rw-r--r--test cases/vala/15 static vapi in source tree/test.vala6
-rw-r--r--test cases/vala/15 static vapi in source tree/vapi/config.vapi4
-rw-r--r--test cases/vala/16 mixed dependence/app.vala7
-rw-r--r--test cases/vala/16 mixed dependence/meson.build16
-rw-r--r--test cases/vala/16 mixed dependence/mixer-glue.c5
-rw-r--r--test cases/vala/16 mixed dependence/mixer.vala3
-rw-r--r--test cases/vala/17 plain consumer/app.c11
-rw-r--r--test cases/vala/17 plain consumer/badger.vala10
-rw-r--r--test cases/vala/17 plain consumer/meson.build12
-rw-r--r--test cases/vala/18 vapi consumed twice/app.vala11
-rw-r--r--test cases/vala/18 vapi consumed twice/beer.vala10
-rw-r--r--test cases/vala/18 vapi consumed twice/meson.build15
-rw-r--r--test cases/vala/18 vapi consumed twice/person.vala16
-rw-r--r--test cases/vala/19 genie/meson.build6
-rw-r--r--test cases/vala/19 genie/prog.gs2
-rw-r--r--test cases/vala/2 multiple files/class1.vala7
-rw-r--r--test cases/vala/2 multiple files/class2.vala6
-rw-r--r--test cases/vala/2 multiple files/main.vala8
-rw-r--r--test cases/vala/2 multiple files/meson.build10
-rw-r--r--test cases/vala/20 genie multiple mixed sources/c_test_one.c5
-rw-r--r--test cases/vala/20 genie multiple mixed sources/c_test_two.c5
-rw-r--r--test cases/vala/20 genie multiple mixed sources/init.gs10
-rw-r--r--test cases/vala/20 genie multiple mixed sources/meson.build19
-rw-r--r--test cases/vala/20 genie multiple mixed sources/test_one.gs5
-rw-r--r--test cases/vala/20 genie multiple mixed sources/test_two.gs5
-rw-r--r--test cases/vala/20 genie multiple mixed sources/vala_test_one.vala7
-rw-r--r--test cases/vala/20 genie multiple mixed sources/vala_test_two.vala7
-rw-r--r--test cases/vala/21 type module/foo.vala17
-rw-r--r--test cases/vala/21 type module/meson.build20
-rw-r--r--test cases/vala/21 type module/plugin-bar.vala11
-rw-r--r--test cases/vala/21 type module/plugin-module.vala54
-rw-r--r--test cases/vala/21 type module/plugin.vala4
-rw-r--r--test cases/vala/22 same target in directories/Subdir/Subdir2/Test.vala5
-rw-r--r--test cases/vala/22 same target in directories/Subdir/Test.vala5
-rw-r--r--test cases/vala/22 same target in directories/Subdir2/Test.vala5
-rw-r--r--test cases/vala/22 same target in directories/Test.vala5
-rw-r--r--test cases/vala/22 same target in directories/meson.build13
-rw-r--r--test cases/vala/22 same target in directories/prog.vala8
-rw-r--r--test cases/vala/23 thread flags/meson.build7
-rw-r--r--test cases/vala/23 thread flags/prog.vala2
-rw-r--r--test cases/vala/24 export dynamic shared module/app.vala21
-rw-r--r--test cases/vala/24 export dynamic shared module/meson.build20
-rw-r--r--test cases/vala/24 export dynamic shared module/module.vala3
-rw-r--r--test cases/vala/25 extract_all_objects/meson.build11
-rw-r--r--test cases/vala/25 extract_all_objects/prog.vala7
-rw-r--r--test cases/vala/26 vala and asm/meson.build23
-rw-r--r--test cases/vala/26 vala and asm/prog.vala9
-rw-r--r--test cases/vala/26 vala and asm/retval-arm.S11
-rw-r--r--test cases/vala/26 vala and asm/retval-x86.S12
-rw-r--r--test cases/vala/26 vala and asm/retval-x86_64.S11
-rw-r--r--test cases/vala/26 vala and asm/symbol-underscore.h5
-rw-r--r--test cases/vala/3 dep/gioprog.vala8
-rw-r--r--test cases/vala/3 dep/meson.build12
-rw-r--r--test cases/vala/4 config/config.vapi1
-rw-r--r--test cases/vala/4 config/meson-something-else.vapi1
-rw-r--r--test cases/vala/4 config/meson.build15
-rw-r--r--test cases/vala/4 config/prog.vala8
-rw-r--r--test cases/vala/5 target glib/GLib.Thread.vala43
-rw-r--r--test cases/vala/5 target glib/meson.build10
-rw-r--r--test cases/vala/5 target glib/retcode.c5
-rw-r--r--test cases/vala/6 static library/meson.build17
-rw-r--r--test cases/vala/6 static library/mylib.vala5
-rw-r--r--test cases/vala/6 static library/prog.vala7
-rw-r--r--test cases/vala/6 static library/test.json5
-rw-r--r--test cases/vala/7 shared library/lib/meson.build35
-rw-r--r--test cases/vala/7 shared library/lib/mylib.vala5
-rw-r--r--test cases/vala/7 shared library/meson.build10
-rw-r--r--test cases/vala/7 shared library/prog/meson.build4
-rw-r--r--test cases/vala/7 shared library/prog/prog.vala7
-rw-r--r--test cases/vala/7 shared library/test.json14
-rw-r--r--test cases/vala/8 generated sources/dependency-generated/enum-types.c.template43
-rw-r--r--test cases/vala/8 generated sources/dependency-generated/enum-types.h.template26
-rw-r--r--test cases/vala/8 generated sources/dependency-generated/enums.h15
-rw-r--r--test cases/vala/8 generated sources/dependency-generated/lib.vala3
-rw-r--r--test cases/vala/8 generated sources/dependency-generated/main.vala3
-rw-r--r--test cases/vala/8 generated sources/dependency-generated/meson.build44
-rw-r--r--test cases/vala/8 generated sources/dependency-generated/null.c1
-rw-r--r--test cases/vala/8 generated sources/meson.build14
-rw-r--r--test cases/vala/8 generated sources/onlygen/maingen.in3
-rw-r--r--test cases/vala/8 generated sources/onlygen/meson.build7
-rw-r--r--test cases/vala/8 generated sources/src/config.vala.in3
-rw-r--r--test cases/vala/8 generated sources/src/copy_file.py6
-rw-r--r--test cases/vala/8 generated sources/src/meson.build17
-rw-r--r--test cases/vala/8 generated sources/src/returncode.in3
-rw-r--r--test cases/vala/8 generated sources/src/test.vala4
-rw-r--r--test cases/vala/8 generated sources/src/write_wrapper.py12
-rw-r--r--test cases/vala/8 generated sources/test.json7
-rw-r--r--test cases/vala/8 generated sources/tools/meson.build3
-rw-r--r--test cases/vala/9 gir/foo.vala7
-rw-r--r--test cases/vala/9 gir/meson.build17
-rw-r--r--test cases/vala/9 gir/test.json7
-rw-r--r--test cases/warning/1 version for string div/a/b.c3
-rw-r--r--test cases/warning/1 version for string div/meson.build3
-rw-r--r--test cases/warning/1 version for string div/test.json8
-rw-r--r--test cases/warning/2 languages missing native/meson.build3
-rw-r--r--test cases/warning/2 languages missing native/test.json7
-rw-r--r--test cases/warning/3 fallback consistency/meson.build7
-rw-r--r--test cases/warning/3 fallback consistency/subprojects/sub/meson.build5
-rw-r--r--test cases/warning/3 fallback consistency/test.json10
-rw-r--r--test cases/warning/4 fallback consistency/meson.build4
-rw-r--r--test cases/warning/4 fallback consistency/subprojects/sub/meson.build5
-rw-r--r--test cases/warning/4 fallback consistency/test.json10
-rw-r--r--test cases/warning/5 fallback consistency/meson.build4
-rw-r--r--test cases/warning/5 fallback consistency/subprojects/foo.wrap6
-rw-r--r--test cases/warning/5 fallback consistency/subprojects/foo/meson.build6
-rw-r--r--test cases/warning/5 fallback consistency/test.json10
-rw-r--r--test cases/warning/6 list add/meson.build7
-rw-r--r--test cases/warning/6 list add/test.json7
-rw-r--r--test cases/warning/7 module without unstable/meson.build3
-rw-r--r--test cases/warning/7 module without unstable/test.json7
-rw-r--r--test cases/warning/8 target with no sources/meson.build3
-rw-r--r--test cases/warning/8 target with no sources/test.json7
-rw-r--r--test cases/wasm/1 basic/hello.c6
-rw-r--r--test cases/wasm/1 basic/hello.cpp6
-rw-r--r--test cases/wasm/1 basic/hello.html8
-rw-r--r--test cases/wasm/1 basic/meson.build4
-rw-r--r--test cases/wasm/2 threads/meson.build10
-rw-r--r--test cases/wasm/2 threads/threads.c21
-rw-r--r--test cases/wasm/2 threads/threads.cpp13
-rw-r--r--test cases/wasm/3 jslib/meson.build8
-rw-r--r--test cases/wasm/3 jslib/prog.c10
-rw-r--r--test cases/wasm/3 jslib/somefuncs.js6
-rw-r--r--test cases/wayland/1 client/both.c11
-rw-r--r--test cases/wayland/1 client/client.c9
-rw-r--r--test cases/wayland/1 client/local.c9
-rw-r--r--test cases/wayland/1 client/meson.build48
-rw-r--r--test cases/wayland/1 client/server.c9
-rw-r--r--test cases/wayland/1 client/test.xml6
-rw-r--r--test cases/wayland/2 core only/core.c9
-rw-r--r--test cases/wayland/2 core only/meson.build14
-rw-r--r--test cases/windows/1 basic/meson.build4
-rw-r--r--test cases/windows/1 basic/prog.c5
-rw-r--r--test cases/windows/1 basic/test.json6
-rw-r--r--test cases/windows/10 vs module defs generated custom target/meson.build5
-rw-r--r--test cases/windows/10 vs module defs generated custom target/prog.c5
-rwxr-xr-xtest cases/windows/10 vs module defs generated custom target/subdir/make_def.py6
-rw-r--r--test cases/windows/10 vs module defs generated custom target/subdir/meson.build7
-rw-r--r--test cases/windows/10 vs module defs generated custom target/subdir/somedll.c3
-rw-r--r--test cases/windows/11 exe implib/meson.build7
-rw-r--r--test cases/windows/11 exe implib/prog.c6
-rw-r--r--test cases/windows/11 exe implib/test.json12
-rw-r--r--test cases/windows/12 resources with custom targets/meson.build70
-rw-r--r--test cases/windows/12 resources with custom targets/prog.c19
-rwxr-xr-xtest cases/windows/12 resources with custom targets/res/gen-res.py6
-rw-r--r--test cases/windows/12 resources with custom targets/res/meson.build19
-rw-r--r--test cases/windows/12 resources with custom targets/res/myres.rc.in4
-rw-r--r--test cases/windows/12 resources with custom targets/res/myres_static.rc3
-rw-r--r--test cases/windows/12 resources with custom targets/res/resource.h0
-rw-r--r--test cases/windows/12 resources with custom targets/res/sample.icobin0 -> 9662 bytes
-rw-r--r--test cases/windows/13 test argument extra paths/exe/main.c5
-rw-r--r--test cases/windows/13 test argument extra paths/exe/meson.build3
-rw-r--r--test cases/windows/13 test argument extra paths/lib/foo.c6
-rw-r--r--test cases/windows/13 test argument extra paths/lib/foo.h14
-rw-r--r--test cases/windows/13 test argument extra paths/lib/meson.build3
-rw-r--r--test cases/windows/13 test argument extra paths/meson.build5
-rw-r--r--test cases/windows/13 test argument extra paths/test/meson.build3
-rw-r--r--test cases/windows/13 test argument extra paths/test/test_run_exe.py12
-rwxr-xr-xtest cases/windows/14 resources with custom target depend_files/ico/gen-ico.py6
-rw-r--r--test cases/windows/14 resources with custom target depend_files/ico/meson.build8
-rw-r--r--test cases/windows/14 resources with custom target depend_files/ico/sample.ico.inbin0 -> 9662 bytes
-rw-r--r--test cases/windows/14 resources with custom target depend_files/meson.build69
-rw-r--r--test cases/windows/14 resources with custom target depend_files/prog.c19
-rw-r--r--test cases/windows/14 resources with custom target depend_files/res/meson.build4
-rw-r--r--test cases/windows/14 resources with custom target depend_files/res/myres.rc3
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/a/meson.build1
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/a/rsrc.rc1
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/b/meson.build2
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/b/rsrc.rc1
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/c/meson.build2
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/c/rsrc.rc1
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe3/meson.build5
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/main.c10
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/version.rc11
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/main.c3
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/version.rc11
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe4/meson.build5
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/main.c10
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/version.rc11
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/main.c3
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/version.rc11
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/meson.build21
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/rsrc.rc1
-rw-r--r--test cases/windows/15 resource scripts with duplicate filenames/verify.c25
-rw-r--r--test cases/windows/16 gui app/console_prog.c3
-rw-r--r--test cases/windows/16 gui app/dummy.c0
-rw-r--r--test cases/windows/16 gui app/gui_app_tester.py19
-rw-r--r--test cases/windows/16 gui app/gui_prog.c11
-rw-r--r--test cases/windows/16 gui app/meson.build26
-rw-r--r--test cases/windows/17 msvc ndebug/main.cpp9
-rw-r--r--test cases/windows/17 msvc ndebug/meson.build7
-rw-r--r--test cases/windows/18 msvc charset/iso-8859-1.c7
-rw-r--r--test cases/windows/18 msvc charset/meson.build15
-rw-r--r--test cases/windows/18 msvc charset/meson_options.txt1
-rw-r--r--test cases/windows/18 msvc charset/utf8.c7
-rw-r--r--test cases/windows/19 msvc cplusplus define/main.cpp7
-rw-r--r--test cases/windows/19 msvc cplusplus define/meson.build14
-rw-r--r--test cases/windows/2 winmain/meson.build4
-rw-r--r--test cases/windows/2 winmain/prog.c15
-rw-r--r--test cases/windows/20 vs install static lib with generated obj deps/both_lib_source.c7
-rw-r--r--test cases/windows/20 vs install static lib with generated obj deps/copyfile.py4
-rw-r--r--test cases/windows/20 vs install static lib with generated obj deps/generated_source.c4
-rw-r--r--test cases/windows/20 vs install static lib with generated obj deps/meson.build20
-rw-r--r--test cases/windows/20 vs install static lib with generated obj deps/static_lib_source.c6
-rw-r--r--test cases/windows/20 vs install static lib with generated obj deps/test.json13
-rw-r--r--test cases/windows/21 masm/hello.masm33
-rw-r--r--test cases/windows/21 masm/meson.build14
-rw-r--r--test cases/windows/3 cpp/meson.build4
-rw-r--r--test cases/windows/3 cpp/prog.cpp7
-rw-r--r--test cases/windows/4 winmaincpp/meson.build4
-rw-r--r--test cases/windows/4 winmaincpp/prog.cpp17
-rw-r--r--test cases/windows/5 resources/inc/meson.build1
-rw-r--r--test cases/windows/5 resources/inc/resource/resource.h1
-rw-r--r--test cases/windows/5 resources/meson.build69
-rw-r--r--test cases/windows/5 resources/prog.c21
-rw-r--r--test cases/windows/5 resources/res/dummy.c0
-rw-r--r--test cases/windows/5 resources/res/meson.build10
-rw-r--r--test cases/windows/5 resources/res/myres.rc4
-rw-r--r--test cases/windows/5 resources/res/sample.icobin0 -> 9662 bytes
-rw-r--r--test cases/windows/6 vs module defs/meson.build5
-rw-r--r--test cases/windows/6 vs module defs/prog.c5
-rw-r--r--test cases/windows/6 vs module defs/subdir/meson.build1
-rw-r--r--test cases/windows/6 vs module defs/subdir/somedll.c3
-rw-r--r--test cases/windows/6 vs module defs/subdir/somedll.def2
-rw-r--r--test cases/windows/7 dll versioning/copyfile.py6
-rw-r--r--test cases/windows/7 dll versioning/exe.orig.c8
-rw-r--r--test cases/windows/7 dll versioning/lib.c6
-rw-r--r--test cases/windows/7 dll versioning/meson.build54
-rw-r--r--test cases/windows/7 dll versioning/test.json34
-rw-r--r--test cases/windows/8 find program/meson.build12
-rw-r--r--test cases/windows/8 find program/test-script3
-rw-r--r--test cases/windows/8 find program/test-script-ext.py3
-rw-r--r--test cases/windows/9 vs module defs generated/meson.build5
-rw-r--r--test cases/windows/9 vs module defs generated/prog.c5
-rw-r--r--test cases/windows/9 vs module defs generated/subdir/meson.build10
-rw-r--r--test cases/windows/9 vs module defs generated/subdir/somedll.c3
-rw-r--r--test cases/windows/9 vs module defs generated/subdir/somedll.def.in2
3745 files changed, 47953 insertions, 0 deletions
diff --git a/test cases/cmake/1 basic/main.cpp b/test cases/cmake/1 basic/main.cpp
new file mode 100644
index 0000000..9507961
--- /dev/null
+++ b/test cases/cmake/1 basic/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/1 basic/meson.build b/test cases/cmake/1 basic/meson.build
new file mode 100644
index 0000000..2464739
--- /dev/null
+++ b/test cases/cmake/1 basic/meson.build
@@ -0,0 +1,14 @@
+project('cmakeSubTest', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib++', include_type: 'system')
+
+assert(sub_pro.found(), 'found() method reports not found, but should be found')
+assert(sub_pro.target_list() == ['cmModLib++'], 'There should be exactly one target')
+assert(sub_pro.target_type('cmModLib++') == 'shared_library', 'Target type should be shared_library')
+assert(sub_dep.include_type() == 'system', 'the include_type kwarg of dependency() works')
+
+exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..2197667
--- /dev/null
+++ b/test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_definitions("-DDO_NOTHING_JUST_A_FLAG=1")
+
+add_library(cmModLib++ SHARED cmMod.cpp)
+target_compile_definitions(cmModLib++ PRIVATE MESON_MAGIC_FLAG=21)
+target_compile_definitions(cmModLib++ INTERFACE MESON_MAGIC_FLAG=42)
+
+# Test PCH support
+if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0")
+ target_precompile_headers(cmModLib++ PRIVATE "cpp_pch.hpp")
+endif()
+
+include(GenerateExportHeader)
+generate_export_header(cmModLib++)
diff --git a/test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp
new file mode 100644
index 0000000..f4cbea0
--- /dev/null
+++ b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp
@@ -0,0 +1,15 @@
+#include "cmMod.hpp"
+
+using namespace std;
+
+#if MESON_MAGIC_FLAG != 21
+#error "Invalid MESON_MAGIC_FLAG (private)"
+#endif
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World";
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
diff --git a/test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp
new file mode 100644
index 0000000..4445e1f
--- /dev/null
+++ b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "cmmodlib++_export.h"
+#include <string>
+
+#if MESON_MAGIC_FLAG != 42 && MESON_MAGIC_FLAG != 21
+#error "Invalid MESON_MAGIC_FLAG"
+#endif
+
+class CMMODLIB___EXPORT cmModClass {
+private:
+ std::string str;
+
+public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+};
diff --git a/test cases/cmake/1 basic/subprojects/cmMod/cpp_pch.hpp b/test cases/cmake/1 basic/subprojects/cmMod/cpp_pch.hpp
new file mode 100644
index 0000000..aa7ceb3
--- /dev/null
+++ b/test cases/cmake/1 basic/subprojects/cmMod/cpp_pch.hpp
@@ -0,0 +1,2 @@
+#include <vector>
+#include <string>
diff --git a/test cases/cmake/10 header only/main.cpp b/test cases/cmake/10 header only/main.cpp
new file mode 100644
index 0000000..1417881
--- /dev/null
+++ b/test cases/cmake/10 header only/main.cpp
@@ -0,0 +1,16 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+#define EXPECTED "Hello World compDef 42"
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ if (obj.getStr() != EXPECTED) {
+ cerr << "Expected: '" << EXPECTED << "'" << endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/cmake/10 header only/meson.build b/test cases/cmake/10 header only/meson.build
new file mode 100644
index 0000000..ca08a3f
--- /dev/null
+++ b/test cases/cmake/10 header only/meson.build
@@ -0,0 +1,12 @@
+project('cmakeSubTest', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib')
+
+assert(sub_pro.target_list() == ['cmModLib'], 'There should be exactly one target')
+assert(sub_pro.target_type('cmModLib') == 'header_only', 'Target type should be header_only')
+
+exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..e01b6e2
--- /dev/null
+++ b/test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+
+add_definitions("-DDO_NOTHING_JUST_A_FLAG=1")
+
+add_library(cmModLib INTERFACE)
+set_target_properties(cmModLib PROPERTIES INTERFACE_COMPILE_OPTIONS "-DCMAKE_FLAG_MUST_BE_PRESENT")
+target_include_directories(cmModLib INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include")
+target_compile_definitions(cmModLib INTERFACE -DCMAKE_COMPILER_DEFINE_STR="compDef")
+target_compile_definitions(cmModLib INTERFACE MESON_MAGIC_FLAG=42)
diff --git a/test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp b/test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp
new file mode 100644
index 0000000..fe01040
--- /dev/null
+++ b/test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <string>
+
+#ifndef CMAKE_FLAG_MUST_BE_PRESENT
+#error "The flag CMAKE_FLAG_MUST_BE_PRESENT was not set"
+#endif
+
+#define xstr(s) str(s)
+#define str(s) #s
+
+class cmModClass {
+ private:
+ std::string str;
+ public:
+ cmModClass(std::string foo) {
+ str = foo + " World ";
+ str += CMAKE_COMPILER_DEFINE_STR;
+ str += ' ';
+ str += xstr(MESON_MAGIC_FLAG);
+ }
+
+ inline std::string getStr() const { return str; }
+};
diff --git a/test cases/cmake/11 cmake_module_path/cmake/FindSomethingLikePython.cmake b/test cases/cmake/11 cmake_module_path/cmake/FindSomethingLikePython.cmake
new file mode 100644
index 0000000..0c663f4
--- /dev/null
+++ b/test cases/cmake/11 cmake_module_path/cmake/FindSomethingLikePython.cmake
@@ -0,0 +1,9 @@
+cmake_policy(VERSION 3.7)
+
+find_package(Python COMPONENTS Interpreter)
+if(Python_FOUND OR PYTHONINTERP_FOUND)
+ set(SomethingLikePython_FOUND ON)
+ set(SomethingLikePython_EXECUTABLE ${Python_EXECUTABLE})
+else()
+ set(SomethingLikePython_FOUND OFF)
+endif()
diff --git a/test cases/cmake/11 cmake_module_path/meson.build b/test cases/cmake/11 cmake_module_path/meson.build
new file mode 100644
index 0000000..e201936
--- /dev/null
+++ b/test cases/cmake/11 cmake_module_path/meson.build
@@ -0,0 +1,25 @@
+# We use Python3 as it's the only thing guaranteed to be available on any platform Meson can run on (unlike Zlib in linuxlike/13 cmake dependency).
+
+project('user CMake find_package module using cmake_module_path', ['c', 'cpp'],
+ meson_version: '>= 0.55.0')
+
+if not find_program('cmake', required: false).found()
+ error('MESON_SKIP_TEST cmake binary not available.')
+endif
+
+# NOTE: can't request Python3 via dependency('Python3', method: 'cmake')
+# Meson intercepts and wants "method: auto"
+
+# Try to find a dependency with a custom CMake module
+
+dependency('SomethingLikePython', required : true, method : 'cmake', cmake_module_path : 'cmake', modules: 'Python::Interpreter')
+
+dependency('SomethingLikePython', method : 'cmake', cmake_module_path : ['doesNotExist', 'cmake'], modules: 'Python::Interpreter')
+
+# Test a custom target with Python::Interpreter in COMMAND
+cm = import('cmake')
+op = cm.subproject_options()
+op.add_cmake_defines({'CMAKE_MODULE_PATH': meson.source_root() / 'cmake'})
+sp = cm.subproject('cmMod', options: op)
+main = sp.target('main')
+test('main', main)
diff --git a/test cases/cmake/11 cmake_module_path/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/11 cmake_module_path/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..88ba9bc
--- /dev/null
+++ b/test cases/cmake/11 cmake_module_path/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+
+message(STATUS "CMAKE_MODULE_PATH: '${CMAKE_MODULE_PATH}'")
+
+find_package(SomethingLikePython REQUIRED)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/main.c"
+ COMMAND Python::Interpreter "${CMAKE_CURRENT_SOURCE_DIR}/gen.py"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+)
+
+add_executable(main "${CMAKE_CURRENT_BINARY_DIR}/main.c")
diff --git a/test cases/cmake/11 cmake_module_path/subprojects/cmMod/gen.py b/test cases/cmake/11 cmake_module_path/subprojects/cmMod/gen.py
new file mode 100644
index 0000000..5c71646
--- /dev/null
+++ b/test cases/cmake/11 cmake_module_path/subprojects/cmMod/gen.py
@@ -0,0 +1,9 @@
+with open('main.c', 'w') as fp:
+ print('''
+#include <stdio.h>
+
+int main(void) {
+ printf(\"Hello World\");
+ return 0;
+}
+''', file=fp)
diff --git a/test cases/cmake/12 generator expressions/main.cpp b/test cases/cmake/12 generator expressions/main.cpp
new file mode 100644
index 0000000..9507961
--- /dev/null
+++ b/test cases/cmake/12 generator expressions/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/12 generator expressions/meson.build b/test cases/cmake/12 generator expressions/meson.build
new file mode 100644
index 0000000..ca08a3f
--- /dev/null
+++ b/test cases/cmake/12 generator expressions/meson.build
@@ -0,0 +1,12 @@
+project('cmakeSubTest', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib')
+
+assert(sub_pro.target_list() == ['cmModLib'], 'There should be exactly one target')
+assert(sub_pro.target_type('cmModLib') == 'header_only', 'Target type should be header_only')
+
+exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/12 generator expressions/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/12 generator expressions/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..27b3721
--- /dev/null
+++ b/test cases/cmake/12 generator expressions/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+
+include(GNUInstallDirs)
+
+add_library(cmModLib INTERFACE)
+
+target_compile_options(cmModLib
+ INTERFACE $<$<AND:$<CONFIG:Release>,$<CONFIG:Debug>>:-DCMAKE_FLAG_ERROR_A> # Check discard = false
+ INTERFACE "-DCMAKE_FLAG_REQUIRED_A"
+ INTERFACE $<$<AND:1,$<STREQUAL:asd,$<LOWER_CASE:AsD>>,$<NOT:$<EQUAL:4,2>>>:-DCMAKE_FLAG_REQUIRED_B>
+ INTERFACE $<$<VERSION_LESS:1.2.3,2.1.0>:-DCMAKE_FLAG_REQUIRED_C>
+ INTERFACE $<IF:$<NOT:$<BOOL:OFF>>,-DCMAKE_TRUE_FLAG,-DCMAKE_FALSE_FLAG>
+ INTERFACE $<IF:$<TARGET_EXISTS:cmModLib>,-DCMAKE_TGT_EXISTS,-DCMAKE_TGT_NEXISTS>
+ INTERFACE $<IF:$<TARGET_PROPERTY:IMPORTED_NO_SONAME>,-DCMAKE_PROP1_OK,-DCMAKE_PROP1_ERROR>
+ INTERFACE $<IF:$<TARGET_PROPERTY:cmModLib,IMPORT_SUFFIX>,-DCMAKE_PROP2_ERROR,-DCMAKE_PROP2_OK>
+)
+
+target_include_directories(cmModLib INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
+
+set_target_properties(cmModLib
+ PROPERTIES
+ IMPORTED_NO_SONAME 1
+ IMPORT_SUFFIX 0
+)
+
+target_compile_definitions(cmModLib INTERFACE -DCMAKE_COMPILER_DEFINE_STR="compDef")
diff --git a/test cases/cmake/12 generator expressions/subprojects/cmMod/include/cmMod.hpp b/test cases/cmake/12 generator expressions/subprojects/cmMod/include/cmMod.hpp
new file mode 100644
index 0000000..416e5bb
--- /dev/null
+++ b/test cases/cmake/12 generator expressions/subprojects/cmMod/include/cmMod.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <string>
+
+#ifndef CMAKE_FLAG_REQUIRED_A
+#error "The flag CMAKE_FLAG_REQUIRED_A was not set"
+#endif
+
+#ifndef CMAKE_FLAG_REQUIRED_B
+#error "The flag CMAKE_FLAG_REQUIRED_B was not set"
+#endif
+
+#ifndef CMAKE_FLAG_REQUIRED_C
+#error "The flag CMAKE_FLAG_REQUIRED_C was not set"
+#endif
+
+#ifdef CMAKE_FLAG_ERROR_A
+#error "The flag CMAKE_FLAG_ERROR_A was set"
+#endif
+
+#ifndef CMAKE_TRUE_FLAG
+#error "The flag CMAKE_TRUE_FLAG was not set"
+#endif
+
+#ifdef CMAKE_FALSE_FLAG
+#error "The flag CMAKE_FALSE_FLAG was set"
+#endif
+
+#ifndef CMAKE_TGT_EXISTS
+#error "The flag CMAKE_TGT_EXISTS was not set"
+#endif
+
+#ifdef CMAKE_TGT_NEXISTS
+#error "The flag CMAKE_TGT_NEXISTS was set"
+#endif
+
+#ifndef CMAKE_PROP1_OK
+#error "The flag CMAKE_PROP1_OK was not set"
+#endif
+
+#ifdef CMAKE_PROP1_ERROR
+#error "The flag CMAKE_PROP1_ERROR was set"
+#endif
+
+#ifndef CMAKE_PROP2_OK
+#error "The flag CMAKE_PROP2_OK was not set"
+#endif
+
+#ifdef CMAKE_PROP2_ERROR
+#error "The flag CMAKE_PROP2_ERROR was set"
+#endif
+
+class cmModClass {
+ private:
+ std::string str;
+ public:
+ cmModClass(std::string foo) {
+ str = foo + " World ";
+ str += CMAKE_COMPILER_DEFINE_STR;
+ }
+
+ inline std::string getStr() const { return str; }
+};
diff --git a/test cases/cmake/12 generator expressions/test.json b/test cases/cmake/12 generator expressions/test.json
new file mode 100644
index 0000000..faf1ff8
--- /dev/null
+++ b/test cases/cmake/12 generator expressions/test.json
@@ -0,0 +1,5 @@
+{
+ "tools": {
+ "cmake": ">=3.19"
+ }
+}
diff --git a/test cases/cmake/13 system includes/main.cpp b/test cases/cmake/13 system includes/main.cpp
new file mode 100644
index 0000000..9507961
--- /dev/null
+++ b/test cases/cmake/13 system includes/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/13 system includes/meson.build b/test cases/cmake/13 system includes/meson.build
new file mode 100644
index 0000000..1265d46
--- /dev/null
+++ b/test cases/cmake/13 system includes/meson.build
@@ -0,0 +1,18 @@
+project(
+ 'meson_cmake_system_include_bug', ['c', 'cpp'],
+ default_options: [
+ 'warning_level=3',
+ 'werror=true',
+ ],
+)
+
+if meson.get_compiler('cpp').get_argument_syntax() == 'msvc'
+ error('MESON_SKIP_TEST: Skip with msvc due to missing -system support')
+endif
+
+cm = import('cmake')
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib')
+
+exe1 = executable('main1', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/13 system includes/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/13 system includes/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..a6b0ba4
--- /dev/null
+++ b/test cases/cmake/13 system includes/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_definitions("-DDO_NOTHING_JUST_A_FLAG=1")
+
+add_library(cmModLib SHARED cmMod.cpp)
+include(GenerateExportHeader)
+generate_export_header(cmModLib)
+
+target_compile_options(cmModLib PRIVATE "-Wall" "-Werror")
+target_include_directories(cmModLib SYSTEM PRIVATE "sysInc")
diff --git a/test cases/cmake/13 system includes/subprojects/cmMod/cmMod.cpp b/test cases/cmake/13 system includes/subprojects/cmMod/cmMod.cpp
new file mode 100644
index 0000000..1eaf0cf
--- /dev/null
+++ b/test cases/cmake/13 system includes/subprojects/cmMod/cmMod.cpp
@@ -0,0 +1,12 @@
+#include "cmMod.hpp"
+#include "triggerWarn.hpp"
+
+using namespace std;
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World " + to_string(bar(World));
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
diff --git a/test cases/cmake/13 system includes/subprojects/cmMod/cmMod.hpp b/test cases/cmake/13 system includes/subprojects/cmMod/cmMod.hpp
new file mode 100644
index 0000000..52f576b
--- /dev/null
+++ b/test cases/cmake/13 system includes/subprojects/cmMod/cmMod.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <string>
+#include "cmmodlib_export.h"
+
+class CMMODLIB_EXPORT cmModClass {
+ private:
+ std::string str;
+ public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+};
diff --git a/test cases/cmake/13 system includes/subprojects/cmMod/sysInc/triggerWarn.hpp b/test cases/cmake/13 system includes/subprojects/cmMod/sysInc/triggerWarn.hpp
new file mode 100644
index 0000000..3b00f2d
--- /dev/null
+++ b/test cases/cmake/13 system includes/subprojects/cmMod/sysInc/triggerWarn.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+enum Foo {
+ Hello,
+ World
+};
+
+inline int bar( Foo foo ) {
+ switch(foo) {
+ case Hello: return 0;
+ // Warn because of missung case for World
+ }
+ return 1;
+}
diff --git a/test cases/cmake/14 fortran threads/meson.build b/test cases/cmake/14 fortran threads/meson.build
new file mode 100644
index 0000000..2d2f892
--- /dev/null
+++ b/test cases/cmake/14 fortran threads/meson.build
@@ -0,0 +1,12 @@
+project('FortranThreads')
+
+if not add_languages('fortran', required: false)
+ error('MESON_SKIP_TEST: Fortran language not available.')
+endif
+
+# want to be sure that CMake can find dependencies where even if the
+# project isn't C, the C language is required to find the library.
+threads = dependency('threads', method: 'cmake', required: false)
+if not threads.found()
+ error('MESON_SKIP_TEST: CMake backend not working for Fortran / threads')
+endif
diff --git a/test cases/cmake/15 object library advanced/main.cpp b/test cases/cmake/15 object library advanced/main.cpp
new file mode 100644
index 0000000..4cc01a8
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+#include "libA.hpp"
+#include "libB.hpp"
+
+using namespace std;
+
+int main(void) {
+ cout << getLibStr() << endl;
+ cout << getZlibVers() << endl;
+ return EXIT_SUCCESS;
+}
diff --git a/test cases/cmake/15 object library advanced/meson.build b/test cases/cmake/15 object library advanced/meson.build
new file mode 100644
index 0000000..4009a0d
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/meson.build
@@ -0,0 +1,17 @@
+project('cmake_object_lib_test', 'cpp', default_options: ['cpp_std=c++11'])
+
+if meson.is_cross_build()
+ error('MESON_SKIP_TEST this test does not cross compile correctly.')
+endif
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmObjLib')
+sub_sha = sub_pro.dependency('lib_sha')
+sub_sta = sub_pro.dependency('lib_sta')
+
+exe_sha = executable('shared', ['main.cpp'], dependencies: [sub_sha])
+exe_sta = executable('static', ['main.cpp'], dependencies: [sub_sta])
+
+test('test1', exe_sha)
+test('test1', exe_sta)
diff --git a/test cases/cmake/15 object library advanced/subprojects/cmObjLib/CMakeLists.txt b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/CMakeLists.txt
new file mode 100644
index 0000000..47f1ad3
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.7)
+project(cmObject CXX)
+
+add_executable(genC genC.cpp)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libC.cpp" "${CMAKE_CURRENT_BINARY_DIR}/libC.hpp"
+ COMMAND genC
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+)
+
+include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+
+add_library(lib_obj OBJECT libA.cpp libB.cpp "${CMAKE_CURRENT_BINARY_DIR}/libC.cpp" "${CMAKE_CURRENT_BINARY_DIR}/libC.hpp")
+add_library(lib_sha SHARED $<TARGET_OBJECTS:lib_obj>)
+add_library(lib_sta STATIC $<TARGET_OBJECTS:lib_obj>)
+
+target_compile_definitions(lib_obj PRIVATE "-DBUILD_AS_OBJ=1")
diff --git a/test cases/cmake/15 object library advanced/subprojects/cmObjLib/genC.cpp b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/genC.cpp
new file mode 100644
index 0000000..a9e4b5e
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/genC.cpp
@@ -0,0 +1,31 @@
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+int main() {
+ ofstream hpp("libC.hpp");
+ ofstream cpp("libC.cpp");
+ if (!hpp.is_open() || !cpp.is_open()) {
+ cerr << "Failed to open 'libC.hpp' or 'libC.cpp' for writing" << endl;
+ return 1;
+ }
+
+ hpp << R"cpp(
+#pragma once
+
+#include <string>
+
+std::string getGenStr();
+)cpp";
+
+ cpp << R"cpp(
+#include "libC.hpp"
+
+std::string getGenStr(void) {
+ return "GEN STR";
+}
+)cpp";
+
+ return 0;
+} \ No newline at end of file
diff --git a/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.cpp b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.cpp
new file mode 100644
index 0000000..fd5aa48
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.cpp
@@ -0,0 +1,9 @@
+#include "libA.hpp"
+
+#if not BUILD_AS_OBJ
+#error "BUILD_AS_OBJ was not defined"
+#endif
+
+std::string getLibStr(void) {
+ return "Hello World";
+}
diff --git a/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.hpp b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.hpp
new file mode 100644
index 0000000..84b7bc7
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libA.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+std::string DLL_PUBLIC getLibStr();
diff --git a/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.cpp b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.cpp
new file mode 100644
index 0000000..4b832ec
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.cpp
@@ -0,0 +1,6 @@
+#include "libB.hpp"
+#include "libC.hpp"
+
+std::string getZlibVers(void) {
+ return getGenStr();
+}
diff --git a/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.hpp b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.hpp
new file mode 100644
index 0000000..52ccc16
--- /dev/null
+++ b/test cases/cmake/15 object library advanced/subprojects/cmObjLib/libB.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+std::string DLL_PUBLIC getZlibVers();
diff --git a/test cases/cmake/16 threads/main.cpp b/test cases/cmake/16 threads/main.cpp
new file mode 100644
index 0000000..67ee110
--- /dev/null
+++ b/test cases/cmake/16 threads/main.cpp
@@ -0,0 +1,9 @@
+#include "cmMod.hpp"
+
+#include <cstdlib>
+
+int main() {
+ CmMod cc;
+ cc.asyncIncrement();
+ return cc.getNum() == 1 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/test cases/cmake/16 threads/meson.build b/test cases/cmake/16 threads/meson.build
new file mode 100644
index 0000000..5efd73e
--- /dev/null
+++ b/test cases/cmake/16 threads/meson.build
@@ -0,0 +1,12 @@
+project('cmMod', ['c', 'cpp'])
+
+cm = import('cmake')
+cmOpts = ['-DUSE_PTHREAD=@0@'.format(get_option('use_pthread'))]
+cmMod = cm.subproject('cmMod', cmake_options: cmOpts)
+cmModDep1 = cmMod.dependency('cmModLib')
+cmModDep2 = cmMod.dependency('cmModLib_shared')
+
+exe1 = executable('exe1', ['main.cpp'], dependencies: [cmModDep1])
+exe2 = executable('exe2', ['main.cpp'], dependencies: [cmModDep2])
+test('exe1_OK', exe1)
+test('exe2_OK', exe2)
diff --git a/test cases/cmake/16 threads/meson_options.txt b/test cases/cmake/16 threads/meson_options.txt
new file mode 100644
index 0000000..1fd9068
--- /dev/null
+++ b/test cases/cmake/16 threads/meson_options.txt
@@ -0,0 +1 @@
+option('use_pthread', type: 'combo', choices: ['ON', 'OFF', 'NOT_SET'], value: 'ON')
diff --git a/test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..4d61b0c
--- /dev/null
+++ b/test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod C CXX)
+set (CMAKE_CXX_STANDARD 14)
+
+if(NOT USE_PTHREAD STREQUAL NOT_SET)
+ set(THREADS_PREFER_PTHREAD_FLAG ${USE_PTHREAD})
+endif()
+find_package(Threads)
+
+add_library(cmModLib STATIC cmMod.cpp)
+target_link_libraries(cmModLib PRIVATE Threads::Threads)
+
+add_library(cmModLib_shared SHARED cmMod.cpp)
+target_link_libraries(cmModLib_shared PUBLIC Threads::Threads)
diff --git a/test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp
new file mode 100644
index 0000000..f971eeb
--- /dev/null
+++ b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp
@@ -0,0 +1,15 @@
+#include "cmMod.hpp"
+
+#include <chrono>
+#include <thread>
+
+using namespace std::chrono_literals;
+
+void CmMod::asyncIncrement() {
+ std::thread t1([this]() {
+ std::this_thread::sleep_for(100ms);
+ num += 1;
+ });
+
+ t1.join();
+}
diff --git a/test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp
new file mode 100644
index 0000000..81c5ec8
--- /dev/null
+++ b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+#if defined __GNUC__
+#define DLL_PUBLIC __attribute__((visibility("default")))
+#else
+#pragma message("Compiler does not support symbol visibility.")
+#define DLL_PUBLIC
+#endif
+#endif
+
+class DLL_PUBLIC CmMod {
+private:
+ int num = 0;
+
+public:
+ inline int getNum() const { return num; }
+ void asyncIncrement();
+};
diff --git a/test cases/cmake/16 threads/subprojects/cmMod/main.cpp b/test cases/cmake/16 threads/subprojects/cmMod/main.cpp
new file mode 100644
index 0000000..67ee110
--- /dev/null
+++ b/test cases/cmake/16 threads/subprojects/cmMod/main.cpp
@@ -0,0 +1,9 @@
+#include "cmMod.hpp"
+
+#include <cstdlib>
+
+int main() {
+ CmMod cc;
+ cc.asyncIncrement();
+ return cc.getNum() == 1 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/test cases/cmake/16 threads/test.json b/test cases/cmake/16 threads/test.json
new file mode 100644
index 0000000..db788b1
--- /dev/null
+++ b/test cases/cmake/16 threads/test.json
@@ -0,0 +1,11 @@
+{
+ "matrix": {
+ "options": {
+ "use_pthread": [
+ { "val": "ON" },
+ { "val": "OFF" },
+ { "val": "NOT_SET" }
+ ]
+ }
+ }
+}
diff --git a/test cases/cmake/17 include path order/main.cpp b/test cases/cmake/17 include path order/main.cpp
new file mode 100644
index 0000000..9507961
--- /dev/null
+++ b/test cases/cmake/17 include path order/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/17 include path order/meson.build b/test cases/cmake/17 include path order/meson.build
new file mode 100644
index 0000000..cf3ec96
--- /dev/null
+++ b/test cases/cmake/17 include path order/meson.build
@@ -0,0 +1,9 @@
+project('include_path_order', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib++')
+
+exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/17 include path order/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..9a252df
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+
+ # The one and only correct include dir
+ ${CMAKE_CURRENT_SOURCE_DIR}/incG
+
+ # All of these are traps
+ ${CMAKE_CURRENT_SOURCE_DIR}/incL
+ ${CMAKE_CURRENT_SOURCE_DIR}/incM
+ ${CMAKE_CURRENT_SOURCE_DIR}/incO
+ ${CMAKE_CURRENT_SOURCE_DIR}/incF
+ ${CMAKE_CURRENT_SOURCE_DIR}/incI
+ ${CMAKE_CURRENT_SOURCE_DIR}/incE
+ ${CMAKE_CURRENT_SOURCE_DIR}/incD
+ ${CMAKE_CURRENT_SOURCE_DIR}/incH
+ ${CMAKE_CURRENT_SOURCE_DIR}/incN
+ ${CMAKE_CURRENT_SOURCE_DIR}/incA
+ ${CMAKE_CURRENT_SOURCE_DIR}/incB
+ ${CMAKE_CURRENT_SOURCE_DIR}/incJ
+ ${CMAKE_CURRENT_SOURCE_DIR}/incP
+ ${CMAKE_CURRENT_SOURCE_DIR}/incC
+ ${CMAKE_CURRENT_SOURCE_DIR}/incK
+)
+
+add_definitions("-DDO_NOTHING_JUST_A_FLAG=1")
+
+add_library(cmModLib++ SHARED cmMod.cpp)
+include(GenerateExportHeader)
+generate_export_header(cmModLib++)
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/cmMod.cpp b/test cases/cmake/17 include path order/subprojects/cmMod/cmMod.cpp
new file mode 100644
index 0000000..d3141d5
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/cmMod.cpp
@@ -0,0 +1,11 @@
+#include "cmMod.hpp"
+
+using namespace std;
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World";
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incA/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incA/cmMod.hpp
new file mode 100644
index 0000000..6228a31
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incA/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (A)
+#pragma once
+
+#error "cmMod.hpp in incA must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incB/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incB/cmMod.hpp
new file mode 100644
index 0000000..60bf14c
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incB/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (B)
+#pragma once
+
+#error "cmMod.hpp in incB must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incC/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incC/cmMod.hpp
new file mode 100644
index 0000000..3229e07
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incC/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (C)
+#pragma once
+
+#error "cmMod.hpp in incC must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incD/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incD/cmMod.hpp
new file mode 100644
index 0000000..b958093
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incD/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (D)
+#pragma once
+
+#error "cmMod.hpp in incD must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incE/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incE/cmMod.hpp
new file mode 100644
index 0000000..aea5b6d
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incE/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (E)
+#pragma once
+
+#error "cmMod.hpp in incE must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incF/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incF/cmMod.hpp
new file mode 100644
index 0000000..1e1e2cb
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incF/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (F)
+#pragma once
+
+#error "cmMod.hpp in incF must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incG/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incG/cmMod.hpp
new file mode 100644
index 0000000..0e6dc04
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incG/cmMod.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "cmmodlib++_export.h"
+#include <string>
+
+class CMMODLIB___EXPORT cmModClass {
+private:
+ std::string str;
+
+public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+};
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incH/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incH/cmMod.hpp
new file mode 100644
index 0000000..263e701
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incH/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (H)
+#pragma once
+
+#error "cmMod.hpp in incH must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incI/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incI/cmMod.hpp
new file mode 100644
index 0000000..a44a89a
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incI/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (I)
+#pragma once
+
+#error "cmMod.hpp in incI must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incJ/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incJ/cmMod.hpp
new file mode 100644
index 0000000..118a809
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incJ/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (J)
+#pragma once
+
+#error "cmMod.hpp in incJ must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incL/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incL/cmMod.hpp
new file mode 100644
index 0000000..8294104
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incL/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (L)
+#pragma once
+
+#error "cmMod.hpp in incL must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incM/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incM/cmMod.hpp
new file mode 100644
index 0000000..031c5e9
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incM/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (M)
+#pragma once
+
+#error "cmMod.hpp in incM must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incN/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incN/cmMod.hpp
new file mode 100644
index 0000000..9dba6da
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incN/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (N)
+#pragma once
+
+#error "cmMod.hpp in incN must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incO/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incO/cmMod.hpp
new file mode 100644
index 0000000..233add9
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incO/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (O)
+#pragma once
+
+#error "cmMod.hpp in incO must not be included"
diff --git a/test cases/cmake/17 include path order/subprojects/cmMod/incP/cmMod.hpp b/test cases/cmake/17 include path order/subprojects/cmMod/incP/cmMod.hpp
new file mode 100644
index 0000000..9578745
--- /dev/null
+++ b/test cases/cmake/17 include path order/subprojects/cmMod/incP/cmMod.hpp
@@ -0,0 +1,4 @@
+// cmMod.hpp (P)
+#pragma once
+
+#error "cmMod.hpp in incP must not be included"
diff --git a/test cases/cmake/18 skip include files/main.cpp b/test cases/cmake/18 skip include files/main.cpp
new file mode 100644
index 0000000..9507961
--- /dev/null
+++ b/test cases/cmake/18 skip include files/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/18 skip include files/meson.build b/test cases/cmake/18 skip include files/meson.build
new file mode 100644
index 0000000..b9a300c
--- /dev/null
+++ b/test cases/cmake/18 skip include files/meson.build
@@ -0,0 +1,9 @@
+project('cmakeSubTest', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib++')
+
+exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/18 skip include files/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..4db01b3
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_definitions("-DDO_NOTHING_JUST_A_FLAG=1")
+
+set(SRCS
+ ${CMAKE_CURRENT_LIST_DIR}/cmMod.hpp
+ ${CMAKE_CURRENT_LIST_DIR}/cmMod.cpp
+)
+
+add_subdirectory(fakeInc)
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.cpp b/test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.cpp
new file mode 100644
index 0000000..7551b75
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.cpp
@@ -0,0 +1,10 @@
+#include "cmMod.hpp"
+
+using namespace std;
+
+#define MESON_INCLUDE_IMPL
+#include "fakeInc/cmModInc1.cpp"
+#include "fakeInc/cmModInc2.cpp"
+#include "fakeInc/cmModInc3.cpp"
+#include "fakeInc/cmModInc4.cpp"
+#undef MESON_INCLUDE_IMPL
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.hpp b/test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.hpp
new file mode 100644
index 0000000..f7b780f
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/cmMod.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "cmmodlib++_export.h"
+#include <string>
+
+class CMMODLIB___EXPORT cmModClass {
+private:
+ std::string str;
+
+ std::string getStr1() const;
+ std::string getStr2() const;
+public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+};
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/CMakeLists.txt b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/CMakeLists.txt
new file mode 100644
index 0000000..39cd080
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/CMakeLists.txt
@@ -0,0 +1,30 @@
+list(APPEND SRCS
+ cmModInc1.cpp
+ cmModInc2.cpp
+ cmModInc3.cpp
+ cmModInc4.cpp
+)
+
+set(SRC_A
+ cmModInc1.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/cmModInc2.cpp
+)
+
+set_property(
+ SOURCE ${SRC_A}
+ PROPERTY
+ HEADER_FILE_ONLY ON
+)
+
+set_source_files_properties(
+ cmModInc3.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/cmModInc4.cpp
+ PROPERTIES
+ LABELS "CMake;Lists;are;fun"
+ HEADER_FILE_ONLY ON
+)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_library(cmModLib++ SHARED ${SRCS})
+include(GenerateExportHeader)
+generate_export_header(cmModLib++)
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc1.cpp b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc1.cpp
new file mode 100644
index 0000000..b637755
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc1.cpp
@@ -0,0 +1,7 @@
+#ifndef MESON_INCLUDE_IMPL
+#error "MESON_INCLUDE_IMPL is not defined"
+#endif // !MESON_INCLUDE_IMPL
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World";
+}
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc2.cpp b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc2.cpp
new file mode 100644
index 0000000..8a53567
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc2.cpp
@@ -0,0 +1,7 @@
+#ifndef MESON_INCLUDE_IMPL
+#error "MESON_INCLUDE_IMPL is not defined"
+#endif // !MESON_INCLUDE_IMPL
+
+string cmModClass::getStr() const {
+ return getStr2();
+}
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc3.cpp b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc3.cpp
new file mode 100644
index 0000000..2c8ad12
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc3.cpp
@@ -0,0 +1,7 @@
+#ifndef MESON_INCLUDE_IMPL
+#error "MESON_INCLUDE_IMPL is not defined"
+#endif // !MESON_INCLUDE_IMPL
+
+string cmModClass::getStr1() const {
+ return getStr2();
+}
diff --git a/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc4.cpp b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc4.cpp
new file mode 100644
index 0000000..78a0673
--- /dev/null
+++ b/test cases/cmake/18 skip include files/subprojects/cmMod/fakeInc/cmModInc4.cpp
@@ -0,0 +1,7 @@
+#ifndef MESON_INCLUDE_IMPL
+#error "MESON_INCLUDE_IMPL is not defined"
+#endif // !MESON_INCLUDE_IMPL
+
+string cmModClass::getStr2() const {
+ return str;
+}
diff --git a/test cases/cmake/19 advanced options/main.cpp b/test cases/cmake/19 advanced options/main.cpp
new file mode 100644
index 0000000..6a071cc
--- /dev/null
+++ b/test cases/cmake/19 advanced options/main.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <cmMod.hpp>
+#include <cmTest.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+
+ int v1 = obj.getInt();
+ int v2 = getTestInt();
+ if (v1 != ((1 + v2) * 2)) {
+ cerr << "Number test failed" << endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/cmake/19 advanced options/meson.build b/test cases/cmake/19 advanced options/meson.build
new file mode 100644
index 0000000..6332ca4
--- /dev/null
+++ b/test cases/cmake/19 advanced options/meson.build
@@ -0,0 +1,29 @@
+project('cmake_set_opt', ['c', 'cpp'])
+
+comp = meson.get_compiler('cpp')
+if comp.get_argument_syntax() == 'msvc'
+ error('MESON_SKIP_TEST: MSVC is not supported because it does not support C++11')
+endif
+
+cm = import('cmake')
+opts = cm.subproject_options()
+
+opts.add_cmake_defines({'SOME_CMAKE_VAR': 'something', 'SOME_OTHER_VAR': true})
+
+opts.set_override_option('cpp_std', 'c++11') # Global is C++11
+opts.set_override_option('cpp_std', 'c++14', target: 'cmModLib++') # Override it with C++14 for cmModLib++
+
+opts.append_compile_args('cpp', '-DMESON_GLOBAL_FLAG=1')
+opts.append_compile_args('cpp', ['-DMESON_SPECIAL_FLAG1=1', ['-DMESON_SPECIAL_FLAG2=1']], target: 'cmModLib++')
+opts.append_compile_args('cpp', '-DMESON_MAGIC_INT=42', target: 'cmModLib++')
+opts.append_compile_args('cpp', [[[['-DMESON_MAGIC_INT=20']]]], target: 'cmTestLib')
+
+opts.set_install(false)
+opts.set_install(true, target: 'testEXE')
+
+sp = cm.subproject('cmOpts', options: opts)
+dep1 = sp.dependency('cmModLib++')
+dep2 = sp.dependency('cmTestLib')
+
+exe1 = executable('main', ['main.cpp'], dependencies: [dep1, dep2])
+test('test1', exe1)
diff --git a/test cases/cmake/19 advanced options/subprojects/cmOpts/CMakeLists.txt b/test cases/cmake/19 advanced options/subprojects/cmOpts/CMakeLists.txt
new file mode 100644
index 0000000..584841e
--- /dev/null
+++ b/test cases/cmake/19 advanced options/subprojects/cmOpts/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.7)
+
+project(CmOpts)
+
+set(CMAKE_CXX_STANDARD 98)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+if(NOT "${SOME_CMAKE_VAR}" STREQUAL "something")
+ message(FATAL_ERROR "Setting the CMake var failed")
+endif()
+
+add_library(cmModLib++ STATIC cmMod.cpp)
+add_library(cmTestLib STATIC cmTest.cpp)
+add_executable(testEXE main.cpp)
+
+target_link_libraries(testEXE cmModLib++)
+
+install(TARGETS cmTestLib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin)
diff --git a/test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.cpp b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.cpp
new file mode 100644
index 0000000..7651b60
--- /dev/null
+++ b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.cpp
@@ -0,0 +1,31 @@
+#include "cmMod.hpp"
+
+using namespace std;
+
+#if __cplusplus < 201402L
+#error "At least C++14 is required"
+#endif
+
+#ifndef MESON_GLOBAL_FLAG
+#error "MESON_GLOBAL_FLAG was not set"
+#endif
+
+#ifndef MESON_SPECIAL_FLAG1
+#error "MESON_SPECIAL_FLAG1 was not set"
+#endif
+
+#ifndef MESON_SPECIAL_FLAG2
+#error "MESON_SPECIAL_FLAG2 was not set"
+#endif
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World";
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
+
+int cmModClass::getInt() const {
+ return MESON_MAGIC_INT;
+}
diff --git a/test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.hpp b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.hpp
new file mode 100644
index 0000000..0748936
--- /dev/null
+++ b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmMod.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <string>
+
+class cmModClass {
+private:
+ std::string str;
+
+public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+ int getInt() const;
+};
diff --git a/test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.cpp b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.cpp
new file mode 100644
index 0000000..a00cdcd
--- /dev/null
+++ b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.cpp
@@ -0,0 +1,25 @@
+#include "cmTest.hpp"
+
+#if __cplusplus < 201103L
+#error "At least C++11 is required"
+#endif
+
+#if __cplusplus >= 201402L
+#error "At most C++11 is required"
+#endif
+
+#ifndef MESON_GLOBAL_FLAG
+#error "MESON_GLOBAL_FLAG was not set"
+#endif
+
+#ifdef MESON_SPECIAL_FLAG1
+#error "MESON_SPECIAL_FLAG1 *was* set"
+#endif
+
+#ifdef MESON_SPECIAL_FLAG2
+#error "MESON_SPECIAL_FLAG2 *was* set"
+#endif
+
+int getTestInt() {
+ return MESON_MAGIC_INT;
+}
diff --git a/test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.hpp b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.hpp
new file mode 100644
index 0000000..5a3bf7b
--- /dev/null
+++ b/test cases/cmake/19 advanced options/subprojects/cmOpts/cmTest.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+int getTestInt();
diff --git a/test cases/cmake/19 advanced options/subprojects/cmOpts/main.cpp b/test cases/cmake/19 advanced options/subprojects/cmOpts/main.cpp
new file mode 100644
index 0000000..497d1ce
--- /dev/null
+++ b/test cases/cmake/19 advanced options/subprojects/cmOpts/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include "cmMod.hpp"
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello (LIB TEST)");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/19 advanced options/test.json b/test cases/cmake/19 advanced options/test.json
new file mode 100644
index 0000000..29888ea
--- /dev/null
+++ b/test cases/cmake/19 advanced options/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/testEXE"}
+ ]
+}
diff --git a/test cases/cmake/2 advanced/main.cpp b/test cases/cmake/2 advanced/main.cpp
new file mode 100644
index 0000000..d823e29
--- /dev/null
+++ b/test cases/cmake/2 advanced/main.cpp
@@ -0,0 +1,15 @@
+#include <iostream>
+#include <cmMod.hpp>
+#include "config.h"
+
+#if CONFIG_OPT != 42
+#error "Invalid value of CONFIG_OPT"
+#endif
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/2 advanced/meson.build b/test cases/cmake/2 advanced/meson.build
new file mode 100644
index 0000000..b301bfe
--- /dev/null
+++ b/test cases/cmake/2 advanced/meson.build
@@ -0,0 +1,27 @@
+project('cmakeSubTest_advanced', ['c', 'cpp'])
+
+dep_test = dependency('ZLIB', method: 'cmake', required: false)
+if not dep_test.found()
+ error('MESON_SKIP_TEST: zlib is not installed')
+endif
+
+cm = import('cmake')
+
+# Test the "normal" subproject call
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib')
+sub_sta = sub_pro.dependency('cmModLibStatic')
+
+# Build some files
+exe1 = executable('main1', ['main.cpp'], dependencies: [sub_dep])
+exe2 = executable('main2', ['main.cpp'], dependencies: [sub_sta])
+test('test1', exe1)
+test('test2', exe2)
+
+# Test if we can also extract executables
+assert(sub_pro.target_type('testEXE') == 'executable', 'The type must be executable for obvious reasons')
+test('test3', sub_pro.target('testEXE'))
+
+# Test that we can add a new target with the same name as the CMake subproject
+exe4 = executable('testEXE', ['main.cpp'], dependencies: [sub_sta])
+test('test4', exe4)
diff --git a/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..0750117
--- /dev/null
+++ b/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set(CMAKE_CXX_STANDARD 14)
+
+find_package(ZLIB REQUIRED)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib)
+
+set(CONFIG_OPT 42)
+configure_file("config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
+
+add_library(cmModLib SHARED lib/cmMod.cpp)
+add_library(cmModLibStatic STATIC lib/cmMod.cpp)
+include(GenerateExportHeader)
+generate_export_header(cmModLib)
+
+set_target_properties(cmModLib PROPERTIES VERSION 1.0.1)
+
+add_executable(testEXE main.cpp "${CMAKE_CURRENT_BINARY_DIR}/config.h")
+
+target_link_libraries(cmModLib ZLIB::ZLIB)
+target_link_libraries(cmModLibStatic ;ZLIB::ZLIB;)
+target_link_libraries(testEXE cmModLib)
+
+if(APPLE)
+ find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
+ if(NOT COREFOUNDATION_FRAMEWORK)
+ message(FATAL_ERROR "CoreFoundation framework not found")
+ endif()
+
+ target_link_libraries(cmModLibStatic "${COREFOUNDATION_FRAMEWORK}")
+ target_compile_definitions(cmModLibStatic PUBLIC USE_FRAMEWORK)
+endif()
+
+target_compile_definitions(cmModLibStatic PUBLIC CMMODLIB_STATIC_DEFINE)
+
+install(TARGETS testEXE LIBRARY DESTINATION lib RUNTIME DESTINATION bin)
diff --git a/test cases/cmake/2 advanced/subprojects/cmMod/config.h.in b/test cases/cmake/2 advanced/subprojects/cmMod/config.h.in
new file mode 100644
index 0000000..f538ac9
--- /dev/null
+++ b/test cases/cmake/2 advanced/subprojects/cmMod/config.h.in
@@ -0,0 +1,3 @@
+#pragma once
+
+#define CONFIG_OPT @CONFIG_OPT@
diff --git a/test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.cpp b/test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.cpp
new file mode 100644
index 0000000..eb41438
--- /dev/null
+++ b/test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.cpp
@@ -0,0 +1,26 @@
+#include "cmMod.hpp"
+#include <zlib.h>
+#include "config.h"
+
+#if CONFIG_OPT != 42
+#error "Invalid value of CONFIG_OPT"
+#endif
+
+#ifdef USE_FRAMEWORK
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+using namespace std;
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World " + zlibVersion();
+
+#ifdef USE_FRAMEWORK
+ CFStringRef ref = CFStringCreateWithCString(NULL, str.c_str(), kCFStringEncodingUTF8);
+ CFRelease(ref);
+#endif
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
diff --git a/test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.hpp b/test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.hpp
new file mode 100644
index 0000000..52f576b
--- /dev/null
+++ b/test cases/cmake/2 advanced/subprojects/cmMod/lib/cmMod.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <string>
+#include "cmmodlib_export.h"
+
+class CMMODLIB_EXPORT cmModClass {
+ private:
+ std::string str;
+ public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+};
diff --git a/test cases/cmake/2 advanced/subprojects/cmMod/main.cpp b/test cases/cmake/2 advanced/subprojects/cmMod/main.cpp
new file mode 100644
index 0000000..77fab68
--- /dev/null
+++ b/test cases/cmake/2 advanced/subprojects/cmMod/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+#include <zlib.h>
+#include "lib/cmMod.hpp"
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello (LIB TEST)");
+ cout << obj.getStr() << " ZLIB: " << zlibVersion() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/2 advanced/test.json b/test cases/cmake/2 advanced/test.json
new file mode 100644
index 0000000..29888ea
--- /dev/null
+++ b/test cases/cmake/2 advanced/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/testEXE"}
+ ]
+}
diff --git a/test cases/cmake/20 cmake file/foolib.cmake.in b/test cases/cmake/20 cmake file/foolib.cmake.in
new file mode 100644
index 0000000..16e992b
--- /dev/null
+++ b/test cases/cmake/20 cmake file/foolib.cmake.in
@@ -0,0 +1 @@
+@foo@
diff --git a/test cases/cmake/20 cmake file/meson.build b/test cases/cmake/20 cmake file/meson.build
new file mode 100644
index 0000000..5c45d66
--- /dev/null
+++ b/test cases/cmake/20 cmake file/meson.build
@@ -0,0 +1,12 @@
+project(
+ 'cmake config file',
+)
+
+cmake = import('cmake')
+
+cmake.configure_package_config_file(
+ name : 'foolib',
+ input : 'foolib.cmake.in',
+ install_dir : get_option('libdir') / 'cmake',
+ configuration : {'foo': '"bar"'},
+)
diff --git a/test cases/cmake/20 cmake file/test.json b/test cases/cmake/20 cmake file/test.json
new file mode 100644
index 0000000..a8c4ba3
--- /dev/null
+++ b/test cases/cmake/20 cmake file/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"file": "usr/lib/cmake/foolibConfig.cmake", "type": "file"}
+ ]
+}
diff --git a/test cases/cmake/21 shared module/meson.build b/test cases/cmake/21 shared module/meson.build
new file mode 100644
index 0000000..c6ff957
--- /dev/null
+++ b/test cases/cmake/21 shared module/meson.build
@@ -0,0 +1,13 @@
+project('cmakeSharedModule', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('myMod')
+
+dl = meson.get_compiler('c').find_library('dl', required: false)
+
+l = shared_library('runtime', 'runtime.c')
+e = executable('prog', ['prog.c'], link_with: l, dependencies: [sub_dep, dl])
+m = sub_pro.target('myMod')
+test('test1', e, args : m)
diff --git a/test cases/cmake/21 shared module/prog.c b/test cases/cmake/21 shared module/prog.c
new file mode 100644
index 0000000..228a976
--- /dev/null
+++ b/test cases/cmake/21 shared module/prog.c
@@ -0,0 +1,108 @@
+
+#include <stdio.h>
+#include "module.h"
+
+#if SPECIAL_MAGIC_DEFINE != 42
+#error "SPECIAL_MAGIC_DEFINE is not defined"
+#endif
+
+int func_from_language_runtime(void);
+typedef int (*fptr) (void);
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+static wchar_t*
+win32_get_last_error (void)
+{
+ wchar_t *msg = NULL;
+
+ FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError (), 0,
+ (LPWSTR) &msg, 0, NULL);
+ return msg;
+}
+
+int main(int argc, char **argv)
+{
+ HINSTANCE handle;
+ fptr importedfunc;
+ int expected, actual;
+ int ret = 1;
+ if(argc==0) {};
+
+ handle = LoadLibraryA (argv[1]);
+ if (!handle) {
+ wchar_t *msg = win32_get_last_error ();
+ printf ("Could not open %s: %S\n", argv[1], msg);
+ goto nohandle;
+ }
+
+ importedfunc = (fptr) GetProcAddress (handle, "func");
+ if (importedfunc == NULL) {
+ wchar_t *msg = win32_get_last_error ();
+ printf ("Could not find 'func': %S\n", msg);
+ goto out;
+ }
+
+ actual = importedfunc ();
+ expected = func_from_language_runtime ();
+ if (actual != expected) {
+ printf ("Got %i instead of %i\n", actual, expected);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ FreeLibrary (handle);
+nohandle:
+ return ret;
+}
+
+#else
+
+#include<dlfcn.h>
+#include<assert.h>
+
+int main(int argc, char **argv) {
+ void *dl;
+ fptr importedfunc;
+ int expected, actual;
+ char *error;
+ int ret = 1;
+ if(argc==0) {};
+
+ dlerror();
+ dl = dlopen(argv[1], RTLD_LAZY);
+ error = dlerror();
+ if(error) {
+ printf("Could not open %s: %s\n", argv[1], error);
+ goto nodl;
+ }
+
+ importedfunc = (fptr) dlsym(dl, "func");
+ if (importedfunc == NULL) {
+ printf ("Could not find 'func'\n");
+ goto out;
+ }
+
+ assert(importedfunc != func_from_language_runtime);
+
+ actual = (*importedfunc)();
+ expected = func_from_language_runtime ();
+ if (actual != expected) {
+ printf ("Got %i instead of %i\n", actual, expected);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ dlclose(dl);
+nodl:
+ return ret;
+}
+
+#endif
diff --git a/test cases/cmake/21 shared module/runtime.c b/test cases/cmake/21 shared module/runtime.c
new file mode 100644
index 0000000..03bde86
--- /dev/null
+++ b/test cases/cmake/21 shared module/runtime.c
@@ -0,0 +1,19 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+/*
+ * This file pretends to be a language runtime that supports extension
+ * modules.
+ */
+
+int DLL_PUBLIC func_from_language_runtime(void) {
+ return 86;
+}
diff --git a/test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..d2fcfe3
--- /dev/null
+++ b/test cases/cmake/21 shared module/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmModule)
+
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}/module")
+
+add_library(myMod MODULE "${CMAKE_CURRENT_SOURCE_DIR}/module/module.c")
diff --git a/test cases/cmake/21 shared module/subprojects/cmMod/module/module.c b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.c
new file mode 100644
index 0000000..5dd26d7
--- /dev/null
+++ b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.c
@@ -0,0 +1,96 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+
+#include <stdio.h>
+
+typedef int (*fptr) (void);
+
+#ifdef __CYGWIN__
+
+#include <dlfcn.h>
+
+fptr find_any_f (const char *name) {
+ return (fptr) dlsym(RTLD_DEFAULT, name);
+}
+#else /* _WIN32 */
+
+#include <windows.h>
+#include <tlhelp32.h>
+
+static wchar_t*
+win32_get_last_error (void)
+{
+ wchar_t *msg = NULL;
+
+ FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError (), 0,
+ (LPWSTR) &msg, 0, NULL);
+ return msg;
+}
+
+/* Unlike Linux and OS X, when a library is loaded, all the symbols aren't
+ * loaded into a single namespace. You must fetch the symbol by iterating over
+ * all loaded modules. Code for finding the function from any of the loaded
+ * modules is taken from gmodule.c in glib */
+fptr find_any_f (const char *name) {
+ fptr f;
+ HANDLE snapshot;
+ MODULEENTRY32 me32;
+
+ snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
+ if (snapshot == (HANDLE) -1) {
+ wchar_t *msg = win32_get_last_error();
+ printf("Could not get snapshot: %S\n", msg);
+ return 0;
+ }
+
+ me32.dwSize = sizeof (me32);
+
+ f = NULL;
+ if (Module32First (snapshot, &me32)) {
+ do {
+ if ((f = (fptr) GetProcAddress (me32.hModule, name)) != NULL)
+ break;
+ } while (Module32Next (snapshot, &me32));
+ }
+
+ CloseHandle (snapshot);
+ return f;
+}
+#endif
+
+int DLL_PUBLIC func(void) {
+ fptr f;
+
+ f = find_any_f ("func_from_language_runtime");
+ if (f != NULL)
+ return f();
+ printf ("Could not find function\n");
+ return 1;
+}
+
+#else
+/*
+ * Shared modules often have references to symbols that are not defined
+ * at link time, but which will be provided from deps of the executable that
+ * dlopens it. We need to make sure that this works, i.e. that we do
+ * not pass -Wl,--no-undefined when linking modules.
+ */
+int func_from_language_runtime(void);
+
+int DLL_PUBLIC func(void) {
+ return func_from_language_runtime();
+}
+#endif
diff --git a/test cases/cmake/21 shared module/subprojects/cmMod/module/module.h b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.h
new file mode 100644
index 0000000..e1d9c13
--- /dev/null
+++ b/test cases/cmake/21 shared module/subprojects/cmMod/module/module.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define SPECIAL_MAGIC_DEFINE 42
diff --git a/test cases/cmake/22 cmake module/cmake_project/CMakeLists.txt b/test cases/cmake/22 cmake module/cmake_project/CMakeLists.txt
new file mode 100644
index 0000000..cd91584
--- /dev/null
+++ b/test cases/cmake/22 cmake module/cmake_project/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8)
+project(cmakeMeson C)
+
+find_package(cmakeModule REQUIRED) \ No newline at end of file
diff --git a/test cases/cmake/22 cmake module/meson.build b/test cases/cmake/22 cmake module/meson.build
new file mode 100644
index 0000000..68f9993
--- /dev/null
+++ b/test cases/cmake/22 cmake module/meson.build
@@ -0,0 +1,31 @@
+project('cmakeModule', 'c', version: '1.0.0')
+
+if build_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST CMake is broken on Cygwin.')
+endif
+
+cmake_bin = find_program('cmake', required: false)
+if not cmake_bin.found()
+ error('MESON_SKIP_TEST CMake not installed.')
+endif
+
+cc = meson.get_compiler('c')
+if cc.get_id() == 'clang-cl' and meson.backend() == 'ninja' and build_machine.system() == 'windows'
+ error('MESON_SKIP_TEST CMake installation nor operational for vs2017 clangclx64ninja')
+endif
+
+cmake = import('cmake')
+
+cmake.write_basic_package_version_file(version: '0.0.1',
+ name: 'cmakeModule',
+)
+
+conf = configuration_data()
+conf.set('MYVAR', 'my variable value')
+conf.set_quoted('MYQUOTEDVAR', 'my quoted variable value')
+
+cmake.configure_package_config_file(
+ input: 'projectConfig.cmake.in',
+ name: 'cmakeModule',
+ configuration: conf,
+)
diff --git a/test cases/cmake/22 cmake module/projectConfig.cmake.in b/test cases/cmake/22 cmake module/projectConfig.cmake.in
new file mode 100644
index 0000000..fa3dfca
--- /dev/null
+++ b/test cases/cmake/22 cmake module/projectConfig.cmake.in
@@ -0,0 +1,4 @@
+@PACKAGE_INIT@
+
+set(MYVAR "@MYVAR@")
+set(MYQUOTEDVAR @MYQUOTEDVAR@)
diff --git a/test cases/cmake/22 cmake module/test.json b/test cases/cmake/22 cmake module/test.json
new file mode 100644
index 0000000..2a5625a
--- /dev/null
+++ b/test cases/cmake/22 cmake module/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/cmake/cmakeModule/cmakeModuleConfig.cmake"},
+ {"type": "file", "file": "usr/lib/cmake/cmakeModule/cmakeModuleConfigVersion.cmake"}
+ ]
+}
diff --git a/test cases/cmake/23 cmake toolchain/CMakeToolchain.cmake b/test cases/cmake/23 cmake toolchain/CMakeToolchain.cmake
new file mode 100644
index 0000000..ab5fbac
--- /dev/null
+++ b/test cases/cmake/23 cmake toolchain/CMakeToolchain.cmake
@@ -0,0 +1 @@
+set(MESON_TEST_VAR2 VAR2)
diff --git a/test cases/cmake/23 cmake toolchain/meson.build b/test cases/cmake/23 cmake toolchain/meson.build
new file mode 100644
index 0000000..8399597
--- /dev/null
+++ b/test cases/cmake/23 cmake toolchain/meson.build
@@ -0,0 +1,13 @@
+project('cmake toolchain test', ['c'])
+
+if meson.is_cross_build()
+ error('MESON_SKIP_TEST: skip this on cross builds')
+endif
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+
+add_languages('cpp')
+
+sub_pro = cm.subproject('cmModFortran')
diff --git a/test cases/cmake/23 cmake toolchain/nativefile.ini.in b/test cases/cmake/23 cmake toolchain/nativefile.ini.in
new file mode 100644
index 0000000..1f4037d
--- /dev/null
+++ b/test cases/cmake/23 cmake toolchain/nativefile.ini.in
@@ -0,0 +1,9 @@
+[properties]
+
+cmake_toolchain_file = '@MESON_TEST_ROOT@/CMakeToolchain.cmake'
+cmake_skip_compiler_test = 'always'
+
+[cmake]
+
+MESON_TEST_VAR1 = 'VAR1 space'
+MESON_TEST_VAR2 = 'VAR2 error'
diff --git a/test cases/cmake/23 cmake toolchain/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/23 cmake toolchain/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..a00affa
--- /dev/null
+++ b/test cases/cmake/23 cmake toolchain/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod NONE)
+
+if(NOT "${MESON_TEST_VAR1}" STREQUAL "VAR1 space")
+ message(FATAL_ERROR "MESON_TEST_VAR1 -- '${MESON_TEST_VAR1}' != 'VAR1 space'")
+endif()
+
+if(NOT "${MESON_TEST_VAR2}" STREQUAL "VAR2")
+ message(FATAL_ERROR "MESON_TEST_VAR2 -- '${MESON_TEST_VAR2}' != 'VAR2'")
+endif()
+
+if(NOT DEFINED CMAKE_C_COMPILER_VERSION)
+ message(FATAL_ERROR "CMAKE_C_COMPILER_VERSION was not defined")
+endif()
diff --git a/test cases/cmake/23 cmake toolchain/subprojects/cmModFortran/CMakeLists.txt b/test cases/cmake/23 cmake toolchain/subprojects/cmModFortran/CMakeLists.txt
new file mode 100644
index 0000000..ecf1737
--- /dev/null
+++ b/test cases/cmake/23 cmake toolchain/subprojects/cmModFortran/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod NONE)
+
+if(NOT "${MESON_TEST_VAR1}" STREQUAL "VAR1 space")
+ message(FATAL_ERROR "MESON_TEST_VAR1 -- '${MESON_TEST_VAR1}' != 'VAR1 space'")
+endif()
+
+if(NOT "${MESON_TEST_VAR2}" STREQUAL "VAR2")
+ message(FATAL_ERROR "MESON_TEST_VAR2 -- '${MESON_TEST_VAR2}' != 'VAR2'")
+endif()
+
+if(NOT DEFINED CMAKE_C_COMPILER_VERSION)
+ message(FATAL_ERROR "CMAKE_C_COMPILER_VERSION was not defined")
+endif()
+
+if(NOT DEFINED CMAKE_CXX_COMPILER_VERSION)
+ message(FATAL_ERROR "CMAKE_CXX_COMPILER_VERSION was not defined")
+endif()
diff --git a/test cases/cmake/24 mixing languages/main.c b/test cases/cmake/24 mixing languages/main.c
new file mode 100644
index 0000000..028a78e
--- /dev/null
+++ b/test cases/cmake/24 mixing languages/main.c
@@ -0,0 +1,5 @@
+#include <cmTest.h>
+
+int main(void) {
+ return doStuff();
+}
diff --git a/test cases/cmake/24 mixing languages/meson.build b/test cases/cmake/24 mixing languages/meson.build
new file mode 100644
index 0000000..4ab1d85
--- /dev/null
+++ b/test cases/cmake/24 mixing languages/meson.build
@@ -0,0 +1,13 @@
+project('CMake mix', ['c', 'cpp'])
+
+if not add_languages('objc', required : false)
+ error('MESON_SKIP_TEST: No ObjC compiler')
+endif
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmTest')
+sub_dep = sub_pro.dependency('cmTest', include_type: 'system')
+
+exe1 = executable('exe1', ['main.c'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/24 mixing languages/subprojects/cmTest/CMakeLists.txt b/test cases/cmake/24 mixing languages/subprojects/cmTest/CMakeLists.txt
new file mode 100644
index 0000000..80a256f
--- /dev/null
+++ b/test cases/cmake/24 mixing languages/subprojects/cmTest/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmTest)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_library(cmTest STATIC cmTest.c cmTest.m)
+target_compile_definitions(cmTest PUBLIC SOME_MAGIC_DEFINE=42)
diff --git a/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.c b/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.c
new file mode 100644
index 0000000..066d676
--- /dev/null
+++ b/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.c
@@ -0,0 +1,13 @@
+#include "cmTest.h"
+#include <stdio.h>
+
+#if SOME_MAGIC_DEFINE != 42
+#error "SOME_MAGIC_DEFINE != 42"
+#endif
+
+int foo(int x);
+
+int doStuff(void) {
+ printf("Hello World\n");
+ return foo(42);
+}
diff --git a/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.h b/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.h
new file mode 100644
index 0000000..a6a5c24
--- /dev/null
+++ b/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int doStuff(void);
diff --git a/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.m b/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.m
new file mode 100644
index 0000000..16ec805
--- /dev/null
+++ b/test cases/cmake/24 mixing languages/subprojects/cmTest/cmTest.m
@@ -0,0 +1,7 @@
+#if SOME_MAGIC_DEFINE != 42
+#error "SOME_MAGIC_DEFINE != 42"
+#endif
+
+int foo(int x) {
+ return 42 - x;
+}
diff --git a/test cases/cmake/25 assembler/main.c b/test cases/cmake/25 assembler/main.c
new file mode 100644
index 0000000..5aef967
--- /dev/null
+++ b/test cases/cmake/25 assembler/main.c
@@ -0,0 +1,18 @@
+#include <stdint.h>
+#include <stdio.h>
+
+int32_t cmTestFunc(void);
+
+int main(void)
+{
+ if (cmTestFunc() > 4200)
+ {
+ printf("Test success.\n");
+ return 0;
+ }
+ else
+ {
+ printf("Test failure.\n");
+ return 1;
+ }
+}
diff --git a/test cases/cmake/25 assembler/meson.build b/test cases/cmake/25 assembler/meson.build
new file mode 100644
index 0000000..7180356
--- /dev/null
+++ b/test cases/cmake/25 assembler/meson.build
@@ -0,0 +1,9 @@
+project('assembler test', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmTest')
+sub_dep = sub_pro.dependency('cmTest')
+
+exe1 = executable('exe1', ['main.c'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt b/test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt
new file mode 100644
index 0000000..bb8834d
--- /dev/null
+++ b/test cases/cmake/25 assembler/subprojects/cmTest/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmTest)
+
+#Detect processor
+if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "amd64")
+ SET(TEST_PROCESSOR "x86_64")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64")
+ SET(TEST_PROCESSOR "x86_64")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i386")
+ SET(TEST_PROCESSOR "x86")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i686")
+ SET(TEST_PROCESSOR "x86")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm")
+ SET(TEST_PROCESSOR "arm")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64")
+ SET(TEST_PROCESSOR "arm")
+else ()
+ message(FATAL_ERROR "MESON_SKIP_TEST: Unsupported Assembler Platform")
+endif ()
+
+#Detect ABI
+if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
+ SET(TEST_ABI "sysv")
+elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
+ SET(TEST_ABI "sysv")
+elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "NetBSD")
+ SET(TEST_ABI "sysv")
+elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
+ SET(TEST_ABI "sysv")
+else ()
+ message(FATAL_ERROR "MESON_SKIP_TEST: Unsupported Assembler Platform")
+endif ()
+
+SET(TEST_PLATFORM "${TEST_PROCESSOR}-${TEST_ABI}")
+
+if ( ("${TEST_PLATFORM}" MATCHES "x86_64-sysv")
+ OR ("${TEST_PLATFORM}" MATCHES "x86-sysv")
+ OR ("${TEST_PLATFORM}" MATCHES "arm-sysv"))
+ SET(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
+ enable_language(ASM)
+ SET(TEST_SOURCE "cmTestAsm.s")
+endif ()
+
+add_library(cmTest STATIC cmTest.c ${TEST_SOURCE})
diff --git a/test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c b/test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c
new file mode 100644
index 0000000..e32415c
--- /dev/null
+++ b/test cases/cmake/25 assembler/subprojects/cmTest/cmTest.c
@@ -0,0 +1,8 @@
+#include <stdint.h>
+
+extern const int32_t cmTestArea;
+
+int32_t cmTestFunc(void)
+{
+ return cmTestArea;
+}
diff --git a/test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s b/test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s
new file mode 100644
index 0000000..8aa83a6
--- /dev/null
+++ b/test cases/cmake/25 assembler/subprojects/cmTest/cmTestAsm.s
@@ -0,0 +1,4 @@
+.text
+.globl cmTestArea
+cmTestArea:
+ .long 4242
diff --git a/test cases/cmake/3 advanced no dep/main.cpp b/test cases/cmake/3 advanced no dep/main.cpp
new file mode 100644
index 0000000..d823e29
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/main.cpp
@@ -0,0 +1,15 @@
+#include <iostream>
+#include <cmMod.hpp>
+#include "config.h"
+
+#if CONFIG_OPT != 42
+#error "Invalid value of CONFIG_OPT"
+#endif
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/3 advanced no dep/meson.build b/test cases/cmake/3 advanced no dep/meson.build
new file mode 100644
index 0000000..f8f1836
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/meson.build
@@ -0,0 +1,19 @@
+project('cmakeSubTest_advanced', ['c', 'cpp'])
+
+cm = import('cmake')
+
+# Test the "normal" subproject call
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib')
+sub_sta = sub_pro.dependency('cmModLibStatic')
+
+# Build some files
+exe1 = executable('main1', ['main.cpp'], dependencies: [sub_dep])
+exe2 = executable('main2', ['main.cpp'], dependencies: [sub_sta])
+test('test1', exe1)
+test('test2', exe2)
+
+# Test if we can also extract executables
+assert(sub_pro.target_type('meson-testEXE') == 'executable', 'The type must be executable for obvious reasons')
+test('test3', sub_pro.target('meson-testEXE'))
+test('test4', sub_pro.target('benchmark'))
diff --git a/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..d738d45
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set(CMAKE_CXX_STANDARD 14)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib)
+
+set(CONFIG_OPT 42)
+configure_file("config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
+
+add_library(cmModLib SHARED lib/cmMod.cpp)
+add_library(cmModLibStatic STATIC lib/cmMod.cpp)
+include(GenerateExportHeader)
+generate_export_header(cmModLib)
+
+set_target_properties(cmModLib PROPERTIES VERSION 1.0.1)
+
+add_executable(meson-testEXE main.cpp)
+add_executable(benchmark main.cpp)
+
+target_link_libraries(meson-testEXE cmModLib)
+target_link_libraries(benchmark cmModLib)
+
+target_compile_definitions(cmModLibStatic PUBLIC CMMODLIB_STATIC_DEFINE)
+
+install(TARGETS meson-testEXE benchmark LIBRARY DESTINATION lib RUNTIME DESTINATION bin)
diff --git a/test cases/cmake/3 advanced no dep/subprojects/cmMod/config.h.in b/test cases/cmake/3 advanced no dep/subprojects/cmMod/config.h.in
new file mode 100644
index 0000000..f538ac9
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/config.h.in
@@ -0,0 +1,3 @@
+#pragma once
+
+#define CONFIG_OPT @CONFIG_OPT@
diff --git a/test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.cpp b/test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.cpp
new file mode 100644
index 0000000..741e8df
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.cpp
@@ -0,0 +1,16 @@
+#include "cmMod.hpp"
+#include "config.h"
+
+#if CONFIG_OPT != 42
+#error "Invalid value of CONFIG_OPT"
+#endif
+
+using namespace std;
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World";
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
diff --git a/test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.hpp b/test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.hpp
new file mode 100644
index 0000000..52f576b
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/lib/cmMod.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <string>
+#include "cmmodlib_export.h"
+
+class CMMODLIB_EXPORT cmModClass {
+ private:
+ std::string str;
+ public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+};
diff --git a/test cases/cmake/3 advanced no dep/subprojects/cmMod/main.cpp b/test cases/cmake/3 advanced no dep/subprojects/cmMod/main.cpp
new file mode 100644
index 0000000..d3e67ca
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include "lib/cmMod.hpp"
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello (LIB TEST)");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/3 advanced no dep/test.json b/test cases/cmake/3 advanced no dep/test.json
new file mode 100644
index 0000000..e75e54a
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "pdb", "file": "usr/bin/cm_meson_testEXE"},
+ {"type": "exe", "file": "usr/bin/cm_meson_testEXE"},
+ {"type": "pdb", "file": "usr/bin/cm_benchmark"},
+ {"type": "exe", "file": "usr/bin/cm_benchmark"}
+ ]
+}
diff --git a/test cases/cmake/4 code gen/main.cpp b/test cases/cmake/4 code gen/main.cpp
new file mode 100644
index 0000000..a41204b
--- /dev/null
+++ b/test cases/cmake/4 code gen/main.cpp
@@ -0,0 +1,8 @@
+#include <iostream>
+#include "test.hpp"
+
+using namespace std;
+
+int main(void) {
+ cout << getStr() << endl;
+}
diff --git a/test cases/cmake/4 code gen/meson.build b/test cases/cmake/4 code gen/meson.build
new file mode 100644
index 0000000..80c801f
--- /dev/null
+++ b/test cases/cmake/4 code gen/meson.build
@@ -0,0 +1,24 @@
+project('cmake_code_gen', ['c', 'cpp'])
+
+if meson.is_cross_build()
+ error('MESON_SKIP_TEST this test does not cross compile correctly.')
+endif
+
+cm = import('cmake')
+
+# Subproject with the "code generator"
+sub_pro = cm.subproject('cmCodeGen')
+sub_exe = sub_pro.target('genA')
+
+# Generate the source
+generated = custom_target(
+ 'cmake-generated',
+ input: [],
+ output: ['test.cpp'],
+ command: [sub_exe, '@OUTPUT@']
+)
+
+# Build the exe
+exe1 = executable('main1', ['main.cpp', generated])
+
+test('test1', exe1)
diff --git a/test cases/cmake/4 code gen/subprojects/cmCodeGen/CMakeLists.txt b/test cases/cmake/4 code gen/subprojects/cmCodeGen/CMakeLists.txt
new file mode 100644
index 0000000..ff50e54
--- /dev/null
+++ b/test cases/cmake/4 code gen/subprojects/cmCodeGen/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.7)
+
+project(CMCodeGen)
+set(CMAKE_CXX_STANDARD 14)
+
+add_executable(genA main.cpp)
diff --git a/test cases/cmake/4 code gen/subprojects/cmCodeGen/main.cpp b/test cases/cmake/4 code gen/subprojects/cmCodeGen/main.cpp
new file mode 100644
index 0000000..5b7fed2
--- /dev/null
+++ b/test cases/cmake/4 code gen/subprojects/cmCodeGen/main.cpp
@@ -0,0 +1,21 @@
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+int main(int argc, const char *argv[]) {
+ if(argc < 2) {
+ cerr << argv[0] << " requires an output file!" << endl;
+ return 1;
+ }
+ ofstream out(argv[1]);
+ out << R"(
+#include "test.hpp"
+
+std::string getStr() {
+ return "Hello World";
+}
+)";
+
+ return 0;
+}
diff --git a/test cases/cmake/4 code gen/test.hpp b/test cases/cmake/4 code gen/test.hpp
new file mode 100644
index 0000000..8e25a0a
--- /dev/null
+++ b/test cases/cmake/4 code gen/test.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <string>
+
+std::string getStr();
diff --git a/test cases/cmake/5 object library/main.cpp b/test cases/cmake/5 object library/main.cpp
new file mode 100644
index 0000000..9933ab4
--- /dev/null
+++ b/test cases/cmake/5 object library/main.cpp
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <iostream>
+#include "libA.hpp"
+#include "libB.hpp"
+
+using namespace std;
+
+int main(void) {
+ cout << getLibStr() << " -- " << getZlibVers() << endl;
+ return EXIT_SUCCESS;
+}
diff --git a/test cases/cmake/5 object library/meson.build b/test cases/cmake/5 object library/meson.build
new file mode 100644
index 0000000..f38a2dd
--- /dev/null
+++ b/test cases/cmake/5 object library/meson.build
@@ -0,0 +1,21 @@
+project('cmake_object_lib_test', ['c', 'cpp'])
+
+dep_test = dependency('ZLIB', method: 'cmake', required: false)
+if not dep_test.found()
+ error('MESON_SKIP_TEST: zlib is not installed')
+endif
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmObjLib')
+sub_sha = sub_pro.dependency('lib_sha')
+sub_sta = sub_pro.dependency('lib_sta')
+
+# Required for the static library
+zlib_dep = dependency('zlib')
+
+exe_sha = executable('shared', ['main.cpp'], dependencies: [sub_sha])
+exe_sta = executable('static', ['main.cpp'], dependencies: [sub_sta, zlib_dep])
+
+test('test1', exe_sha)
+test('test1', exe_sta)
diff --git a/test cases/cmake/5 object library/subprojects/cmObjLib/CMakeLists.txt b/test cases/cmake/5 object library/subprojects/cmObjLib/CMakeLists.txt
new file mode 100644
index 0000000..062496e
--- /dev/null
+++ b/test cases/cmake/5 object library/subprojects/cmObjLib/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.7)
+project(cmObject CXX)
+
+find_package(ZLIB REQUIRED)
+
+add_library(lib_obj OBJECT libA.cpp libB.cpp)
+add_library(lib_sha SHARED $<TARGET_OBJECTS:lib_obj>)
+add_library(lib_sta STATIC $<TARGET_OBJECTS:lib_obj>)
+
+target_link_libraries(lib_sha ZLIB::ZLIB)
+target_link_libraries(lib_sta ZLIB::ZLIB)
diff --git a/test cases/cmake/5 object library/subprojects/cmObjLib/libA.cpp b/test cases/cmake/5 object library/subprojects/cmObjLib/libA.cpp
new file mode 100644
index 0000000..1d579cf
--- /dev/null
+++ b/test cases/cmake/5 object library/subprojects/cmObjLib/libA.cpp
@@ -0,0 +1,5 @@
+#include "libA.hpp"
+
+std::string getLibStr(void) {
+ return "Hello World";
+}
diff --git a/test cases/cmake/5 object library/subprojects/cmObjLib/libA.hpp b/test cases/cmake/5 object library/subprojects/cmObjLib/libA.hpp
new file mode 100644
index 0000000..84b7bc7
--- /dev/null
+++ b/test cases/cmake/5 object library/subprojects/cmObjLib/libA.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+std::string DLL_PUBLIC getLibStr();
diff --git a/test cases/cmake/5 object library/subprojects/cmObjLib/libB.cpp b/test cases/cmake/5 object library/subprojects/cmObjLib/libB.cpp
new file mode 100644
index 0000000..22fe7c2
--- /dev/null
+++ b/test cases/cmake/5 object library/subprojects/cmObjLib/libB.cpp
@@ -0,0 +1,6 @@
+#include "libB.hpp"
+#include <zlib.h>
+
+std::string getZlibVers(void) {
+ return zlibVersion();
+}
diff --git a/test cases/cmake/5 object library/subprojects/cmObjLib/libB.hpp b/test cases/cmake/5 object library/subprojects/cmObjLib/libB.hpp
new file mode 100644
index 0000000..52ccc16
--- /dev/null
+++ b/test cases/cmake/5 object library/subprojects/cmObjLib/libB.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+std::string DLL_PUBLIC getZlibVers();
diff --git a/test cases/cmake/6 object library no dep/main.cpp b/test cases/cmake/6 object library no dep/main.cpp
new file mode 100644
index 0000000..9933ab4
--- /dev/null
+++ b/test cases/cmake/6 object library no dep/main.cpp
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <iostream>
+#include "libA.hpp"
+#include "libB.hpp"
+
+using namespace std;
+
+int main(void) {
+ cout << getLibStr() << " -- " << getZlibVers() << endl;
+ return EXIT_SUCCESS;
+}
diff --git a/test cases/cmake/6 object library no dep/meson.build b/test cases/cmake/6 object library no dep/meson.build
new file mode 100644
index 0000000..65b8700
--- /dev/null
+++ b/test cases/cmake/6 object library no dep/meson.build
@@ -0,0 +1,13 @@
+project('cmake_object_lib_test', 'cpp')
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmObjLib')
+sub_sha = sub_pro.dependency('lib_sha')
+sub_sta = sub_pro.dependency('lib_sta')
+
+exe_sha = executable('shared', ['main.cpp'], dependencies: [sub_sha])
+exe_sta = executable('static', ['main.cpp'], dependencies: [sub_sta])
+
+test('test1', exe_sha)
+test('test1', exe_sta)
diff --git a/test cases/cmake/6 object library no dep/subprojects/cmObjLib/CMakeLists.txt b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/CMakeLists.txt
new file mode 100644
index 0000000..9e136af
--- /dev/null
+++ b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.7)
+project(cmObject CXX)
+
+add_library(lib_obj OBJECT libA.cpp libB.cpp)
+add_library(lib_sha SHARED $<TARGET_OBJECTS:lib_obj>)
+add_library(lib_sta STATIC $<TARGET_OBJECTS:lib_obj>)
diff --git a/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.cpp b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.cpp
new file mode 100644
index 0000000..1d579cf
--- /dev/null
+++ b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.cpp
@@ -0,0 +1,5 @@
+#include "libA.hpp"
+
+std::string getLibStr(void) {
+ return "Hello World";
+}
diff --git a/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.hpp b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.hpp
new file mode 100644
index 0000000..84b7bc7
--- /dev/null
+++ b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libA.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+std::string DLL_PUBLIC getLibStr();
diff --git a/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.cpp b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.cpp
new file mode 100644
index 0000000..aa44816
--- /dev/null
+++ b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.cpp
@@ -0,0 +1,5 @@
+#include "libB.hpp"
+
+std::string getZlibVers(void) {
+ return "STUB";
+}
diff --git a/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.hpp b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.hpp
new file mode 100644
index 0000000..52ccc16
--- /dev/null
+++ b/test cases/cmake/6 object library no dep/subprojects/cmObjLib/libB.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+std::string DLL_PUBLIC getZlibVers();
diff --git a/test cases/cmake/7 cmake options/meson.build b/test cases/cmake/7 cmake options/meson.build
new file mode 100644
index 0000000..8bb6d1d
--- /dev/null
+++ b/test cases/cmake/7 cmake options/meson.build
@@ -0,0 +1,3 @@
+project('cmake_set_opt', ['c', 'cpp'])
+
+import('cmake').subproject('cmOpts', cmake_options: '-DSOME_CMAKE_VAR=something')
diff --git a/test cases/cmake/7 cmake options/subprojects/cmOpts/CMakeLists.txt b/test cases/cmake/7 cmake options/subprojects/cmOpts/CMakeLists.txt
new file mode 100644
index 0000000..873b9b3
--- /dev/null
+++ b/test cases/cmake/7 cmake options/subprojects/cmOpts/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.7)
+project(testPro)
+
+if(NOT "${SOME_CMAKE_VAR}" STREQUAL "something")
+ message(FATAL_ERROR "Setting the CMake var failed")
+endif()
+
+if(NOT "${CMAKE_PREFIX_PATH}" STREQUAL "val1;val2")
+ message(FATAL_ERROR "Setting the CMAKE_PREFIX_PATH failed '${CMAKE_PREFIX_PATH}'")
+endif()
diff --git a/test cases/cmake/7 cmake options/test.json b/test cases/cmake/7 cmake options/test.json
new file mode 100644
index 0000000..f9f0b05
--- /dev/null
+++ b/test cases/cmake/7 cmake options/test.json
@@ -0,0 +1,12 @@
+{
+ "matrix": {
+ "options": {
+ "cmake_prefix_path": [
+ { "val": ["val1", "val2"] }
+ ],
+ "build.cmake_prefix_path": [
+ { "val": ["val1", "val2"] }
+ ]
+ }
+ }
+}
diff --git a/test cases/cmake/8 custom command/main.cpp b/test cases/cmake/8 custom command/main.cpp
new file mode 100644
index 0000000..7558d60
--- /dev/null
+++ b/test cases/cmake/8 custom command/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ cout << obj.getOther() << endl;
+ return 0;
+}
diff --git a/test cases/cmake/8 custom command/meson.build b/test cases/cmake/8 custom command/meson.build
new file mode 100644
index 0000000..a262252
--- /dev/null
+++ b/test cases/cmake/8 custom command/meson.build
@@ -0,0 +1,16 @@
+project('cmakeSubTest', ['c', 'cpp'])
+
+if meson.is_cross_build()
+ error('MESON_SKIP_TEST this test does not cross compile correctly.')
+endif
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('cmMod')
+sub_dep = sub_pro.dependency('cmModLib')
+
+assert(sub_pro.target_type('cmModLib') == 'shared_library', 'Target type should be shared_library')
+assert(sub_pro.target_type('gen') == 'executable', 'Target type should be executable')
+
+exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/8 custom command/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..0185ddc
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,163 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+set (CMAKE_CXX_STANDARD_REQUIRED ON)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_definitions("-DDO_NOTHING_JUST_A_FLAG=1")
+
+add_executable(genMain genMain.cpp)
+add_custom_command(OUTPUT main.cpp COMMAND genMain > main.cpp)
+
+add_executable(gen main.cpp)
+add_executable(mycpy cp.cpp)
+
+# cpyBase
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/genTest.cpp" "${CMAKE_CURRENT_BINARY_DIR}/genTest.hpp"
+ COMMAND gen ARGS genTest
+)
+
+set(CMD_PART)
+list(APPEND CMD_PART COMMAND mycpy cpyBase.cpp.in cpyBase.cpp.in.gen)
+list(APPEND CMD_PART COMMAND mycpy cpyBase.cpp.in.gen cpyBase.cpp.out)
+list(APPEND CMD_PART COMMAND mycpy cpyBase.cpp.out cpyBase.cpp.something)
+
+add_custom_command(
+ OUTPUT cpyBase.cpp
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyBase.cpp.am" cpyBase.cpp.in
+ ${CMD_PART}
+ COMMAND mycpy cpyBase.cpp.in cpyBase.cpp.something
+ COMMAND mycpy cpyBase.cpp.something cpyBase.cpp.IAmRunningOutOfIdeas
+ COMMAND mycpy cpyBase.cpp.IAmRunningOutOfIdeas cpyBase.cpp
+ DEPENDS cpyBase.cpp.am;gen
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyBase.hpp.in"
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyBase.hpp.am" cpyBase.hpp.in
+ DEPENDS cpyBase.hpp.am
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyBase.hpp.something"
+ COMMAND mycpy cpyBase.hpp.in cpyBase.hpp.something
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/cpyBase.hpp.in"
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyBase.hpp"
+ COMMAND mycpy cpyBase.hpp.something cpyBase.hpp
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/cpyBase.hpp.something"
+)
+
+# cpyNext (out of order is on purpose)
+# -- first copy round
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/s1_a_hpp/file.txt"
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyNext.hpp.am" file.txt
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cpyNext.hpp.am"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/s1_a_hpp"
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/s1_b_cpp/file.txt"
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyNext.cpp.am" file.txt
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cpyNext.cpp.am"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/s1_b_cpp"
+)
+
+# -- final cpy round
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyNext.hpp"
+ COMMAND mycpy "${CMAKE_CURRENT_BINARY_DIR}/s2_b_hpp/file.txt" cpyNext.hpp
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/s2_b_hpp/file.txt"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyNext.cpp"
+ COMMAND mycpy "${CMAKE_CURRENT_BINARY_DIR}/s2_a_cpp/file.txt" cpyNext.cpp
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/s2_a_cpp/file.txt"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+)
+
+# -- second copy round
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/s2_b_hpp/file.txt"
+ COMMAND mycpy "${CMAKE_CURRENT_BINARY_DIR}/s1_a_hpp/file.txt" file.txt
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/s1_a_hpp/file.txt"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/s2_b_hpp"
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/s2_a_cpp/file.txt"
+ COMMAND mycpy "${CMAKE_CURRENT_BINARY_DIR}/s1_b_cpp/file.txt" file.txt
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/s1_b_cpp/file.txt"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/s2_a_cpp"
+)
+
+# cpyTest (copy file without renaming)
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyTest.hpp"
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest/cpyTest.hpp" "${CMAKE_CURRENT_BINARY_DIR}/cpyTest.hpp"
+ DEPENDS "cpyTest/cpyTest.hpp"
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyTest2.hpp"
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest/cpyTest2.hpp" "${CMAKE_CURRENT_BINARY_DIR}/cpyTest2.hpp"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest/cpyTest2.hpp"
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyTest3.hpp"
+ COMMAND mycpy cpyTest3.hpp "${CMAKE_CURRENT_BINARY_DIR}/cpyTest3.hpp"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest/cpyTest3.hpp"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest"
+)
+
+add_subdirectory(cpyTest ccppyyTTeesstt)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyTest/some/directory/cpyTest5.hpp"
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest/cpyTest5.hpp" "${CMAKE_CURRENT_BINARY_DIR}/cpyTest/some/directory/cpyTest5.hpp"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest/cpyTest5.hpp"
+)
+include_directories("${CMAKE_CURRENT_BINARY_DIR}/cpyTest/some")
+
+add_library(cmModLib SHARED cmMod.cpp genTest.cpp cpyBase.cpp cpyBase.hpp cpyNext.cpp cpyNext.hpp cpyTest.cpp cpyTest.hpp cpyTest2.hpp cpyTest3.hpp cpyTest/some/directory/cpyTest5.hpp)
+include(GenerateExportHeader)
+generate_export_header(cmModLib)
+
+set(ARGS_TEST arg1)
+set(ARGS_TEST ${ARGS_TEST} arg2)
+
+add_executable(macro_name macro_name.cpp)
+add_executable(args_test args_test.cpp)
+add_custom_target(args_test_cmd
+ COMMAND args_test ${ARGS_TEST}
+)
+add_custom_target(macro_name_cmd COMMAND macro_name)
+
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ message(STATUS "Running the -include test case on macro_name")
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cpyInc.hpp"
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyInc.hpp.am" "${CMAKE_CURRENT_BINARY_DIR}/cpyInc.hpp"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cpyInc.hpp.am"
+ )
+ target_compile_options(macro_name PUBLIC -DTEST_CMD_INCLUDE -include "${CMAKE_CURRENT_BINARY_DIR}/cpyInc.hpp")
+endif()
+
+# Only executable targets are replaced in the command
+# all other target names are kept as is
+add_custom_target(clang-format COMMAND clang-format -i cmMod.cpp)
+
+add_dependencies(cmModLib args_test_cmd tgtCpyTest4)
+add_dependencies(args_test_cmd macro_name_cmd;gen;mycpy)
+
+# Reproduce https://github.com/mesonbuild/meson/issues/10244
+add_custom_target(mycpy.all)
+add_dependencies(mycpy.all mycpy)
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/args_test.cpp b/test cases/cmake/8 custom command/subprojects/cmMod/args_test.cpp
new file mode 100644
index 0000000..abb8a42
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/args_test.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+int main(int argc, const char *argv[]) {
+ if(argc != 3 || string(argv[1]) != "arg1" || string(argv[2]) != "arg2") {
+ cerr << argv[0] << " requires 2 args" << endl;
+ return 1;
+ }
+
+ ifstream in1("macro_name.txt");
+ ofstream out1("cmModLib.hpp");
+ out1 << "#define " << in1.rdbuf() << " = \"plop\"";
+
+
+ return 0;
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cmMod.cpp b/test cases/cmake/8 custom command/subprojects/cmMod/cmMod.cpp
new file mode 100644
index 0000000..a466399
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cmMod.cpp
@@ -0,0 +1,24 @@
+#include "cmMod.hpp"
+#include "genTest.hpp"
+#include "cpyBase.hpp"
+#include "cpyNext.hpp"
+#include "cpyTest.hpp"
+#include "cmModLib.hpp"
+
+#ifndef FOO
+#error FOO not declared
+#endif
+
+using namespace std;
+
+cmModClass::cmModClass(string foo) {
+ str = foo + " World";
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
+
+string cmModClass::getOther() const {
+ return "Strings:\n - " + getStrCpy() + "\n - " + getStrNext() + "\n - " + getStrCpyTest();
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cmMod.hpp b/test cases/cmake/8 custom command/subprojects/cmMod/cmMod.hpp
new file mode 100644
index 0000000..cfdbe88
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cmMod.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <string>
+#include "cmmodlib_export.h"
+
+class CMMODLIB_EXPORT cmModClass {
+ private:
+ std::string str;
+ public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+ std::string getOther() const;
+};
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cp.cpp b/test cases/cmake/8 custom command/subprojects/cmMod/cp.cpp
new file mode 100644
index 0000000..09433f2
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cp.cpp
@@ -0,0 +1,22 @@
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+int main(int argc, char *argv[]) {
+ if(argc < 3) {
+ cerr << argv[0] << " requires an input and an output file!" << endl;
+ return 1;
+ }
+
+ ifstream src(argv[1]);
+ ofstream dst(argv[2]);
+
+ if(!src.is_open()) {
+ cerr << "Failed to open " << argv[1] << endl;
+ return 2;
+ }
+
+ dst << src.rdbuf();
+ return 0;
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.cpp.am b/test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.cpp.am
new file mode 100644
index 0000000..98dd09c
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.cpp.am
@@ -0,0 +1,5 @@
+#include "cpyBase.hpp"
+
+std::string getStrCpy() {
+ return "Hello Copied File";
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.hpp.am b/test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.hpp.am
new file mode 100644
index 0000000..c255fb1
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyBase.hpp.am
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <string>
+
+std::string getStrCpy();
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyInc.hpp.am b/test cases/cmake/8 custom command/subprojects/cmMod/cpyInc.hpp.am
new file mode 100644
index 0000000..07c8ff7
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyInc.hpp.am
@@ -0,0 +1,3 @@
+#pragma once
+
+#define CPY_INC_WAS_INCLUDED 1
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.cpp.am b/test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.cpp.am
new file mode 100644
index 0000000..20a8815
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.cpp.am
@@ -0,0 +1,5 @@
+#include "cpyNext.hpp"
+
+std::string getStrNext() {
+ return "Hello Copied File -- now even more convoluted!";
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.hpp.am b/test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.hpp.am
new file mode 100644
index 0000000..41919d8
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyNext.hpp.am
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <string>
+
+std::string getStrNext();
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest.cpp b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest.cpp
new file mode 100644
index 0000000..627b8f9
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest.cpp
@@ -0,0 +1,9 @@
+#include "cpyTest.hpp"
+#include "cpyTest2.hpp"
+#include "cpyTest3.hpp"
+#include "ccppyyTTeesstt/cpyTest4.hpp"
+#include "directory/cpyTest5.hpp"
+
+std::string getStrCpyTest() {
+ return CPY_TEST_STR_2 CPY_TEST_STR_3 CPY_TEST_STR_4 CPY_TEST_STR_5;
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/CMakeLists.txt b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/CMakeLists.txt
new file mode 100644
index 0000000..f577dcf
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_custom_command(
+ OUTPUT cpyTest4.hpp
+ COMMAND mycpy "${CMAKE_CURRENT_SOURCE_DIR}/cpyTest4.hpp" cpyTest4.hpp
+ DEPENDS cpyTest4.hpp
+)
+
+add_custom_target(tgtCpyTest4 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/cpyTest4.hpp")
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest.hpp b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest.hpp
new file mode 100644
index 0000000..e8dec13
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <string>
+
+std::string getStrCpyTest();
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest2.hpp b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest2.hpp
new file mode 100644
index 0000000..bdbcc56
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest2.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+#define CPY_TEST_STR_2 "Hello "
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest3.hpp b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest3.hpp
new file mode 100644
index 0000000..2d13376
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest3.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+#define CPY_TEST_STR_3 "CopyFile"
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest4.hpp b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest4.hpp
new file mode 100644
index 0000000..4124c43
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest4.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+#define CPY_TEST_STR_4 " test"
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest5.hpp b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest5.hpp
new file mode 100644
index 0000000..3669f00
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/cpyTest/cpyTest5.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+#define CPY_TEST_STR_5 " test"
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/genMain.cpp b/test cases/cmake/8 custom command/subprojects/cmMod/genMain.cpp
new file mode 100644
index 0000000..33f0201
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/genMain.cpp
@@ -0,0 +1,40 @@
+#include <iostream>
+
+using namespace std;
+
+int main() {
+ cout << R"asd(
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+int main(int argc, const char *argv[]) {
+ if(argc < 2) {
+ cerr << argv[0] << " requires an output file!" << endl;
+ return 1;
+ }
+ ofstream out1(string(argv[1]) + ".hpp");
+ ofstream out2(string(argv[1]) + ".cpp");
+ out1 << R"(
+#pragma once
+
+#include <string>
+
+std::string getStr();
+)";
+
+ out2 << R"(
+#include ")" << argv[1] << R"(.hpp"
+
+std::string getStr() {
+ return "Hello World";
+}
+)";
+
+ return 0;
+}
+)asd";
+
+ return 0;
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/macro_name.cpp b/test cases/cmake/8 custom command/subprojects/cmMod/macro_name.cpp
new file mode 100644
index 0000000..964062f
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/macro_name.cpp
@@ -0,0 +1,20 @@
+#include <iostream>
+#include <fstream>
+#include <chrono>
+#include <thread>
+
+using namespace std;
+
+#ifdef TEST_CMD_INCLUDE
+#if CPY_INC_WAS_INCLUDED != 1
+#error "cpyInc.hpp was not included"
+#endif
+#endif
+
+int main() {
+ this_thread::sleep_for(chrono::seconds(1));
+ ofstream out1("macro_name.txt");
+ out1 << "FOO";
+
+ return 0;
+}
diff --git a/test cases/cmake/8 custom command/subprojects/cmMod/mycpy/.gitkeep b/test cases/cmake/8 custom command/subprojects/cmMod/mycpy/.gitkeep
new file mode 100644
index 0000000..22c19ce
--- /dev/null
+++ b/test cases/cmake/8 custom command/subprojects/cmMod/mycpy/.gitkeep
@@ -0,0 +1 @@
+# Required to reproduce https://github.com/mesonbuild/meson/issues/10244
diff --git a/test cases/cmake/9 disabled subproject/meson.build b/test cases/cmake/9 disabled subproject/meson.build
new file mode 100644
index 0000000..c153fa3
--- /dev/null
+++ b/test cases/cmake/9 disabled subproject/meson.build
@@ -0,0 +1,6 @@
+project('cmakeSubTest', ['c', 'cpp'])
+
+cm = import('cmake')
+
+sub_pro = cm.subproject('nothinig', required: false)
+assert(not sub_pro.found(), 'subproject found() reports wrong value')
diff --git a/test cases/common/1 trivial/meson.build b/test cases/common/1 trivial/meson.build
new file mode 100644
index 0000000..2e424d5
--- /dev/null
+++ b/test cases/common/1 trivial/meson.build
@@ -0,0 +1,29 @@
+# Comment on the first line
+project('trivial test',
+ # Comment inside a function call + array for language list
+ ['c'], default_options: ['buildtype=debug'],
+ meson_version : '>=0.52.0')
+#this is a comment
+sources = 'trivial.c'
+
+cc = meson.get_compiler('c')
+if cc.get_id() == 'intel'
+ # Error out if the -std=xxx option is incorrect
+ add_project_arguments('-diag-error', '10159', language : 'c')
+elif cc.get_id() == 'intel-cl'
+ add_project_arguments('/Qdiag-error:10159', language : 'c')
+endif
+
+exe = executable('trivialprog', sources : sources)
+assert(exe.name() == 'trivialprog')
+test('runtest', exe) # This is a comment
+
+has_not_changed = false
+if is_disabler(exe)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'Executable has changed.')
+
+assert(not is_disabler(exe), 'Executable is a disabler.')
diff --git a/test cases/common/1 trivial/trivial.c b/test cases/common/1 trivial/trivial.c
new file mode 100644
index 0000000..96612d4
--- /dev/null
+++ b/test cases/common/1 trivial/trivial.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Trivial test is working.\n");
+ return 0;
+}
diff --git a/test cases/common/10 man install/bar.2 b/test cases/common/10 man install/bar.2
new file mode 100644
index 0000000..9d82d7e
--- /dev/null
+++ b/test cases/common/10 man install/bar.2
@@ -0,0 +1 @@
+this is a man page of bar.2, its contents are irrelevant \ No newline at end of file
diff --git a/test cases/common/10 man install/baz.1.in b/test cases/common/10 man install/baz.1.in
new file mode 100644
index 0000000..d0b79b4
--- /dev/null
+++ b/test cases/common/10 man install/baz.1.in
@@ -0,0 +1,6 @@
+This is a man page of baz.1 it was generated @TODAY@.
+
+You should not put generation timestamps in real world projects
+because they break reproducible builds. This manpage is written
+by professionals or under the supervision of professionals. Do
+not try this at home.
diff --git a/test cases/common/10 man install/foo.1 b/test cases/common/10 man install/foo.1
new file mode 100644
index 0000000..647c097
--- /dev/null
+++ b/test cases/common/10 man install/foo.1
@@ -0,0 +1 @@
+this is a man page of foo.1 its contents are irrelevant
diff --git a/test cases/common/10 man install/foo.fr.1 b/test cases/common/10 man install/foo.fr.1
new file mode 100644
index 0000000..647c097
--- /dev/null
+++ b/test cases/common/10 man install/foo.fr.1
@@ -0,0 +1 @@
+this is a man page of foo.1 its contents are irrelevant
diff --git a/test cases/common/10 man install/meson.build b/test cases/common/10 man install/meson.build
new file mode 100644
index 0000000..d0f3be8
--- /dev/null
+++ b/test cases/common/10 man install/meson.build
@@ -0,0 +1,14 @@
+project('man install')
+m1 = install_man('foo.1')
+m2 = install_man('bar.2')
+m3 = install_man('foo.fr.1', locale: 'fr')
+install_man('vanishing/vanishing.2')
+subdir('vanishing')
+
+cdata = configuration_data()
+cdata.set('TODAY', '$this_day')
+b1 = configure_file(input : 'baz.1.in',
+ output : 'baz.1',
+ configuration : cdata)
+
+install_man(b1)
diff --git a/test cases/common/10 man install/test.json b/test cases/common/10 man install/test.json
new file mode 100644
index 0000000..5ef673a
--- /dev/null
+++ b/test cases/common/10 man install/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ { "type": "file", "file": "usr/share/man/man1/foo.1" },
+ { "type": "file", "file": "usr/share/man/fr/man1/foo.1" },
+ { "type": "file", "file": "usr/share/man/man2/bar.2" },
+ { "type": "file", "file": "usr/share/man/man1/vanishing.1" },
+ { "type": "file", "file": "usr/share/man/man2/vanishing.2" },
+ { "type": "file", "file": "usr/share/man/man1/baz.1" }
+ ]
+}
diff --git a/test cases/common/10 man install/vanishing/meson.build b/test cases/common/10 man install/vanishing/meson.build
new file mode 100644
index 0000000..1015450
--- /dev/null
+++ b/test cases/common/10 man install/vanishing/meson.build
@@ -0,0 +1 @@
+install_man('vanishing.1')
diff --git a/test cases/common/10 man install/vanishing/vanishing.1 b/test cases/common/10 man install/vanishing/vanishing.1
new file mode 100644
index 0000000..532608e
--- /dev/null
+++ b/test cases/common/10 man install/vanishing/vanishing.1
@@ -0,0 +1 @@
+This is a man page of the vanishing subdirectory.
diff --git a/test cases/common/10 man install/vanishing/vanishing.2 b/test cases/common/10 man install/vanishing/vanishing.2
new file mode 100644
index 0000000..d12f76a
--- /dev/null
+++ b/test cases/common/10 man install/vanishing/vanishing.2
@@ -0,0 +1 @@
+This is a second man page of the vanishing subdirectory.
diff --git a/test cases/common/100 postconf with args/meson.build b/test cases/common/100 postconf with args/meson.build
new file mode 100644
index 0000000..a34502c
--- /dev/null
+++ b/test cases/common/100 postconf with args/meson.build
@@ -0,0 +1,10 @@
+project('postconf script', 'c')
+
+conf = configure_file(
+ configuration : configuration_data(),
+ output : 'out'
+)
+
+meson.add_postconf_script(find_program('postconf.py'), '5', '33', conf)
+
+test('post', executable('prog', 'prog.c'))
diff --git a/test cases/common/100 postconf with args/postconf.py b/test cases/common/100 postconf with args/postconf.py
new file mode 100644
index 0000000..cef7f79
--- /dev/null
+++ b/test cases/common/100 postconf with args/postconf.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+template = '''#pragma once
+
+#define THE_NUMBER {}
+#define THE_ARG1 {}
+#define THE_ARG2 {}
+'''
+
+input_file = os.path.join(os.environ['MESON_SOURCE_ROOT'], 'raw.dat')
+output_file = os.path.join(os.environ['MESON_BUILD_ROOT'], 'generated.h')
+
+with open(input_file) as f:
+ data = f.readline().strip()
+with open(output_file, 'w') as f:
+ f.write(template.format(data, sys.argv[1], sys.argv[2]))
diff --git a/test cases/common/100 postconf with args/prog.c b/test cases/common/100 postconf with args/prog.c
new file mode 100644
index 0000000..5db9d17
--- /dev/null
+++ b/test cases/common/100 postconf with args/prog.c
@@ -0,0 +1,5 @@
+#include"generated.h"
+
+int main(void) {
+ return THE_NUMBER != 9 || THE_ARG1 != 5 || THE_ARG2 != 33;
+}
diff --git a/test cases/common/100 postconf with args/raw.dat b/test cases/common/100 postconf with args/raw.dat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/test cases/common/100 postconf with args/raw.dat
@@ -0,0 +1 @@
+9
diff --git a/test cases/common/101 testframework options/meson.build b/test cases/common/101 testframework options/meson.build
new file mode 100644
index 0000000..4621b30
--- /dev/null
+++ b/test cases/common/101 testframework options/meson.build
@@ -0,0 +1,8 @@
+# normally run only from run_tests.py or run_project_tests.py
+# else do like
+# meson build '-Dtestoption=A string with spaces' -Dother_one=true -Dcombo_opt=one -Dprefix=/usr -Dlibdir=lib -Dbackend=ninja -Dwerror=True
+project('options')
+
+assert(get_option('testoption') == 'A string with spaces', 'Incorrect value for testoption option.')
+assert(get_option('other_one') == true, 'Incorrect value for other_one option.')
+assert(get_option('combo_opt') == 'one', 'Incorrect value for combo_opt option.')
diff --git a/test cases/common/101 testframework options/meson_options.txt b/test cases/common/101 testframework options/meson_options.txt
new file mode 100644
index 0000000..653dd75
--- /dev/null
+++ b/test cases/common/101 testframework options/meson_options.txt
@@ -0,0 +1,3 @@
+option('testoption', type : 'string', value : 'optval', description : 'An option to do something')
+option('other_one', type : 'boolean', value : false)
+option('combo_opt', type : 'combo', choices : ['one', 'two', 'combo'], value : 'combo')
diff --git a/test cases/common/101 testframework options/test.json b/test cases/common/101 testframework options/test.json
new file mode 100644
index 0000000..65bf3c0
--- /dev/null
+++ b/test cases/common/101 testframework options/test.json
@@ -0,0 +1,10 @@
+{
+ "matrix": {
+ "options": {
+ "testoption": [{ "val": "A string with spaces" }],
+ "other_one": [{ "val": "true" }],
+ "combo_opt": [{ "val": "one" }],
+ "werror": [{ "val": "true" }]
+ }
+ }
+}
diff --git a/test cases/common/102 extract same name/lib.c b/test cases/common/102 extract same name/lib.c
new file mode 100644
index 0000000..f3d0417
--- /dev/null
+++ b/test cases/common/102 extract same name/lib.c
@@ -0,0 +1,3 @@
+int func1(void) {
+ return 23;
+}
diff --git a/test cases/common/102 extract same name/main.c b/test cases/common/102 extract same name/main.c
new file mode 100644
index 0000000..e5a0c1e
--- /dev/null
+++ b/test cases/common/102 extract same name/main.c
@@ -0,0 +1,6 @@
+int func1(void);
+int func2(void);
+
+int main(void) {
+ return !(func1() == 23 && func2() == 42);
+}
diff --git a/test cases/common/102 extract same name/meson.build b/test cases/common/102 extract same name/meson.build
new file mode 100644
index 0000000..08daa5b
--- /dev/null
+++ b/test cases/common/102 extract same name/meson.build
@@ -0,0 +1,19 @@
+project('object extraction', 'c')
+
+if meson.backend() == 'xcode'
+ # Xcode gives object files unique names but only if they would clash. For example
+ # two files named lib.o instead get the following names:
+ #
+ # lib-4fbe522d8ba4cb1f1b89cc2df640a2336b92e1a5565f0a4c5a79b5b5e2969eb9.o
+ # lib-4fbe522d8ba4cb1f1b89cc2df640a2336deeff2bc2297affaadbe20f5cbfee56.o
+ #
+ # No-one has reverse engineered the naming scheme so we would access them.
+ # IF you feel up to the challenge, patches welcome.
+ error('MESON_SKIP_TEST, Xcode can not extract objs when they would have the same filename.')
+endif
+
+lib = library('somelib', ['lib.c', 'src/lib.c'])
+# Also tests that the object list is flattened properly
+obj = lib.extract_objects(['lib.c', ['src/lib.c']])
+exe = executable('main', 'main.c', objects: obj)
+test('extraction', exe)
diff --git a/test cases/common/102 extract same name/src/lib.c b/test cases/common/102 extract same name/src/lib.c
new file mode 100644
index 0000000..a7d7e77
--- /dev/null
+++ b/test cases/common/102 extract same name/src/lib.c
@@ -0,0 +1,3 @@
+int func2(void) {
+ return 42;
+}
diff --git a/test cases/common/103 has header symbol/meson.build b/test cases/common/103 has header symbol/meson.build
new file mode 100644
index 0000000..4590491
--- /dev/null
+++ b/test cases/common/103 has header symbol/meson.build
@@ -0,0 +1,40 @@
+project(
+ 'has header symbol',
+ 'c', 'cpp',
+ default_options : ['cpp_std=c++11'],
+)
+
+cc = meson.get_compiler('c')
+cpp = meson.get_compiler('cpp')
+
+foreach comp : [cc, cpp]
+ assert (comp.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
+ assert (comp.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
+ assert (comp.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
+ assert (comp.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
+ assert (not comp.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
+ assert (not comp.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
+ assert (not comp.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
+ assert (not comp.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
+endforeach
+
+# This is available on Glibc, Solaris & the BSD's, so just test for _GNU_SOURCE
+# on Linux
+if cc.has_function('ppoll') and host_machine.system() == 'linux'
+ assert (not cc.has_header_symbol('poll.h', 'ppoll'), 'ppoll should not be accessible without _GNU_SOURCE')
+ assert (cc.has_header_symbol('poll.h', 'ppoll', prefix : '#define _GNU_SOURCE'), 'ppoll should be accessible with _GNU_SOURCE')
+endif
+
+assert (cpp.has_header_symbol('iostream', 'std::iostream'), 'iostream not found in iostream.h')
+assert (cpp.has_header_symbol('vector', 'std::vector'), 'vector not found in vector.h')
+assert (not cpp.has_header_symbol('limits.h', 'std::iostream'), 'iostream should not be defined in limits.h')
+
+# Cross compilation and boost do not mix.
+if not meson.is_cross_build()
+ boost = dependency('boost', required : false)
+ if boost.found()
+ assert (cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion not found')
+ else
+ assert (not cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion found?!')
+ endif
+endif
diff --git a/test cases/common/104 has arg/meson.build b/test cases/common/104 has arg/meson.build
new file mode 100644
index 0000000..ba07311
--- /dev/null
+++ b/test cases/common/104 has arg/meson.build
@@ -0,0 +1,60 @@
+project('has arg', 'c', 'cpp')
+
+cc = meson.get_compiler('c')
+cpp = meson.get_compiler('cpp')
+
+if cc.get_id() == 'msvc'
+ is_arg = '/O2'
+ useless = '/DFOO'
+else
+ is_arg = '-O2'
+ useless = '-DFOO'
+endif
+
+isnt_arg = '-fiambroken'
+
+assert(cc.has_argument(is_arg), 'Arg that should have worked does not work.')
+assert(not cc.has_argument(isnt_arg), 'Arg that should be broken is not.')
+
+assert(cpp.has_argument(is_arg), 'Arg that should have worked does not work.')
+assert(not cpp.has_argument(isnt_arg), 'Arg that should be broken is not.')
+
+assert(cc.get_supported_arguments([is_arg, isnt_arg, useless]) == [is_arg, useless], 'Arg filtering returned different result.')
+assert(cpp.get_supported_arguments([is_arg, isnt_arg, useless]) == [is_arg, useless], 'Arg filtering returned different result.')
+
+# Have useless at the end to ensure that the search goes from front to back.
+l1 = cc.first_supported_argument([isnt_arg, is_arg, isnt_arg, useless])
+l2 = cc.first_supported_argument(isnt_arg, isnt_arg, isnt_arg)
+
+assert(l1.length() == 1, 'First supported returned wrong result.')
+assert(l1.get(0) == is_arg, 'First supported returned wrong argument.')
+assert(l2.length() == 0, 'First supported did not return empty array.')
+
+l1 = cpp.first_supported_argument([isnt_arg, is_arg, isnt_arg, useless])
+l2 = cpp.first_supported_argument(isnt_arg, isnt_arg, isnt_arg)
+
+assert(l1.length() == 1, 'First supported returned wrong result.')
+assert(l1.get(0) == is_arg, 'First supported returned wrong argument.')
+assert(l2.length() == 0, 'First supported did not return empty array.')
+
+if cc.get_id() == 'gcc'
+ pre_arg = '-Wformat'
+ # NOTE: We have special handling for -Wno-foo args because gcc silently
+ # ignores unknown -Wno-foo args unless you pass -Werror, so for this test, we
+ # pass it as two separate arguments.
+ anti_pre_arg = ['-W', 'no-format']
+ arg = '-Werror=format-security'
+ assert(not cc.has_multi_arguments([anti_pre_arg, arg]), 'Arg that should be broken is not.')
+ assert(cc.has_multi_arguments(pre_arg), 'Arg that should have worked does not work.')
+ assert(cc.has_multi_arguments([pre_arg, arg]), 'Arg that should have worked does not work.')
+ # Test that gcc correctly errors out on unknown -Wno flags
+ assert(not cc.has_argument('-Wno-lol-meson-test-flags'), 'should error out on unknown -Wno args')
+ assert(not cc.has_multi_arguments(['-Wno-pragmas', '-Wno-lol-meson-test-flags']), 'should error out even if some -Wno args are valid')
+endif
+
+if cc.get_id() == 'clang' and cc.version().version_compare('<=4.0.0')
+ # 4.0.0 does not support -fpeel-loops. Newer versions may.
+ # Please adjust above version number as new versions of clang are released.
+ notyet_arg = '-fpeel-loops'
+ assert(not cc.has_argument(notyet_arg), 'Arg that should be broken (unless clang added support recently) is not.')
+endif
diff --git a/test cases/common/105 generatorcustom/catter.py b/test cases/common/105 generatorcustom/catter.py
new file mode 100755
index 0000000..c272672
--- /dev/null
+++ b/test cases/common/105 generatorcustom/catter.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import sys
+
+output = sys.argv[-1]
+inputs = sys.argv[1:-1]
+
+with open(output, 'w') as ofile:
+ ofile.write('#pragma once\n')
+ for i in inputs:
+ with open(i) as ifile:
+ content = ifile.read()
+ ofile.write(content)
+ ofile.write('\n')
diff --git a/test cases/common/105 generatorcustom/gen-resx.py b/test cases/common/105 generatorcustom/gen-resx.py
new file mode 100755
index 0000000..242a962
--- /dev/null
+++ b/test cases/common/105 generatorcustom/gen-resx.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import sys
+
+ofile = sys.argv[1]
+num = sys.argv[2]
+
+with open(ofile, 'w') as f:
+ f.write(f'res{num}\n')
diff --git a/test cases/common/105 generatorcustom/gen.c b/test cases/common/105 generatorcustom/gen.c
new file mode 100644
index 0000000..59518c0
--- /dev/null
+++ b/test cases/common/105 generatorcustom/gen.c
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/* Copyright © 2023 Intel Corporation */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, const char ** argv) {
+ if (argc != 3) {
+ fprintf(stderr, "%s %i %s\n", "Got incorrect number of arguments, got ", argc - 1, ", but expected 2");
+ exit(1);
+ }
+
+ FILE * input, * output;
+
+ if ((input = fopen(argv[1], "rb")) == NULL) {
+ exit(1);
+ }
+ if ((output = fopen(argv[2], "wb")) == NULL) {
+ exit(1);
+ }
+
+ fprintf(output, "#pragma once\n");
+ fprintf(output, "#define ");
+
+ char c;
+ while((c = fgetc(input)) != EOF) {
+ fputc(c, output);
+ }
+ fputc('\n', output);
+
+ fclose(input);
+ fclose(output);
+
+ return 0;
+}
diff --git a/test cases/common/105 generatorcustom/gen.py b/test cases/common/105 generatorcustom/gen.py
new file mode 100755
index 0000000..1464008
--- /dev/null
+++ b/test cases/common/105 generatorcustom/gen.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import sys
+
+ifile = sys.argv[1]
+ofile = sys.argv[2]
+
+with open(ifile) as f:
+ resname = f.readline().strip()
+
+templ = 'const char %s[] = "%s";\n'
+with open(ofile, 'w') as f:
+ f.write(templ % (resname, resname))
diff --git a/test cases/common/105 generatorcustom/host.c b/test cases/common/105 generatorcustom/host.c
new file mode 100644
index 0000000..1ddfa88
--- /dev/null
+++ b/test cases/common/105 generatorcustom/host.c
@@ -0,0 +1,9 @@
+#include "res1-cpp.h"
+
+int main(void) {
+ #ifdef res1
+ return 0;
+ #else
+ return 1;
+ #endif
+}
diff --git a/test cases/common/105 generatorcustom/main.c b/test cases/common/105 generatorcustom/main.c
new file mode 100644
index 0000000..153dc12
--- /dev/null
+++ b/test cases/common/105 generatorcustom/main.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+#include "alltogether.h"
+
+int main(void) {
+ printf("%s - %s - %s - %s\n", res1, res2, res3, res4);
+ return 0;
+}
diff --git a/test cases/common/105 generatorcustom/meson.build b/test cases/common/105 generatorcustom/meson.build
new file mode 100644
index 0000000..dab55de
--- /dev/null
+++ b/test cases/common/105 generatorcustom/meson.build
@@ -0,0 +1,44 @@
+project('generatorcustom', 'c')
+
+creator = find_program('gen.py')
+catter = find_program('catter.py')
+gen_resx = find_program('gen-resx.py')
+
+gen = generator(creator,
+ output: '@BASENAME@.h',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+res3 = custom_target('gen-res3',
+ output : 'res3.txt',
+ command : [gen_resx, '@OUTPUT@', '3'])
+
+res4 = custom_target('gen-res4',
+ output : 'res4.txt',
+ command : [gen_resx, '@OUTPUT@', '4'])
+
+hs = gen.process('res1.txt', 'res2.txt', res3, res4[0])
+
+allinone = custom_target('alltogether',
+ input : hs,
+ output : 'alltogether.h',
+ command : [catter, '@INPUT@', '@OUTPUT@'])
+
+proggie = executable('proggie', 'main.c', allinone)
+
+test('proggie', proggie)
+
+# specifically testing that cross binaries are run with an exe_wrapper
+if meson.can_run_host_binaries()
+ gen_tool = executable('generator', 'gen.c', native : false)
+
+ c_gen = generator(
+ gen_tool,
+ output : '@BASENAME@-cpp.h',
+ arguments : ['@INPUT@', '@OUTPUT@']
+ )
+
+ hs2 = c_gen.process('res1.txt')
+
+ host_exe = executable('host_test', 'host.c', hs2, native : false)
+ test('compiled generator', host_exe)
+endif
diff --git a/test cases/common/105 generatorcustom/res1.txt b/test cases/common/105 generatorcustom/res1.txt
new file mode 100644
index 0000000..6487c56
--- /dev/null
+++ b/test cases/common/105 generatorcustom/res1.txt
@@ -0,0 +1 @@
+res1
diff --git a/test cases/common/105 generatorcustom/res2.txt b/test cases/common/105 generatorcustom/res2.txt
new file mode 100644
index 0000000..0a8879d
--- /dev/null
+++ b/test cases/common/105 generatorcustom/res2.txt
@@ -0,0 +1 @@
+res2
diff --git a/test cases/common/106 multiple dir configure file/meson.build b/test cases/common/106 multiple dir configure file/meson.build
new file mode 100644
index 0000000..18408fb
--- /dev/null
+++ b/test cases/common/106 multiple dir configure file/meson.build
@@ -0,0 +1,11 @@
+project('multiple dir configure file')
+
+subdir('subdir')
+
+configure_file(input : 'subdir/someinput.in',
+ output : 'outputhere',
+ copy: true)
+
+configure_file(input : cfile1,
+ output : '@BASENAME@',
+ copy: true)
diff --git a/test cases/common/106 multiple dir configure file/subdir/foo.txt b/test cases/common/106 multiple dir configure file/subdir/foo.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/106 multiple dir configure file/subdir/foo.txt
diff --git a/test cases/common/106 multiple dir configure file/subdir/meson.build b/test cases/common/106 multiple dir configure file/subdir/meson.build
new file mode 100644
index 0000000..503df96
--- /dev/null
+++ b/test cases/common/106 multiple dir configure file/subdir/meson.build
@@ -0,0 +1,11 @@
+configure_file(input : 'someinput.in',
+ output : 'outputsubdir',
+ install : false,
+ copy: true)
+
+py3 = import('python3').find_python()
+
+cfile1 = configure_file(input : 'foo.txt',
+ output : 'foo.h.in',
+ capture : true,
+ command : [py3, '-c', 'print("#mesondefine FOO_BAR")'])
diff --git a/test cases/common/106 multiple dir configure file/subdir/someinput.in b/test cases/common/106 multiple dir configure file/subdir/someinput.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/106 multiple dir configure file/subdir/someinput.in
diff --git a/test cases/common/107 spaces backslash/asm output/meson.build b/test cases/common/107 spaces backslash/asm output/meson.build
new file mode 100644
index 0000000..43f61f0
--- /dev/null
+++ b/test cases/common/107 spaces backslash/asm output/meson.build
@@ -0,0 +1 @@
+configure_file(output : 'blank.txt', configuration : configuration_data())
diff --git a/test cases/common/107 spaces backslash/comparer-end-notstring.c b/test cases/common/107 spaces backslash/comparer-end-notstring.c
new file mode 100644
index 0000000..8b8190f
--- /dev/null
+++ b/test cases/common/107 spaces backslash/comparer-end-notstring.c
@@ -0,0 +1,20 @@
+#include "comparer.h"
+
+#ifndef COMPARER_INCLUDED
+#error "comparer.h not included"
+#endif
+
+/* This converts foo\\\\bar\\\\ to "foo\\bar\\" (string literal) */
+#define Q(x) #x
+#define QUOTE(x) Q(x)
+
+#define COMPARE_WITH "foo\\bar\\" /* This is the literal `foo\bar\` */
+
+int main(void) {
+ if(strcmp(QUOTE(DEF_WITH_BACKSLASH), COMPARE_WITH)) {
+ printf("Arg string is quoted incorrectly: %s instead of %s\n",
+ QUOTE(DEF_WITH_BACKSLASH), COMPARE_WITH);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/107 spaces backslash/comparer-end.c b/test cases/common/107 spaces backslash/comparer-end.c
new file mode 100644
index 0000000..8cff1b1
--- /dev/null
+++ b/test cases/common/107 spaces backslash/comparer-end.c
@@ -0,0 +1,16 @@
+#include "comparer.h"
+
+#ifndef COMPARER_INCLUDED
+#error "comparer.h not included"
+#endif
+
+#define COMPARE_WITH "foo\\bar\\" /* This is `foo\bar\` */
+
+int main(void) {
+ if (strcmp (DEF_WITH_BACKSLASH, COMPARE_WITH)) {
+ printf ("Arg string is quoted incorrectly: %s vs %s\n",
+ DEF_WITH_BACKSLASH, COMPARE_WITH);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/107 spaces backslash/comparer.c b/test cases/common/107 spaces backslash/comparer.c
new file mode 100644
index 0000000..7e3033e
--- /dev/null
+++ b/test cases/common/107 spaces backslash/comparer.c
@@ -0,0 +1,16 @@
+#include "comparer.h"
+
+#ifndef COMPARER_INCLUDED
+#error "comparer.h not included"
+#endif
+
+#define COMPARE_WITH "foo\\bar" /* This is the literal `foo\bar` */
+
+int main(void) {
+ if (strcmp (DEF_WITH_BACKSLASH, COMPARE_WITH)) {
+ printf ("Arg string is quoted incorrectly: %s instead of %s\n",
+ DEF_WITH_BACKSLASH, COMPARE_WITH);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/107 spaces backslash/include/comparer.h b/test cases/common/107 spaces backslash/include/comparer.h
new file mode 100644
index 0000000..624d96c
--- /dev/null
+++ b/test cases/common/107 spaces backslash/include/comparer.h
@@ -0,0 +1,4 @@
+#include <string.h>
+#include <stdio.h>
+
+#define COMPARER_INCLUDED
diff --git a/test cases/common/107 spaces backslash/meson.build b/test cases/common/107 spaces backslash/meson.build
new file mode 100644
index 0000000..d590494
--- /dev/null
+++ b/test cases/common/107 spaces backslash/meson.build
@@ -0,0 +1,28 @@
+project('comparer', 'c')
+
+# Added manually as a c_arg to test handling of include paths with backslashes
+# and spaces. This is especially useful on Windows in vcxproj files since it
+# stores include directories in a separate element that has its own
+# context-specific escaping/quoting.
+include_dir = meson.current_source_dir() + '/include'
+default_c_args = ['-I' + include_dir]
+
+if meson.get_compiler('c').get_argument_syntax() == 'msvc'
+ default_c_args += ['/Faasm output\\']
+ # Hack to create the 'asm output' directory in the builddir
+ subdir('asm output')
+endif
+
+# Path can contain \. Here we're sending `"foo\bar"`.
+test('backslash quoting',
+ executable('comparer', 'comparer.c',
+ c_args : default_c_args + ['-DDEF_WITH_BACKSLASH="foo\\bar"']))
+# Path can end in \ without any special quoting. Here we send `"foo\bar\"`.
+test('backslash end quoting',
+ executable('comparer-end', 'comparer-end.c',
+ c_args : default_c_args + ['-DDEF_WITH_BACKSLASH="foo\\bar\\"']))
+# Path can (really) end in \ if we're not passing a string literal without any
+# special quoting. Here we're sending `foo\bar\`.
+test('backslash end quoting when not a string literal',
+ executable('comparer-end-notstring', 'comparer-end-notstring.c',
+ c_args : default_c_args + ['-DDEF_WITH_BACKSLASH=foo\\bar\\']))
diff --git a/test cases/common/108 ternary/meson.build b/test cases/common/108 ternary/meson.build
new file mode 100644
index 0000000..0073a1e
--- /dev/null
+++ b/test cases/common/108 ternary/meson.build
@@ -0,0 +1,12 @@
+project('ternary operator')
+
+x = true
+one = true ? 1 : error('False branch should not be evaluated')
+two = false ? error('True branch should not be evaluated.') : 2
+three = '@0@'.format(x ? 'yes' : 'no')
+four = [x ? '0' : '1']
+
+assert(one == 1, 'Return value from ternary true is wrong.')
+assert(two == 2, 'Return value from ternary false is wrong.')
+assert(three == 'yes', 'Return value for ternary inside method call is wrong.')
+assert(four == ['0'], 'Return value for ternary inside of list is wrong.')
diff --git a/test cases/common/109 custom target capture/data_source.txt b/test cases/common/109 custom target capture/data_source.txt
new file mode 100644
index 0000000..0c23cc0
--- /dev/null
+++ b/test cases/common/109 custom target capture/data_source.txt
@@ -0,0 +1 @@
+This is a text only input file.
diff --git a/test cases/common/109 custom target capture/meson.build b/test cases/common/109 custom target capture/meson.build
new file mode 100644
index 0000000..b762201
--- /dev/null
+++ b/test cases/common/109 custom target capture/meson.build
@@ -0,0 +1,24 @@
+project('custom target')
+
+python3 = import('python3').find_python()
+
+# Note that this will not add a dependency to the compiler executable.
+# Code will not be rebuilt if it changes.
+comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
+
+mytarget = custom_target('bindat',
+ output : 'data.dat',
+ input : 'data_source.txt',
+ capture : true,
+ command : [python3, comp, '@INPUT@'],
+ install : true,
+ install_dir : 'subdir'
+)
+
+ct_output_exists = '''import os, sys
+if not os.path.exists(sys.argv[1]):
+ print("could not find {!r} in {!r}".format(sys.argv[1], os.getcwd()))
+ sys.exit(1)
+'''
+
+test('capture-wrote', python3, args : ['-c', ct_output_exists, mytarget])
diff --git a/test cases/common/109 custom target capture/my_compiler.py b/test cases/common/109 custom target capture/my_compiler.py
new file mode 100755
index 0000000..b60722a
--- /dev/null
+++ b/test cases/common/109 custom target capture/my_compiler.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import sys
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print(sys.argv[0], 'input_file')
+ sys.exit(1)
+ with open(sys.argv[1]) as f:
+ ifile = f.read()
+ if ifile != 'This is a text only input file.\n':
+ print('Malformed input')
+ sys.exit(1)
+ print('This is a binary output file.')
diff --git a/test cases/common/109 custom target capture/test.json b/test cases/common/109 custom target capture/test.json
new file mode 100644
index 0000000..ba66b02
--- /dev/null
+++ b/test cases/common/109 custom target capture/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/subdir/data.dat"}
+ ]
+}
diff --git a/test cases/common/11 subdir/meson.build b/test cases/common/11 subdir/meson.build
new file mode 100644
index 0000000..bda1f90
--- /dev/null
+++ b/test cases/common/11 subdir/meson.build
@@ -0,0 +1,2 @@
+project('subdir test', 'c')
+subdir('subdir')
diff --git a/test cases/common/11 subdir/subdir/meson.build b/test cases/common/11 subdir/subdir/meson.build
new file mode 100644
index 0000000..d84ec13
--- /dev/null
+++ b/test cases/common/11 subdir/subdir/meson.build
@@ -0,0 +1,2 @@
+prog = executable('prog', 'prog.c')
+test('subdirprog', prog)
diff --git a/test cases/common/11 subdir/subdir/prog.c b/test cases/common/11 subdir/subdir/prog.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/11 subdir/subdir/prog.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/110 allgenerate/converter.py b/test cases/common/110 allgenerate/converter.py
new file mode 100755
index 0000000..f8e2ca0
--- /dev/null
+++ b/test cases/common/110 allgenerate/converter.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import sys
+
+ifile = sys.argv[1]
+ofile = sys.argv[2]
+
+open(ofile, 'w').write(open(ifile).read())
diff --git a/test cases/common/110 allgenerate/foobar.cpp.in b/test cases/common/110 allgenerate/foobar.cpp.in
new file mode 100644
index 0000000..32e1261
--- /dev/null
+++ b/test cases/common/110 allgenerate/foobar.cpp.in
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I am a program.\n");
+ return 0;
+}
diff --git a/test cases/common/110 allgenerate/meson.build b/test cases/common/110 allgenerate/meson.build
new file mode 100644
index 0000000..049e849
--- /dev/null
+++ b/test cases/common/110 allgenerate/meson.build
@@ -0,0 +1,20 @@
+# Must have two languages here to exercise linker language
+# selection bug
+project('all sources generated', 'c', 'cpp')
+
+comp = find_program('converter.py')
+
+g = generator(comp,
+ output : '@BASENAME@',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+c = g.process('foobar.cpp.in')
+
+prog = executable('genexe', c)
+
+c2 = custom_target('c2gen',
+ output : '@BASENAME@',
+ input : 'foobar.cpp.in',
+ command : [comp, '@INPUT@', '@OUTPUT@'])
+
+prog2 = executable('genexe2', c2)
diff --git a/test cases/common/111 pathjoin/meson.build b/test cases/common/111 pathjoin/meson.build
new file mode 100644
index 0000000..64aa338
--- /dev/null
+++ b/test cases/common/111 pathjoin/meson.build
@@ -0,0 +1,27 @@
+project('pathjoin')
+
+# Test string-args form since that is the canonical way
+assert(join_paths('foo') == 'foo', 'Single argument join is broken')
+assert(join_paths('foo', 'bar') == 'foo/bar', 'Path joining is broken')
+assert(join_paths('foo', 'bar', 'baz') == 'foo/bar/baz', 'Path joining is broken')
+assert(join_paths('/foo', 'bar') == '/foo/bar', 'Path joining is broken')
+assert(join_paths('foo', '/bar') == '/bar', 'Absolute path joining is broken')
+assert(join_paths('/foo', '/bar') == '/bar', 'Absolute path joining is broken')
+assert(join_paths('/foo', '') == '/foo/', 'Trailing / on path')
+
+# Test array form since people are using that too
+assert(join_paths(['foo']) == 'foo', 'Single argument join is broken')
+assert(join_paths(['foo', 'bar']) == 'foo/bar', 'Path joining is broken')
+assert(join_paths(['foo', 'bar', 'baz']) == 'foo/bar/baz', 'Path joining is broken')
+assert(join_paths(['/foo', 'bar']) == '/foo/bar', 'Path joining is broken')
+assert(join_paths(['foo', '/bar']) == '/bar', 'Absolute path joining is broken')
+assert(join_paths(['/foo', '/bar']) == '/bar', 'Absolute path joining is broken')
+assert(join_paths(['/foo', '']) == '/foo/', 'Trailing / on path')
+
+# Division operator should do the same as join_paths
+assert('foo' / 'bar' == 'foo/bar', 'Path division is broken')
+assert('foo' /'bar' /'baz' == 'foo/bar/baz', 'Path division is broken')
+assert('/foo' / 'bar' == '/foo/bar', 'Path division is broken')
+assert('foo' / '/bar' == '/bar', 'Absolute path division is broken')
+assert('/foo' / '/bar' == '/bar', 'Absolute path division is broken')
+assert('/foo' / '' == '/foo/', 'Trailing / on path')
diff --git a/test cases/common/112 subdir subproject/meson.build b/test cases/common/112 subdir subproject/meson.build
new file mode 100644
index 0000000..54ecfe0
--- /dev/null
+++ b/test cases/common/112 subdir subproject/meson.build
@@ -0,0 +1,2 @@
+project('proj', 'c')
+subdir('prog')
diff --git a/test cases/common/112 subdir subproject/prog/meson.build b/test cases/common/112 subdir subproject/prog/meson.build
new file mode 100644
index 0000000..360b5f5
--- /dev/null
+++ b/test cases/common/112 subdir subproject/prog/meson.build
@@ -0,0 +1,5 @@
+subproject('sub')
+libSub = dependency('sub', fallback: ['sub', 'libSub'])
+
+exe = executable('prog', 'prog.c', dependencies: libSub)
+test('subdir subproject', exe)
diff --git a/test cases/common/112 subdir subproject/prog/prog.c b/test cases/common/112 subdir subproject/prog/prog.c
new file mode 100644
index 0000000..9035ff1
--- /dev/null
+++ b/test cases/common/112 subdir subproject/prog/prog.c
@@ -0,0 +1,5 @@
+#include <sub.h>
+
+int main(void) {
+ return sub();
+}
diff --git a/test cases/common/112 subdir subproject/subprojects/sub/meson.build b/test cases/common/112 subdir subproject/subprojects/sub/meson.build
new file mode 100644
index 0000000..94e9eec
--- /dev/null
+++ b/test cases/common/112 subdir subproject/subprojects/sub/meson.build
@@ -0,0 +1,3 @@
+project('sub', 'c')
+lib = static_library('sub', 'sub.c')
+libSub = declare_dependency(include_directories: include_directories('.'), link_with: lib)
diff --git a/test cases/common/112 subdir subproject/subprojects/sub/sub.c b/test cases/common/112 subdir subproject/subprojects/sub/sub.c
new file mode 100644
index 0000000..e748ac7
--- /dev/null
+++ b/test cases/common/112 subdir subproject/subprojects/sub/sub.c
@@ -0,0 +1,5 @@
+#include "sub.h"
+
+int sub(void) {
+ return 0;
+}
diff --git a/test cases/common/112 subdir subproject/subprojects/sub/sub.h b/test cases/common/112 subdir subproject/subprojects/sub/sub.h
new file mode 100644
index 0000000..2b59a3a
--- /dev/null
+++ b/test cases/common/112 subdir subproject/subprojects/sub/sub.h
@@ -0,0 +1,6 @@
+#ifndef SUB_H
+#define SUB_H
+
+int sub(void);
+
+#endif
diff --git a/test cases/common/113 interpreter copy mutable var on assignment/meson.build b/test cases/common/113 interpreter copy mutable var on assignment/meson.build
new file mode 100644
index 0000000..d414bfc
--- /dev/null
+++ b/test cases/common/113 interpreter copy mutable var on assignment/meson.build
@@ -0,0 +1,19 @@
+project('foo')
+
+a = configuration_data()
+a.set('HELLO', 1)
+
+b = a
+
+assert(a.has('HELLO'), 'Original config data should be set on a')
+assert(b.has('HELLO'), 'Original config data should be set on copy')
+
+configure_file(output : 'b.h', configuration : b)
+
+# This should still work, as we didn't use the original above but a copy!
+a.set('WORLD', 1)
+
+assert(a.has('WORLD'), 'New config data should have been set')
+assert(not b.has('WORLD'), 'New config data set should not affect var copied earlier')
+
+configure_file(output : 'a.h', configuration : a)
diff --git a/test cases/common/114 skip/meson.build b/test cases/common/114 skip/meson.build
new file mode 100644
index 0000000..ead955f
--- /dev/null
+++ b/test cases/common/114 skip/meson.build
@@ -0,0 +1,3 @@
+project('skip')
+
+error('MESON_SKIP_TEST this test is always skipped.')
diff --git a/test cases/common/115 subproject project arguments/exe.c b/test cases/common/115 subproject project arguments/exe.c
new file mode 100644
index 0000000..e8f2271
--- /dev/null
+++ b/test cases/common/115 subproject project arguments/exe.c
@@ -0,0 +1,27 @@
+#ifndef PROJECT_OPTION
+#error
+#endif
+
+#ifndef PROJECT_OPTION_1
+#error
+#endif
+
+#ifndef GLOBAL_ARGUMENT
+#error
+#endif
+
+#ifdef SUBPROJECT_OPTION
+#error
+#endif
+
+#ifdef OPTION_CPP
+#error
+#endif
+
+#ifndef PROJECT_OPTION_C_CPP
+#error
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/115 subproject project arguments/exe.cpp b/test cases/common/115 subproject project arguments/exe.cpp
new file mode 100644
index 0000000..a8f5dff
--- /dev/null
+++ b/test cases/common/115 subproject project arguments/exe.cpp
@@ -0,0 +1,27 @@
+#ifdef PROJECT_OPTION
+#error
+#endif
+
+#ifdef PROJECT_OPTION_1
+#error
+#endif
+
+#ifdef GLOBAL_ARGUMENT
+#error
+#endif
+
+#ifdef SUBPROJECT_OPTION
+#error
+#endif
+
+#ifndef PROJECT_OPTION_CPP
+#error
+#endif
+
+#ifndef PROJECT_OPTION_C_CPP
+#error
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/115 subproject project arguments/meson.build b/test cases/common/115 subproject project arguments/meson.build
new file mode 100644
index 0000000..90d4c05
--- /dev/null
+++ b/test cases/common/115 subproject project arguments/meson.build
@@ -0,0 +1,17 @@
+project('project options tester', 'c', 'cpp',
+ version : '2.3.4',
+ license : 'mylicense')
+
+add_global_arguments('-DGLOBAL_ARGUMENT', language: 'c')
+add_project_arguments('-DPROJECT_OPTION', language: 'c')
+add_project_arguments('-DPROJECT_OPTION_CPP', language: 'cpp')
+add_project_arguments('-DPROJECT_OPTION_C_CPP', language: ['c', 'cpp'])
+
+sub = subproject('subexe', version : '1.0.0')
+
+add_project_arguments('-DPROJECT_OPTION_1', language: 'c')
+
+e = executable('exe', 'exe.c')
+e = executable('execpp', 'exe.cpp')
+test('exetest', e)
+test('execpptest', e)
diff --git a/test cases/common/115 subproject project arguments/subprojects/subexe/meson.build b/test cases/common/115 subproject project arguments/subprojects/subexe/meson.build
new file mode 100644
index 0000000..ef141dc
--- /dev/null
+++ b/test cases/common/115 subproject project arguments/subprojects/subexe/meson.build
@@ -0,0 +1,13 @@
+project('subproject', 'c',
+ version : '1.0.0',
+ license : ['sublicense1', 'sublicense2'])
+
+if not meson.is_subproject()
+ error('Claimed to be master project even though we are a subproject.')
+endif
+
+assert(meson.project_name() == 'subproject', 'Incorrect subproject name')
+
+add_project_arguments('-DSUBPROJECT_OPTION', language: 'c')
+e = executable('subexe', 'subexe.c')
+test('subexetest', e)
diff --git a/test cases/common/115 subproject project arguments/subprojects/subexe/subexe.c b/test cases/common/115 subproject project arguments/subprojects/subexe/subexe.c
new file mode 100644
index 0000000..bd5316d
--- /dev/null
+++ b/test cases/common/115 subproject project arguments/subprojects/subexe/subexe.c
@@ -0,0 +1,27 @@
+#ifdef PROJECT_OPTION
+#error
+#endif
+
+#ifdef PROJECT_OPTION_1
+#error
+#endif
+
+#ifdef PROJECT_OPTION_C_CPP
+#error
+#endif
+
+#ifndef GLOBAL_ARGUMENT
+#error
+#endif
+
+#ifndef SUBPROJECT_OPTION
+#error
+#endif
+
+#ifdef OPTION_CPP
+#error
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/116 test skip/meson.build b/test cases/common/116 test skip/meson.build
new file mode 100644
index 0000000..568527f
--- /dev/null
+++ b/test cases/common/116 test skip/meson.build
@@ -0,0 +1,4 @@
+project('test skip', 'c')
+
+exe_test_skip = executable('test_skip', 'test_skip.c')
+test('test_skip', exe_test_skip)
diff --git a/test cases/common/116 test skip/test_skip.c b/test cases/common/116 test skip/test_skip.c
new file mode 100644
index 0000000..59c134b
--- /dev/null
+++ b/test cases/common/116 test skip/test_skip.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 77;
+}
diff --git a/test cases/common/117 shared module/meson.build b/test cases/common/117 shared module/meson.build
new file mode 100644
index 0000000..936c839
--- /dev/null
+++ b/test cases/common/117 shared module/meson.build
@@ -0,0 +1,40 @@
+project('shared module', 'c')
+
+c = meson.get_compiler('c')
+
+# Windows UWP doesn't support the ToolHelp API we use in this test to emulate
+# runtime symbol resolution.
+if host_machine.system() == 'windows'
+ if not c.compiles('''
+#include <windows.h>
+#include <tlhelp32.h>
+
+HANDLE func(void)
+{
+ return CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
+}
+''')
+ error('MESON_SKIP_TEST Windows UWP does not support this test.')
+ endif
+endif
+
+dl = c.find_library('dl', required : false)
+l = shared_library('runtime', 'runtime.c')
+# Do NOT link the module with the runtime library. This
+# is a common approach for plugins that are only used
+# with dlopen. Any symbols are resolved dynamically
+# at runtime. This requires extra help on Windows, so
+# should be avoided unless really necessary.
+m = shared_module('mymodule', 'module.c')
+e = executable('prog', 'prog.c',
+ link_with : l, export_dynamic : true, dependencies : dl)
+test('import test', e, args : m)
+
+# Same as above, but module created with build_target()
+m2 = build_target('mymodule2', 'module.c', target_type: 'shared_module')
+test('import test 2', e, args : m2)
+
+# Shared module that does not export any symbols
+shared_module('nosyms', 'nosyms.c',
+ install : true,
+ install_dir : join_paths(get_option('libdir'), 'modules'))
diff --git a/test cases/common/117 shared module/module.c b/test cases/common/117 shared module/module.c
new file mode 100644
index 0000000..5dd26d7
--- /dev/null
+++ b/test cases/common/117 shared module/module.c
@@ -0,0 +1,96 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+
+#include <stdio.h>
+
+typedef int (*fptr) (void);
+
+#ifdef __CYGWIN__
+
+#include <dlfcn.h>
+
+fptr find_any_f (const char *name) {
+ return (fptr) dlsym(RTLD_DEFAULT, name);
+}
+#else /* _WIN32 */
+
+#include <windows.h>
+#include <tlhelp32.h>
+
+static wchar_t*
+win32_get_last_error (void)
+{
+ wchar_t *msg = NULL;
+
+ FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError (), 0,
+ (LPWSTR) &msg, 0, NULL);
+ return msg;
+}
+
+/* Unlike Linux and OS X, when a library is loaded, all the symbols aren't
+ * loaded into a single namespace. You must fetch the symbol by iterating over
+ * all loaded modules. Code for finding the function from any of the loaded
+ * modules is taken from gmodule.c in glib */
+fptr find_any_f (const char *name) {
+ fptr f;
+ HANDLE snapshot;
+ MODULEENTRY32 me32;
+
+ snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
+ if (snapshot == (HANDLE) -1) {
+ wchar_t *msg = win32_get_last_error();
+ printf("Could not get snapshot: %S\n", msg);
+ return 0;
+ }
+
+ me32.dwSize = sizeof (me32);
+
+ f = NULL;
+ if (Module32First (snapshot, &me32)) {
+ do {
+ if ((f = (fptr) GetProcAddress (me32.hModule, name)) != NULL)
+ break;
+ } while (Module32Next (snapshot, &me32));
+ }
+
+ CloseHandle (snapshot);
+ return f;
+}
+#endif
+
+int DLL_PUBLIC func(void) {
+ fptr f;
+
+ f = find_any_f ("func_from_language_runtime");
+ if (f != NULL)
+ return f();
+ printf ("Could not find function\n");
+ return 1;
+}
+
+#else
+/*
+ * Shared modules often have references to symbols that are not defined
+ * at link time, but which will be provided from deps of the executable that
+ * dlopens it. We need to make sure that this works, i.e. that we do
+ * not pass -Wl,--no-undefined when linking modules.
+ */
+int func_from_language_runtime(void);
+
+int DLL_PUBLIC func(void) {
+ return func_from_language_runtime();
+}
+#endif
diff --git a/test cases/common/117 shared module/nosyms.c b/test cases/common/117 shared module/nosyms.c
new file mode 100644
index 0000000..3432b1c
--- /dev/null
+++ b/test cases/common/117 shared module/nosyms.c
@@ -0,0 +1,4 @@
+static int
+func_not_exported (void) {
+ return 99;
+}
diff --git a/test cases/common/117 shared module/prog.c b/test cases/common/117 shared module/prog.c
new file mode 100644
index 0000000..4741185
--- /dev/null
+++ b/test cases/common/117 shared module/prog.c
@@ -0,0 +1,103 @@
+
+#include <stdio.h>
+
+int func_from_language_runtime(void);
+typedef int (*fptr) (void);
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+static wchar_t*
+win32_get_last_error (void)
+{
+ wchar_t *msg = NULL;
+
+ FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError (), 0,
+ (LPWSTR) &msg, 0, NULL);
+ return msg;
+}
+
+int main(int argc, char **argv)
+{
+ HINSTANCE handle;
+ fptr importedfunc;
+ int expected, actual;
+ int ret = 1;
+ if(argc==0) {};
+
+ handle = LoadLibraryA (argv[1]);
+ if (!handle) {
+ wchar_t *msg = win32_get_last_error ();
+ printf ("Could not open %s: %S\n", argv[1], msg);
+ goto nohandle;
+ }
+
+ importedfunc = (fptr) GetProcAddress (handle, "func");
+ if (importedfunc == NULL) {
+ wchar_t *msg = win32_get_last_error ();
+ printf ("Could not find 'func': %S\n", msg);
+ goto out;
+ }
+
+ actual = importedfunc ();
+ expected = func_from_language_runtime ();
+ if (actual != expected) {
+ printf ("Got %i instead of %i\n", actual, expected);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ FreeLibrary (handle);
+nohandle:
+ return ret;
+}
+
+#else
+
+#include<dlfcn.h>
+#include<assert.h>
+
+int main(int argc, char **argv) {
+ void *dl;
+ fptr importedfunc;
+ int expected, actual;
+ char *error;
+ int ret = 1;
+ if(argc==0) {};
+
+ dlerror();
+ dl = dlopen(argv[1], RTLD_LAZY);
+ error = dlerror();
+ if(error) {
+ printf("Could not open %s: %s\n", argv[1], error);
+ goto nodl;
+ }
+
+ importedfunc = (fptr) dlsym(dl, "func");
+ if (importedfunc == NULL) {
+ printf ("Could not find 'func'\n");
+ goto out;
+ }
+
+ assert(importedfunc != func_from_language_runtime);
+
+ actual = (*importedfunc)();
+ expected = func_from_language_runtime ();
+ if (actual != expected) {
+ printf ("Got %i instead of %i\n", actual, expected);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ dlclose(dl);
+nodl:
+ return ret;
+}
+
+#endif
diff --git a/test cases/common/117 shared module/runtime.c b/test cases/common/117 shared module/runtime.c
new file mode 100644
index 0000000..03bde86
--- /dev/null
+++ b/test cases/common/117 shared module/runtime.c
@@ -0,0 +1,19 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+/*
+ * This file pretends to be a language runtime that supports extension
+ * modules.
+ */
+
+int DLL_PUBLIC func_from_language_runtime(void) {
+ return 86;
+}
diff --git a/test cases/common/117 shared module/test.json b/test cases/common/117 shared module/test.json
new file mode 100644
index 0000000..33bfeff
--- /dev/null
+++ b/test cases/common/117 shared module/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "expr", "file": "usr/lib/modules/libnosyms?so"},
+ {"type": "implibempty", "file": "usr/lib/modules/libnosyms"},
+ {"type": "pdb", "file": "usr/lib/modules/nosyms"}
+ ]
+}
diff --git a/test cases/common/118 llvm ir and assembly/main.c b/test cases/common/118 llvm ir and assembly/main.c
new file mode 100644
index 0000000..35e8ed6
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/main.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+unsigned square_unsigned (unsigned a);
+
+int main(void)
+{
+ unsigned int ret = square_unsigned (2);
+ if (ret != 4) {
+ printf("Got %u instead of 4\n", ret);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/118 llvm ir and assembly/main.cpp b/test cases/common/118 llvm ir and assembly/main.cpp
new file mode 100644
index 0000000..aac3cbf
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/main.cpp
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+extern "C" {
+ unsigned square_unsigned (unsigned a);
+}
+
+int main (void)
+{
+ unsigned int ret = square_unsigned (2);
+ if (ret != 4) {
+ printf("Got %u instead of 4\n", ret);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/118 llvm ir and assembly/meson.build b/test cases/common/118 llvm ir and assembly/meson.build
new file mode 100644
index 0000000..8bc3f43
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/meson.build
@@ -0,0 +1,79 @@
+project('llvm-ir', 'c', 'cpp')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: asm not supported with the Xcode backend. Patches welcome.')
+endif
+
+cpu = host_machine.cpu_family()
+supported_cpus = ['arm', 'aarch64', 'x86', 'x86_64']
+
+foreach lang : ['c', 'cpp']
+ cc = meson.get_compiler(lang)
+ cc_id = cc.get_id()
+ ## Build a trivial executable with mixed LLVM IR source
+ if cc_id == 'clang'
+ e = executable('square_ir_' + lang, 'square.ll', 'main.' + lang)
+ test('test IR square' + lang, e)
+ endif
+ ## Build a trivial executable with mixed assembly source
+ # This also helps test whether cc.symbols_have_underscore_prefix() is working
+ # properly. This is done by assembling some assembly into an object that will
+ # provide the unsigned_squared() symbol to main.c/cpp. This requires the
+ # C symbol mangling to be known in advance.
+ if cc.symbols_have_underscore_prefix()
+ uscore_args = ['-DMESON_TEST__UNDERSCORE_SYMBOL']
+ message('underscore is prefixed')
+ else
+ uscore_args = []
+ message('underscore is NOT prefixed')
+ endif
+ square_base = 'square-' + cpu
+ square_impl = square_base + '.S'
+ # MSVC cannot directly compile assembly files, so we pass it through the
+ # cl.exe pre-processor first and then assemble it with ml.exe or armasm.exe
+ # assembler. Then we can link it into the executable.
+ if cc.get_argument_syntax() == 'msvc'
+ cl = cc.cmd_array()
+ if cpu == 'x86'
+ asmcmd = 'ml'
+ elif cpu == 'x86_64'
+ asmcmd = 'ml64'
+ elif cpu == 'aarch64'
+ asmcmd = 'armasm64'
+ elif cpu == 'arm'
+ asmcmd = 'armasm'
+ else
+ error('Unsupported cpu family: "' + cpu + '"')
+ endif
+ ml = find_program(asmcmd, required: false)
+ if not ml.found()
+ error('MESON_SKIP_TEST: Microsoft assembler (ml/armasm) not found')
+ endif
+ # Preprocess file (ml doesn't support pre-processing)
+ # Force the input to be C (/Tc) because ICL otherwise assumes it's an object (.obj) file
+ preproc_name = lang + square_base + '.i'
+ square_preproc = custom_target(lang + square_impl + 'preproc',
+ input : square_impl,
+ output : preproc_name,
+ command : [cl, '/nologo', '/EP', '/P', '/Fi' + preproc_name, '/Tc', '@INPUT@'] + uscore_args)
+ # Use assembled object file instead of the original .S assembly source
+ if asmcmd.startswith('armasm')
+ square_impl = custom_target(lang + square_impl,
+ input : square_preproc,
+ output : lang + square_base + '.obj',
+ command : [ml, '-nologo', '-o', '@OUTPUT@', '@INPUT@'])
+ else
+ square_impl = custom_target(lang + square_impl,
+ input : square_preproc,
+ output : lang + square_base + '.obj',
+ command : [ml, '/nologo', '/safeseh', '/Fo', '@OUTPUT@', '/c', '@INPUT@'])
+ endif
+ endif
+ if supported_cpus.contains(cpu)
+ e = executable('square_asm_' + lang, square_impl, 'main.' + lang,
+ c_args : uscore_args, cpp_args : uscore_args)
+ test('test ASM square' + lang, e)
+ elif cc_id != 'clang'
+ error('MESON_SKIP_TEST: Unsupported cpu: "' + cpu + '", and LLVM not found')
+ endif
+endforeach
diff --git a/test cases/common/118 llvm ir and assembly/square-aarch64.S b/test cases/common/118 llvm ir and assembly/square-aarch64.S
new file mode 100644
index 0000000..02f1a12
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/square-aarch64.S
@@ -0,0 +1,29 @@
+#include "symbol-underscore.h"
+
+#ifdef _MSC_VER
+
+ AREA _TEXT, ARM64, CODE, READONLY
+
+ EXPORT SYMBOL_NAME(square_unsigned)
+SYMBOL_NAME(square_unsigned) PROC
+ mul x1, x0, x0
+ mov x0, x1
+ ret
+SYMBOL_NAME(square_unsigned) ENDP
+
+ END
+
+#else
+
+.text
+.globl SYMBOL_NAME(square_unsigned)
+# ifdef __linux__
+.type square_unsigned, %function
+#endif
+
+SYMBOL_NAME(square_unsigned):
+ mul x1, x0, x0
+ mov x0, x1
+ ret
+
+#endif
diff --git a/test cases/common/118 llvm ir and assembly/square-arm.S b/test cases/common/118 llvm ir and assembly/square-arm.S
new file mode 100644
index 0000000..aea3f1f
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/square-arm.S
@@ -0,0 +1,29 @@
+#include "symbol-underscore.h"
+
+#ifdef _MSC_VER
+
+ AREA _TEXT, ARM, CODE, READONLY
+
+ EXPORT SYMBOL_NAME(square_unsigned)
+SYMBOL_NAME(square_unsigned) PROC
+ mul r1, r0, r0
+ mov r0, r1
+ mov pc, lr
+SYMBOL_NAME(square_unsigned) ENDP
+
+ END
+
+#else
+
+.text
+.globl SYMBOL_NAME(square_unsigned)
+# ifdef __linux__
+.type square_unsigned, %function
+#endif
+
+SYMBOL_NAME(square_unsigned):
+ mul r1, r0, r0
+ mov r0, r1
+ mov pc, lr
+
+#endif
diff --git a/test cases/common/118 llvm ir and assembly/square-x86.S b/test cases/common/118 llvm ir and assembly/square-x86.S
new file mode 100644
index 0000000..18284c1
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/square-x86.S
@@ -0,0 +1,36 @@
+#include "symbol-underscore.h"
+
+/* This sadly doesn't test the symbol underscore stuff. I can't figure out how
+ * to not use an automatic stdcall mechanism and do everything manually. */
+#ifdef _MSC_VER
+
+.386
+.MODEL FLAT, C
+
+PUBLIC square_unsigned
+_TEXT SEGMENT
+
+square_unsigned PROC var1:DWORD
+ mov eax, var1
+ imul eax, eax
+ ret
+
+square_unsigned ENDP
+
+_TEXT ENDS
+END
+
+#else
+
+.text
+.globl SYMBOL_NAME(square_unsigned)
+# ifdef __linux__
+.type square_unsigned, %function
+#endif
+
+SYMBOL_NAME(square_unsigned):
+ movl 4(%esp), %eax
+ imull %eax, %eax
+ retl
+
+#endif
diff --git a/test cases/common/118 llvm ir and assembly/square-x86_64.S b/test cases/common/118 llvm ir and assembly/square-x86_64.S
new file mode 100644
index 0000000..5678d00
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/square-x86_64.S
@@ -0,0 +1,37 @@
+#include "symbol-underscore.h"
+
+#ifdef _MSC_VER /* MSVC on Windows */
+
+PUBLIC SYMBOL_NAME(square_unsigned)
+_TEXT SEGMENT
+
+SYMBOL_NAME(square_unsigned) PROC
+ mov eax, ecx
+ imul eax, eax
+ ret
+SYMBOL_NAME(square_unsigned) ENDP
+
+_TEXT ENDS
+END
+
+#else
+
+.text
+.globl SYMBOL_NAME(square_unsigned)
+# ifdef __linux__
+.type square_unsigned, %function
+#endif
+
+# if defined(_WIN32) || defined(__CYGWIN__) /* msabi */
+SYMBOL_NAME(square_unsigned):
+ imull %ecx, %ecx
+ movl %ecx, %eax
+ retq
+# else /* sysvabi */
+SYMBOL_NAME(square_unsigned):
+ imull %edi, %edi
+ movl %edi, %eax
+ retq
+# endif
+
+#endif
diff --git a/test cases/common/118 llvm ir and assembly/square.ll b/test cases/common/118 llvm ir and assembly/square.ll
new file mode 100644
index 0000000..7c321aa
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/square.ll
@@ -0,0 +1,4 @@
+define i32 @square_unsigned(i32 %a) {
+ %1 = mul i32 %a, %a
+ ret i32 %1
+}
diff --git a/test cases/common/118 llvm ir and assembly/symbol-underscore.h b/test cases/common/118 llvm ir and assembly/symbol-underscore.h
new file mode 100644
index 0000000..d0f3ef9
--- /dev/null
+++ b/test cases/common/118 llvm ir and assembly/symbol-underscore.h
@@ -0,0 +1,5 @@
+#if defined(MESON_TEST__UNDERSCORE_SYMBOL)
+# define SYMBOL_NAME(name) _##name
+#else
+# define SYMBOL_NAME(name) name
+#endif
diff --git a/test cases/common/119 cpp and asm/meson.build b/test cases/common/119 cpp and asm/meson.build
new file mode 100644
index 0000000..99713d4
--- /dev/null
+++ b/test cases/common/119 cpp and asm/meson.build
@@ -0,0 +1,33 @@
+project('c++ and assembly test')
+add_languages('cpp')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: asm not supported with the Xcode backend. Patches welcome.')
+endif
+
+cpp = meson.get_compiler('cpp')
+cpu = host_machine.cpu_family()
+
+supported_cpus = ['arm', 'x86', 'x86_64']
+
+if not supported_cpus.contains(cpu)
+ error('MESON_SKIP_TEST unsupported cpu:' + cpu)
+endif
+
+if cpp.symbols_have_underscore_prefix()
+ add_project_arguments('-DMESON_TEST__UNDERSCORE_SYMBOL', language : 'cpp')
+endif
+
+sources = ['trivial.cc']
+# If the compiler cannot compile assembly, don't use it
+if not ['msvc', 'clang-cl', 'intel-cl'].contains(meson.get_compiler('cpp').get_id())
+ sources += ['retval-' + cpu + '.S']
+ cpp_args = ['-DUSE_ASM']
+ message('Using ASM')
+else
+ cpp_args = ['-DNO_USE_ASM']
+endif
+
+exe = executable('trivialprog', sources,
+ cpp_args : cpp_args)
+test('runtest', exe)
diff --git a/test cases/common/119 cpp and asm/retval-arm.S b/test cases/common/119 cpp and asm/retval-arm.S
new file mode 100644
index 0000000..a892362
--- /dev/null
+++ b/test cases/common/119 cpp and asm/retval-arm.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ mov r0, #0
+ mov pc, lr
diff --git a/test cases/common/119 cpp and asm/retval-x86.S b/test cases/common/119 cpp and asm/retval-x86.S
new file mode 100644
index 0000000..f9e8190
--- /dev/null
+++ b/test cases/common/119 cpp and asm/retval-x86.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retl
diff --git a/test cases/common/119 cpp and asm/retval-x86_64.S b/test cases/common/119 cpp and asm/retval-x86_64.S
new file mode 100644
index 0000000..1a5f3eb
--- /dev/null
+++ b/test cases/common/119 cpp and asm/retval-x86_64.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retq
diff --git a/test cases/common/119 cpp and asm/symbol-underscore.h b/test cases/common/119 cpp and asm/symbol-underscore.h
new file mode 100644
index 0000000..d0f3ef9
--- /dev/null
+++ b/test cases/common/119 cpp and asm/symbol-underscore.h
@@ -0,0 +1,5 @@
+#if defined(MESON_TEST__UNDERSCORE_SYMBOL)
+# define SYMBOL_NAME(name) _##name
+#else
+# define SYMBOL_NAME(name) name
+#endif
diff --git a/test cases/common/119 cpp and asm/trivial.cc b/test cases/common/119 cpp and asm/trivial.cc
new file mode 100644
index 0000000..19d5e94
--- /dev/null
+++ b/test cases/common/119 cpp and asm/trivial.cc
@@ -0,0 +1,16 @@
+#include<iostream>
+
+extern "C" {
+ int get_retval(void);
+}
+
+int main(void) {
+ std::cout << "C++ seems to be working." << std::endl;
+#if defined(USE_ASM)
+ return get_retval();
+#elif defined(NO_USE_ASM)
+ return 0;
+#else
+ #error "Forgot to pass asm define"
+#endif
+}
diff --git a/test cases/common/12 data/datafile.dat b/test cases/common/12 data/datafile.dat
new file mode 100644
index 0000000..ff3104b
--- /dev/null
+++ b/test cases/common/12 data/datafile.dat
@@ -0,0 +1 @@
+this is a data file
diff --git a/test cases/common/12 data/etcfile.dat b/test cases/common/12 data/etcfile.dat
new file mode 100644
index 0000000..93db8cb
--- /dev/null
+++ b/test cases/common/12 data/etcfile.dat
@@ -0,0 +1 @@
+This goes into /etc/etcfile.dat
diff --git a/test cases/common/12 data/fileobject_datafile.dat b/test cases/common/12 data/fileobject_datafile.dat
new file mode 100644
index 0000000..872aa5a
--- /dev/null
+++ b/test cases/common/12 data/fileobject_datafile.dat
@@ -0,0 +1 @@
+This is a data file that is installed via a File object.
diff --git a/test cases/common/12 data/meson.build b/test cases/common/12 data/meson.build
new file mode 100644
index 0000000..d318633
--- /dev/null
+++ b/test cases/common/12 data/meson.build
@@ -0,0 +1,24 @@
+project('data install test',
+ default_options : ['install_umask=preserve'])
+install_data(sources : 'datafile.dat', install_dir : 'share/progname')
+# Some file in /etc that is only read-write by root; add a sticky bit for testing
+install_data(sources : 'etcfile.dat', install_dir : '/etc', install_mode : 'rw------T')
+# Some script that needs to be executable by the group
+install_data('runscript.sh',
+ install_dir : get_option('bindir'),
+ install_mode : ['rwxr-sr-x', 'root', 0])
+install_data(files('fileobject_datafile.dat'),
+ install_dir : 'share/progname',
+ install_mode : [false, false, 0])
+
+install_data(files('somefile.txt'))
+
+subdir('vanishing')
+
+install_data(sources : 'vanishing/vanishing2.dat', install_dir : 'share/progname')
+
+install_data(sources : 'to_be_renamed_1.txt', rename : 'renamed file.txt')
+install_data(sources : ['vanishing/to_be_renamed_2.txt', 'to_be_renamed_3.txt'],
+ install_dir : 'share/renamed',
+ rename : ['renamed 2.txt', 'renamed 3.txt'])
+install_data(sources : 'to_be_renamed_4.txt', rename : 'some/nested/path.txt')
diff --git a/test cases/common/12 data/runscript.sh b/test cases/common/12 data/runscript.sh
new file mode 100644
index 0000000..8bc5ca6
--- /dev/null
+++ b/test cases/common/12 data/runscript.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "Runscript"
diff --git a/test cases/common/12 data/somefile.txt b/test cases/common/12 data/somefile.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/12 data/somefile.txt
diff --git a/test cases/common/12 data/test.json b/test cases/common/12 data/test.json
new file mode 100644
index 0000000..f392e9a
--- /dev/null
+++ b/test cases/common/12 data/test.json
@@ -0,0 +1,15 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/progname/datafile.dat"},
+ {"type": "file", "file": "usr/share/progname/fileobject_datafile.dat"},
+ {"type": "file", "file": "usr/share/progname/vanishing.dat"},
+ {"type": "file", "file": "usr/share/progname/vanishing2.dat"},
+ {"type": "file", "file": "usr/share/data install test/renamed file.txt"},
+ {"type": "file", "file": "usr/share/data install test/somefile.txt"},
+ {"type": "file", "file": "usr/share/data install test/some/nested/path.txt"},
+ {"type": "file", "file": "usr/share/renamed/renamed 2.txt"},
+ {"type": "file", "file": "usr/share/renamed/renamed 3.txt"},
+ {"type": "file", "file": "etc/etcfile.dat"},
+ {"type": "file", "file": "usr/bin/runscript.sh"}
+ ]
+}
diff --git a/test cases/common/12 data/to_be_renamed_1.txt b/test cases/common/12 data/to_be_renamed_1.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/12 data/to_be_renamed_1.txt
diff --git a/test cases/common/12 data/to_be_renamed_3.txt b/test cases/common/12 data/to_be_renamed_3.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/12 data/to_be_renamed_3.txt
diff --git a/test cases/common/12 data/to_be_renamed_4.txt b/test cases/common/12 data/to_be_renamed_4.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/12 data/to_be_renamed_4.txt
diff --git a/test cases/common/12 data/vanishing/meson.build b/test cases/common/12 data/vanishing/meson.build
new file mode 100644
index 0000000..1a27137
--- /dev/null
+++ b/test cases/common/12 data/vanishing/meson.build
@@ -0,0 +1 @@
+install_data(sources : 'vanishing.dat', install_dir : 'share/progname')
diff --git a/test cases/common/12 data/vanishing/to_be_renamed_2.txt b/test cases/common/12 data/vanishing/to_be_renamed_2.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/12 data/vanishing/to_be_renamed_2.txt
diff --git a/test cases/common/12 data/vanishing/vanishing.dat b/test cases/common/12 data/vanishing/vanishing.dat
new file mode 100644
index 0000000..b7d0609
--- /dev/null
+++ b/test cases/common/12 data/vanishing/vanishing.dat
@@ -0,0 +1 @@
+This is a data file to be installed in a subdirectory.
diff --git a/test cases/common/12 data/vanishing/vanishing2.dat b/test cases/common/12 data/vanishing/vanishing2.dat
new file mode 100644
index 0000000..99c923b
--- /dev/null
+++ b/test cases/common/12 data/vanishing/vanishing2.dat
@@ -0,0 +1,4 @@
+This is a data file to be installed in a subdirectory.
+
+It is installed from a different subdir to test that the
+installer strips the source tree dir prefix.
diff --git a/test cases/common/120 extract all shared library/extractor.h b/test cases/common/120 extract all shared library/extractor.h
new file mode 100644
index 0000000..cfb7ff6
--- /dev/null
+++ b/test cases/common/120 extract all shared library/extractor.h
@@ -0,0 +1,6 @@
+#pragma once
+
+int func1(void);
+int func2(void);
+int func3(void);
+int func4(void);
diff --git a/test cases/common/120 extract all shared library/four.c b/test cases/common/120 extract all shared library/four.c
new file mode 100644
index 0000000..f67a85e
--- /dev/null
+++ b/test cases/common/120 extract all shared library/four.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func4(void) {
+ return 4;
+}
diff --git a/test cases/common/120 extract all shared library/func1234.def b/test cases/common/120 extract all shared library/func1234.def
new file mode 100644
index 0000000..d62c08d
--- /dev/null
+++ b/test cases/common/120 extract all shared library/func1234.def
@@ -0,0 +1,5 @@
+EXPORTS
+ func1
+ func2
+ func3
+ func4
diff --git a/test cases/common/120 extract all shared library/meson.build b/test cases/common/120 extract all shared library/meson.build
new file mode 100644
index 0000000..e7c5809
--- /dev/null
+++ b/test cases/common/120 extract all shared library/meson.build
@@ -0,0 +1,15 @@
+project('extract all', 'c', 'cpp')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: Xcode backend does not handle libraries with only objects, not sources.')
+endif
+
+a = static_library('a', 'one.c', 'two.c')
+b = static_library('b', 'three.c', 'four.c')
+# libc.so cannot be used, it already exists as a reserved name
+c = shared_library('cee',
+ objects : [a.extract_all_objects(), b.extract_all_objects()],
+ vs_module_defs : 'func1234.def')
+
+e = executable('proggie', 'prog.c', link_with : c)
+test('extall', e)
diff --git a/test cases/common/120 extract all shared library/one.c b/test cases/common/120 extract all shared library/one.c
new file mode 100644
index 0000000..152a145
--- /dev/null
+++ b/test cases/common/120 extract all shared library/one.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func1(void) {
+ return 1;
+}
diff --git a/test cases/common/120 extract all shared library/prog.c b/test cases/common/120 extract all shared library/prog.c
new file mode 100644
index 0000000..de0cc7f
--- /dev/null
+++ b/test cases/common/120 extract all shared library/prog.c
@@ -0,0 +1,10 @@
+#include"extractor.h"
+#include<stdio.h>
+
+int main(void) {
+ if((1+2+3+4) != (func1() + func2() + func3() + func4())) {
+ printf("Arithmetic is fail.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/120 extract all shared library/three.c b/test cases/common/120 extract all shared library/three.c
new file mode 100644
index 0000000..24604ed
--- /dev/null
+++ b/test cases/common/120 extract all shared library/three.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func3(void) {
+ return 3;
+}
diff --git a/test cases/common/120 extract all shared library/two.c b/test cases/common/120 extract all shared library/two.c
new file mode 100644
index 0000000..800cd2d
--- /dev/null
+++ b/test cases/common/120 extract all shared library/two.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func2(void) {
+ return 2;
+}
diff --git a/test cases/common/121 object only target/meson.build b/test cases/common/121 object only target/meson.build
new file mode 100644
index 0000000..c3c4e52
--- /dev/null
+++ b/test cases/common/121 object only target/meson.build
@@ -0,0 +1,51 @@
+project('object generator', 'c')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST object-only libraries not supported in Xcode. Patches welcome.')
+endif
+
+# FIXME: Note that this will not add a dependency to the compiler executable.
+# Code will not be rebuilt if it changes.
+comp = find_program('obj_generator.py')
+
+if host_machine.system() == 'windows'
+ ext = '.obj'
+else
+ ext = '.o'
+endif
+
+cc = meson.get_compiler('c').cmd_array().get(-1)
+
+# Generate an object file with configure_file to mimic prebuilt objects
+# provided by the source tree
+source1 = configure_file(input : 'source.c',
+ output : 'source' + ext,
+ command : [comp, cc, files('source.c'),
+ join_paths(meson.current_build_dir(), 'source' + ext)])
+
+obj = static_library('obj', objects : source1)
+
+# Generate an object file manually.
+gen = generator(comp,
+ output : '@BASENAME@' + ext,
+ arguments : [cc, '@INPUT@', '@OUTPUT@'])
+
+generated = gen.process(['source2.c'])
+
+shr = shared_library('shr', generated,
+ vs_module_defs : 'source2.def')
+
+# Generate an object file with indexed OUTPUT replacement.
+gen2 = generator(comp,
+ output : '@BASENAME@' + ext,
+ arguments : [cc, '@INPUT@', '@OUTPUT0@'])
+generated2 = gen2.process(['source3.c'])
+
+stc = static_library('stc', generated2)
+
+subdir('objdir')
+
+e = executable('prog', 'prog.c', link_with : [obj, shr, stc, subdirfilebuilt_obj, subdirfile_obj, subdirstr_obj],
+ install : true)
+
+test('objgen', e)
diff --git a/test cases/common/121 object only target/obj_generator.py b/test cases/common/121 object only target/obj_generator.py
new file mode 100755
index 0000000..afdbc09
--- /dev/null
+++ b/test cases/common/121 object only target/obj_generator.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+# Mimic a binary that generates an object file (e.g. windres).
+
+import sys, subprocess
+
+if __name__ == '__main__':
+ if len(sys.argv) != 4:
+ print(sys.argv[0], 'compiler input_file output_file')
+ sys.exit(1)
+ compiler = sys.argv[1]
+ ifile = sys.argv[2]
+ ofile = sys.argv[3]
+ if compiler.endswith('cl'):
+ cmd = [compiler, '/nologo', '/MDd', '/Fo' + ofile, '/c', ifile]
+ elif sys.platform == 'sunos5':
+ cmd = [compiler, '-fpic', '-c', ifile, '-o', ofile]
+ else:
+ cmd = [compiler, '-c', ifile, '-o', ofile]
+ sys.exit(subprocess.call(cmd))
diff --git a/test cases/common/121 object only target/objdir/meson.build b/test cases/common/121 object only target/objdir/meson.build
new file mode 100644
index 0000000..631c1a1
--- /dev/null
+++ b/test cases/common/121 object only target/objdir/meson.build
@@ -0,0 +1,27 @@
+
+#mesonlib.File built
+source4 = configure_file(input : 'source4.c',
+ output : 'source4' + ext,
+ command : [comp, cc, files('source4.c'),
+ join_paths(meson.current_build_dir(), 'source4' + ext)])
+
+subdirfilebuilt_obj = static_library('subdirfilebuilt_obj', objects : source4)
+
+
+#mesonlib.File not built
+configure_file(input : 'source5.c',
+ output : 'source5' + ext,
+ command : [comp, cc, files('source5.c'),
+ join_paths(meson.current_build_dir(), 'source5' + ext)])
+
+subdirfile_obj = static_library('subdirfile_obj', objects : files(meson.current_build_dir()/'source5' + ext))
+
+
+#str
+configure_file(input : 'source6.c',
+ output : 'source6' + ext,
+ command : [comp, cc, files('source6.c'),
+ join_paths(meson.current_build_dir(), 'source6' + ext)])
+
+
+subdirstr_obj = static_library('subdirstr_obj', objects : meson.current_build_dir()/'source6' + ext)
diff --git a/test cases/common/121 object only target/objdir/source4.c b/test cases/common/121 object only target/objdir/source4.c
new file mode 100644
index 0000000..83f4fab
--- /dev/null
+++ b/test cases/common/121 object only target/objdir/source4.c
@@ -0,0 +1,3 @@
+int func4_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/121 object only target/objdir/source5.c b/test cases/common/121 object only target/objdir/source5.c
new file mode 100644
index 0000000..c512fc3
--- /dev/null
+++ b/test cases/common/121 object only target/objdir/source5.c
@@ -0,0 +1,3 @@
+int func5_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/121 object only target/objdir/source6.c b/test cases/common/121 object only target/objdir/source6.c
new file mode 100644
index 0000000..adcf2cd
--- /dev/null
+++ b/test cases/common/121 object only target/objdir/source6.c
@@ -0,0 +1,3 @@
+int func6_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/121 object only target/prog.c b/test cases/common/121 object only target/prog.c
new file mode 100644
index 0000000..a27663b
--- /dev/null
+++ b/test cases/common/121 object only target/prog.c
@@ -0,0 +1,11 @@
+int func1_in_obj(void);
+int func2_in_obj(void);
+int func3_in_obj(void);
+int func4_in_obj(void);
+int func5_in_obj(void);
+int func6_in_obj(void);
+
+int main(void) {
+ return func1_in_obj() + func2_in_obj() + func3_in_obj()
+ + func4_in_obj() + func5_in_obj() + func6_in_obj();
+}
diff --git a/test cases/common/121 object only target/source.c b/test cases/common/121 object only target/source.c
new file mode 100644
index 0000000..1dc08e1
--- /dev/null
+++ b/test cases/common/121 object only target/source.c
@@ -0,0 +1,3 @@
+int func1_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/121 object only target/source2.c b/test cases/common/121 object only target/source2.c
new file mode 100644
index 0000000..8024b97
--- /dev/null
+++ b/test cases/common/121 object only target/source2.c
@@ -0,0 +1,3 @@
+int func2_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/121 object only target/source2.def b/test cases/common/121 object only target/source2.def
new file mode 100644
index 0000000..a993ab8
--- /dev/null
+++ b/test cases/common/121 object only target/source2.def
@@ -0,0 +1,2 @@
+EXPORTS
+ func2_in_obj
diff --git a/test cases/common/121 object only target/source3.c b/test cases/common/121 object only target/source3.c
new file mode 100644
index 0000000..c4362c4
--- /dev/null
+++ b/test cases/common/121 object only target/source3.c
@@ -0,0 +1,3 @@
+int func3_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/121 object only target/test.json b/test cases/common/121 object only target/test.json
new file mode 100644
index 0000000..135300d
--- /dev/null
+++ b/test cases/common/121 object only target/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/common/122 no buildincdir/include/header.h b/test cases/common/122 no buildincdir/include/header.h
new file mode 100644
index 0000000..1170ee3
--- /dev/null
+++ b/test cases/common/122 no buildincdir/include/header.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int foobar(void);
diff --git a/test cases/common/122 no buildincdir/meson.build b/test cases/common/122 no buildincdir/meson.build
new file mode 100644
index 0000000..53f1a7f
--- /dev/null
+++ b/test cases/common/122 no buildincdir/meson.build
@@ -0,0 +1,14 @@
+project('nobuilddir', 'c',
+ default_options : ['werror=true', 'buildtype=plain'])
+
+cc = meson.get_compiler('c')
+
+incwarg = '-Wmissing-include-dirs'
+
+if cc.has_argument(incwarg)
+ executable('prog', 'prog.c',
+ c_args : incwarg,
+ include_directories : include_directories('include'))
+else
+ error('MESON_SKIP_TEST compiler does not support bad inc dir argument.')
+endif
diff --git a/test cases/common/122 no buildincdir/prog.c b/test cases/common/122 no buildincdir/prog.c
new file mode 100644
index 0000000..b356f65
--- /dev/null
+++ b/test cases/common/122 no buildincdir/prog.c
@@ -0,0 +1,5 @@
+#include"header.h"
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/123 custom target directory install/docgen.py b/test cases/common/123 custom target directory install/docgen.py
new file mode 100644
index 0000000..97a3f90
--- /dev/null
+++ b/test cases/common/123 custom target directory install/docgen.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+out = sys.argv[1]
+
+try:
+ os.mkdir(out)
+except FileExistsError:
+ pass
+
+for name in ('a', 'b', 'c'):
+ with open(os.path.join(out, name + '.html'), 'w') as f:
+ f.write(name)
diff --git a/test cases/common/123 custom target directory install/meson.build b/test cases/common/123 custom target directory install/meson.build
new file mode 100644
index 0000000..c3bfa20
--- /dev/null
+++ b/test cases/common/123 custom target directory install/meson.build
@@ -0,0 +1,9 @@
+project('custom-target-dir-install')
+
+docgen = find_program('docgen.py')
+
+custom_target('docgen',
+ output : 'html',
+ command : [docgen, '@OUTPUT@'],
+ install : true,
+ install_dir : join_paths(get_option('datadir'), 'doc/testpkgname'))
diff --git a/test cases/common/123 custom target directory install/test.json b/test cases/common/123 custom target directory install/test.json
new file mode 100644
index 0000000..c7eebf5
--- /dev/null
+++ b/test cases/common/123 custom target directory install/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/doc/testpkgname/html/a.html"},
+ {"type": "file", "file": "usr/share/doc/testpkgname/html/b.html"},
+ {"type": "file", "file": "usr/share/doc/testpkgname/html/c.html"}
+ ]
+}
diff --git a/test cases/common/124 dependency file generation/main .c b/test cases/common/124 dependency file generation/main .c
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/test cases/common/124 dependency file generation/main .c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/124 dependency file generation/meson.build b/test cases/common/124 dependency file generation/meson.build
new file mode 100644
index 0000000..b5ee47b
--- /dev/null
+++ b/test cases/common/124 dependency file generation/meson.build
@@ -0,0 +1,14 @@
+project('dep file gen', 'c')
+
+cc_id = meson.get_compiler('c').get_id()
+cc_ver = meson.get_compiler('c').version()
+
+if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08'))
+ # ICC and LCC <= 1.23.08 do not escape spaces in paths in the dependency file, so Ninja
+ # (correctly) thinks that the rule has multiple outputs and errors out:
+ # 'depfile has multiple output paths'
+ error('MESON_SKIP_TEST: Skipping test because your compiler is known to generate broken dependency files')
+endif
+
+e = executable('main file', 'main .c')
+test('test it', e)
diff --git a/test cases/common/125 configure file in generator/inc/confdata.in b/test cases/common/125 configure file in generator/inc/confdata.in
new file mode 100644
index 0000000..e44cdea
--- /dev/null
+++ b/test cases/common/125 configure file in generator/inc/confdata.in
@@ -0,0 +1 @@
+@VALUE@
diff --git a/test cases/common/125 configure file in generator/inc/meson.build b/test cases/common/125 configure file in generator/inc/meson.build
new file mode 100644
index 0000000..05d2dcb
--- /dev/null
+++ b/test cases/common/125 configure file in generator/inc/meson.build
@@ -0,0 +1,6 @@
+cdata = configuration_data()
+cdata.set('VALUE', '42')
+
+cfile = configure_file(input : 'confdata.in',
+output : 'confdata',
+configuration : cdata)
diff --git a/test cases/common/125 configure file in generator/meson.build b/test cases/common/125 configure file in generator/meson.build
new file mode 100644
index 0000000..e1c26b6
--- /dev/null
+++ b/test cases/common/125 configure file in generator/meson.build
@@ -0,0 +1,4 @@
+project('conf file in generator', 'c')
+
+subdir('inc')
+subdir('src')
diff --git a/test cases/common/125 configure file in generator/src/gen.py b/test cases/common/125 configure file in generator/src/gen.py
new file mode 100755
index 0000000..426d0b7
--- /dev/null
+++ b/test cases/common/125 configure file in generator/src/gen.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import sys
+
+ifile = sys.argv[1]
+ofile = sys.argv[2]
+
+with open(ifile) as f:
+ resval = f.readline().strip()
+
+templ = '#define RESULT (%s)\n'
+with open(ofile, 'w') as f:
+ f.write(templ % (resval, ))
diff --git a/test cases/common/125 configure file in generator/src/main.c b/test cases/common/125 configure file in generator/src/main.c
new file mode 100644
index 0000000..6329e47
--- /dev/null
+++ b/test cases/common/125 configure file in generator/src/main.c
@@ -0,0 +1,17 @@
+#include<stdio.h>
+
+#include"confdata.h"
+#if RESULT != 42
+#error Configuration RESULT is not defined correctly
+#endif
+
+#undef RESULT
+
+#include"source.h"
+#if RESULT != 23
+#error Source RESULT is not defined correctly
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/125 configure file in generator/src/meson.build b/test cases/common/125 configure file in generator/src/meson.build
new file mode 100644
index 0000000..2fb804e
--- /dev/null
+++ b/test cases/common/125 configure file in generator/src/meson.build
@@ -0,0 +1,7 @@
+compiler = find_program('gen.py')
+gen = generator(compiler,
+ output: '@BASENAME@.h',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+hs = gen.process(cfile, files('source'))
+
+executable('proggie', 'main.c', hs)
diff --git a/test cases/common/125 configure file in generator/src/source b/test cases/common/125 configure file in generator/src/source
new file mode 100644
index 0000000..4099407
--- /dev/null
+++ b/test cases/common/125 configure file in generator/src/source
@@ -0,0 +1 @@
+23
diff --git a/test cases/common/126 generated llvm ir/copyfile.py b/test cases/common/126 generated llvm ir/copyfile.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/common/126 generated llvm ir/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/126 generated llvm ir/main.c b/test cases/common/126 generated llvm ir/main.c
new file mode 100644
index 0000000..35e8ed6
--- /dev/null
+++ b/test cases/common/126 generated llvm ir/main.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+unsigned square_unsigned (unsigned a);
+
+int main(void)
+{
+ unsigned int ret = square_unsigned (2);
+ if (ret != 4) {
+ printf("Got %u instead of 4\n", ret);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/126 generated llvm ir/meson.build b/test cases/common/126 generated llvm ir/meson.build
new file mode 100644
index 0000000..fddee2b
--- /dev/null
+++ b/test cases/common/126 generated llvm ir/meson.build
@@ -0,0 +1,28 @@
+project('generated llvm ir', 'c')
+
+if meson.get_compiler('c').get_id() != 'clang'
+ error('MESON_SKIP_TEST: LLVM IR files can only be built with clang')
+endif
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: LLVM ir not supported with the Xcode backend. Patches welcome.')
+endif
+
+copy = find_program('copyfile.py')
+
+copygen = generator(copy,
+ arguments : ['@INPUT@', '@OUTPUT@'],
+ output : '@BASENAME@')
+
+l = library('square-gen', copygen.process('square.ll.in'))
+
+test('square-gen-test', executable('square-gen-test', 'main.c', link_with : l))
+
+copyct = custom_target('square',
+ input : 'square.ll.in',
+ output : 'square.ll',
+ command : [copy, '@INPUT@', '@OUTPUT@'])
+
+l = library('square-ct', copyct)
+
+test('square-ct-test', executable('square-ct-test', 'main.c', link_with : l))
diff --git a/test cases/common/126 generated llvm ir/square.ll.in b/test cases/common/126 generated llvm ir/square.ll.in
new file mode 100644
index 0000000..7c321aa
--- /dev/null
+++ b/test cases/common/126 generated llvm ir/square.ll.in
@@ -0,0 +1,4 @@
+define i32 @square_unsigned(i32 %a) {
+ %1 = mul i32 %a, %a
+ ret i32 %1
+}
diff --git a/test cases/common/127 generated assembly/copyfile.py b/test cases/common/127 generated assembly/copyfile.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/common/127 generated assembly/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/127 generated assembly/empty.c b/test cases/common/127 generated assembly/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/127 generated assembly/empty.c
diff --git a/test cases/common/127 generated assembly/main.c b/test cases/common/127 generated assembly/main.c
new file mode 100644
index 0000000..fb38f9d
--- /dev/null
+++ b/test cases/common/127 generated assembly/main.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ __declspec(dllimport)
+#endif
+unsigned square_unsigned (unsigned a);
+
+int main(void)
+{
+ unsigned int ret = square_unsigned (2);
+ if (ret != 4) {
+ printf("Got %u instead of 4\n", ret);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/127 generated assembly/meson.build b/test cases/common/127 generated assembly/meson.build
new file mode 100644
index 0000000..31a5f17
--- /dev/null
+++ b/test cases/common/127 generated assembly/meson.build
@@ -0,0 +1,66 @@
+project('generated assembly', 'c')
+
+cc = meson.get_compiler('c')
+
+if ['msvc', 'intel-cl'].contains(cc.get_id())
+ error('MESON_SKIP_TEST: assembly files cannot be compiled directly by the compiler')
+endif
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: asm not supported with the Xcode backend. Patches welcome.')
+endif
+
+
+crt_workaround = []
+if cc.get_linker_id() == 'lld-link'
+ # It seems that when building without a .c file, lld-link.exe
+ # misses the fact that it needs to include the c runtime to
+ # make a working .dll. So here we add an empty .c file to easily
+ # pull in crt.
+ crt_workaround += 'empty.c'
+ if host_machine.cpu_family() == 'x86'
+ # x86 assembly needs manual annotation to be compatible with
+ # Safe Exception Handlers (?) This assembly doesn't have such
+ # annotation, so just disable the feature.
+ add_project_link_arguments('/SAFESEH:NO', language : 'c')
+ endif
+endif
+
+cpu = host_machine.cpu_family()
+supported_cpus = ['arm', 'x86', 'x86_64']
+
+if not supported_cpus.contains(cpu)
+ error('MESON_SKIP_TEST: unsupported cpu family: ' + cpu)
+endif
+
+if cc.get_id() == 'clang-cl' and cc.version().version_compare('< 12.0.0') and cpu == 'arm'
+ # https://reviews.llvm.org/D89622
+ error('MESON_SKIP_TEST: arm debug symbols not supported in clang-cl < 12.0.0')
+endif
+
+if cc.symbols_have_underscore_prefix()
+ add_project_arguments('-DMESON_TEST__UNDERSCORE_SYMBOL', language : 'c')
+endif
+
+copy = find_program('copyfile.py')
+output = 'square-@0@.S'.format(cpu)
+input = output + '.in'
+
+copygen = generator(copy,
+ arguments : ['@INPUT@', '@OUTPUT@'],
+ output : '@BASENAME@')
+
+l = library('square-gen', crt_workaround + [copygen.process(input)],
+ vs_module_defs: 'square.def')
+
+test('square-gen-test', executable('square-gen-test', 'main.c', link_with : l))
+
+copyct = custom_target('square',
+ input : input,
+ output : output,
+ command : [copy, '@INPUT@', '@OUTPUT@'])
+
+l = library('square-ct', crt_workaround + [copyct],
+ vs_module_defs: 'square.def')
+
+test('square-ct-test', executable('square-ct-test', 'main.c', link_with : l))
diff --git a/test cases/common/127 generated assembly/square-arm.S.in b/test cases/common/127 generated assembly/square-arm.S.in
new file mode 100644
index 0000000..d2fb7ac
--- /dev/null
+++ b/test cases/common/127 generated assembly/square-arm.S.in
@@ -0,0 +1,13 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(square_unsigned)
+/* Only supported with GAS */
+# if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
+.type square_unsigned,%function
+#endif
+
+SYMBOL_NAME(square_unsigned):
+ mul r1, r0, r0
+ mov r0, r1
+ mov pc, lr
diff --git a/test cases/common/127 generated assembly/square-x86.S.in b/test cases/common/127 generated assembly/square-x86.S.in
new file mode 100644
index 0000000..1a48fc4
--- /dev/null
+++ b/test cases/common/127 generated assembly/square-x86.S.in
@@ -0,0 +1,34 @@
+#include "symbol-underscore.h"
+
+#if defined(_MSC_VER) && !defined(__clang__)
+
+.386
+.MODEL FLAT, C
+
+PUBLIC square_unsigned
+_TEXT SEGMENT
+
+square_unsigned PROC var1:DWORD
+ mov eax, var1
+ imul eax, eax
+ ret
+square_unsigned ENDP
+
+_TEXT ENDS
+END
+
+#else
+
+.text
+.globl SYMBOL_NAME(square_unsigned)
+/* Only supported with GAS */
+# if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
+.type square_unsigned,@function
+# endif
+
+SYMBOL_NAME(square_unsigned):
+ movl 4(%esp), %eax
+ imull %eax, %eax
+ retl
+
+#endif
diff --git a/test cases/common/127 generated assembly/square-x86_64.S.in b/test cases/common/127 generated assembly/square-x86_64.S.in
new file mode 100644
index 0000000..d504341
--- /dev/null
+++ b/test cases/common/127 generated assembly/square-x86_64.S.in
@@ -0,0 +1,38 @@
+#include "symbol-underscore.h"
+
+#if defined(_MSC_VER) && !defined(__clang__) /* MSVC on Windows */
+
+PUBLIC SYMBOL_NAME(square_unsigned)
+_TEXT SEGMENT
+
+SYMBOL_NAME(square_unsigned) PROC
+ mov eax, ecx
+ imul eax, eax
+ ret
+SYMBOL_NAME(square_unsigned) ENDP
+
+_TEXT ENDS
+END
+
+#else
+
+.text
+.globl SYMBOL_NAME(square_unsigned)
+/* Only supported with GAS */
+# if defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__sun)
+.type square_unsigned,@function
+# endif
+
+# if defined(_WIN32) || defined(__CYGWIN__) /* msabi */
+SYMBOL_NAME(square_unsigned):
+ imull %ecx, %ecx
+ movl %ecx, %eax
+ retq
+# else /* sysvabi */
+SYMBOL_NAME(square_unsigned):
+ imull %edi, %edi
+ movl %edi, %eax
+ retq
+# endif
+
+#endif
diff --git a/test cases/common/127 generated assembly/square.def b/test cases/common/127 generated assembly/square.def
new file mode 100644
index 0000000..79f3d65
--- /dev/null
+++ b/test cases/common/127 generated assembly/square.def
@@ -0,0 +1,2 @@
+EXPORTS
+ square_unsigned
diff --git a/test cases/common/127 generated assembly/symbol-underscore.h b/test cases/common/127 generated assembly/symbol-underscore.h
new file mode 100644
index 0000000..d0f3ef9
--- /dev/null
+++ b/test cases/common/127 generated assembly/symbol-underscore.h
@@ -0,0 +1,5 @@
+#if defined(MESON_TEST__UNDERSCORE_SYMBOL)
+# define SYMBOL_NAME(name) _##name
+#else
+# define SYMBOL_NAME(name) name
+#endif
diff --git a/test cases/common/128 build by default targets in tests/main.c b/test cases/common/128 build by default targets in tests/main.c
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/test cases/common/128 build by default targets in tests/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/128 build by default targets in tests/meson.build b/test cases/common/128 build by default targets in tests/meson.build
new file mode 100644
index 0000000..5cc5055
--- /dev/null
+++ b/test cases/common/128 build by default targets in tests/meson.build
@@ -0,0 +1,23 @@
+project('unit-test', 'c', version : '1.0')
+
+write_file = find_program('write_file.py')
+
+# A test that consumes and verifies the output generated by a custom target.
+# Should work even if target is not built by default. Makes sure that foo.out
+# is actually created before the test command that uses foo_out is run.
+foo_out = custom_target('foo.out',
+ output : 'foo.out',
+ command : [write_file, '@OUTPUT@'])
+
+# Also verify that a build_by_default : false BuildTarget added to a test is
+# built before the test is run.
+exe_out = executable('out', 'main.c', build_by_default : false)
+
+py_file_exists = '''import os, sys
+if not os.path.exists(sys.argv[1]) or not os.path.exists(sys.argv[2]):
+ print("could not find {!r} or {!r} in {!r}"
+ "".format(sys.argv[1], sys.argv[2], os.getcwd()))
+ sys.exit(1)'''
+
+python = import('python3').find_python()
+test('output-check', python, args : ['-c', py_file_exists, foo_out, exe_out])
diff --git a/test cases/common/128 build by default targets in tests/write_file.py b/test cases/common/128 build by default targets in tests/write_file.py
new file mode 100644
index 0000000..ff9c224
--- /dev/null
+++ b/test cases/common/128 build by default targets in tests/write_file.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ f.write('Test')
diff --git a/test cases/common/129 build by default/checkexists.py b/test cases/common/129 build by default/checkexists.py
new file mode 100644
index 0000000..6664f72
--- /dev/null
+++ b/test cases/common/129 build by default/checkexists.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+
+import os.path, sys
+
+invert = False
+for path in sys.argv[1:]:
+ if path == '--not':
+ invert = True
+ elif not os.path.exists(path) ^ invert:
+ sys.exit(1)
diff --git a/test cases/common/129 build by default/foo.c b/test cases/common/129 build by default/foo.c
new file mode 100644
index 0000000..0322828
--- /dev/null
+++ b/test cases/common/129 build by default/foo.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Existentialism.\n");
+ return 0;
+}
diff --git a/test cases/common/129 build by default/meson.build b/test cases/common/129 build by default/meson.build
new file mode 100644
index 0000000..b797f76
--- /dev/null
+++ b/test cases/common/129 build by default/meson.build
@@ -0,0 +1,44 @@
+project('build on all', 'c')
+
+py3_mod = import('python3')
+py3 = py3_mod.find_python()
+
+executable('fooprog', 'foo.c',
+ build_by_default : false,
+)
+
+executable('barprog', 'foo.c',
+ build_by_default : false,
+)
+
+comp = files('mygen.py')
+checkexists = files('checkexists.py')
+
+mytarget = custom_target('gendat1',
+ output : 'generated1.dat',
+ input : 'source.txt',
+ command : [py3] + comp + ['@INPUT@', '@OUTPUT@'],
+ build_by_default : true,
+)
+
+mytarget = custom_target('gendat2',
+ output : 'generated2.dat',
+ input : 'source.txt',
+ command : [py3] + comp + ['@INPUT@', '@OUTPUT@'],
+ build_by_default : true,
+ build_always : false,
+)
+
+ct1_output = join_paths(meson.build_root(), 'generated1.dat')
+ct2_output = join_paths(meson.build_root(), 'generated2.dat')
+exe1_output = join_paths(meson.build_root(), 'fooprog')
+exe2_output = join_paths(meson.build_root(), 'barprog')
+
+if host_machine.system() == 'windows'
+ exe1_output += '.exe'
+ exe2_output += '.exe'
+endif
+
+test('check-build-by-default', py3,
+ args : [checkexists,
+ ct1_output, ct2_output, '--not', exe1_output, exe2_output])
diff --git a/test cases/common/129 build by default/mygen.py b/test cases/common/129 build by default/mygen.py
new file mode 100644
index 0000000..5a74153
--- /dev/null
+++ b/test cases/common/129 build by default/mygen.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import sys
+
+ifile = open(sys.argv[1])
+ofile = open(sys.argv[2], 'w')
+
+ofile.write(ifile.read())
diff --git a/test cases/common/129 build by default/source.txt b/test cases/common/129 build by default/source.txt
new file mode 100644
index 0000000..3573f4b
--- /dev/null
+++ b/test cases/common/129 build by default/source.txt
@@ -0,0 +1 @@
+I am a bunch of text.
diff --git a/test cases/common/13 pch/c/meson.build b/test cases/common/13 pch/c/meson.build
new file mode 100644
index 0000000..6fba15b
--- /dev/null
+++ b/test cases/common/13 pch/c/meson.build
@@ -0,0 +1,14 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+# PGI compiler only supports PCH for C++
+if cc_id == 'pgi'
+ subdir_done()
+endif
+
+exe = executable('prog', 'prog.c',
+c_pch : 'pch/prog.h')
diff --git a/test cases/common/13 pch/c/pch/prog.h b/test cases/common/13 pch/c/pch/prog.h
new file mode 100644
index 0000000..c89890a
--- /dev/null
+++ b/test cases/common/13 pch/c/pch/prog.h
@@ -0,0 +1,6 @@
+#ifndef PROG_H
+// Header guards for PCH confuse msvc in some situations.
+// Using them here makes sure we handle this correctly.
+#define PROG_H
+#include<stdio.h>
+#endif
diff --git a/test cases/common/13 pch/c/prog.c b/test cases/common/13 pch/c/prog.c
new file mode 100644
index 0000000..4ef2fd8
--- /dev/null
+++ b/test cases/common/13 pch/c/prog.c
@@ -0,0 +1,9 @@
+// No includes here, they need to come from the PCH
+
+void func(void) {
+ fprintf(stdout, "This is a function that fails if stdio is not #included.\n");
+}
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/13 pch/cpp/meson.build b/test cases/common/13 pch/cpp/meson.build
new file mode 100644
index 0000000..b01cd58
--- /dev/null
+++ b/test cases/common/13 pch/cpp/meson.build
@@ -0,0 +1 @@
+exe = executable('prog', 'prog.cc', cpp_pch : 'pch/prog.hh')
diff --git a/test cases/common/13 pch/cpp/pch/prog.hh b/test cases/common/13 pch/cpp/pch/prog.hh
new file mode 100644
index 0000000..751cc4a
--- /dev/null
+++ b/test cases/common/13 pch/cpp/pch/prog.hh
@@ -0,0 +1 @@
+#include<iostream>
diff --git a/test cases/common/13 pch/cpp/prog.cc b/test cases/common/13 pch/cpp/prog.cc
new file mode 100644
index 0000000..0ba8519
--- /dev/null
+++ b/test cases/common/13 pch/cpp/prog.cc
@@ -0,0 +1,11 @@
+// Note: if using PGI compilers, you will need to add #include "prog.hh"
+// even though you're using precompiled headers.
+void func(void) {
+ std::cout << "This is a function that fails to compile if iostream is not included."
+ << std::endl;
+}
+
+int main(void) {
+ func();
+ return 0;
+}
diff --git a/test cases/common/13 pch/generated/gen_custom.py b/test cases/common/13 pch/generated/gen_custom.py
new file mode 100644
index 0000000..650e03c
--- /dev/null
+++ b/test cases/common/13 pch/generated/gen_custom.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ f.write("#define FOO 0")
diff --git a/test cases/common/13 pch/generated/gen_generator.py b/test cases/common/13 pch/generated/gen_generator.py
new file mode 100644
index 0000000..a245e7a
--- /dev/null
+++ b/test cases/common/13 pch/generated/gen_generator.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1]) as f:
+ content = f.read()
+with open(sys.argv[2], 'w') as f:
+ f.write(content)
diff --git a/test cases/common/13 pch/generated/generated_generator.in b/test cases/common/13 pch/generated/generated_generator.in
new file mode 100644
index 0000000..1a00ebd
--- /dev/null
+++ b/test cases/common/13 pch/generated/generated_generator.in
@@ -0,0 +1 @@
+#define BAR 0
diff --git a/test cases/common/13 pch/generated/meson.build b/test cases/common/13 pch/generated/meson.build
new file mode 100644
index 0000000..ba06bce
--- /dev/null
+++ b/test cases/common/13 pch/generated/meson.build
@@ -0,0 +1,22 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+# PGI compiler only supports PCH for C++
+if cc_id == 'pgi'
+ subdir_done()
+endif
+
+generated_customTarget = custom_target('makeheader',
+ output: 'generated_customTarget.h',
+ command : [find_program('gen_custom.py'), '@OUTPUT0@'])
+
+generated_generator = generator(find_program('gen_generator.py'),
+ output: '@BASENAME@.h',
+ arguments: ['@INPUT@', '@OUTPUT@'])
+
+exe = executable('prog', 'prog.c', generated_customTarget, generated_generator.process('generated_generator.in'),
+ c_pch: 'pch/prog.h')
diff --git a/test cases/common/13 pch/generated/pch/prog.h b/test cases/common/13 pch/generated/pch/prog.h
new file mode 100644
index 0000000..15fec38
--- /dev/null
+++ b/test cases/common/13 pch/generated/pch/prog.h
@@ -0,0 +1,2 @@
+#include "generated_customTarget.h"
+#include "generated_generator.h"
diff --git a/test cases/common/13 pch/generated/prog.c b/test cases/common/13 pch/generated/prog.c
new file mode 100644
index 0000000..a75c2d2
--- /dev/null
+++ b/test cases/common/13 pch/generated/prog.c
@@ -0,0 +1,5 @@
+// No includes here, they need to come from the PCH
+
+int main(void) {
+ return FOO + BAR;
+}
diff --git a/test cases/common/13 pch/linkwhole/lib1.c b/test cases/common/13 pch/linkwhole/lib1.c
new file mode 100644
index 0000000..b56c17b
--- /dev/null
+++ b/test cases/common/13 pch/linkwhole/lib1.c
@@ -0,0 +1,4 @@
+void func1() {
+ printf("Calling func2.");
+ func2();
+}
diff --git a/test cases/common/13 pch/linkwhole/lib2.c b/test cases/common/13 pch/linkwhole/lib2.c
new file mode 100644
index 0000000..0a13f60
--- /dev/null
+++ b/test cases/common/13 pch/linkwhole/lib2.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+void func2() {
+ const char *cl = GetCommandLineA();
+ printf("Command line was: %s\n", cl);
+}
diff --git a/test cases/common/13 pch/linkwhole/main.c b/test cases/common/13 pch/linkwhole/main.c
new file mode 100644
index 0000000..6615a8b
--- /dev/null
+++ b/test cases/common/13 pch/linkwhole/main.c
@@ -0,0 +1,9 @@
+#include<stdio.h>
+
+void func1();
+
+int main(int argc, char **argv) {
+ printf("Calling func1\n");
+ func1();
+ return 0;
+}
diff --git a/test cases/common/13 pch/linkwhole/meson.build b/test cases/common/13 pch/linkwhole/meson.build
new file mode 100644
index 0000000..dec76ba
--- /dev/null
+++ b/test cases/common/13 pch/linkwhole/meson.build
@@ -0,0 +1,8 @@
+# https://github.com/mesonbuild/meson/issues/10745
+
+l2 = static_library('two', 'lib2.c', c_pch: 'pch2/pch_two.h')
+l1 = static_library('one', 'lib1.c', c_pch: 'pch1/pch_one.h',
+ link_whole: l2)
+
+executable('linkprog', 'main.c',
+ link_with: l1)
diff --git a/test cases/common/13 pch/linkwhole/pch1/pch_one.h b/test cases/common/13 pch/linkwhole/pch1/pch_one.h
new file mode 100644
index 0000000..757c206
--- /dev/null
+++ b/test cases/common/13 pch/linkwhole/pch1/pch_one.h
@@ -0,0 +1,4 @@
+#ifndef PCH_ONE
+#define PCH_ONE
+#include<stdio.h>
+#endif
diff --git a/test cases/common/13 pch/linkwhole/pch2/pch_two.h b/test cases/common/13 pch/linkwhole/pch2/pch_two.h
new file mode 100644
index 0000000..1be0a20
--- /dev/null
+++ b/test cases/common/13 pch/linkwhole/pch2/pch_two.h
@@ -0,0 +1,4 @@
+#ifndef PCH_TWO
+#define PCH_TWO
+#include<windows.h>
+#endif
diff --git a/test cases/common/13 pch/meson.build b/test cases/common/13 pch/meson.build
new file mode 100644
index 0000000..4bb3e1f
--- /dev/null
+++ b/test cases/common/13 pch/meson.build
@@ -0,0 +1,26 @@
+project('pch test', 'c', 'cpp',
+ meson_version: '>= 0.46.0')
+
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+if cc_id == 'pgi'
+ error('MESON_SKIP_TEST: PGI compiler does support PCH, however, PGI cannot tolerate spaces in the --pch_dir path and Meson run_project_tests.py uses spaces in temporary build path names. If this test is run individually with no spaces in build path, it will pass.')
+endif
+
+subdir('c')
+subdir('cpp')
+subdir('generated')
+subdir('userDefined')
+subdir('withIncludeDirectories')
+subdir('withIncludeFile')
+
+if meson.backend() == 'xcode'
+ warning('Xcode backend only supports one precompiled header per target. Skipping "mixed" which has various precompiled headers.')
+else
+ subdir('mixed')
+endif
+
+if cc_id == 'msvc'
+ subdir('linkwhole')
+endif
diff --git a/test cases/common/13 pch/mixed/func.c b/test cases/common/13 pch/mixed/func.c
new file mode 100644
index 0000000..620eca1
--- /dev/null
+++ b/test cases/common/13 pch/mixed/func.c
@@ -0,0 +1,7 @@
+void tmp_func(void) {
+ fprintf(stdout, "This is a function that fails if stdio is not #included.\n");
+}
+
+int cfunc(void) {
+ return 0;
+}
diff --git a/test cases/common/13 pch/mixed/main.cc b/test cases/common/13 pch/mixed/main.cc
new file mode 100644
index 0000000..4321203
--- /dev/null
+++ b/test cases/common/13 pch/mixed/main.cc
@@ -0,0 +1,10 @@
+extern "C" int cfunc();
+
+void func(void) {
+ std::cout << "This is a function that fails to compile if iostream is not included."
+ << std::endl;
+}
+
+int main(void) {
+ return cfunc();
+}
diff --git a/test cases/common/13 pch/mixed/meson.build b/test cases/common/13 pch/mixed/meson.build
new file mode 100644
index 0000000..266e7a5
--- /dev/null
+++ b/test cases/common/13 pch/mixed/meson.build
@@ -0,0 +1,14 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+# PGI compiler only supports PCH for C++
+if cc_id == 'pgi'
+ subdir_done()
+endif
+
+exe = executable(
+ 'prog',
+ files('main.cc', 'func.c'),
+ c_pch : ['pch/func.h'],
+ cpp_pch : ['pch/main.h'],
+)
diff --git a/test cases/common/13 pch/mixed/pch/func.h b/test cases/common/13 pch/mixed/pch/func.h
new file mode 100644
index 0000000..354499a
--- /dev/null
+++ b/test cases/common/13 pch/mixed/pch/func.h
@@ -0,0 +1 @@
+#include<stdio.h>
diff --git a/test cases/common/13 pch/mixed/pch/main.h b/test cases/common/13 pch/mixed/pch/main.h
new file mode 100644
index 0000000..751cc4a
--- /dev/null
+++ b/test cases/common/13 pch/mixed/pch/main.h
@@ -0,0 +1 @@
+#include<iostream>
diff --git a/test cases/common/13 pch/userDefined/meson.build b/test cases/common/13 pch/userDefined/meson.build
new file mode 100644
index 0000000..9b60572
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/meson.build
@@ -0,0 +1,10 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+# User supplied PCH implementation should override the auto
+# generated one. PCH implementations are only supported for
+# msvc and generally should not be used at all. Support for
+# them is only kept for backwards compatibility.
+if cc_id == 'msvc'
+ exe = executable('prog', 'prog.c', c_pch : ['pch/pch.h', 'pch/pch.c'])
+endif
diff --git a/test cases/common/13 pch/userDefined/pch/pch.c b/test cases/common/13 pch/userDefined/pch/pch.c
new file mode 100644
index 0000000..6a97140
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/pch/pch.c
@@ -0,0 +1,5 @@
+#include "pch.h"
+
+int foo(void) {
+ return 0;
+}
diff --git a/test cases/common/13 pch/userDefined/pch/pch.h b/test cases/common/13 pch/userDefined/pch/pch.h
new file mode 100644
index 0000000..5d5f8f0
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/pch/pch.h
@@ -0,0 +1 @@
+int foo();
diff --git a/test cases/common/13 pch/userDefined/prog.c b/test cases/common/13 pch/userDefined/prog.c
new file mode 100644
index 0000000..475131b
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/prog.c
@@ -0,0 +1,8 @@
+// No includes here, they need to come from the PCH
+
+int main(void) {
+ // Method is implemented in pch.c.
+ // This makes sure that we can properly handle user defined
+ // pch implementation files and not only auto-generated ones.
+ return foo();
+}
diff --git a/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h b/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h
new file mode 100644
index 0000000..53c5fdf
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h
@@ -0,0 +1 @@
+#include <stdio.h>
diff --git a/test cases/common/13 pch/withIncludeDirectories/meson.build b/test cases/common/13 pch/withIncludeDirectories/meson.build
new file mode 100644
index 0000000..95f7888
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/meson.build
@@ -0,0 +1,15 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+# PGI compiler only supports PCH for C++
+if cc_id == 'pgi'
+ subdir_done()
+endif
+
+exe = executable('prog', 'prog.c',
+ include_directories: 'include',
+ c_pch : 'pch/prog.h')
diff --git a/test cases/common/13 pch/withIncludeDirectories/pch/prog.h b/test cases/common/13 pch/withIncludeDirectories/pch/prog.h
new file mode 100644
index 0000000..383b2c5
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/pch/prog.h
@@ -0,0 +1 @@
+#include<lib/lib.h>
diff --git a/test cases/common/13 pch/withIncludeDirectories/prog.c b/test cases/common/13 pch/withIncludeDirectories/prog.c
new file mode 100644
index 0000000..4ef2fd8
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/prog.c
@@ -0,0 +1,9 @@
+// No includes here, they need to come from the PCH
+
+void func(void) {
+ fprintf(stdout, "This is a function that fails if stdio is not #included.\n");
+}
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/13 pch/withIncludeFile/meson.build b/test cases/common/13 pch/withIncludeFile/meson.build
new file mode 100644
index 0000000..4fd2322
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeFile/meson.build
@@ -0,0 +1,18 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+if cc.get_argument_syntax() == 'gcc'
+ c_args = ['-include', 'locale.h']
+elif cc.get_argument_syntax() == 'msvc'
+ c_args = ['/FI' + 'locale.h']
+else
+ subdir_done()
+endif
+
+exe = executable('prog', 'prog.c',
+c_args: c_args,
+c_pch : 'pch/prog.h')
diff --git a/test cases/common/13 pch/withIncludeFile/pch/prog.h b/test cases/common/13 pch/withIncludeFile/pch/prog.h
new file mode 100644
index 0000000..c89890a
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeFile/pch/prog.h
@@ -0,0 +1,6 @@
+#ifndef PROG_H
+// Header guards for PCH confuse msvc in some situations.
+// Using them here makes sure we handle this correctly.
+#define PROG_H
+#include<stdio.h>
+#endif
diff --git a/test cases/common/13 pch/withIncludeFile/prog.c b/test cases/common/13 pch/withIncludeFile/prog.c
new file mode 100644
index 0000000..9d495f6
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeFile/prog.c
@@ -0,0 +1,10 @@
+// No includes here, they need to come from the PCH or explicit inclusion
+
+void func(void) {
+ fprintf(stdout, "This is a function that fails if stdio is not #included.\n");
+ setlocale(LC_ALL, ""); /* This will fail if locale.h is not included */
+}
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/130 include order/ctsub/copyfile.py b/test cases/common/130 include order/ctsub/copyfile.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/common/130 include order/ctsub/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/130 include order/ctsub/emptyfile.c b/test cases/common/130 include order/ctsub/emptyfile.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/130 include order/ctsub/emptyfile.c
diff --git a/test cases/common/130 include order/ctsub/main.h b/test cases/common/130 include order/ctsub/main.h
new file mode 100644
index 0000000..9d9acf3
--- /dev/null
+++ b/test cases/common/130 include order/ctsub/main.h
@@ -0,0 +1 @@
+#error "ctsub/main.h included"
diff --git a/test cases/common/130 include order/ctsub/meson.build b/test cases/common/130 include order/ctsub/meson.build
new file mode 100644
index 0000000..a242e07
--- /dev/null
+++ b/test cases/common/130 include order/ctsub/meson.build
@@ -0,0 +1,9 @@
+# https://github.com/mesonbuild/meson/pull/2291
+copy = find_program('copyfile.py')
+configure_file(input : 'main.h',
+ output : 'main.h',
+ command : [copy, '@INPUT@', '@OUTPUT@'])
+ctfile = custom_target('emptyfile',
+ input : 'emptyfile.c',
+ output : 'emptyfile.c',
+ command : [copy, '@INPUT@', '@OUTPUT@'])
diff --git a/test cases/common/130 include order/inc1/hdr.h b/test cases/common/130 include order/inc1/hdr.h
new file mode 100644
index 0000000..9d755a8
--- /dev/null
+++ b/test cases/common/130 include order/inc1/hdr.h
@@ -0,0 +1 @@
+#define SOME_DEFINE 42
diff --git a/test cases/common/130 include order/inc2/hdr.h b/test cases/common/130 include order/inc2/hdr.h
new file mode 100644
index 0000000..2ebcaca
--- /dev/null
+++ b/test cases/common/130 include order/inc2/hdr.h
@@ -0,0 +1 @@
+#undef SOME_DEFINE
diff --git a/test cases/common/130 include order/meson.build b/test cases/common/130 include order/meson.build
new file mode 100644
index 0000000..9f275b8
--- /dev/null
+++ b/test cases/common/130 include order/meson.build
@@ -0,0 +1,36 @@
+project('include order', 'c')
+
+# Test that the order of priority of include paths (from first to last) is:
+#
+# 1. Target's current build directory
+# 2. Target's current source directory
+# 3. Include paths added with the `c_args:` kwarg
+# 4. Include paths added with the `include_directories`: kwarg
+# Within this, the build dir takes precedence over the source dir
+# 5. Include paths added via `include_directories:` of internal deps
+# Within this, the build dir takes precedence over the source dir
+
+# Custom target dir with a built header
+subdir('ctsub')
+# Defines an internal dep
+subdir('sub1')
+# Defines a per-target include path
+subdir('sub2')
+# Directory for `c_args:` include path
+subdir('sub3')
+# The directory where the target resides
+subdir('sub4')
+
+# Test that the order in which internal dependencies are specified is
+# preserved. This is needed especially when subprojects get involved and
+# multiple build-root config.h files exist, and we must be sure that the
+# correct one is found: https://github.com/mesonbuild/meson/issues/1495
+f = executable('somefxe', 'sub4/main.c',
+ dependencies : [correctinc, dep, wronginc])
+
+test('eh', e)
+test('oh', f)
+
+# Test that the order in include_directories() is maintained
+incs = include_directories('inc1', 'inc2')
+executable('ordertest', 'ordertest.c', include_directories: incs)
diff --git a/test cases/common/130 include order/ordertest.c b/test cases/common/130 include order/ordertest.c
new file mode 100644
index 0000000..775e34f
--- /dev/null
+++ b/test cases/common/130 include order/ordertest.c
@@ -0,0 +1,10 @@
+#include "hdr.h"
+
+#if !defined(SOME_DEFINE) || SOME_DEFINE != 42
+#error "Should have picked up hdr.h from inc1/hdr.h"
+#endif
+
+int main(void)
+{
+ return 0;
+}
diff --git a/test cases/common/130 include order/sub1/main.h b/test cases/common/130 include order/sub1/main.h
new file mode 100644
index 0000000..acf4a35
--- /dev/null
+++ b/test cases/common/130 include order/sub1/main.h
@@ -0,0 +1 @@
+#error "sub1/main.h included"
diff --git a/test cases/common/130 include order/sub1/meson.build b/test cases/common/130 include order/sub1/meson.build
new file mode 100644
index 0000000..9672945
--- /dev/null
+++ b/test cases/common/130 include order/sub1/meson.build
@@ -0,0 +1,4 @@
+i = include_directories('.')
+l = shared_library('somelib', 'some.c')
+dep = declare_dependency(link_with : l,
+ include_directories : i)
diff --git a/test cases/common/130 include order/sub1/some.c b/test cases/common/130 include order/sub1/some.c
new file mode 100644
index 0000000..1ab0db4
--- /dev/null
+++ b/test cases/common/130 include order/sub1/some.c
@@ -0,0 +1,6 @@
+#if defined _WIN32 || defined __CYGWIN__
+ __declspec(dllexport)
+#endif
+int somefunc(void) {
+ return 1984;
+}
diff --git a/test cases/common/130 include order/sub1/some.h b/test cases/common/130 include order/sub1/some.h
new file mode 100644
index 0000000..6479492
--- /dev/null
+++ b/test cases/common/130 include order/sub1/some.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllimport)
+#else
+ #define DLL_PUBLIC
+#endif
+
+DLL_PUBLIC
+int somefunc(void);
diff --git a/test cases/common/130 include order/sub2/main.h b/test cases/common/130 include order/sub2/main.h
new file mode 100644
index 0000000..b9c0da9
--- /dev/null
+++ b/test cases/common/130 include order/sub2/main.h
@@ -0,0 +1 @@
+#error "sub2/main.h included"
diff --git a/test cases/common/130 include order/sub2/meson.build b/test cases/common/130 include order/sub2/meson.build
new file mode 100644
index 0000000..b1e6190
--- /dev/null
+++ b/test cases/common/130 include order/sub2/meson.build
@@ -0,0 +1,2 @@
+j = include_directories('.')
+wronginc = declare_dependency(include_directories : j)
diff --git a/test cases/common/130 include order/sub3/main.h b/test cases/common/130 include order/sub3/main.h
new file mode 100644
index 0000000..1ab7231
--- /dev/null
+++ b/test cases/common/130 include order/sub3/main.h
@@ -0,0 +1 @@
+#error "sub3/main.h included"
diff --git a/test cases/common/130 include order/sub3/meson.build b/test cases/common/130 include order/sub3/meson.build
new file mode 100644
index 0000000..0bd3906
--- /dev/null
+++ b/test cases/common/130 include order/sub3/meson.build
@@ -0,0 +1 @@
+sub3 = meson.current_source_dir()
diff --git a/test cases/common/130 include order/sub4/main.c b/test cases/common/130 include order/sub4/main.c
new file mode 100644
index 0000000..89226a4
--- /dev/null
+++ b/test cases/common/130 include order/sub4/main.c
@@ -0,0 +1,8 @@
+/* Use the <> include notation to force searching in include directories */
+#include <main.h>
+
+int main(void) {
+ if (somefunc() == 1984)
+ return 0;
+ return 1;
+}
diff --git a/test cases/common/130 include order/sub4/main.h b/test cases/common/130 include order/sub4/main.h
new file mode 100644
index 0000000..194d7fe
--- /dev/null
+++ b/test cases/common/130 include order/sub4/main.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include "some.h"
diff --git a/test cases/common/130 include order/sub4/meson.build b/test cases/common/130 include order/sub4/meson.build
new file mode 100644
index 0000000..c01edaa
--- /dev/null
+++ b/test cases/common/130 include order/sub4/meson.build
@@ -0,0 +1,6 @@
+e = executable('someexe', 'main.c', ctfile,
+ c_args : ['-I' + sub3],
+ include_directories : j,
+ dependencies : dep)
+
+correctinc = declare_dependency(include_directories : include_directories('.'))
diff --git a/test cases/common/131 override options/four.c b/test cases/common/131 override options/four.c
new file mode 100644
index 0000000..44e344f
--- /dev/null
+++ b/test cases/common/131 override options/four.c
@@ -0,0 +1,9 @@
+int func(void);
+
+static int duplicate_func(void) {
+ return -4;
+}
+
+int main(void) {
+ return duplicate_func() + func();
+}
diff --git a/test cases/common/131 override options/meson.build b/test cases/common/131 override options/meson.build
new file mode 100644
index 0000000..4dd8d79
--- /dev/null
+++ b/test cases/common/131 override options/meson.build
@@ -0,0 +1,6 @@
+project('option override', 'c',
+ default_options : 'unity=on')
+
+executable('mustunity', 'one.c', 'two.c')
+executable('notunity', 'three.c', 'four.c',
+ override_options : ['unity=off'])
diff --git a/test cases/common/131 override options/one.c b/test cases/common/131 override options/one.c
new file mode 100644
index 0000000..6120d48
--- /dev/null
+++ b/test cases/common/131 override options/one.c
@@ -0,0 +1,3 @@
+static int hidden_func(void) {
+ return 0;
+}
diff --git a/test cases/common/131 override options/three.c b/test cases/common/131 override options/three.c
new file mode 100644
index 0000000..094260e
--- /dev/null
+++ b/test cases/common/131 override options/three.c
@@ -0,0 +1,7 @@
+static int duplicate_func(void) {
+ return 4;
+}
+
+int func(void) {
+ return duplicate_func();
+}
diff --git a/test cases/common/131 override options/two.c b/test cases/common/131 override options/two.c
new file mode 100644
index 0000000..0f8048c
--- /dev/null
+++ b/test cases/common/131 override options/two.c
@@ -0,0 +1,6 @@
+/*
+ * Requires a Unity build. Otherwise hidden_func is not specified.
+ */
+int main(void) {
+ return hidden_func();
+}
diff --git a/test cases/common/132 get define/concat.h b/test cases/common/132 get define/concat.h
new file mode 100644
index 0000000..6eb3e5e
--- /dev/null
+++ b/test cases/common/132 get define/concat.h
@@ -0,0 +1,24 @@
+#define __STRINGIFY(x) #x
+#define TEST_STRINGIFY(x) __STRINGIFY(x)
+
+#define TEST_VERSION_MAJOR 6
+#define TEST_VERSION_MINOR 0
+#define TEST_VERSION_BUGFIX 0
+
+#define TEST_VERSION_STR \
+ TEST_STRINGIFY(TEST_VERSION_MAJOR) \
+ "." TEST_STRINGIFY(TEST_VERSION_MINOR) "." TEST_STRINGIFY( \
+ TEST_VERSION_BUGFIX)
+
+#define TEST_CONCAT_1 \
+ "ab" \
+ "cd" \
+ "ef" \
+ ""
+#define TEST_CONCAT_2 1
+#define TEST_CONCAT_3 1 2 3
+#define TEST_CONCAT_4 "ab" 1 "cd"
+#define TEST_CONCAT_5 \
+ "ab\"" \
+ "cd"
+#define TEST_CONCAT_6 "ab\" \"cd"
diff --git a/test cases/common/132 get define/meson.build b/test cases/common/132 get define/meson.build
new file mode 100644
index 0000000..02e5a0c
--- /dev/null
+++ b/test cases/common/132 get define/meson.build
@@ -0,0 +1,111 @@
+project('get define', 'c', 'cpp')
+
+host_system = host_machine.system()
+
+foreach lang : ['c', 'cpp']
+ cc = meson.get_compiler(lang)
+ if host_system == 'linux'
+ d = cc.get_define('__linux__')
+ assert(d == '1', '__linux__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'darwin'
+ d = cc.get_define('__APPLE__')
+ assert(d == '1', '__APPLE__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'windows'
+ d = cc.get_define('_WIN32')
+ assert(d == '1', '_WIN32 value is @0@ instead of 1'.format(d))
+ elif host_system == 'cygwin'
+ d = cc.get_define('__CYGWIN__')
+ assert(d == '1', '__CYGWIN__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'haiku'
+ d = cc.get_define('__HAIKU__')
+ assert(d == '1', '__HAIKU__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'freebsd'
+ # the __FreeBSD__ define will be equal to the major version of the release
+ # (ex, in FreeBSD 11.x, __FreeBSD__ == 11). To make the test robust when
+ # being run on various versions of FreeBSD, just test that the define is
+ # set.
+ d = cc.get_define('__FreeBSD__')
+ assert(d != '', '__FreeBSD__ value is unset')
+ elif host_system == 'dragonfly'
+ d = cc.get_define('__DragonFly__')
+ assert(d == '1', '__DragonFly__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'netbsd'
+ d = cc.get_define('__NetBSD__')
+ assert(d == '1', '__NetBSD__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'openbsd'
+ d = cc.get_define('__OpenBSD__')
+ assert(d == '1', '__OpenBSD__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'gnu'
+ d = cc.get_define('__GNU__')
+ assert(d == '1', '__GNU__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'sunos'
+ d = cc.get_define('__sun__')
+ assert(d == '1', '__sun__ value is @0@ instead of 1'.format(d))
+ else
+ error('Please report a bug and help us improve support for this platform')
+ endif
+
+ if cc.find_library('z', required : false).found()
+ # When a C file containing #include <foo.h> is pre-processed and foo.h is
+ # found in the compiler's default search path, GCC inserts an extra comment
+ # between the delimiter and the define which causes a parsing error.
+ # https://github.com/mesonbuild/meson/issues/1726
+ if host_machine.system() == 'netbsd' or host_machine.system() == 'openbsd'
+ # NetBSD and OpenBSD's zlib don't have a ZLIB_VER_MAJOR, but they do have
+ # a ZLIB_VERSION (which is a string), so check the first non-quote
+ # character of that.
+ ver = cc.get_define('ZLIB_VERSION', prefix : '#include <zlib.h>')[1]
+ assert(ver == '1', 'ZLIB_VERSION (major) value is "@0@" instead of "1"'.format(ver))
+ else
+ ver = cc.get_define('ZLIB_VER_MAJOR', prefix : '#include <zlib.h>')
+ assert(ver == '1', 'ZLIB_VER_MAJOR value is "@0@" instead of "1"'.format(ver))
+ endif
+ endif
+
+ # Check that an undefined value is empty.
+ have = cc.get_define('MESON_FAIL_VALUE')
+ assert(have == '', 'MESON_FAIL_VALUE value is "@0@" instead of ""'.format(have))
+
+ # Check if prefix array works properly and has the expected order
+ have = cc.get_define('MESON_FAIL_VALUE', prefix: ['#define MESON_FAIL_VALUE 1', '#undef MESON_FAIL_VALUE'])
+ assert(have == '', 'MESON_FAIL_VALUE value is "@0@" instead of ""'.format(have))
+
+ have = cc.get_define('MESON_SUCCESS_VALUE', prefix: ['#undef MESON_SUCCESS_VALUE', '#define MESON_SUCCESS_VALUE 1'])
+ assert(have == '1', 'MESON_SUCCESS_VALUE value is "@0@" instead of ""'.format(have))
+
+ # This is used in the test_preprocessor_checks_CPPFLAGS() unit test.
+ have = cc.get_define('MESON_TEST_DEFINE_VALUE')
+ expect = get_option('MESON_TEST_DEFINE_VALUE')
+ assert(have == expect, 'MESON_TEST_DEFINE_VALUE value is "@0@" instead of "@1@"'.format(have, expect))
+
+ run_1665_test = false
+ if meson.is_cross_build()
+ lang_arg = meson.get_cross_property(lang + '_args', '')
+ if lang_arg == '-DMESON_TEST_ISSUE_1665=1'
+ run_1665_test = true
+ endif
+ endif
+
+ if run_1665_test
+ have = cc.get_define('MESON_TEST_ISSUE_1665')
+ assert(have == '1', 'MESON_TEST_ISSUE_1665 value is "@0@" instead of "1"'.format(have))
+ endif
+
+ have = cc.get_define('TEST_VERSION_STR',
+ prefix : '#include <concat.h>', include_directories: include_directories('.'))
+ assert(have == '"6.0.0"', 'TEST_VERSION_STR value is "@0@" instead of ""6.0.0""'.format(have))
+
+ concat_examples = {
+ 'TEST_CONCAT_1': '"abcdef"',
+ 'TEST_CONCAT_2': '1',
+ 'TEST_CONCAT_3': '1 2 3',
+ 'TEST_CONCAT_4': '"ab" 1 "cd"',
+ 'TEST_CONCAT_5': '"ab\"cd"',
+ 'TEST_CONCAT_6': '"ab\" \"cd"',
+ }
+ foreach def,expected : concat_examples
+ have = cc.get_define(def,
+ prefix : '#include <concat.h>', include_directories: include_directories('.'))
+ assert(have == expected, '@0@ value is "@1@" instead of "@2@"'.format(def, have, expected))
+ endforeach
+endforeach
diff --git a/test cases/common/132 get define/meson_options.txt b/test cases/common/132 get define/meson_options.txt
new file mode 100644
index 0000000..7d34a2e
--- /dev/null
+++ b/test cases/common/132 get define/meson_options.txt
@@ -0,0 +1 @@
+option('MESON_TEST_DEFINE_VALUE', type : 'string', value : '')
diff --git a/test cases/common/133 c cpp and asm/main.c b/test cases/common/133 c cpp and asm/main.c
new file mode 100644
index 0000000..293258f
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/main.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int get_retval(void);
+
+int main(void) {
+ printf("C seems to be working.\n");
+ return get_retval();
+}
diff --git a/test cases/common/133 c cpp and asm/main.cpp b/test cases/common/133 c cpp and asm/main.cpp
new file mode 100644
index 0000000..debb97a
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+
+extern "C" {
+ int get_retval(void);
+ int get_cval(void);
+}
+
+int main(void) {
+ std::cout << "C++ seems to be working." << std::endl;
+ return get_retval();
+}
diff --git a/test cases/common/133 c cpp and asm/meson.build b/test cases/common/133 c cpp and asm/meson.build
new file mode 100644
index 0000000..ca820e2
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/meson.build
@@ -0,0 +1,23 @@
+project('c cpp and asm', 'c', 'cpp')
+
+cpu = host_machine.cpu_family()
+cc = meson.get_compiler('c')
+
+supported_cpus = ['arm', 'x86', 'x86_64']
+
+if not supported_cpus.contains(cpu)
+ error('MESON_SKIP_TEST unsupported cpu:' + cpu)
+endif
+
+if meson.get_compiler('c').get_argument_syntax() == 'msvc'
+ error('MESON_SKIP_TEST MSVC can\'t compile assembly')
+endif
+
+if cc.symbols_have_underscore_prefix()
+ add_project_arguments('-DMESON_TEST__UNDERSCORE_SYMBOL', language: 'c')
+endif
+
+test('test-c-asm', executable('c-asm', ['main.c', 'retval-' + cpu + '.S']))
+test('test-cpp-asm', executable('cpp-asm', ['main.cpp', 'retval-' + cpu + '.S']))
+test('test-c-cpp-asm', executable('c-cpp-asm', ['somelib.c', 'main.cpp', 'retval-' + cpu + '.S']))
+test('test-cpp-c-asm', executable('cpp-c-asm', ['main.cpp', 'somelib.c', 'retval-' + cpu + '.S']))
diff --git a/test cases/common/133 c cpp and asm/retval-arm.S b/test cases/common/133 c cpp and asm/retval-arm.S
new file mode 100644
index 0000000..a892362
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/retval-arm.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ mov r0, #0
+ mov pc, lr
diff --git a/test cases/common/133 c cpp and asm/retval-x86.S b/test cases/common/133 c cpp and asm/retval-x86.S
new file mode 100644
index 0000000..3cb0237
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/retval-x86.S
@@ -0,0 +1,12 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+/* Only supported on Linux with GAS */
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retl
diff --git a/test cases/common/133 c cpp and asm/retval-x86_64.S b/test cases/common/133 c cpp and asm/retval-x86_64.S
new file mode 100644
index 0000000..1a5f3eb
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/retval-x86_64.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retq
diff --git a/test cases/common/133 c cpp and asm/somelib.c b/test cases/common/133 c cpp and asm/somelib.c
new file mode 100644
index 0000000..e585b8e
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/somelib.c
@@ -0,0 +1,3 @@
+int get_cval (void) {
+ return 0;
+}
diff --git a/test cases/common/133 c cpp and asm/symbol-underscore.h b/test cases/common/133 c cpp and asm/symbol-underscore.h
new file mode 100644
index 0000000..d0f3ef9
--- /dev/null
+++ b/test cases/common/133 c cpp and asm/symbol-underscore.h
@@ -0,0 +1,5 @@
+#if defined(MESON_TEST__UNDERSCORE_SYMBOL)
+# define SYMBOL_NAME(name) _##name
+#else
+# define SYMBOL_NAME(name) name
+#endif
diff --git a/test cases/common/134 compute int/config.h.in b/test cases/common/134 compute int/config.h.in
new file mode 100644
index 0000000..0de63ab
--- /dev/null
+++ b/test cases/common/134 compute int/config.h.in
@@ -0,0 +1,4 @@
+#define INTSIZE @INTSIZE@
+#define FOOBAR_IN_CONFIG_H @FOOBAR@
+#define MAXINT @MAXINT@
+#define MININT @MININT@
diff --git a/test cases/common/134 compute int/foobar.h b/test cases/common/134 compute int/foobar.h
new file mode 100644
index 0000000..fd3cb5e
--- /dev/null
+++ b/test cases/common/134 compute int/foobar.h
@@ -0,0 +1,6 @@
+#ifndef __FOOBAR_H__
+#define __FOOBAR_H__
+
+#define FOOBAR_IN_FOOBAR_H 10
+
+#endif /*__FOOBAR_H__*/
diff --git a/test cases/common/134 compute int/meson.build b/test cases/common/134 compute int/meson.build
new file mode 100644
index 0000000..89f4746
--- /dev/null
+++ b/test cases/common/134 compute int/meson.build
@@ -0,0 +1,46 @@
+project('compute int', 'c', 'cpp')
+
+inc = include_directories('.')
+
+# Test with C
+cc = meson.get_compiler('c')
+
+intsize = cc.compute_int('sizeof(int)', low : 1, high : 16, guess : 4)
+foobar = cc.compute_int('FOOBAR_IN_FOOBAR_H', prefix : '#include "foobar.h"', include_directories : inc)
+maxint = cc.compute_int('INT_MAX', prefix: '#include <limits.h>')
+minint = cc.compute_int('INT_MIN', prefix: '#include <limits.h>')
+
+# Regression test for the special case -1 that used to fail when cross compiling
+assert(cc.compute_int('-1') == -1, 'compute_int(-1) failed')
+
+cd = configuration_data()
+cd.set('INTSIZE', intsize)
+cd.set('FOOBAR', foobar)
+cd.set('CONFIG', 'config.h')
+cd.set('MAXINT', maxint)
+cd.set('MININT', minint)
+configure_file(input : 'config.h.in', output : 'config.h', configuration : cd)
+s = configure_file(input : 'prog.c.in', output : 'prog.c', configuration : cd)
+
+e = executable('prog', s)
+test('compute int test', e)
+
+# Test with C++
+cpp = meson.get_compiler('cpp')
+
+intsize = cpp.compute_int('sizeof(int)')
+foobar = cpp.compute_int('FOOBAR_IN_FOOBAR_H', prefix : '#include "foobar.h"', include_directories : inc)
+maxint = cpp.compute_int('INT_MAX', prefix: '#include <limits.h>')
+minint = cpp.compute_int('INT_MIN', prefix: '#include <limits.h>')
+
+cdpp = configuration_data()
+cdpp.set('INTSIZE', intsize)
+cdpp.set('FOOBAR', foobar)
+cdpp.set('CONFIG', 'config.hpp')
+cdpp.set('MAXINT', maxint)
+cdpp.set('MININT', minint)
+configure_file(input : 'config.h.in', output : 'config.hpp', configuration : cdpp)
+spp = configure_file(input : 'prog.c.in', output : 'prog.cc', configuration : cdpp)
+
+epp = executable('progpp', spp)
+test('compute int test c++', epp)
diff --git a/test cases/common/134 compute int/prog.c.in b/test cases/common/134 compute int/prog.c.in
new file mode 100644
index 0000000..0983aff
--- /dev/null
+++ b/test cases/common/134 compute int/prog.c.in
@@ -0,0 +1,25 @@
+#include "@CONFIG@"
+#include <stdio.h>
+#include <wchar.h>
+#include <limits.h>
+#include "foobar.h"
+
+int main(void) {
+ if(INTSIZE != sizeof(int)) {
+ fprintf(stderr, "Mismatch: computed int size %d, actual size %d.\n", INTSIZE, (int)sizeof(int));
+ return 1;
+ }
+ if(FOOBAR_IN_CONFIG_H != FOOBAR_IN_FOOBAR_H) {
+ fprintf(stderr, "Mismatch: computed int %d, should be %d.\n", FOOBAR_IN_CONFIG_H, FOOBAR_IN_FOOBAR_H);
+ return 1;
+ }
+ if(MAXINT != INT_MAX) {
+ fprintf(stderr, "Mismatch: computed max int %d, should be %d.\n", MAXINT, INT_MAX);
+ return 1;
+ }
+ if(MININT != INT_MIN) {
+ fprintf(stderr, "Mismatch: computed min int %d, should be %d.\n", MININT, INT_MIN);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/135 custom target object output/meson.build b/test cases/common/135 custom target object output/meson.build
new file mode 100644
index 0000000..ede165b
--- /dev/null
+++ b/test cases/common/135 custom target object output/meson.build
@@ -0,0 +1,16 @@
+project('custom target object output', 'c')
+
+comp = find_program('obj_generator.py')
+
+if host_machine.system() == 'windows'
+ outputname = '@BASENAME@.obj'
+else
+ outputname = '@BASENAME@.o'
+endif
+
+cc = meson.get_compiler('c').cmd_array().get(-1)
+
+subdir('objdir')
+subdir('progdir')
+
+test('objgen', e)
diff --git a/test cases/common/135 custom target object output/obj_generator.py b/test cases/common/135 custom target object output/obj_generator.py
new file mode 100644
index 0000000..a33872a
--- /dev/null
+++ b/test cases/common/135 custom target object output/obj_generator.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+# Mimic a binary that generates an object file (e.g. windres).
+
+import sys, subprocess
+
+if __name__ == '__main__':
+ if len(sys.argv) != 4:
+ print(sys.argv[0], 'compiler input_file output_file')
+ sys.exit(1)
+ compiler = sys.argv[1]
+ ifile = sys.argv[2]
+ ofile = sys.argv[3]
+ if compiler.endswith('cl'):
+ cmd = [compiler, '/nologo', '/MDd', '/Fo' + ofile, '/c', ifile]
+ else:
+ cmd = [compiler, '-c', ifile, '-o', ofile]
+ sys.exit(subprocess.call(cmd))
diff --git a/test cases/common/135 custom target object output/objdir/meson.build b/test cases/common/135 custom target object output/objdir/meson.build
new file mode 100644
index 0000000..0d7f6c2
--- /dev/null
+++ b/test cases/common/135 custom target object output/objdir/meson.build
@@ -0,0 +1,5 @@
+# Generate an object file manually.
+object = custom_target('object',
+ input : 'source.c',
+ output : outputname,
+ command : [comp, cc, '@INPUT@', '@OUTPUT@'])
diff --git a/test cases/common/135 custom target object output/objdir/source.c b/test cases/common/135 custom target object output/objdir/source.c
new file mode 100644
index 0000000..1dc08e1
--- /dev/null
+++ b/test cases/common/135 custom target object output/objdir/source.c
@@ -0,0 +1,3 @@
+int func1_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/135 custom target object output/progdir/meson.build b/test cases/common/135 custom target object output/progdir/meson.build
new file mode 100644
index 0000000..4216c24
--- /dev/null
+++ b/test cases/common/135 custom target object output/progdir/meson.build
@@ -0,0 +1 @@
+e = executable('prog', 'prog.c', object)
diff --git a/test cases/common/135 custom target object output/progdir/prog.c b/test cases/common/135 custom target object output/progdir/prog.c
new file mode 100644
index 0000000..bc3caf3
--- /dev/null
+++ b/test cases/common/135 custom target object output/progdir/prog.c
@@ -0,0 +1,5 @@
+int func1_in_obj(void);
+
+int main(void) {
+ return func1_in_obj();
+}
diff --git a/test cases/common/136 empty build file/meson.build b/test cases/common/136 empty build file/meson.build
new file mode 100644
index 0000000..807c401
--- /dev/null
+++ b/test cases/common/136 empty build file/meson.build
@@ -0,0 +1,2 @@
+project('subdir with empty meson.build test')
+subdir('subdir')
diff --git a/test cases/common/136 empty build file/subdir/meson.build b/test cases/common/136 empty build file/subdir/meson.build
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/136 empty build file/subdir/meson.build
diff --git a/test cases/common/137 whole archive/exe/meson.build b/test cases/common/137 whole archive/exe/meson.build
new file mode 100644
index 0000000..91d298d
--- /dev/null
+++ b/test cases/common/137 whole archive/exe/meson.build
@@ -0,0 +1 @@
+exe = executable('prog', '../prog.c', link_with : sh_func2_linked_func1)
diff --git a/test cases/common/137 whole archive/exe2/meson.build b/test cases/common/137 whole archive/exe2/meson.build
new file mode 100644
index 0000000..9184864
--- /dev/null
+++ b/test cases/common/137 whole archive/exe2/meson.build
@@ -0,0 +1 @@
+exe2 = executable('prog2', '../prog.c', link_with : sh_only_link_whole)
diff --git a/test cases/common/137 whole archive/exe3/meson.build b/test cases/common/137 whole archive/exe3/meson.build
new file mode 100644
index 0000000..82cf57e
--- /dev/null
+++ b/test cases/common/137 whole archive/exe3/meson.build
@@ -0,0 +1 @@
+exe3 = executable('prog3', '../prog.c', link_with : sh_func2_dep_func1)
diff --git a/test cases/common/137 whole archive/exe4/meson.build b/test cases/common/137 whole archive/exe4/meson.build
new file mode 100644
index 0000000..0781250
--- /dev/null
+++ b/test cases/common/137 whole archive/exe4/meson.build
@@ -0,0 +1 @@
+exe4 = executable('prog4', '../prog.c', link_with : sh_func2_transdep_func1)
diff --git a/test cases/common/137 whole archive/func1.c b/test cases/common/137 whole archive/func1.c
new file mode 100644
index 0000000..161c5da
--- /dev/null
+++ b/test cases/common/137 whole archive/func1.c
@@ -0,0 +1,7 @@
+#define BUILDING_DLL
+
+#include<mylib.h>
+
+int func1(void) {
+ return 42;
+}
diff --git a/test cases/common/137 whole archive/func2.c b/test cases/common/137 whole archive/func2.c
new file mode 100644
index 0000000..4fe7150
--- /dev/null
+++ b/test cases/common/137 whole archive/func2.c
@@ -0,0 +1,7 @@
+#define BUILDING_DLL
+
+#include<mylib.h>
+
+int func2(void) {
+ return 42;
+}
diff --git a/test cases/common/137 whole archive/meson.build b/test cases/common/137 whole archive/meson.build
new file mode 100644
index 0000000..d4cbb83
--- /dev/null
+++ b/test cases/common/137 whole archive/meson.build
@@ -0,0 +1,49 @@
+project('whole archive', 'c')
+
+if meson.backend() == 'xcode' or \
+ meson.backend() == 'vs2010' or \
+ meson.backend() == 'vs2012' or \
+ meson.backend() == 'vs2013'
+ error('MESON_SKIP_TEST: whole-archive not supported in Xcode nor pre-VS2015 IDE. Patches welcome.')
+endif
+
+add_project_arguments('-I' + meson.source_root(), language : 'c')
+
+# Test 1: link_whole keeps all symbols
+# Make static func1
+subdir('st_func1')
+# Make shared func2 linking whole func1 archive
+subdir('sh_func2_linked_func1')
+# Link exe with shared library only
+subdir('exe')
+# Test that both func1 and func2 are accessible from shared library
+test('prog', exe)
+
+# Test 2: link_whole can be used instead of source list, see #2180
+# Make static func2
+subdir('st_func2')
+# Link both func1 and func2 into same shared library
+# which does not have any sources other than 2 static libraries
+subdir('sh_only_link_whole')
+# Link exe2 with shared library only
+subdir('exe2')
+# Test that both func1 and func2 are accessible from shared library
+test('prog2', exe2)
+
+# Test 3: link_whole can be used in declare_dependency()
+func1_dep = declare_dependency(link_whole : [st_func1])
+# Use dependency to link func1 into shared library
+subdir('sh_func2_dep_func1')
+# Link exe3 with shared library
+subdir('exe3')
+# Test that both func1 and func2 are accessible from shared library
+test('prog3', exe3)
+
+# Test 4: link_whole can be used in transitive declare_dependency()
+func1_trans_dep = declare_dependency(dependencies : func1_dep)
+# Use transitive dependency to link func1 into shared library
+subdir('sh_func2_transdep_func1')
+# Link exe4 with shared library
+subdir('exe4')
+# Test that both func1 and func2 are accessible from shared library
+test('prog4', exe4)
diff --git a/test cases/common/137 whole archive/mylib.h b/test cases/common/137 whole archive/mylib.h
new file mode 100644
index 0000000..79ce585
--- /dev/null
+++ b/test cases/common/137 whole archive/mylib.h
@@ -0,0 +1,21 @@
+#pragma once
+
+/* Both funcs here for simplicity. */
+
+#if defined _WIN32 || defined __CYGWIN__
+#if defined BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #define DLL_PUBLIC __declspec(dllimport)
+#endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func1(void);
+int DLL_PUBLIC func2(void);
diff --git a/test cases/common/137 whole archive/prog.c b/test cases/common/137 whole archive/prog.c
new file mode 100644
index 0000000..1f553e5
--- /dev/null
+++ b/test cases/common/137 whole archive/prog.c
@@ -0,0 +1,5 @@
+#include<mylib.h>
+
+int main(void) {
+ return func1() - func2();
+}
diff --git a/test cases/common/137 whole archive/sh_func2_dep_func1/meson.build b/test cases/common/137 whole archive/sh_func2_dep_func1/meson.build
new file mode 100644
index 0000000..92baca6
--- /dev/null
+++ b/test cases/common/137 whole archive/sh_func2_dep_func1/meson.build
@@ -0,0 +1,4 @@
+# Same as sh_func2_linked_func1, # func2.c does not depend on func1(),
+# so without link_whole compiler would throw func1() away.
+# This is the same version of the test with a dependency object instead.
+sh_func2_dep_func1 = shared_library('sh_func2_dep_func1', '../func2.c', dependencies : func1_dep)
diff --git a/test cases/common/137 whole archive/sh_func2_linked_func1/meson.build b/test cases/common/137 whole archive/sh_func2_linked_func1/meson.build
new file mode 100644
index 0000000..2858f65
--- /dev/null
+++ b/test cases/common/137 whole archive/sh_func2_linked_func1/meson.build
@@ -0,0 +1,3 @@
+# Nothing in func2.c uses func1, so the linker would throw it
+# away and thus linking the exe would fail.
+sh_func2_linked_func1 = shared_library('sh_func2_linked_func1', '../func2.c', link_whole : st_func1)
diff --git a/test cases/common/137 whole archive/sh_func2_transdep_func1/meson.build b/test cases/common/137 whole archive/sh_func2_transdep_func1/meson.build
new file mode 100644
index 0000000..0703077
--- /dev/null
+++ b/test cases/common/137 whole archive/sh_func2_transdep_func1/meson.build
@@ -0,0 +1,6 @@
+# Same as sh_func2_dep_func1 but dependency is transitive.
+# func2.c does not have any reference to func1() so without link_whole compiler
+# should throw func1() out.
+sh_func2_transdep_func1 = shared_library(
+ 'sh_func2_transdep_func1', '../func2.c',
+ dependencies : func1_trans_dep)
diff --git a/test cases/common/137 whole archive/sh_only_link_whole/meson.build b/test cases/common/137 whole archive/sh_only_link_whole/meson.build
new file mode 100644
index 0000000..64baabd
--- /dev/null
+++ b/test cases/common/137 whole archive/sh_only_link_whole/meson.build
@@ -0,0 +1 @@
+sh_only_link_whole = shared_library('sh_only_link_whole', link_whole : [st_func1, st_func2])
diff --git a/test cases/common/137 whole archive/st_func1/meson.build b/test cases/common/137 whole archive/st_func1/meson.build
new file mode 100644
index 0000000..c84d781
--- /dev/null
+++ b/test cases/common/137 whole archive/st_func1/meson.build
@@ -0,0 +1 @@
+st_func1 = static_library('st_func1', '../func1.c')
diff --git a/test cases/common/137 whole archive/st_func2/meson.build b/test cases/common/137 whole archive/st_func2/meson.build
new file mode 100644
index 0000000..2732f96
--- /dev/null
+++ b/test cases/common/137 whole archive/st_func2/meson.build
@@ -0,0 +1 @@
+st_func2 = static_library('st_func2', '../func2.c')
diff --git a/test cases/common/138 C and CPP link/dummy.c b/test cases/common/138 C and CPP link/dummy.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/138 C and CPP link/dummy.c
diff --git a/test cases/common/138 C and CPP link/foo.c b/test cases/common/138 C and CPP link/foo.c
new file mode 100644
index 0000000..77c7e39
--- /dev/null
+++ b/test cases/common/138 C and CPP link/foo.c
@@ -0,0 +1,19 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "foo.h"
+
+int forty_two(void) {
+ return 42;
+}
diff --git a/test cases/common/138 C and CPP link/foo.cpp b/test cases/common/138 C and CPP link/foo.cpp
new file mode 100644
index 0000000..9db7fb2
--- /dev/null
+++ b/test cases/common/138 C and CPP link/foo.cpp
@@ -0,0 +1,34 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <vector>
+
+const int cnums[] = {0, 61};
+
+/* Provided by foobar.c */
+extern "C" int get_number_index (void);
+
+template<typename T, int N>
+std::vector<T> makeVector(const T (&data)[N])
+{
+ return std::vector<T>(data, data+N);
+}
+
+namespace {
+ std::vector<int> numbers = makeVector(cnums);
+}
+
+extern "C" int six_one(void) {
+ return numbers[get_number_index ()];
+}
diff --git a/test cases/common/138 C and CPP link/foo.h b/test cases/common/138 C and CPP link/foo.h
new file mode 100644
index 0000000..1ed8ce9
--- /dev/null
+++ b/test cases/common/138 C and CPP link/foo.h
@@ -0,0 +1,16 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+int forty_two(void);
diff --git a/test cases/common/138 C and CPP link/foo.hpp b/test cases/common/138 C and CPP link/foo.hpp
new file mode 100644
index 0000000..e47f01d
--- /dev/null
+++ b/test cases/common/138 C and CPP link/foo.hpp
@@ -0,0 +1,24 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int six_one(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test cases/common/138 C and CPP link/foobar.c b/test cases/common/138 C and CPP link/foobar.c
new file mode 100644
index 0000000..27928bf
--- /dev/null
+++ b/test cases/common/138 C and CPP link/foobar.c
@@ -0,0 +1,27 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "foo.h"
+#include "foo.hpp"
+#include "foobar.h"
+
+int get_number_index (void) {
+ return 1;
+}
+
+void mynumbers(int nums[]) {
+ nums[0] = forty_two();
+ nums[1] = six_one();
+}
diff --git a/test cases/common/138 C and CPP link/foobar.h b/test cases/common/138 C and CPP link/foobar.h
new file mode 100644
index 0000000..6dcb096
--- /dev/null
+++ b/test cases/common/138 C and CPP link/foobar.h
@@ -0,0 +1,16 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+void mynumbers(int nums[]);
diff --git a/test cases/common/138 C and CPP link/meson.build b/test cases/common/138 C and CPP link/meson.build
new file mode 100644
index 0000000..32d1843
--- /dev/null
+++ b/test cases/common/138 C and CPP link/meson.build
@@ -0,0 +1,133 @@
+# Copyright © 2017 Dylan Baker
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('C and C++ static link test', ['c', 'cpp'])
+
+if meson.backend() == 'xcode'
+ error('''MESON_SKIP_TEST: overriding link language is not supported in Xcode.
+
+If you really need this, then patches are welcome. The only known way is
+to create a dummy C++ file in the meson-private directory and adding
+that to the target's source list when needed. The primitives exist
+but may need some tweaking. Grep for language_stdlib_only_link_flags to find
+where this is handled in other backends.''')
+endif
+
+# Verify that adding link arguments works.
+add_global_link_arguments('', language : 'c')
+add_project_link_arguments('', language : 'c')
+
+libc = static_library('cfoo', ['foo.c', 'foo.h'])
+
+# Test that linking C libs to external static C++ libs uses the C++ linker
+# Since we can't depend on the test system to provide this, we create one
+# ourselves at configure time and then 'find' it with cxx.find_library().
+cxx = meson.get_compiler('cpp')
+
+if cxx.get_argument_syntax() == 'msvc'
+ if cxx.get_id() == 'msvc'
+ static_linker = find_program('lib')
+ elif cxx.get_id() == 'clang-cl'
+ static_linker = find_program('llvm-lib')
+ elif cxx.get_id() == 'intel-cl'
+ static_linker = find_program('xilib')
+ else
+ error('unable to determine static linker to use with this compiler')
+ endif
+ compile_cmd = ['/c', '@INPUT@', '/Fo@OUTPUT@']
+ stlib_cmd = [static_linker, '/OUT:@OUTPUT@', '@INPUT@']
+else
+ picflag = []
+ if not ['darwin', 'windows'].contains(host_machine.system())
+ picflag = ['-fPIC']
+ endif
+ compile_cmd = ['-c', picflag, '@INPUT@', '-o', '@OUTPUT@']
+ stlib_cmd = ['ar', 'csr', '@OUTPUT@', '@INPUT@']
+endif
+
+foo_cpp_o = configure_file(
+ input : 'foo.cpp',
+ output : 'foo.cpp.o',
+ command : cxx.cmd_array() + compile_cmd)
+
+configure_file(
+ input : foo_cpp_o,
+ output : 'libstcppext.a',
+ command : stlib_cmd)
+
+libstcppext = cxx.find_library('stcppext', dirs : meson.current_build_dir())
+lib_type_name = libstcppext.type_name()
+assert(lib_type_name == 'library', 'type name is ' + lib_type_name)
+
+libfooext = shared_library(
+ 'fooext',
+ ['foobar.c', 'foobar.h'],
+ link_with : libc,
+ dependencies : libstcppext,
+)
+
+# Test that linking C libs to internal static C++ libs uses the C++ linker
+libcpp = static_library('cppfoo', ['foo.cpp', 'foo.hpp'])
+
+libfoo = shared_library(
+ 'foo',
+ ['foobar.c', 'foobar.h'],
+ link_with : [libc, libcpp],
+)
+
+# Test that link_whole is also honored
+#
+# VS2010 lacks the /WHOLEARCHIVE option that later versions of MSVC support, so
+# don't run this tests on that backend.
+if not (cxx.get_id() == 'msvc' and cxx.version().version_compare('<19'))
+ libfoowhole = shared_library(
+ 'foowhole',
+ ['foobar.c', 'foobar.h'],
+ link_whole : [libc, libcpp],
+ )
+endif
+
+# Test sublinking (linking C and C++, then linking that to C)
+libfoo_static = static_library(
+ 'foo_static',
+ ['foobar.c', 'foobar.h'],
+ link_with : [libc, libcpp],
+)
+
+libsub = shared_library(
+ 'sub',
+ ['sub.c', 'sub.h'],
+ link_with : libfoo_static,
+)
+
+if not (cxx.get_id() == 'msvc' and cxx.version().version_compare('<19'))
+ libsubwhole = shared_library(
+ 'subwhole',
+ ['sub.c', 'sub.h'],
+ link_whole : libfoo_static,
+ )
+endif
+
+# Test that it really is recursive
+libsub_static = static_library(
+ 'sub_static',
+ ['sub.c', 'sub.h'],
+ link_with : libfoo_static,
+)
+
+libsubsub = shared_library(
+ 'subsub',
+ ['dummy.c'],
+ link_with : libsub_static,
+)
diff --git a/test cases/common/138 C and CPP link/sub.c b/test cases/common/138 C and CPP link/sub.c
new file mode 100644
index 0000000..7c078f8
--- /dev/null
+++ b/test cases/common/138 C and CPP link/sub.c
@@ -0,0 +1,19 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "sub.h"
+
+float a_half(void) {
+ return .5;
+}
diff --git a/test cases/common/138 C and CPP link/sub.h b/test cases/common/138 C and CPP link/sub.h
new file mode 100644
index 0000000..5b02e17
--- /dev/null
+++ b/test cases/common/138 C and CPP link/sub.h
@@ -0,0 +1,16 @@
+/* Copyright © 2017 Dylan Baker
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+float a_half(void);
diff --git a/test cases/common/139 mesonintrospect from scripts/check_env.py b/test cases/common/139 mesonintrospect from scripts/check_env.py
new file mode 100644
index 0000000..61de546
--- /dev/null
+++ b/test cases/common/139 mesonintrospect from scripts/check_env.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import shlex
+
+do_print = False
+
+if len(sys.argv) > 1:
+ do_print = bool(sys.argv[1])
+
+if 'MESONINTROSPECT' not in os.environ:
+ raise RuntimeError('MESONINTROSPECT not found')
+
+mesonintrospect = os.environ['MESONINTROSPECT']
+
+introspect_arr = shlex.split(mesonintrospect)
+
+# print(mesonintrospect)
+# print(introspect_arr)
+
+some_executable = introspect_arr[0]
+
+if not os.path.isfile(some_executable):
+ raise RuntimeError(f'{mesonintrospect!r} does not exist')
+
+if do_print:
+ print(some_executable, end='')
diff --git a/test cases/common/139 mesonintrospect from scripts/check_introspection.py b/test cases/common/139 mesonintrospect from scripts/check_introspection.py
new file mode 100644
index 0000000..851a415
--- /dev/null
+++ b/test cases/common/139 mesonintrospect from scripts/check_introspection.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+import os
+import shlex
+import subprocess
+
+
+if 'MESONINTROSPECT' not in os.environ:
+ raise RuntimeError('MESONINTROSPECT not found')
+if 'MESON_BUILD_ROOT' not in os.environ:
+ raise RuntimeError('MESON_BUILD_ROOT not found')
+
+mesonintrospect = os.environ['MESONINTROSPECT']
+introspect_arr = shlex.split(mesonintrospect)
+
+buildroot = os.environ['MESON_BUILD_ROOT']
+
+subprocess.check_output([*introspect_arr, '--all', buildroot])
diff --git a/test cases/common/139 mesonintrospect from scripts/meson.build b/test cases/common/139 mesonintrospect from scripts/meson.build
new file mode 100644
index 0000000..7db4be4
--- /dev/null
+++ b/test cases/common/139 mesonintrospect from scripts/meson.build
@@ -0,0 +1,14 @@
+project('mesonintrospect from scripts')
+
+python = import('python3').find_python()
+
+ret = run_command(python, ['check_env.py', '1'], check: false)
+if ret.returncode() == 0
+ find_program(ret.stdout())
+else
+ message(ret.stdout())
+ message(ret.stderr())
+endif
+
+meson.add_postconf_script('check_introspection.py')
+meson.add_install_script('check_env.py')
diff --git a/test cases/common/14 configure file/basename.py b/test cases/common/14 configure file/basename.py
new file mode 100644
index 0000000..d2c8662
--- /dev/null
+++ b/test cases/common/14 configure file/basename.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+
+import sys
+import argparse
+import os
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('text', nargs='*', type=str)
+ args = parser.parse_args()
+
+ text = args.text if isinstance(args.text, list) else [args.text]
+
+ output = ''
+ for t in text:
+ t = os.path.basename(t)
+
+ if not output:
+ output += t
+ else:
+ output += ' ' + t
+
+ output += '\n'
+
+ sys.stdout.write(output)
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/test cases/common/14 configure file/check_file.py b/test cases/common/14 configure file/check_file.py
new file mode 100644
index 0000000..7d96b2a
--- /dev/null
+++ b/test cases/common/14 configure file/check_file.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+def permit_osx_workaround(m1, m2):
+ import platform
+ if platform.system().lower() != 'darwin':
+ return False
+ if m2 % 10000 != 0:
+ return False
+ if m1//10000 != m2//10000:
+ return False
+ return True
+
+if len(sys.argv) == 2:
+ assert os.path.exists(sys.argv[1])
+elif len(sys.argv) == 3:
+ f1 = sys.argv[1]
+ f2 = sys.argv[2]
+ m1 = os.stat(f1).st_mtime_ns
+ m2 = os.stat(f2).st_mtime_ns
+ # Compare only os.stat()
+ if m1 != m2:
+ # Under macOS the lower four digits sometimes get assigned
+ # zero, even though shutil.copy2 should preserve metadata.
+ # Just have to accept it, I guess.
+ if not permit_osx_workaround(m1, m2):
+ raise RuntimeError(f'mtime of {f1!r} ({m1!r}) != mtime of {f2!r} ({m2!r})')
+ import filecmp
+ if not filecmp.cmp(f1, f2):
+ raise RuntimeError(f'{f1!r} != {f2!r}')
+else:
+ raise AssertionError
diff --git a/test cases/common/14 configure file/check_inputs.py b/test cases/common/14 configure file/check_inputs.py
new file mode 100644
index 0000000..1faa8ba
--- /dev/null
+++ b/test cases/common/14 configure file/check_inputs.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import sys
+from pathlib import Path
+
+files = [Path(f) for f in sys.argv[1:]]
+names = [f.name for f in files]
+
+assert names == ['check_inputs.txt', 'prog.c', 'prog.c', 'prog2.c', 'prog4.c', 'prog5.c']
+for f in files[1:]:
+ assert f.exists()
+
+with files[0].open('w') as ofile:
+ ofile.write("#define ZERO_RESULT 0\n")
diff --git a/test cases/common/14 configure file/config.h b/test cases/common/14 configure file/config.h
new file mode 100644
index 0000000..e85b634
--- /dev/null
+++ b/test cases/common/14 configure file/config.h
@@ -0,0 +1 @@
+#error "This file should not be included. Build dir must become before source dir in search order"
diff --git a/test cases/common/14 configure file/config.h.in b/test cases/common/14 configure file/config.h.in
new file mode 100644
index 0000000..14a1558
--- /dev/null
+++ b/test cases/common/14 configure file/config.h.in
@@ -0,0 +1,5 @@
+#define MESSAGE "@var@"
+#define OTHER "@other@" "@second@" "@empty@"
+
+#mesondefine BE_TRUE
+#mesondefine SHOULD_BE_UNDEF
diff --git a/test cases/common/14 configure file/config4a.h.in b/test cases/common/14 configure file/config4a.h.in
new file mode 100644
index 0000000..aafd195
--- /dev/null
+++ b/test cases/common/14 configure file/config4a.h.in
@@ -0,0 +1,2 @@
+/* Dummy file */
+#define RESULTA @ZERO@
diff --git a/test cases/common/14 configure file/config4b.h.in b/test cases/common/14 configure file/config4b.h.in
new file mode 100644
index 0000000..3408bab
--- /dev/null
+++ b/test cases/common/14 configure file/config4b.h.in
@@ -0,0 +1,2 @@
+/* Dummy file */
+#define RESULTB @ZERO@
diff --git a/test cases/common/14 configure file/config5.h.in b/test cases/common/14 configure file/config5.h.in
new file mode 100644
index 0000000..323bec6
--- /dev/null
+++ b/test cases/common/14 configure file/config5.h.in
@@ -0,0 +1 @@
+#define MESSAGE "@var@"
diff --git a/test cases/common/14 configure file/config6.h.in b/test cases/common/14 configure file/config6.h.in
new file mode 100644
index 0000000..9719f87
--- /dev/null
+++ b/test cases/common/14 configure file/config6.h.in
@@ -0,0 +1,19 @@
+/* No escape */
+#define MESSAGE1 "@var1@"
+
+/* Single escape means no replace */
+#define MESSAGE2 "\@var1@"
+
+/* Replace pairs of escapes before '@' or '\@' with escape characters
+ * (note we have to double number of pairs due to C string escaping)
+ */
+#define MESSAGE3 "\\\\@var1@"
+
+/* Pairs of escapes and then single escape to avoid replace */
+#define MESSAGE4 "\\\\\@var1@"
+
+/* Check escaped variable does not overlap following variable */
+#define MESSAGE5 "\@var1@var2@"
+
+/* Check escape character outside variables */
+#define MESSAGE6 "\\ @ \@ \\\\@ \\\\\@"
diff --git a/test cases/common/14 configure file/config7.h.in b/test cases/common/14 configure file/config7.h.in
new file mode 100644
index 0000000..edd0bb3
--- /dev/null
+++ b/test cases/common/14 configure file/config7.h.in
@@ -0,0 +1,16 @@
+/* No escape */
+#define MESSAGE1 "${var1}"
+
+/* Single escape means no replace */
+#define MESSAGE2 "\${var1}"
+
+/* Replace pairs of escapes before '@' or '\@' with escape characters
+ * (note we have to double number of pairs due to C string escaping)
+ */
+#define MESSAGE3 "\\\\${var1}"
+
+/* Pairs of escapes and then single escape to avoid replace */
+#define MESSAGE4 "\\\\\${var1}"
+
+/* Check escape character outside variables */
+#define MESSAGE5 "\\ ${ \${ \\\\${ \\\\\${"
diff --git a/test cases/common/14 configure file/config8.h.in b/test cases/common/14 configure file/config8.h.in
new file mode 100644
index 0000000..b854ea0
--- /dev/null
+++ b/test cases/common/14 configure file/config8.h.in
@@ -0,0 +1,3 @@
+#define MESSAGE "@var@"
+
+#define "non isolatin1 char Ä fails decode with utf-8"
diff --git a/test cases/common/14 configure file/depfile b/test cases/common/14 configure file/depfile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/14 configure file/depfile
diff --git a/test cases/common/14 configure file/differentafterbasename1.in b/test cases/common/14 configure file/differentafterbasename1.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/14 configure file/differentafterbasename1.in
diff --git a/test cases/common/14 configure file/differentafterbasename2.in b/test cases/common/14 configure file/differentafterbasename2.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/14 configure file/differentafterbasename2.in
diff --git a/test cases/common/14 configure file/dummy.dat b/test cases/common/14 configure file/dummy.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/14 configure file/dummy.dat
diff --git a/test cases/common/14 configure file/dumpprog.c b/test cases/common/14 configure file/dumpprog.c
new file mode 100644
index 0000000..9f63b23
--- /dev/null
+++ b/test cases/common/14 configure file/dumpprog.c
@@ -0,0 +1,52 @@
+#define SHOULD_BE_UNDEFINED 1
+
+#include"config3.h"
+#include<string.h>
+#include<stdio.h>
+
+#ifdef SHOULD_BE_UNDEFINED
+#error Token did not get undefined.
+#endif
+
+#ifndef SHOULD_BE_DEFINED
+#error Token did not get defined
+#endif
+
+#define stringify(s) str(s)
+#define str(s) #s
+
+int main(void) {
+#if !(SHOULD_BE_UNQUOTED_STRING == string)
+ printf("String token (unquoted) defined wrong.\n");
+ return 1;
+#endif
+ if(strcmp(SHOULD_BE_STRING, "string") != 0) {
+ printf("String token defined wrong.\n");
+ return 1;
+ }
+ if(strcmp(SHOULD_BE_STRING2, "A \"B\" C") != 0) {
+ printf("String token 2 defined wrong.\n");
+ return 1;
+ }
+ if(strcmp(SHOULD_BE_STRING3, "A \"\" C") != 0) {
+ printf("String token 3 defined wrong.\n");
+ return 1;
+ }
+ if(strcmp(SHOULD_BE_STRING4, "A \" C") != 0) {
+ printf("String token 4 defined wrong.\n");
+ return 1;
+ }
+ if(SHOULD_BE_ONE != 1) {
+ printf("One defined incorrectly.\n");
+ return 1;
+ }
+ if(SHOULD_BE_ZERO != 0) {
+ printf("Zero defined incorrectly.\n");
+ return 1;
+ }
+ if(strcmp(SHOULD_BE_QUOTED_ONE, "1") != 0) {
+ printf("Quoted number defined incorrectly.\n");
+ return 1;
+ }
+ SHOULD_BE_RETURN 0;
+}
diff --git a/test cases/common/14 configure file/file_contains.py b/test cases/common/14 configure file/file_contains.py
new file mode 100644
index 0000000..409f09c
--- /dev/null
+++ b/test cases/common/14 configure file/file_contains.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+
+import sys
+import argparse
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('file', nargs=1, type=str)
+ parser.add_argument('text', nargs=1, type=str)
+ args = parser.parse_args()
+
+ text = args.text[0]
+
+ with open(args.file[0], encoding='utf-8') as f:
+ for line in f:
+ if line.strip() == text:
+ return 0
+
+ return 1
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/test cases/common/14 configure file/generator-deps.py b/test cases/common/14 configure file/generator-deps.py
new file mode 100755
index 0000000..cca253c
--- /dev/null
+++ b/test cases/common/14 configure file/generator-deps.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+import sys, os
+from pathlib import Path
+
+if len(sys.argv) != 3:
+ print("Wrong amount of parameters.")
+
+build_dir = Path(os.environ['MESON_BUILD_ROOT'])
+subdir = Path(os.environ['MESON_SUBDIR'])
+outputf = Path(sys.argv[1])
+
+with outputf.open('w') as ofile:
+ ofile.write("#define ZERO_RESULT 0\n")
+
+depf = Path(sys.argv[2])
+if not depf.exists():
+ with depf.open('w') as ofile:
+ ofile.write(f"{outputf.name}: depfile\n")
diff --git a/test cases/common/14 configure file/generator-without-input-file.py b/test cases/common/14 configure file/generator-without-input-file.py
new file mode 100755
index 0000000..2ee059e
--- /dev/null
+++ b/test cases/common/14 configure file/generator-without-input-file.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import sys, os
+from pathlib import Path
+
+if len(sys.argv) != 2:
+ print("Wrong amount of parameters.")
+
+build_dir = Path(os.environ['MESON_BUILD_ROOT'])
+subdir = Path(os.environ['MESON_SUBDIR'])
+outputf = Path(sys.argv[1])
+
+with outputf.open('w') as ofile:
+ ofile.write("#define ZERO_RESULT 0\n")
diff --git a/test cases/common/14 configure file/generator.py b/test cases/common/14 configure file/generator.py
new file mode 100755
index 0000000..832a7b8
--- /dev/null
+++ b/test cases/common/14 configure file/generator.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+
+import sys, os
+from pathlib import Path
+
+if len(sys.argv) != 3:
+ print("Wrong amount of parameters.")
+
+build_dir = Path(os.environ['MESON_BUILD_ROOT'])
+subdir = Path(os.environ['MESON_SUBDIR'])
+inputf = Path(sys.argv[1])
+outputf = Path(sys.argv[2])
+
+assert inputf.exists()
+
+with outputf.open('w') as ofile:
+ ofile.write("#define ZERO_RESULT 0\n")
diff --git a/test cases/common/14 configure file/invalid-utf8.bin.in b/test cases/common/14 configure file/invalid-utf8.bin.in
new file mode 100644
index 0000000..98e9ed9
--- /dev/null
+++ b/test cases/common/14 configure file/invalid-utf8.bin.in
Binary files differ
diff --git a/test cases/common/14 configure file/meson.build b/test cases/common/14 configure file/meson.build
new file mode 100644
index 0000000..569dd09
--- /dev/null
+++ b/test cases/common/14 configure file/meson.build
@@ -0,0 +1,330 @@
+project('configure file test', 'c', meson_version: '>=0.63.0')
+
+fs = import('fs')
+
+conf = configuration_data()
+
+conf.set('var', 'mystring')
+conf.set('other', 'string 2')
+conf.set('second', ' bonus')
+conf.set('BE_TRUE', true)
+
+assert(conf.get('var') == 'mystring', 'Get function is not working.')
+assert(conf.get('var', 'default') == 'mystring', 'Get function is not working.')
+assert(conf.get('notthere', 'default') == 'default', 'Default value getting is not working.')
+assert(conf.keys() == ['BE_TRUE', 'other', 'second', 'var'], 'Keys function is not working')
+
+cfile = configure_file(input : 'config.h.in',
+ output : 'config.h',
+ configuration : conf)
+
+e = executable('inctest', 'prog.c',
+# Note that you should NOT do this. Don't add generated headers here
+# This tests that we do the right thing even if people add in conf files
+# to their sources.
+ cfile)
+test('inctest', e)
+
+# Test if we can also pass files() as input
+configure_file(input : files('config.h.in'),
+ output : 'config2.h',
+ configuration : conf)
+
+# Now generate a header file with an external script.
+genprog = import('python3').find_python()
+scriptfile = '@0@/generator.py'.format(meson.current_source_dir())
+ifile = '@0@/dummy.dat'.format(meson.current_source_dir())
+ofile = '@0@/config2.h'.format(meson.current_build_dir())
+
+check_file = find_program('check_file.py')
+# Configure in source root with command and absolute paths
+outf = configure_file(input : 'dummy.dat',
+ output : 'config2.h',
+ command : [genprog, scriptfile, ifile, ofile],
+ install_dir : 'share/appdir')
+ret = run_command(check_file, outf, check: false)
+if ret.returncode() != 0
+ error('Error running command: @0@\n@1@'.format(ret.stdout(), ret.stderr()))
+endif
+
+# Same again as before, but an input file should not be required in
+# this case where we use a command/script to generate the output file.
+genscript2b = '@0@/generator-without-input-file.py'.format(meson.current_source_dir())
+ofile2b = '@0@/config2b.h'.format(meson.current_build_dir())
+outf = configure_file(
+ output : 'config2b.h',
+ command : [genprog, genscript2b, ofile2b],
+ install_dir : 'share/appdir')
+ret = run_command(check_file, outf, check: false)
+if ret.returncode() != 0
+ error('Error running command: @0@\n@1@'.format(ret.stdout(), ret.stderr()))
+endif
+
+genscript2deps = '@0@/generator-deps.py'.format(meson.current_source_dir())
+ofile2deps = '@0@/config2deps.h'.format(meson.current_build_dir())
+outf = configure_file(
+ output : 'config2deps.h',
+ depfile : 'depfile.d',
+ command : [genprog, genscript2deps, ofile2deps, '@DEPFILE@'])
+ret = run_command(check_file, outf, check: false)
+if ret.returncode() != 0
+ error('Error running command: @0@\n@1@'.format(ret.stdout(), ret.stderr()))
+endif
+
+found_script = find_program('generator.py')
+# More configure_file tests in here
+subdir('subdir')
+
+test('inctest2', executable('prog2', 'prog2.c'))
+
+# Generate a conf file without an input file.
+
+dump = configuration_data()
+dump.set_quoted('SHOULD_BE_STRING', 'string', description : 'A string')
+dump.set_quoted('SHOULD_BE_STRING2', 'A "B" C')
+dump.set_quoted('SHOULD_BE_STRING3', 'A "" C')
+dump.set_quoted('SHOULD_BE_STRING4', 'A " C')
+dump.set('SHOULD_BE_RETURN', 'return')
+dump.set('SHOULD_BE_DEFINED', true)
+dump.set('SHOULD_BE_UNDEFINED', false)
+dump.set('SHOULD_BE_ONE', 1)
+dump.set('SHOULD_BE_ZERO', 0, description : 'Absolutely zero')
+dump.set('SHOULD_BE_QUOTED_ONE', '"1"')
+
+dump.set_quoted('INTEGER_AS_STRING', '12')
+if dump.get_unquoted('INTEGER_AS_STRING').to_int() == 12
+ dump.set('SHOULD_BE_UNQUOTED_STRING', dump.get_unquoted('SHOULD_BE_STRING'))
+endif
+
+configure_file(output : 'config3.h',
+ configuration : dump)
+
+test('Configless.', executable('dumpprog', 'dumpprog.c'))
+
+
+# Config file generation in a loop with @BASENAME@ substitution
+dump = configuration_data()
+dump.set('ZERO', 0)
+config_templates = files(['config4a.h.in', 'config4b.h.in'])
+foreach config_template : config_templates
+ configure_file(input : config_template, output : '@BASENAME@', configuration : dump)
+endforeach
+
+test('Substituted', executable('prog4', 'prog4.c'))
+
+# Test `capture` keyword
+
+basename_py = find_program('basename.py')
+file_contains_py = find_program('file_contains.py')
+test_string = 'hello world'
+test_input_file = join_paths(meson.current_build_dir(), test_string)
+run_command(find_program('touch.py'), test_input_file, check: true)
+configs = [
+ # no input
+ configure_file(command: [ basename_py, test_string ], capture: true, output: 'capture test 1'),
+ # with input
+ configure_file(input: test_input_file, command: [ basename_py, '@INPUT@' ], capture: true, output: 'capture test 2'),
+]
+foreach c : configs
+ test('@0@'.format(c), file_contains_py, args: [ c, test_string ])
+endforeach
+
+# Test variable is substituted only once
+conf5 = configuration_data()
+conf5.set('var', '@var2@')
+conf5.set('var2', 'error')
+configure_file(
+ input : 'config5.h.in',
+ output : '@BASENAME@',
+ configuration : conf5)
+test('test5', executable('prog5', 'prog5.c'))
+
+# Test escaping
+conf6 = configuration_data()
+conf6.set('var1', 'foo')
+conf6.set('var2', 'bar')
+configure_file(
+ input : 'config6.h.in',
+ output : '@BASENAME@',
+ configuration : conf6)
+test('test6', executable('prog6', 'prog6.c'))
+
+# test empty install dir string
+cfile = configure_file(input : 'config.h.in',
+ output : 'do_not_get_installed.h',
+ install_dir : '',
+ configuration : conf)
+
+# test install_dir : false (deprecated)
+cfile = configure_file(input : 'config.h.in',
+ output : 'do_not_get_installed_please.h',
+ install_dir : false,
+ configuration : conf)
+
+# test intsall_dir with install: false
+cfile = configure_file(input : 'config.h.in',
+ output : 'do_not_get_installed_in_install_dir.h',
+ install : false,
+ install_dir : 'share/appdir',
+ configuration : conf)
+
+# Test escaping with cmake format
+conf7 = configuration_data()
+conf7.set('var1', 'foo')
+conf7.set('var2', 'bar')
+configure_file(
+ input : 'config7.h.in',
+ output : '@BASENAME@',
+ format : 'cmake',
+ configuration : conf7)
+test('test7', executable('prog7', 'prog7.c'))
+
+# Test copying of an empty configuration data object
+inf = 'invalid-utf8.bin.in'
+outf = configure_file(input : inf,
+ output : 'invalid-utf8.bin',
+ copy: true)
+ret = run_command(check_file, inf, outf, check: false)
+if ret.returncode() != 0
+ error('Error running command: @0@\n@1@'.format(ret.stdout(), ret.stderr()))
+endif
+# Now the same, but using a File object as an argument.
+inf2 = files('invalid-utf8.bin.in')[0]
+outf = configure_file(input : inf2,
+ output : 'invalid-utf8.bin',
+ copy: true)
+ret = run_command(check_file, inf2, outf, check: false)
+if ret.returncode() != 0
+ error('Error running command: @0@\n@1@'.format(ret.stdout(), ret.stderr()))
+endif
+
+# Test copy of a binary file
+outf = configure_file(input : inf,
+ output : 'somebinary.bin',
+ copy : true)
+ret = run_command(check_file, inf, outf, check: false)
+if ret.returncode() != 0
+ error('Error running command: @0@\n@1@'.format(ret.stdout(), ret.stderr()))
+endif
+
+# Test the fs replacement
+# Test copying of an empty configuration data object
+inf = 'invalid-utf8.bin.in'
+outf = fs.copyfile(inf, 'invalid-utf8-1.bin',
+ install: true,
+ install_dir: get_option('datadir') / meson.project_name(),
+ install_tag: 'copyfile',
+)
+test('fs.copyfile string', check_file, args: [files(inf), outf])
+
+# Test with default outname of string
+outf = fs.copyfile(inf)
+test('fs.copyfile default name', check_file, args: [files(inf), outf])
+
+# Now the same, but using a File object as an argument.
+inf2 = files('invalid-utf8.bin.in')[0]
+outf = fs.copyfile(inf2, 'invalid-utf8-2.bin')
+test('fs.copyfile file', check_file, args: [inf2, outf])
+
+# Test non isolatin1 encoded input file which fails to decode with utf-8
+conf8 = configuration_data()
+conf8.set('var', 'foo')
+configure_file(
+ input : 'config8.h.in',
+ output : '@BASENAME@',
+ encoding : 'koi8-r',
+ configuration : conf8)
+
+# Test that passing an empty configuration_data() object to a file with
+# #mesondefine substitutions does not print the warning.
+configure_file(
+ input: 'nosubst-nocopy1.txt.in',
+ output: 'nosubst-nocopy1.txt',
+ configuration : configuration_data())
+
+# test that passing an empty configuration_data() object to a file with
+# @foo@ substitutions does not print the warning.
+configure_file(
+ input: 'nosubst-nocopy2.txt.in',
+ output: 'nosubst-nocopy2.txt',
+ configuration : configuration_data())
+
+# test that passing a configured file object to test() works, and that passing
+# an empty configuration_data() object to a file that leads to no substitutions
+# prints a warning (see unit tests)
+test_file = configure_file(
+ input: 'test.py.in',
+ output: 'test.py',
+ configuration: configuration_data())
+
+# Test that overwriting an existing file creates a warning.
+configure_file(
+ input: 'test.py.in',
+ output: 'double_output.txt',
+ configuration: conf)
+configure_file(
+ input: 'test.py.in',
+ output: 'double_output.txt',
+ configuration: conf)
+
+# Test that the same file name in a different subdir will not create a warning
+configure_file(
+ input: 'test.py.in',
+ output: 'no_write_conflict.txt',
+ configuration: conf)
+
+# Test that @BASENAME@ is substituted before checking and does not create a warning.
+configure_file(
+ input: 'differentafterbasename1.in',
+ output: '@BASENAME@',
+ configuration: conf
+)
+configure_file(
+ input: 'differentafterbasename2.in',
+ output: '@BASENAME@',
+ configuration: conf
+)
+
+# Test that @BASENAME@ is substituted before checking and does create a warning on conflict.
+configure_file(
+ input: 'sameafterbasename.in',
+ output: '@BASENAME@',
+ configuration: conf
+)
+configure_file(
+ input: 'sameafterbasename.in2',
+ output: '@BASENAME@',
+ configuration: conf
+)
+
+test('configure-file', test_file)
+
+# Dictionaries
+
+cdata = configuration_data({
+ 'A_STRING' : '"foo"',
+ 'A_INT' : 42,
+ 'A_DEFINED' : true,
+ 'A_UNDEFINED' : false,
+})
+
+configure_file(output : 'config9a.h',
+ configuration : cdata,
+)
+
+configure_file(output : 'config9b.h',
+ configuration : {
+ 'B_STRING' : '"foo"',
+ 'B_INT' : 42,
+ 'B_DEFINED' : true,
+ 'B_UNDEFINED' : false,
+ }
+)
+
+test('test9', executable('prog9', 'prog9.c'))
+
+check_inputs = find_program('check_inputs.py')
+configure_file(output : 'check_inputs.txt',
+ input : ['prog.c', files('prog2.c', 'prog4.c')],
+ command : [check_inputs, '@OUTPUT@', '@INPUT0@', '@INPUT@', files('prog5.c')]
+)
diff --git a/test cases/common/14 configure file/nosubst-nocopy1.txt.in b/test cases/common/14 configure file/nosubst-nocopy1.txt.in
new file mode 100644
index 0000000..6e893a1
--- /dev/null
+++ b/test cases/common/14 configure file/nosubst-nocopy1.txt.in
@@ -0,0 +1 @@
+#mesondefine FOO_BAR
diff --git a/test cases/common/14 configure file/nosubst-nocopy2.txt.in b/test cases/common/14 configure file/nosubst-nocopy2.txt.in
new file mode 100644
index 0000000..a6a7cca
--- /dev/null
+++ b/test cases/common/14 configure file/nosubst-nocopy2.txt.in
@@ -0,0 +1 @@
+@FOO_BAR@
diff --git a/test cases/common/14 configure file/prog.c b/test cases/common/14 configure file/prog.c
new file mode 100644
index 0000000..85e66b9
--- /dev/null
+++ b/test cases/common/14 configure file/prog.c
@@ -0,0 +1,17 @@
+#include <string.h>
+/* config.h must not be in quotes:
+ * https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
+ */
+#include <config.h>
+
+#ifdef SHOULD_BE_UNDEF
+#error "FAIL!"
+#endif
+
+int main(void) {
+#ifndef BE_TRUE
+ return 1;
+#else
+ return strcmp(MESSAGE, "mystring");
+#endif
+}
diff --git a/test cases/common/14 configure file/prog2.c b/test cases/common/14 configure file/prog2.c
new file mode 100644
index 0000000..8b90bfb
--- /dev/null
+++ b/test cases/common/14 configure file/prog2.c
@@ -0,0 +1,5 @@
+#include<config2.h>
+
+int main(void) {
+ return ZERO_RESULT;
+}
diff --git a/test cases/common/14 configure file/prog4.c b/test cases/common/14 configure file/prog4.c
new file mode 100644
index 0000000..1e32a31
--- /dev/null
+++ b/test cases/common/14 configure file/prog4.c
@@ -0,0 +1,6 @@
+#include <config4a.h>
+#include <config4b.h>
+
+int main(void) {
+ return RESULTA + RESULTB;
+}
diff --git a/test cases/common/14 configure file/prog5.c b/test cases/common/14 configure file/prog5.c
new file mode 100644
index 0000000..1a8f785
--- /dev/null
+++ b/test cases/common/14 configure file/prog5.c
@@ -0,0 +1,6 @@
+#include <string.h>
+#include <config5.h>
+
+int main(void) {
+ return strcmp(MESSAGE, "@var2@");
+}
diff --git a/test cases/common/14 configure file/prog6.c b/test cases/common/14 configure file/prog6.c
new file mode 100644
index 0000000..57f5586
--- /dev/null
+++ b/test cases/common/14 configure file/prog6.c
@@ -0,0 +1,11 @@
+#include <string.h>
+#include <config6.h>
+
+int main(void) {
+ return strcmp(MESSAGE1, "foo")
+ || strcmp(MESSAGE2, "@var1@")
+ || strcmp(MESSAGE3, "\\foo")
+ || strcmp(MESSAGE4, "\\@var1@")
+ || strcmp(MESSAGE5, "@var1bar")
+ || strcmp(MESSAGE6, "\\ @ @ \\@ \\@");
+}
diff --git a/test cases/common/14 configure file/prog7.c b/test cases/common/14 configure file/prog7.c
new file mode 100644
index 0000000..802bc46
--- /dev/null
+++ b/test cases/common/14 configure file/prog7.c
@@ -0,0 +1,10 @@
+#include <string.h>
+#include <config7.h>
+
+int main(void) {
+ return strcmp(MESSAGE1, "foo")
+ || strcmp(MESSAGE2, "${var1}")
+ || strcmp(MESSAGE3, "\\foo")
+ || strcmp(MESSAGE4, "\\${var1}")
+ || strcmp(MESSAGE5, "\\ ${ ${ \\${ \\${");
+}
diff --git a/test cases/common/14 configure file/prog9.c b/test cases/common/14 configure file/prog9.c
new file mode 100644
index 0000000..3f77601
--- /dev/null
+++ b/test cases/common/14 configure file/prog9.c
@@ -0,0 +1,18 @@
+#include <string.h>
+#include <config9a.h>
+#include <config9b.h>
+
+#if defined(A_UNDEFINED) || defined(B_UNDEFINED)
+#error "Should not be defined"
+#endif
+
+#if !defined(A_DEFINED) || !defined(B_DEFINED)
+#error "Should be defined"
+#endif
+
+int main(void) {
+ return strcmp(A_STRING, "foo")
+ || strcmp(B_STRING, "foo")
+ || A_INT != 42
+ || B_INT != 42;
+}
diff --git a/test cases/common/14 configure file/sameafterbasename.in b/test cases/common/14 configure file/sameafterbasename.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/14 configure file/sameafterbasename.in
diff --git a/test cases/common/14 configure file/sameafterbasename.in2 b/test cases/common/14 configure file/sameafterbasename.in2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/14 configure file/sameafterbasename.in2
diff --git a/test cases/common/14 configure file/subdir/meson.build b/test cases/common/14 configure file/subdir/meson.build
new file mode 100644
index 0000000..98b672c
--- /dev/null
+++ b/test cases/common/14 configure file/subdir/meson.build
@@ -0,0 +1,38 @@
+# Configure in subdir with absolute paths for input and relative for output
+configure_file(input : '../dummy.dat',
+ output : 'config2-1.h',
+ command : [genprog, scriptfile, ifile, 'config2-1.h'],
+ install_dir : 'share/appdireh')
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2-1.h'), check: true)
+
+# Configure in subdir with files() for input and relative for output
+configure_file(input : '../dummy.dat',
+ output : 'config2-2.h',
+ command : [genprog, scriptfile, files('../dummy.dat'), 'config2-2.h'],
+ install_dir : 'share/appdirok')
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2-2.h'), check: true)
+
+# Configure in subdir with string templates for input and output
+configure_file(input : '../dummy.dat',
+ output : 'config2-3.h',
+ command : [found_script, '@INPUT@', '@OUTPUT@'])
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2-3.h'), check: true)
+
+# Test that overwriting an existing file creates a warning.
+configure_file(
+ input: '../test.py.in',
+ output: 'double_output2.txt',
+ configuration: conf
+)
+configure_file(
+ input: '../test.py.in',
+ output: 'double_output2.txt',
+ configuration: conf
+)
+
+# Test that the same file name in a different subdir will not create a warning
+configure_file(
+ input: '../test.py.in',
+ output: 'no_write_conflict.txt',
+ configuration: conf
+)
diff --git a/test cases/common/14 configure file/test.json b/test cases/common/14 configure file/test.json
new file mode 100644
index 0000000..5a6ccd5
--- /dev/null
+++ b/test cases/common/14 configure file/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/appdir/config2.h"},
+ {"type": "file", "file": "usr/share/appdir/config2b.h"},
+ {"type": "file", "file": "usr/share/appdireh/config2-1.h"},
+ {"type": "file", "file": "usr/share/appdirok/config2-2.h"},
+ {"type": "file", "file": "usr/share/configure file test/invalid-utf8-1.bin"}
+ ]
+}
diff --git a/test cases/common/14 configure file/test.py.in b/test cases/common/14 configure file/test.py.in
new file mode 100644
index 0000000..15a61f5
--- /dev/null
+++ b/test cases/common/14 configure file/test.py.in
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+import sys
+sys.exit(0)
diff --git a/test cases/common/14 configure file/touch.py b/test cases/common/14 configure file/touch.py
new file mode 100644
index 0000000..b48f481
--- /dev/null
+++ b/test cases/common/14 configure file/touch.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import sys
+import argparse
+from pathlib import Path
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('files', nargs='*', type=str)
+ args = parser.parse_args()
+
+ for filepath in args.files:
+ Path(filepath).touch()
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/test cases/common/140 custom target multiple outputs/generator.py b/test cases/common/140 custom target multiple outputs/generator.py
new file mode 100755
index 0000000..39dbd11
--- /dev/null
+++ b/test cases/common/140 custom target multiple outputs/generator.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+if len(sys.argv) != 3:
+ print(sys.argv[0], '<namespace>', '<output dir>')
+
+name = sys.argv[1]
+odir = sys.argv[2]
+
+with open(os.path.join(odir, name + '.h'), 'w') as f:
+ f.write('int func();\n')
+with open(os.path.join(odir, name + '.sh'), 'w') as f:
+ f.write('#!/bin/bash')
diff --git a/test cases/common/140 custom target multiple outputs/meson.build b/test cases/common/140 custom target multiple outputs/meson.build
new file mode 100644
index 0000000..abc5728
--- /dev/null
+++ b/test cases/common/140 custom target multiple outputs/meson.build
@@ -0,0 +1,44 @@
+project('multiple outputs install')
+
+gen = find_program('generator.py')
+
+custom_target('different-install-dirs',
+ output : ['diff.h', 'diff.sh'],
+ command : [gen, 'diff', '@OUTDIR@'],
+ install : true,
+ install_dir : [join_paths(get_option('prefix'), get_option('includedir')),
+ join_paths(get_option('prefix'), get_option('bindir'))])
+
+custom_target('same-install-dir',
+ output : ['same.h', 'same.sh'],
+ command : [gen, 'same', '@OUTDIR@'],
+ install : true,
+ install_dir : '/opt')
+
+custom_target('only-install-first',
+ output : ['first.h', 'first.sh'],
+ command : [gen, 'first', '@OUTDIR@'],
+ install : true,
+ install_dir : [join_paths(get_option('prefix'), get_option('includedir')), false])
+
+targets = custom_target('only-install-second',
+ output : ['second.h', 'second.sh'],
+ command : [gen, 'second', '@OUTDIR@'],
+ install : true,
+ install_dir : [false, join_paths(get_option('prefix'), get_option('bindir'))])
+
+paths = []
+foreach i : targets.to_list()
+ paths += i.full_path()
+endforeach
+
+# The Xcode backend has a different output naming scheme.
+if meson.backend() == 'xcode'
+ assert(paths == [meson.project_build_root() / get_option('buildtype') / 'second.h',
+ meson.project_build_root() / get_option('buildtype') / 'second.sh'])
+
+# Skip on Windows because paths are not identical, '/' VS '\'.
+elif host_machine.system() != 'windows'
+ assert(paths == [meson.current_build_dir() / 'second.h',
+ meson.current_build_dir() / 'second.sh'])
+endif
diff --git a/test cases/common/140 custom target multiple outputs/test.json b/test cases/common/140 custom target multiple outputs/test.json
new file mode 100644
index 0000000..e59cb9f
--- /dev/null
+++ b/test cases/common/140 custom target multiple outputs/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/diff.h"},
+ {"type": "file", "file": "usr/include/first.h"},
+ {"type": "file", "file": "usr/bin/diff.sh"},
+ {"type": "file", "file": "usr/bin/second.sh"},
+ {"type": "file", "file": "opt/same.h"},
+ {"type": "file", "file": "opt/same.sh"}
+ ]
+}
diff --git a/test cases/common/141 special characters/.editorconfig b/test cases/common/141 special characters/.editorconfig
new file mode 100644
index 0000000..6c026f8
--- /dev/null
+++ b/test cases/common/141 special characters/.editorconfig
@@ -0,0 +1,2 @@
+[meson.build]
+trim_trailing_whitespace = false
diff --git a/test cases/common/141 special characters/arg-char-test.c b/test cases/common/141 special characters/arg-char-test.c
new file mode 100644
index 0000000..044857e
--- /dev/null
+++ b/test cases/common/141 special characters/arg-char-test.c
@@ -0,0 +1,11 @@
+#include <assert.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ char c = CHAR;
+ assert(argc == 2);
+ if (c != argv[1][0])
+ fprintf(stderr, "Expected %x, got %x\n", (unsigned int) c, (unsigned int) argv[1][0]);
+ assert(c == argv[1][0]);
+ return 0;
+}
diff --git a/test cases/common/141 special characters/arg-string-test.c b/test cases/common/141 special characters/arg-string-test.c
new file mode 100644
index 0000000..1d93f45
--- /dev/null
+++ b/test cases/common/141 special characters/arg-string-test.c
@@ -0,0 +1,13 @@
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+ const char *s = CHAR;
+ assert(argc == 2);
+ assert(strlen(s) == 1);
+ if (s[0] != argv[1][0])
+ fprintf(stderr, "Expected %x, got %x\n", (unsigned int) s[0], (unsigned int) argv[1][0]);
+ assert(s[0] == argv[1][0]);
+ return 0;
+}
diff --git a/test cases/common/141 special characters/arg-unquoted-test.c b/test cases/common/141 special characters/arg-unquoted-test.c
new file mode 100644
index 0000000..9c51bff
--- /dev/null
+++ b/test cases/common/141 special characters/arg-unquoted-test.c
@@ -0,0 +1,18 @@
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#define Q(x) #x
+#define QUOTE(x) Q(x)
+
+int main(int argc, char **argv) {
+ const char *s = QUOTE(CHAR);
+ assert(argc == 2);
+ assert(strlen(s) == 1);
+ if (s[0] != argv[1][0])
+ fprintf(stderr, "Expected %x, got %x\n", (unsigned int) s[0], (unsigned int) argv[1][0]);
+ assert(s[0] == argv[1][0]);
+ // There is no way to convert a macro argument into a character constant.
+ // Otherwise we'd test that as well
+ return 0;
+}
diff --git a/test cases/common/141 special characters/check_quoting.py b/test cases/common/141 special characters/check_quoting.py
new file mode 100644
index 0000000..d6e50ea
--- /dev/null
+++ b/test cases/common/141 special characters/check_quoting.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+
+import sys
+
+expected = {
+ 'newline': '\n',
+ 'dollar': '$',
+ 'colon': ':',
+ 'space': ' ',
+ 'multi1': ' ::$$ ::$$',
+ 'multi2': ' ::$$\n\n \n\n::$$',
+}
+
+output = None
+
+for arg in sys.argv[1:]:
+ try:
+ name, value = arg.split('=', 1)
+ except ValueError:
+ output = arg
+ continue
+
+ if expected[name] != value:
+ raise RuntimeError('{!r} is {!r} but should be {!r}'.format(name, value, expected[name]))
+
+if output is not None:
+ with open(output, 'w') as f:
+ f.write('Success!')
diff --git a/test cases/common/141 special characters/meson.build b/test cases/common/141 special characters/meson.build
new file mode 100644
index 0000000..579601e
--- /dev/null
+++ b/test cases/common/141 special characters/meson.build
@@ -0,0 +1,75 @@
+project('ninja special characters' ,'c')
+
+python = import('python3').find_python()
+
+# Without newlines, this should appear directly in build.ninja.
+gen = custom_target('gen',
+ command : [
+ python,
+ files('check_quoting.py'),
+ 'dollar=$',
+ 'colon=:',
+ 'space= ',
+ '''multi1= ::$$ ::$$''',
+ '@OUTPUT@'],
+ output : 'result',
+ install : true,
+ install_dir : get_option('datadir'))
+
+# With newlines, this should go through the exe wrapper.
+gen2 = custom_target('gen2',
+ command : [
+ python,
+ files('check_quoting.py'),
+ '''newline=
+''',
+ 'dollar=$',
+ 'colon=:',
+ 'space= ',
+ '''multi2= ::$$
+
+
+
+::$$''',
+ '@OUTPUT@'],
+ output : 'result2',
+ install : true,
+ install_dir : get_option('datadir'))
+
+# Test that we can pass these special characters in compiler arguments
+#
+# (this part of the test is crafted so we don't try to use these special
+# characters in filenames or target names)
+#
+# TODO: similar tests needed for languages other than C
+# TODO: add similar test for quote, doublequote, and hash, carefully
+# Re hash, see
+# https://docs.microsoft.com/en-us/cpp/build/reference/d-preprocessor-definitions
+
+special = [
+ ['amp', '&'],
+ ['at', '@'],
+ ['backslash', '\\'],
+ ['dollar', '$'],
+ ['gt', '>'],
+ ['lt', '<'],
+ ['slash', '/'],
+]
+
+cc = meson.get_compiler('c')
+
+foreach s : special
+ args = '-DCHAR="@0@"'.format(s[1])
+ e = executable('arg-string-' + s[0], 'arg-string-test.c', c_args: args)
+ test('arg-string-' + s[0], e, args: s[1])
+
+ args = '-DCHAR=@0@'.format(s[1])
+ e = executable('arg-unquoted-' + s[0], 'arg-unquoted-test.c', c_args: args)
+ test('arg-unquoted-' + s[0], e, args: s[1])
+endforeach
+
+foreach s : special
+ args = '-DCHAR=\'@0@\''.format(s[1])
+ e = executable('arg-char-' + s[0], 'arg-char-test.c', c_args: args)
+ test('arg-char-' + s[0], e, args: s[1])
+endforeach
diff --git a/test cases/common/141 special characters/test.json b/test cases/common/141 special characters/test.json
new file mode 100644
index 0000000..9709e5b
--- /dev/null
+++ b/test cases/common/141 special characters/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/result"},
+ {"type": "file", "file": "usr/share/result2"}
+ ]
+}
diff --git a/test cases/common/142 nested links/meson.build b/test cases/common/142 nested links/meson.build
new file mode 100644
index 0000000..0821b03
--- /dev/null
+++ b/test cases/common/142 nested links/meson.build
@@ -0,0 +1,8 @@
+project('test', 'c')
+
+libxserver_dri3 = []
+libxserver = [ libxserver_dri3 ]
+
+executable('Xephyr', 'xephyr.c', link_with: [ libxserver ])
+
+executable('Zephyr', 'xephyr.c', link_args: [[], []])
diff --git a/test cases/common/142 nested links/xephyr.c b/test cases/common/142 nested links/xephyr.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/common/142 nested links/xephyr.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/143 list of file sources/foo b/test cases/common/143 list of file sources/foo
new file mode 100644
index 0000000..7b57bd2
--- /dev/null
+++ b/test cases/common/143 list of file sources/foo
@@ -0,0 +1 @@
+some text
diff --git a/test cases/common/143 list of file sources/gen.py b/test cases/common/143 list of file sources/gen.py
new file mode 100644
index 0000000..2337d3d
--- /dev/null
+++ b/test cases/common/143 list of file sources/gen.py
@@ -0,0 +1,7 @@
+import shutil
+import sys
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ raise Exception('Requires exactly 2 args')
+ shutil.copy2(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/143 list of file sources/meson.build b/test cases/common/143 list of file sources/meson.build
new file mode 100644
index 0000000..40c1b8c
--- /dev/null
+++ b/test cases/common/143 list of file sources/meson.build
@@ -0,0 +1,12 @@
+project('test')
+
+mod_py = import('python3')
+python = mod_py.find_python()
+
+test_target = custom_target(
+ 'test_target',
+ input : [files('gen.py'), files('foo')],
+ output : 'bar',
+ command : [python, '@INPUT0@', '@INPUT1@', '@OUTPUT@'],
+ build_by_default : true,
+)
diff --git a/test cases/common/144 link depends custom target/foo.c b/test cases/common/144 link depends custom target/foo.c
new file mode 100644
index 0000000..58c86a6
--- /dev/null
+++ b/test cases/common/144 link depends custom target/foo.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main(void) {
+ const char *fn = DEPFILE;
+ FILE *f = fopen(fn, "r");
+ if (!f) {
+ printf("could not open %s", fn);
+ return 1;
+ }
+ else {
+ printf("successfully opened %s", fn);
+ }
+
+ return 0;
+}
diff --git a/test cases/common/144 link depends custom target/make_file.py b/test cases/common/144 link depends custom target/make_file.py
new file mode 100755
index 0000000..ceb6e19
--- /dev/null
+++ b/test cases/common/144 link depends custom target/make_file.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ print('# this file does nothing', file=f)
diff --git a/test cases/common/144 link depends custom target/meson.build b/test cases/common/144 link depends custom target/meson.build
new file mode 100644
index 0000000..babd58a
--- /dev/null
+++ b/test cases/common/144 link depends custom target/meson.build
@@ -0,0 +1,14 @@
+project('link_depends_custom_target', 'c')
+
+cmd = find_program('make_file.py')
+
+dep_file = custom_target('gen_dep',
+ command: [cmd, '@OUTPUT@'],
+ output: 'dep_file')
+
+exe = executable('foo', 'foo.c',
+ link_depends: dep_file,
+ c_args: ['-DDEPFILE="' + dep_file.full_path()+ '"'])
+
+# check that dep_file exists, which means that link_depends target ran
+test('runtest', exe)
diff --git a/test cases/common/145 recursive linking/3rdorderdeps/lib.c.in b/test cases/common/145 recursive linking/3rdorderdeps/lib.c.in
new file mode 100644
index 0000000..461f859
--- /dev/null
+++ b/test cases/common/145 recursive linking/3rdorderdeps/lib.c.in
@@ -0,0 +1,8 @@
+#include "../lib.h"
+
+int get_@DEPENDENCY@dep_value (void);
+
+SYMBOL_EXPORT
+int get_@LIBTYPE@@DEPENDENCY@dep_value (void) {
+ return get_@DEPENDENCY@dep_value ();
+}
diff --git a/test cases/common/145 recursive linking/3rdorderdeps/main.c.in b/test cases/common/145 recursive linking/3rdorderdeps/main.c.in
new file mode 100644
index 0000000..643c246
--- /dev/null
+++ b/test cases/common/145 recursive linking/3rdorderdeps/main.c.in
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+#include "../lib.h"
+
+SYMBOL_IMPORT int get_@LIBTYPE@@DEPENDENCY@dep_value (void);
+
+int main(void) {
+ int val;
+
+ val = get_@LIBTYPE@@DEPENDENCY@dep_value ();
+ if (val != @VALUE@) {
+ printf("@LIBTYPE@@DEPENDENCY@ was %i instead of @VALUE@\n", val);
+ return -1;
+ }
+ return 0;
+}
diff --git a/test cases/common/145 recursive linking/3rdorderdeps/meson.build b/test cases/common/145 recursive linking/3rdorderdeps/meson.build
new file mode 100644
index 0000000..4c5ac73
--- /dev/null
+++ b/test cases/common/145 recursive linking/3rdorderdeps/meson.build
@@ -0,0 +1,49 @@
+dep3_libs = []
+
+# Permutate all combinations of shared and static libraries up to three levels
+# executable -> shared -> static -> shared (etc)
+foreach dep2 : ['sh', 'st']
+ foreach dep1 : ['sh', 'st']
+ foreach libtype : ['sh', 'st']
+ name = libtype + dep1 + dep2
+ if dep2 == 'sh'
+ libret = 1
+ elif dep2 == 'st'
+ libret = 2
+ else
+ error('Unknown dep2 "@0@"'.format(dep2))
+ endif
+
+ if libtype == 'sh'
+ target = 'shared_library'
+ build_args = []
+ elif libtype == 'st'
+ target = 'static_library'
+ build_args = ['-DMESON_STATIC_BUILD']
+ else
+ error('Unknown libtype "@0@"'.format(libtype))
+ endif
+
+ cdata = configuration_data()
+ cdata.set('DEPENDENCY', dep1 + dep2)
+ cdata.set('LIBTYPE', libtype)
+ cdata.set('VALUE', libret)
+
+ lib_c = configure_file(input : 'lib.c.in',
+ output : name + '-lib.c',
+ configuration : cdata)
+ dep = get_variable(dep1 + dep2 + 'dep')
+ dep3_lib = build_target(name, lib_c, link_with : dep,
+ target_type : target,
+ c_args : build_args)
+ dep3_libs += [dep3_lib]
+
+ main_c = configure_file(input : 'main.c.in',
+ output : name + '-main.c',
+ configuration : cdata)
+ dep3_bin = executable(name + '_test', main_c, link_with : dep3_lib,
+ c_args : build_args)
+ test(name + 'test', dep3_bin)
+ endforeach
+ endforeach
+endforeach
diff --git a/test cases/common/145 recursive linking/circular/lib1.c b/test cases/common/145 recursive linking/circular/lib1.c
new file mode 100644
index 0000000..38889cf
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/lib1.c
@@ -0,0 +1,6 @@
+int get_st2_prop (void);
+int get_st3_prop (void);
+
+int get_st1_value (void) {
+ return get_st2_prop () + get_st3_prop ();
+}
diff --git a/test cases/common/145 recursive linking/circular/lib2.c b/test cases/common/145 recursive linking/circular/lib2.c
new file mode 100644
index 0000000..31cd37c
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/lib2.c
@@ -0,0 +1,6 @@
+int get_st1_prop (void);
+int get_st3_prop (void);
+
+int get_st2_value (void) {
+ return get_st1_prop () + get_st3_prop ();
+}
diff --git a/test cases/common/145 recursive linking/circular/lib3.c b/test cases/common/145 recursive linking/circular/lib3.c
new file mode 100644
index 0000000..67d473a
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/lib3.c
@@ -0,0 +1,6 @@
+int get_st1_prop (void);
+int get_st2_prop (void);
+
+int get_st3_value (void) {
+ return get_st1_prop () + get_st2_prop ();
+}
diff --git a/test cases/common/145 recursive linking/circular/main.c b/test cases/common/145 recursive linking/circular/main.c
new file mode 100644
index 0000000..164abdf
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/main.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+#include "../lib.h"
+
+int get_st1_value (void);
+int get_st2_value (void);
+int get_st3_value (void);
+
+int main(void) {
+ int val;
+
+ val = get_st1_value ();
+ if (val != 5) {
+ printf("st1 value was %i instead of 5\n", val);
+ return -1;
+ }
+ val = get_st2_value ();
+ if (val != 4) {
+ printf("st2 value was %i instead of 4\n", val);
+ return -2;
+ }
+ val = get_st3_value ();
+ if (val != 3) {
+ printf("st3 value was %i instead of 3\n", val);
+ return -3;
+ }
+ return 0;
+}
diff --git a/test cases/common/145 recursive linking/circular/meson.build b/test cases/common/145 recursive linking/circular/meson.build
new file mode 100644
index 0000000..b7a70a8
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/meson.build
@@ -0,0 +1,5 @@
+st1 = static_library('st1', 'lib1.c', 'prop1.c')
+st2 = static_library('st2', 'lib2.c', 'prop2.c')
+st3 = static_library('st3', 'lib3.c', 'prop3.c')
+
+test('circular', executable('circular', 'main.c', link_with : [st1, st2, st3]))
diff --git a/test cases/common/145 recursive linking/circular/prop1.c b/test cases/common/145 recursive linking/circular/prop1.c
new file mode 100644
index 0000000..4e571f5
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/prop1.c
@@ -0,0 +1,3 @@
+int get_st1_prop (void) {
+ return 1;
+}
diff --git a/test cases/common/145 recursive linking/circular/prop2.c b/test cases/common/145 recursive linking/circular/prop2.c
new file mode 100644
index 0000000..ceabba0
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/prop2.c
@@ -0,0 +1,3 @@
+int get_st2_prop (void) {
+ return 2;
+}
diff --git a/test cases/common/145 recursive linking/circular/prop3.c b/test cases/common/145 recursive linking/circular/prop3.c
new file mode 100644
index 0000000..246206c
--- /dev/null
+++ b/test cases/common/145 recursive linking/circular/prop3.c
@@ -0,0 +1,3 @@
+int get_st3_prop (void) {
+ return 3;
+}
diff --git a/test cases/common/145 recursive linking/edge-cases/libsto.c b/test cases/common/145 recursive linking/edge-cases/libsto.c
new file mode 100644
index 0000000..93f46a8
--- /dev/null
+++ b/test cases/common/145 recursive linking/edge-cases/libsto.c
@@ -0,0 +1,8 @@
+#include "../lib.h"
+
+int get_builto_value (void);
+
+SYMBOL_EXPORT
+int get_stodep_value (void) {
+ return get_builto_value ();
+}
diff --git a/test cases/common/145 recursive linking/edge-cases/meson.build b/test cases/common/145 recursive linking/edge-cases/meson.build
new file mode 100644
index 0000000..6a46266
--- /dev/null
+++ b/test cases/common/145 recursive linking/edge-cases/meson.build
@@ -0,0 +1,9 @@
+# Test https://github.com/mesonbuild/meson/issues/2096
+# Note that removing 'shnodep' from link_with: makes the error go away because
+# then it is added after the static library is added to the link command.
+test('shared-static', executable('shstexe', 'shstmain.c', link_with : [shnodep, stshdep]))
+
+# Static library that needs a symbol defined in an object file. This already
+# works, but good to add a test case early.
+stodep = static_library('stodep', 'libsto.c')
+test('stodep', executable('stodep', 'stomain.c', 'stobuilt.c', link_with : stodep))
diff --git a/test cases/common/145 recursive linking/edge-cases/shstmain.c b/test cases/common/145 recursive linking/edge-cases/shstmain.c
new file mode 100644
index 0000000..334f867
--- /dev/null
+++ b/test cases/common/145 recursive linking/edge-cases/shstmain.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+#include "../lib.h"
+
+int get_stshdep_value (void);
+
+int main(void) {
+ int val;
+
+ val = get_stshdep_value ();
+ if (val != 1) {
+ printf("st1 value was %i instead of 1\n", val);
+ return -1;
+ }
+ return 0;
+}
diff --git a/test cases/common/145 recursive linking/edge-cases/stobuilt.c b/test cases/common/145 recursive linking/edge-cases/stobuilt.c
new file mode 100644
index 0000000..9cc15bc
--- /dev/null
+++ b/test cases/common/145 recursive linking/edge-cases/stobuilt.c
@@ -0,0 +1,7 @@
+#include "../lib.h"
+
+
+SYMBOL_EXPORT
+int get_builto_value (void) {
+ return 1;
+}
diff --git a/test cases/common/145 recursive linking/edge-cases/stomain.c b/test cases/common/145 recursive linking/edge-cases/stomain.c
new file mode 100644
index 0000000..a16a89b
--- /dev/null
+++ b/test cases/common/145 recursive linking/edge-cases/stomain.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+#include "../lib.h"
+
+int get_stodep_value (void);
+
+int main(void) {
+ int val;
+
+ val = get_stodep_value ();
+ if (val != 1) {
+ printf("st1 value was %i instead of 1\n", val);
+ return -1;
+ }
+ return 0;
+}
diff --git a/test cases/common/145 recursive linking/lib.h b/test cases/common/145 recursive linking/lib.h
new file mode 100644
index 0000000..b54bf36
--- /dev/null
+++ b/test cases/common/145 recursive linking/lib.h
@@ -0,0 +1,17 @@
+#if defined _WIN32
+ #ifdef MESON_STATIC_BUILD
+ #define SYMBOL_EXPORT
+ #define SYMBOL_IMPORT
+ #else
+ #define SYMBOL_IMPORT __declspec(dllimport)
+ #define SYMBOL_EXPORT __declspec(dllexport)
+ #endif
+#else
+ #define SYMBOL_IMPORT
+ #if defined __GNUC__
+ #define SYMBOL_EXPORT __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define SYMBOL_EXPORT
+ #endif
+#endif
diff --git a/test cases/common/145 recursive linking/main.c b/test cases/common/145 recursive linking/main.c
new file mode 100644
index 0000000..cf091d0
--- /dev/null
+++ b/test cases/common/145 recursive linking/main.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+#include "lib.h"
+
+int get_stnodep_value (void);
+int get_stshdep_value (void);
+int get_ststdep_value (void);
+SYMBOL_IMPORT int get_shnodep_value (void);
+SYMBOL_IMPORT int get_shshdep_value (void);
+SYMBOL_IMPORT int get_shstdep_value (void);
+
+int main(void) {
+ int val;
+
+ val = get_shnodep_value ();
+ if (val != 1) {
+ printf("shnodep was %i instead of 1\n", val);
+ return -1;
+ }
+ val = get_stnodep_value ();
+ if (val != 2) {
+ printf("stnodep was %i instead of 2\n", val);
+ return -2;
+ }
+ val = get_shshdep_value ();
+ if (val != 1) {
+ printf("shshdep was %i instead of 1\n", val);
+ return -3;
+ }
+ val = get_shstdep_value ();
+ if (val != 2) {
+ printf("shstdep was %i instead of 2\n", val);
+ return -4;
+ }
+ val = get_stshdep_value ();
+ if (val != 1) {
+ printf("shstdep was %i instead of 1\n", val);
+ return -5;
+ }
+ val = get_ststdep_value ();
+ if (val != 2) {
+ printf("ststdep was %i instead of 2\n", val);
+ return -6;
+ }
+ return 0;
+}
diff --git a/test cases/common/145 recursive linking/meson.build b/test cases/common/145 recursive linking/meson.build
new file mode 100644
index 0000000..2ca7151
--- /dev/null
+++ b/test cases/common/145 recursive linking/meson.build
@@ -0,0 +1,29 @@
+project('recursive dependencies', 'c')
+
+# Test that you can link a shared executable to:
+# - A shared library with no other deps
+subdir('shnodep')
+# - A static library with no other deps
+subdir('stnodep')
+# - A shared library with a shared library dep
+subdir('shshdep')
+# - A shared library with a static library dep
+subdir('shstdep')
+# - A static library with a shared library dep
+subdir('stshdep')
+# - A static library with a static library dep
+subdir('ststdep')
+
+test('alldeps',
+ executable('alldeps', 'main.c',
+ link_with : [shshdep, shstdep, ststdep, stshdep]))
+
+# More combinations of static and shared libraries
+subdir('3rdorderdeps')
+
+# Circular dependencies between static libraries
+# This requires the use of --start/end-group with GNU ld
+subdir('circular')
+
+# Various edge cases that have been reported
+subdir('edge-cases')
diff --git a/test cases/common/145 recursive linking/shnodep/lib.c b/test cases/common/145 recursive linking/shnodep/lib.c
new file mode 100644
index 0000000..a3b7993
--- /dev/null
+++ b/test cases/common/145 recursive linking/shnodep/lib.c
@@ -0,0 +1,6 @@
+#include "../lib.h"
+
+SYMBOL_EXPORT
+int get_shnodep_value (void) {
+ return 1;
+}
diff --git a/test cases/common/145 recursive linking/shnodep/meson.build b/test cases/common/145 recursive linking/shnodep/meson.build
new file mode 100644
index 0000000..66cfd9b
--- /dev/null
+++ b/test cases/common/145 recursive linking/shnodep/meson.build
@@ -0,0 +1 @@
+shnodep = shared_library('shnodep', 'lib.c', version: '0.0.0')
diff --git a/test cases/common/145 recursive linking/shshdep/lib.c b/test cases/common/145 recursive linking/shshdep/lib.c
new file mode 100644
index 0000000..715d120
--- /dev/null
+++ b/test cases/common/145 recursive linking/shshdep/lib.c
@@ -0,0 +1,8 @@
+#include "../lib.h"
+
+int get_shnodep_value (void);
+
+SYMBOL_EXPORT
+int get_shshdep_value (void) {
+ return get_shnodep_value ();
+}
diff --git a/test cases/common/145 recursive linking/shshdep/meson.build b/test cases/common/145 recursive linking/shshdep/meson.build
new file mode 100644
index 0000000..020b481
--- /dev/null
+++ b/test cases/common/145 recursive linking/shshdep/meson.build
@@ -0,0 +1 @@
+shshdep = shared_library('shshdep', 'lib.c', link_with : shnodep)
diff --git a/test cases/common/145 recursive linking/shstdep/lib.c b/test cases/common/145 recursive linking/shstdep/lib.c
new file mode 100644
index 0000000..5da8d0b
--- /dev/null
+++ b/test cases/common/145 recursive linking/shstdep/lib.c
@@ -0,0 +1,8 @@
+#include "../lib.h"
+
+int get_stnodep_value (void);
+
+SYMBOL_EXPORT
+int get_shstdep_value (void) {
+ return get_stnodep_value ();
+}
diff --git a/test cases/common/145 recursive linking/shstdep/meson.build b/test cases/common/145 recursive linking/shstdep/meson.build
new file mode 100644
index 0000000..008f9f8
--- /dev/null
+++ b/test cases/common/145 recursive linking/shstdep/meson.build
@@ -0,0 +1 @@
+shstdep = shared_library('shstdep', 'lib.c', link_with : stnodep)
diff --git a/test cases/common/145 recursive linking/stnodep/lib.c b/test cases/common/145 recursive linking/stnodep/lib.c
new file mode 100644
index 0000000..4bc50be
--- /dev/null
+++ b/test cases/common/145 recursive linking/stnodep/lib.c
@@ -0,0 +1,6 @@
+#include "../lib.h"
+
+SYMBOL_EXPORT
+int get_stnodep_value (void) {
+ return 2;
+}
diff --git a/test cases/common/145 recursive linking/stnodep/meson.build b/test cases/common/145 recursive linking/stnodep/meson.build
new file mode 100644
index 0000000..77f7129
--- /dev/null
+++ b/test cases/common/145 recursive linking/stnodep/meson.build
@@ -0,0 +1,2 @@
+stnodep = static_library('stnodep', 'lib.c',
+ c_args : '-DMESON_STATIC_BUILD')
diff --git a/test cases/common/145 recursive linking/stshdep/lib.c b/test cases/common/145 recursive linking/stshdep/lib.c
new file mode 100644
index 0000000..3cfa12b
--- /dev/null
+++ b/test cases/common/145 recursive linking/stshdep/lib.c
@@ -0,0 +1,8 @@
+#include "../lib.h"
+
+int get_shnodep_value (void);
+
+SYMBOL_EXPORT
+int get_stshdep_value (void) {
+ return get_shnodep_value ();
+}
diff --git a/test cases/common/145 recursive linking/stshdep/meson.build b/test cases/common/145 recursive linking/stshdep/meson.build
new file mode 100644
index 0000000..0967c1c
--- /dev/null
+++ b/test cases/common/145 recursive linking/stshdep/meson.build
@@ -0,0 +1,2 @@
+stshdep = static_library('stshdep', 'lib.c', link_with : shnodep,
+ c_args : '-DMESON_STATIC_BUILD')
diff --git a/test cases/common/145 recursive linking/ststdep/lib.c b/test cases/common/145 recursive linking/ststdep/lib.c
new file mode 100644
index 0000000..fca8706
--- /dev/null
+++ b/test cases/common/145 recursive linking/ststdep/lib.c
@@ -0,0 +1,8 @@
+#include "../lib.h"
+
+int get_stnodep_value (void);
+
+SYMBOL_EXPORT
+int get_ststdep_value (void) {
+ return get_stnodep_value ();
+}
diff --git a/test cases/common/145 recursive linking/ststdep/meson.build b/test cases/common/145 recursive linking/ststdep/meson.build
new file mode 100644
index 0000000..3602442
--- /dev/null
+++ b/test cases/common/145 recursive linking/ststdep/meson.build
@@ -0,0 +1,2 @@
+ststdep = static_library('ststdep', 'lib.c', link_with : stnodep,
+ c_args : '-DMESON_STATIC_BUILD')
diff --git a/test cases/common/146 library at root/lib.c b/test cases/common/146 library at root/lib.c
new file mode 100644
index 0000000..a5b3dc3
--- /dev/null
+++ b/test cases/common/146 library at root/lib.c
@@ -0,0 +1,6 @@
+#if defined _WIN32 || defined __CYGWIN__
+__declspec(dllexport)
+#endif
+int fn(void) {
+ return -1;
+}
diff --git a/test cases/common/146 library at root/main/main.c b/test cases/common/146 library at root/main/main.c
new file mode 100644
index 0000000..eadf7e8
--- /dev/null
+++ b/test cases/common/146 library at root/main/main.c
@@ -0,0 +1,5 @@
+extern int fn(void);
+
+int main(void) {
+ return 1 + fn();
+}
diff --git a/test cases/common/146 library at root/main/meson.build b/test cases/common/146 library at root/main/meson.build
new file mode 100644
index 0000000..557378a
--- /dev/null
+++ b/test cases/common/146 library at root/main/meson.build
@@ -0,0 +1,2 @@
+exe = executable('main', 'main.c', link_with : lib)
+test('stuff works', exe)
diff --git a/test cases/common/146 library at root/meson.build b/test cases/common/146 library at root/meson.build
new file mode 100644
index 0000000..e652671
--- /dev/null
+++ b/test cases/common/146 library at root/meson.build
@@ -0,0 +1,3 @@
+project('lib@root', 'c')
+lib = library('lib', 'lib.c')
+subdir('main')
diff --git a/test cases/common/147 simd/fallback.c b/test cases/common/147 simd/fallback.c
new file mode 100644
index 0000000..ab435f4
--- /dev/null
+++ b/test cases/common/147 simd/fallback.c
@@ -0,0 +1,8 @@
+#include<simdfuncs.h>
+
+void increment_fallback(float arr[4]) {
+ int i;
+ for(i=0; i<4; i++) {
+ arr[i]++;
+ }
+}
diff --git a/test cases/common/147 simd/include/simdheader.h b/test cases/common/147 simd/include/simdheader.h
new file mode 100644
index 0000000..6515e41
--- /dev/null
+++ b/test cases/common/147 simd/include/simdheader.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define I_CAN_HAZ_SIMD
diff --git a/test cases/common/147 simd/meson.build b/test cases/common/147 simd/meson.build
new file mode 100644
index 0000000..101fdb8
--- /dev/null
+++ b/test cases/common/147 simd/meson.build
@@ -0,0 +1,43 @@
+project('simd', 'c')
+
+simd = import('unstable-simd')
+
+cc = meson.get_compiler('c')
+
+cdata = configuration_data()
+
+if not meson.is_cross_build() and host_machine.cpu_family() == 'arm' and cc.get_id() == 'clang'
+ message('Adding -march=armv7 because assuming that this build happens on Raspbian.')
+ message('Its Clang seems to be misconfigured and does not support NEON by default.')
+ add_project_arguments('-march=armv7', language : 'c')
+endif
+
+if cc.get_id() == 'msvc' and cc.version().version_compare('<17')
+ error('MESON_SKIP_TEST VS2010 produces broken binaries on x86.')
+endif
+
+# FIXME add [a, b] = function()
+rval = simd.check('mysimds',
+ mmx : 'simd_mmx.c',
+ sse : 'simd_sse.c',
+ sse2 : 'simd_sse2.c',
+ sse3 : 'simd_sse3.c',
+ ssse3 : 'simd_ssse3.c',
+ sse41 : 'simd_sse41.c',
+ sse42 : 'simd_sse42.c',
+ avx : 'simd_avx.c',
+ avx2 : 'simd_avx2.c',
+ neon : 'simd_neon.c',
+ compiler : cc,
+ include_directories : include_directories('include'))
+
+simdlibs = rval[0]
+cdata.merge_from(rval[1])
+
+configure_file(output : 'simdconfig.h',
+ configuration : cdata)
+
+p = executable('simdtest', 'simdchecker.c', 'fallback.c',
+ link_with : simdlibs)
+
+test('simdtest', p)
diff --git a/test cases/common/147 simd/simd_avx.c b/test cases/common/147 simd/simd_avx.c
new file mode 100644
index 0000000..5f45a4e
--- /dev/null
+++ b/test cases/common/147 simd/simd_avx.c
@@ -0,0 +1,49 @@
+#include<simdheader.h>
+
+#ifndef I_CAN_HAZ_SIMD
+#error The correct internal header was not used
+#endif
+
+#include<simdconfig.h>
+#include<simdfuncs.h>
+#include<stdint.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+int avx_available(void) {
+ return 1;
+}
+#else
+#include<immintrin.h>
+#include<cpuid.h>
+
+#ifdef __APPLE__
+/*
+ * Apple ships a broken __builtin_cpu_supports and
+ * some machines in the CI farm seem to be too
+ * old to have AVX so just always return 0 here.
+ */
+int avx_available(void) { return 0; }
+#else
+
+int avx_available(void) {
+ return __builtin_cpu_supports("avx");
+}
+#endif
+#endif
+
+void increment_avx(float arr[4]) {
+ double darr[4];
+ darr[0] = arr[0];
+ darr[1] = arr[1];
+ darr[2] = arr[2];
+ darr[3] = arr[3];
+ __m256d val = _mm256_loadu_pd(darr);
+ __m256d one = _mm256_set1_pd(1.0);
+ __m256d result = _mm256_add_pd(val, one);
+ _mm256_storeu_pd(darr, result);
+ arr[0] = (float)darr[0];
+ arr[1] = (float)darr[1];
+ arr[2] = (float)darr[2];
+ arr[3] = (float)darr[3];
+}
diff --git a/test cases/common/147 simd/simd_avx2.c b/test cases/common/147 simd/simd_avx2.c
new file mode 100644
index 0000000..c79819b
--- /dev/null
+++ b/test cases/common/147 simd/simd_avx2.c
@@ -0,0 +1,42 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+#include<stdint.h>
+
+/*
+ * FIXME add proper runtime detection for VS.
+ */
+
+#ifdef _MSC_VER
+#include<intrin.h>
+int avx2_available(void) {
+ return 0;
+}
+#else
+#include<immintrin.h>
+#include<cpuid.h>
+
+#if defined(__APPLE__)
+int avx2_available(void) { return 0; }
+#else
+int avx2_available(void) {
+ return __builtin_cpu_supports("avx2");
+}
+#endif
+#endif
+
+void increment_avx2(float arr[4]) {
+ double darr[4];
+ darr[0] = arr[0];
+ darr[1] = arr[1];
+ darr[2] = arr[2];
+ darr[3] = arr[3];
+ __m256d val = _mm256_loadu_pd(darr);
+ __m256d one = _mm256_set1_pd(1.0);
+ __m256d result = _mm256_add_pd(val, one);
+ _mm256_storeu_pd(darr, result);
+ one = _mm256_permute4x64_pd(one, 66); /* A no-op, just here to use AVX2. */
+ arr[0] = (float)darr[0];
+ arr[1] = (float)darr[1];
+ arr[2] = (float)darr[2];
+ arr[3] = (float)darr[3];
+}
diff --git a/test cases/common/147 simd/simd_mmx.c b/test cases/common/147 simd/simd_mmx.c
new file mode 100644
index 0000000..7605442
--- /dev/null
+++ b/test cases/common/147 simd/simd_mmx.c
@@ -0,0 +1,67 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+
+#include<stdint.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+int mmx_available(void) {
+ return 1;
+}
+/* Contrary to MSDN documentation, MMX intrinsics
+ * just plain don't work.
+ */
+void increment_mmx(float arr[4]) {
+ arr[0]++;
+ arr[1]++;
+ arr[2]++;
+ arr[3]++;
+}
+#elif defined(__MINGW32__)
+int mmx_available(void) {
+ return 1;
+}
+/* MinGW does not seem to ship with MMX or it is broken.
+ */
+void increment_mmx(float arr[4]) {
+ arr[0]++;
+ arr[1]++;
+ arr[2]++;
+ arr[3]++;
+}
+#else
+#include<mmintrin.h>
+#include<cpuid.h>
+
+#if defined(__APPLE__)
+int mmx_available(void) { return 1; }
+#else
+int mmx_available(void) {
+ return __builtin_cpu_supports("mmx");
+}
+#endif
+void increment_mmx(float arr[4]) {
+ /* Super ugly but we know that values in arr are always small
+ * enough to fit in int16;
+ */
+ int i;
+ __m64 packed = _mm_set_pi16(arr[3], arr[2], arr[1], arr[0]);
+ __m64 incr = _mm_set1_pi16(1);
+ __m64 result = _mm_add_pi16(packed, incr);
+ /* Should be
+ * int64_t unpacker = _m_to_int64(result);
+ * but it does not exist on 32 bit platforms for some reason.
+ */
+ int64_t unpacker = (int64_t)(result);
+ _mm_empty();
+ for(i=0; i<4; i++) {
+ /* This fails on GCC 8 when optimizations are enabled.
+ * Disable it. Patches welcome to fix this.
+ arr[i] = (float)(unpacker & ((1<<16)-1));
+ unpacker >>= 16;
+ */
+ arr[i] += 1.0f;
+ }
+}
+
+#endif
diff --git a/test cases/common/147 simd/simd_neon.c b/test cases/common/147 simd/simd_neon.c
new file mode 100644
index 0000000..2834b30
--- /dev/null
+++ b/test cases/common/147 simd/simd_neon.c
@@ -0,0 +1,20 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+
+#include<arm_neon.h>
+#include<stdint.h>
+
+int neon_available(void) {
+ return 1; /* Incorrect, but I don't know how to check this properly. */
+}
+
+void increment_neon(float arr[4]) {
+ float32x2_t a1, a2, one;
+ a1 = vld1_f32(arr);
+ a2 = vld1_f32(&arr[2]);
+ one = vdup_n_f32(1.0);
+ a1 = vadd_f32(a1, one);
+ a2 = vadd_f32(a2, one);
+ vst1_f32(arr, a1);
+ vst1_f32(&arr[2], a2);
+}
diff --git a/test cases/common/147 simd/simd_sse.c b/test cases/common/147 simd/simd_sse.c
new file mode 100644
index 0000000..6014e0c
--- /dev/null
+++ b/test cases/common/147 simd/simd_sse.c
@@ -0,0 +1,29 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+int sse_available(void) {
+ return 1;
+}
+#else
+
+#include<xmmintrin.h>
+#include<cpuid.h>
+#include<stdint.h>
+
+#if defined(__APPLE__)
+int sse_available(void) { return 1; }
+#else
+int sse_available(void) {
+ return __builtin_cpu_supports("sse");
+}
+#endif
+#endif
+
+void increment_sse(float arr[4]) {
+ __m128 val = _mm_load_ps(arr);
+ __m128 one = _mm_set_ps1(1.0);
+ __m128 result = _mm_add_ps(val, one);
+ _mm_storeu_ps(arr, result);
+}
diff --git a/test cases/common/147 simd/simd_sse2.c b/test cases/common/147 simd/simd_sse2.c
new file mode 100644
index 0000000..3a57a5b
--- /dev/null
+++ b/test cases/common/147 simd/simd_sse2.c
@@ -0,0 +1,36 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+#include<emmintrin.h>
+
+#ifdef _MSC_VER
+int sse2_available(void) {
+ return 1;
+}
+
+#else
+#include<cpuid.h>
+#include<stdint.h>
+
+#if defined(__APPLE__)
+int sse2_available(void) { return 1; }
+#else
+int sse2_available(void) {
+ return __builtin_cpu_supports("sse2");
+}
+#endif
+#endif
+
+void increment_sse2(float arr[4]) {
+ ALIGN_16 double darr[4];
+ __m128d val1 = _mm_set_pd(arr[0], arr[1]);
+ __m128d val2 = _mm_set_pd(arr[2], arr[3]);
+ __m128d one = _mm_set_pd(1.0, 1.0);
+ __m128d result = _mm_add_pd(val1, one);
+ _mm_store_pd(darr, result);
+ result = _mm_add_pd(val2, one);
+ _mm_store_pd(&darr[2], result);
+ arr[0] = (float)darr[1];
+ arr[1] = (float)darr[0];
+ arr[2] = (float)darr[3];
+ arr[3] = (float)darr[2];
+}
diff --git a/test cases/common/147 simd/simd_sse3.c b/test cases/common/147 simd/simd_sse3.c
new file mode 100644
index 0000000..29a35e6
--- /dev/null
+++ b/test cases/common/147 simd/simd_sse3.c
@@ -0,0 +1,38 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+int sse3_available(void) {
+ return 1;
+}
+#else
+
+#include<pmmintrin.h>
+#include<cpuid.h>
+#include<stdint.h>
+
+#if defined(__APPLE__)
+int sse3_available(void) { return 1; }
+#else
+int sse3_available(void) {
+ return __builtin_cpu_supports("sse3");
+}
+#endif
+#endif
+
+void increment_sse3(float arr[4]) {
+ ALIGN_16 double darr[4];
+ __m128d val1 = _mm_set_pd(arr[0], arr[1]);
+ __m128d val2 = _mm_set_pd(arr[2], arr[3]);
+ __m128d one = _mm_set_pd(1.0, 1.0);
+ __m128d result = _mm_add_pd(val1, one);
+ _mm_store_pd(darr, result);
+ result = _mm_add_pd(val2, one);
+ _mm_store_pd(&darr[2], result);
+ result = _mm_hadd_pd(val1, val2); /* This does nothing. Only here so we use an SSE3 instruction. */
+ arr[0] = (float)darr[1];
+ arr[1] = (float)darr[0];
+ arr[2] = (float)darr[3];
+ arr[3] = (float)darr[2];
+}
diff --git a/test cases/common/147 simd/simd_sse41.c b/test cases/common/147 simd/simd_sse41.c
new file mode 100644
index 0000000..29f2555
--- /dev/null
+++ b/test cases/common/147 simd/simd_sse41.c
@@ -0,0 +1,40 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+
+#include<stdint.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+
+int sse41_available(void) {
+ return 1;
+}
+
+#else
+#include<smmintrin.h>
+#include<cpuid.h>
+
+#if defined(__APPLE__)
+int sse41_available(void) { return 1; }
+#else
+int sse41_available(void) {
+ return __builtin_cpu_supports("sse4.1");
+}
+#endif
+#endif
+
+void increment_sse41(float arr[4]) {
+ ALIGN_16 double darr[4];
+ __m128d val1 = _mm_set_pd(arr[0], arr[1]);
+ __m128d val2 = _mm_set_pd(arr[2], arr[3]);
+ __m128d one = _mm_set_pd(1.0, 1.0);
+ __m128d result = _mm_add_pd(val1, one);
+ result = _mm_ceil_pd(result); /* A no-op, only here to use a SSE4.1 intrinsic. */
+ _mm_store_pd(darr, result);
+ result = _mm_add_pd(val2, one);
+ _mm_store_pd(&darr[2], result);
+ arr[0] = (float)darr[1];
+ arr[1] = (float)darr[0];
+ arr[2] = (float)darr[3];
+ arr[3] = (float)darr[2];
+}
diff --git a/test cases/common/147 simd/simd_sse42.c b/test cases/common/147 simd/simd_sse42.c
new file mode 100644
index 0000000..f1564e2
--- /dev/null
+++ b/test cases/common/147 simd/simd_sse42.c
@@ -0,0 +1,43 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+#include<stdint.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+
+int sse42_available(void) {
+ return 1;
+}
+
+#else
+
+#include<nmmintrin.h>
+#include<cpuid.h>
+
+#ifdef __APPLE__
+int sse42_available(void) {
+ return 1;
+}
+#else
+int sse42_available(void) {
+ return __builtin_cpu_supports("sse4.2");
+}
+#endif
+
+#endif
+
+void increment_sse42(float arr[4]) {
+ ALIGN_16 double darr[4];
+ __m128d val1 = _mm_set_pd(arr[0], arr[1]);
+ __m128d val2 = _mm_set_pd(arr[2], arr[3]);
+ __m128d one = _mm_set_pd(1.0, 1.0);
+ __m128d result = _mm_add_pd(val1, one);
+ _mm_store_pd(darr, result);
+ result = _mm_add_pd(val2, one);
+ _mm_store_pd(&darr[2], result);
+ _mm_crc32_u32(42, 99); /* A no-op, only here to use an SSE4.2 instruction. */
+ arr[0] = (float)darr[1];
+ arr[1] = (float)darr[0];
+ arr[2] = (float)darr[3];
+ arr[3] = (float)darr[2];
+}
diff --git a/test cases/common/147 simd/simd_ssse3.c b/test cases/common/147 simd/simd_ssse3.c
new file mode 100644
index 0000000..fa557f4
--- /dev/null
+++ b/test cases/common/147 simd/simd_ssse3.c
@@ -0,0 +1,48 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+
+#include<emmintrin.h>
+#include<tmmintrin.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+
+int ssse3_available(void) {
+ return 1;
+}
+
+#else
+
+#include<cpuid.h>
+#include<stdint.h>
+
+int ssse3_available(void) {
+#ifdef __APPLE__
+ return 1;
+#elif defined(__clang__)
+ /* https://github.com/numpy/numpy/issues/8130 */
+ return __builtin_cpu_supports("sse4.1");
+#else
+ return __builtin_cpu_supports("ssse3");
+#endif
+}
+
+#endif
+
+void increment_ssse3(float arr[4]) {
+ ALIGN_16 double darr[4];
+ __m128d val1 = _mm_set_pd(arr[0], arr[1]);
+ __m128d val2 = _mm_set_pd(arr[2], arr[3]);
+ __m128d one = _mm_set_pd(1.0, 1.0);
+ __m128d result = _mm_add_pd(val1, one);
+ __m128i tmp1, tmp2;
+ tmp1 = tmp2 = _mm_set1_epi16(0);
+ _mm_store_pd(darr, result);
+ result = _mm_add_pd(val2, one);
+ _mm_store_pd(&darr[2], result);
+ tmp1 = _mm_hadd_epi32(tmp1, tmp2); /* This does nothing. Only here so we use an SSSE3 instruction. */
+ arr[0] = (float)darr[1];
+ arr[1] = (float)darr[0];
+ arr[2] = (float)darr[3];
+ arr[3] = (float)darr[2];
+}
diff --git a/test cases/common/147 simd/simdchecker.c b/test cases/common/147 simd/simdchecker.c
new file mode 100644
index 0000000..c7a0a97
--- /dev/null
+++ b/test cases/common/147 simd/simdchecker.c
@@ -0,0 +1,143 @@
+#include<simdfuncs.h>
+#include<stdio.h>
+#include<string.h>
+
+typedef void (*simd_func)(float*);
+
+int check_simd_implementation(float *four,
+ const float *four_initial,
+ const char *simd_type,
+ const float *expected,
+ simd_func fptr,
+ const int blocksize) {
+ int rv = 0;
+ memcpy(four, four_initial, blocksize*sizeof(float));
+ printf("Using %s.\n", simd_type);
+ fptr(four);
+ for(int i=0; i<blocksize; i++) {
+ if(four[i] != expected[i]) {
+ printf("Increment function failed, got %f expected %f.\n", four[i], expected[i]);
+ rv = 1;
+ }
+ }
+ return rv;
+}
+
+int main(void) {
+ static const float four_initial[4] = {2.0, 3.0, 4.0, 5.0};
+ ALIGN_16 float four[4];
+ const float expected[4] = {3.0, 4.0, 5.0, 6.0};
+ int r=0;
+ const int blocksize = 4;
+
+/*
+ * Test all implementations that the current CPU supports.
+ */
+#if HAVE_NEON
+ if(neon_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "NEON",
+ expected,
+ increment_neon,
+ blocksize);
+ }
+#endif
+#if HAVE_AVX2
+ if(avx2_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "AVX2",
+ expected,
+ increment_avx2,
+ blocksize);
+ }
+#endif
+#if HAVE_AVX
+ if(avx_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "AVC",
+ expected,
+ increment_avx,
+ blocksize);
+ }
+#endif
+#if HAVE_SSE42
+ if(sse42_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "SSR42",
+ expected,
+ increment_sse42,
+ blocksize);
+ }
+#endif
+#if HAVE_SSE41
+ if(sse41_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "SSE41",
+ expected,
+ increment_sse41,
+ blocksize);
+ }
+#endif
+#if HAVE_SSSE3
+ if(ssse3_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "SSSE3",
+ expected,
+ increment_ssse3,
+ blocksize);
+ }
+#endif
+#if HAVE_SSE3
+ if(sse3_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "SSE3",
+ expected,
+ increment_sse3,
+ blocksize);
+ }
+#endif
+#if HAVE_SSE2
+ if(sse2_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "SSE2",
+ expected,
+ increment_sse2,
+ blocksize);
+ }
+#endif
+#if HAVE_SSE
+ if(sse_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "SSE",
+ expected,
+ increment_sse,
+ blocksize);
+ }
+#endif
+#if HAVE_MMX
+ if(mmx_available()) {
+ r += check_simd_implementation(four,
+ four_initial,
+ "MMX",
+ expected,
+ increment_mmx,
+ blocksize);
+ }
+#endif
+ r += check_simd_implementation(four,
+ four_initial,
+ "fallback",
+ expected,
+ increment_fallback,
+ blocksize);
+ return r;
+}
diff --git a/test cases/common/147 simd/simdfuncs.h b/test cases/common/147 simd/simdfuncs.h
new file mode 100644
index 0000000..d820f25
--- /dev/null
+++ b/test cases/common/147 simd/simdfuncs.h
@@ -0,0 +1,75 @@
+#pragma once
+
+#include<simdconfig.h>
+
+#ifdef _MSC_VER
+#define ALIGN_16 __declspec(align(16))
+#else
+#include<stdalign.h>
+#define ALIGN_16 alignas(16)
+#endif
+
+
+/* Yes, I do know that arr[4] decays into a pointer
+ * as a function argument. Don't do this in real code
+ * but for this test it is ok.
+ */
+
+void increment_fallback(float arr[4]);
+
+#if HAVE_MMX
+int mmx_available(void);
+void increment_mmx(float arr[4]);
+#endif
+
+#if HAVE_SSE
+int sse_available(void);
+void increment_sse(float arr[4]);
+#endif
+
+#if HAVE_SSE2
+int sse2_available(void);
+void increment_sse2(float arr[4]);
+#endif
+
+#if HAVE_SSE3
+int sse3_available(void);
+void increment_sse3(float arr[4]);
+#endif
+
+#if HAVE_SSSE3
+int ssse3_available(void);
+void increment_ssse3(float arr[4]);
+#endif
+
+#if HAVE_SSE41
+int sse41_available(void);
+void increment_sse41(float arr[4]);
+#endif
+
+#if HAVE_SSE42
+int sse42_available(void);
+void increment_sse42(float arr[4]);
+#endif
+
+#if HAVE_AVX
+int avx_available(void);
+void increment_avx(float arr[4]);
+#endif
+
+#if HAVE_AVX2
+int avx2_available(void);
+void increment_avx2(float arr[4]);
+#endif
+
+#if HAVE_NEON
+int neon_available(void);
+void increment_neon(float arr[4]);
+#endif
+
+#if HAVE_ALTIVEC
+int altivec_available(void);
+void increment_altivec(float arr[4]);
+#endif
+
+/* And so on. */
diff --git a/test cases/common/148 shared module resolving symbol in executable/meson.build b/test cases/common/148 shared module resolving symbol in executable/meson.build
new file mode 100644
index 0000000..bbc7453
--- /dev/null
+++ b/test cases/common/148 shared module resolving symbol in executable/meson.build
@@ -0,0 +1,25 @@
+project('shared module resolving symbol in executable', 'c')
+
+# The shared module contains a reference to the symbol 'func_from_executable',
+# which is always provided by the executable which loads it. This symbol can be
+# resolved at run-time by an ELF loader. But when building PE/COFF objects, all
+# symbols must be resolved at link-time, so an implib is generated for the
+# executable, and the shared module linked with it.
+#
+# See testcase 125 for an example of the more complex portability gymnastics
+# required if we do not know (at link-time) what provides the symbol.
+
+cc = meson.get_compiler('c')
+if cc.get_id() == 'pgi'
+ error('MESON_SKIP_TEST PGI has its own unique set of macros that would need to be handled')
+endif
+
+dl = meson.get_compiler('c').find_library('dl', required: false)
+e = executable('prog', 'prog.c', dependencies: dl, export_dynamic: true)
+e_dep = declare_dependency(link_with: e)
+
+m = shared_module('module', 'module.c', link_with: e)
+m2 = shared_module('module2', 'module.c', dependencies: e_dep)
+
+test('test', e, args: m.full_path())
+test('test2', e, args: m2.full_path())
diff --git a/test cases/common/148 shared module resolving symbol in executable/module.c b/test cases/common/148 shared module resolving symbol in executable/module.c
new file mode 100644
index 0000000..64374d5
--- /dev/null
+++ b/test cases/common/148 shared module resolving symbol in executable/module.c
@@ -0,0 +1,16 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+extern int func_from_executable(void);
+
+int DLL_PUBLIC func(void) {
+ return func_from_executable();
+}
diff --git a/test cases/common/148 shared module resolving symbol in executable/prog.c b/test cases/common/148 shared module resolving symbol in executable/prog.c
new file mode 100644
index 0000000..b2abcdb
--- /dev/null
+++ b/test cases/common/148 shared module resolving symbol in executable/prog.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <assert.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+typedef int (*fptr) (void);
+
+int DLL_PUBLIC
+func_from_executable(void)
+{
+ return 42;
+}
+
+int main(int argc, char **argv)
+{
+ int expected, actual;
+ fptr importedfunc;
+
+ if (argc=0) {}; // noop
+
+#ifdef _WIN32
+ HMODULE h = LoadLibraryA(argv[1]);
+#else
+ void *h = dlopen(argv[1], RTLD_NOW);
+#endif
+ assert(h != NULL);
+
+#ifdef _WIN32
+ importedfunc = (fptr) GetProcAddress (h, "func");
+#else
+ importedfunc = (fptr) dlsym(h, "func");
+#endif
+ assert(importedfunc != NULL);
+ assert(importedfunc != func_from_executable);
+
+ actual = (*importedfunc)();
+ expected = func_from_executable();
+ assert(actual == expected);
+
+#ifdef _WIN32
+ FreeLibrary(h);
+#else
+ dlclose(h);
+#endif
+
+ return 0;
+}
diff --git a/test cases/common/149 dotinclude/dotproc.c b/test cases/common/149 dotinclude/dotproc.c
new file mode 100644
index 0000000..f48c330
--- /dev/null
+++ b/test cases/common/149 dotinclude/dotproc.c
@@ -0,0 +1,10 @@
+#include"stdio.h"
+
+#ifndef WRAPPER_INCLUDED
+#error The wrapper stdio.h was not included.
+#endif
+
+int main(void) {
+ printf("Eventually I got printed.\n");
+ return 0;
+}
diff --git a/test cases/common/149 dotinclude/meson.build b/test cases/common/149 dotinclude/meson.build
new file mode 100644
index 0000000..f094ba1
--- /dev/null
+++ b/test cases/common/149 dotinclude/meson.build
@@ -0,0 +1,4 @@
+project('dotinclude', 'c')
+
+executable('dotproc', 'dotproc.c',
+ implicit_include_directories : false)
diff --git a/test cases/common/149 dotinclude/stdio.h b/test cases/common/149 dotinclude/stdio.h
new file mode 100644
index 0000000..b6bd09f
--- /dev/null
+++ b/test cases/common/149 dotinclude/stdio.h
@@ -0,0 +1,6 @@
+// There is no #pragma once because we _want_ to cause an eternal loop
+// if this wrapper invokes itself.
+
+#define WRAPPER_INCLUDED
+
+#include<stdio.h>
diff --git a/test cases/common/15 if/meson.build b/test cases/common/15 if/meson.build
new file mode 100644
index 0000000..f8d8295
--- /dev/null
+++ b/test cases/common/15 if/meson.build
@@ -0,0 +1,72 @@
+project('if test', 'c')
+
+var1 = true
+set_variable('var2', false)
+
+if var1
+ exe = executable('prog', 'prog.c')
+endif
+
+if var2
+ exe = executable('breakbreakbreak', 'crashing.c')
+endif
+
+test('iftest', exe)
+
+if not is_variable('var1')
+ error('Is_variable fail.')
+endif
+
+if is_variable('nonexisting')
+ error('Is_variable fail 2.')
+endif
+
+if not get_variable('var1', false)
+ error('Get_variable fail.')
+endif
+
+if get_variable('nonexisting', false)
+ error('Get_variable fail.')
+endif
+
+
+# Now test elseif
+
+t = true
+f = false
+
+if true
+ message('Ok.')
+elif true
+ error('Error')
+else
+ error('Error')
+endif
+
+if f
+ error('Error.')
+elif t
+ message('Ok')
+else
+ error('Error')
+endif
+
+if f
+ error('Error.')
+elif false
+ error('Error')
+else
+ message('Ok')
+endif
+
+# Test plain else
+
+var = false
+
+if var
+ exe = executable('break', 'break.c')
+else
+ exe = executable('eprog', 'prog.c')
+endif
+
+test('elsetest', exe)
diff --git a/test cases/common/15 if/prog.c b/test cases/common/15 if/prog.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/15 if/prog.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/150 reserved targets/all/meson.build b/test cases/common/150 reserved targets/all/meson.build
new file mode 100644
index 0000000..adee882
--- /dev/null
+++ b/test cases/common/150 reserved targets/all/meson.build
@@ -0,0 +1 @@
+executable('test-all', '../test.c')
diff --git a/test cases/common/150 reserved targets/benchmark/meson.build b/test cases/common/150 reserved targets/benchmark/meson.build
new file mode 100644
index 0000000..242cc23
--- /dev/null
+++ b/test cases/common/150 reserved targets/benchmark/meson.build
@@ -0,0 +1 @@
+executable('test-benchmark', '../test.c')
diff --git a/test cases/common/150 reserved targets/clean-ctlist/meson.build b/test cases/common/150 reserved targets/clean-ctlist/meson.build
new file mode 100644
index 0000000..75eb207
--- /dev/null
+++ b/test cases/common/150 reserved targets/clean-ctlist/meson.build
@@ -0,0 +1 @@
+executable('test-clean-ctlist', '../test.c')
diff --git a/test cases/common/150 reserved targets/clean-gcda/meson.build b/test cases/common/150 reserved targets/clean-gcda/meson.build
new file mode 100644
index 0000000..488a527
--- /dev/null
+++ b/test cases/common/150 reserved targets/clean-gcda/meson.build
@@ -0,0 +1 @@
+executable('test-clean-gcda', '../test.c')
diff --git a/test cases/common/150 reserved targets/clean-gcno/meson.build b/test cases/common/150 reserved targets/clean-gcno/meson.build
new file mode 100644
index 0000000..eec789a
--- /dev/null
+++ b/test cases/common/150 reserved targets/clean-gcno/meson.build
@@ -0,0 +1 @@
+executable('test-clean-gcno', '../test.c')
diff --git a/test cases/common/150 reserved targets/clean/meson.build b/test cases/common/150 reserved targets/clean/meson.build
new file mode 100644
index 0000000..4e27b6c
--- /dev/null
+++ b/test cases/common/150 reserved targets/clean/meson.build
@@ -0,0 +1 @@
+executable('test-clean', '../test.c')
diff --git a/test cases/common/150 reserved targets/coverage-html/meson.build b/test cases/common/150 reserved targets/coverage-html/meson.build
new file mode 100644
index 0000000..10a4cc8
--- /dev/null
+++ b/test cases/common/150 reserved targets/coverage-html/meson.build
@@ -0,0 +1 @@
+executable('test-coverage-html', '../test.c')
diff --git a/test cases/common/150 reserved targets/coverage-sonarqube/meson.build b/test cases/common/150 reserved targets/coverage-sonarqube/meson.build
new file mode 100644
index 0000000..ac4c0d2
--- /dev/null
+++ b/test cases/common/150 reserved targets/coverage-sonarqube/meson.build
@@ -0,0 +1 @@
+executable('test-coverage-sonarqube', '../test.c')
diff --git a/test cases/common/150 reserved targets/coverage-text/meson.build b/test cases/common/150 reserved targets/coverage-text/meson.build
new file mode 100644
index 0000000..21dcae5
--- /dev/null
+++ b/test cases/common/150 reserved targets/coverage-text/meson.build
@@ -0,0 +1 @@
+executable('test-coverage-text', '../test.c')
diff --git a/test cases/common/150 reserved targets/coverage-xml/meson.build b/test cases/common/150 reserved targets/coverage-xml/meson.build
new file mode 100644
index 0000000..44d7bfb
--- /dev/null
+++ b/test cases/common/150 reserved targets/coverage-xml/meson.build
@@ -0,0 +1 @@
+executable('test-coverage-xml', '../test.c')
diff --git a/test cases/common/150 reserved targets/coverage/meson.build b/test cases/common/150 reserved targets/coverage/meson.build
new file mode 100644
index 0000000..b401055
--- /dev/null
+++ b/test cases/common/150 reserved targets/coverage/meson.build
@@ -0,0 +1 @@
+executable('test-coverage', '../test.c')
diff --git a/test cases/common/150 reserved targets/dist/meson.build b/test cases/common/150 reserved targets/dist/meson.build
new file mode 100644
index 0000000..951bbb4
--- /dev/null
+++ b/test cases/common/150 reserved targets/dist/meson.build
@@ -0,0 +1 @@
+executable('test-dist', '../test.c')
diff --git a/test cases/common/150 reserved targets/distcheck/meson.build b/test cases/common/150 reserved targets/distcheck/meson.build
new file mode 100644
index 0000000..12b9328
--- /dev/null
+++ b/test cases/common/150 reserved targets/distcheck/meson.build
@@ -0,0 +1 @@
+executable('test-distcheck', '../test.c')
diff --git a/test cases/common/150 reserved targets/install/meson.build b/test cases/common/150 reserved targets/install/meson.build
new file mode 100644
index 0000000..4839901
--- /dev/null
+++ b/test cases/common/150 reserved targets/install/meson.build
@@ -0,0 +1 @@
+executable('test-install', '../test.c')
diff --git a/test cases/common/150 reserved targets/meson.build b/test cases/common/150 reserved targets/meson.build
new file mode 100644
index 0000000..24fd937
--- /dev/null
+++ b/test cases/common/150 reserved targets/meson.build
@@ -0,0 +1,34 @@
+project('reserved target names', 'c')
+ # FIXME: Setting this causes it to leak to all other tests
+ #default_options : ['b_coverage=true']
+
+subdir('all')
+subdir('benchmark')
+subdir('clean')
+subdir('clean-ctlist')
+subdir('clean-gcda')
+subdir('clean-gcno')
+subdir('coverage')
+subdir('coverage-html')
+subdir('coverage-text')
+subdir('coverage-xml')
+subdir('dist')
+subdir('distcheck')
+subdir('install')
+# We don't have a 'PHONY' directory because Windows and OSX
+# choke horribly when there are two entries with the same
+# name but different case.
+subdir('phony')
+subdir('reconfigure')
+subdir('scan-build')
+subdir('test')
+subdir('uninstall')
+
+subdir('runtarget')
+
+py3 = import('python3').find_python()
+
+custom_target('ctlist-test', output : 'out.txt',
+ command : [py3, '-c', 'print("")'],
+ capture : true,
+ build_by_default : true)
diff --git a/test cases/common/150 reserved targets/phony/meson.build b/test cases/common/150 reserved targets/phony/meson.build
new file mode 100644
index 0000000..6710fc1
--- /dev/null
+++ b/test cases/common/150 reserved targets/phony/meson.build
@@ -0,0 +1 @@
+executable('test-phony', '../test.c')
diff --git a/test cases/common/150 reserved targets/reconfigure/meson.build b/test cases/common/150 reserved targets/reconfigure/meson.build
new file mode 100644
index 0000000..c3ea3da
--- /dev/null
+++ b/test cases/common/150 reserved targets/reconfigure/meson.build
@@ -0,0 +1 @@
+executable('test-reconfigure', '../test.c')
diff --git a/test cases/common/150 reserved targets/runtarget/echo.py b/test cases/common/150 reserved targets/runtarget/echo.py
new file mode 100644
index 0000000..7f9f179
--- /dev/null
+++ b/test cases/common/150 reserved targets/runtarget/echo.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+
+if len(sys.argv) > 1:
+ print(sys.argv[1])
diff --git a/test cases/common/150 reserved targets/runtarget/meson.build b/test cases/common/150 reserved targets/runtarget/meson.build
new file mode 100644
index 0000000..7ba0b8c
--- /dev/null
+++ b/test cases/common/150 reserved targets/runtarget/meson.build
@@ -0,0 +1,2 @@
+configure_file(output : 'config.h', configuration: configuration_data())
+run_target('runtarget', command : [find_program('echo.py')])
diff --git a/test cases/common/150 reserved targets/scan-build/meson.build b/test cases/common/150 reserved targets/scan-build/meson.build
new file mode 100644
index 0000000..1002053
--- /dev/null
+++ b/test cases/common/150 reserved targets/scan-build/meson.build
@@ -0,0 +1 @@
+executable('test-scan-build', '../test.c')
diff --git a/test cases/common/150 reserved targets/test.c b/test cases/common/150 reserved targets/test.c
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/test cases/common/150 reserved targets/test.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/150 reserved targets/test/meson.build b/test cases/common/150 reserved targets/test/meson.build
new file mode 100644
index 0000000..4ab123c
--- /dev/null
+++ b/test cases/common/150 reserved targets/test/meson.build
@@ -0,0 +1 @@
+executable('test-test', '../test.c')
diff --git a/test cases/common/150 reserved targets/uninstall/meson.build b/test cases/common/150 reserved targets/uninstall/meson.build
new file mode 100644
index 0000000..21c6ca6
--- /dev/null
+++ b/test cases/common/150 reserved targets/uninstall/meson.build
@@ -0,0 +1 @@
+executable('test-uninstall', '../test.c')
diff --git a/test cases/common/151 duplicate source names/dir1/file.c b/test cases/common/151 duplicate source names/dir1/file.c
new file mode 100644
index 0000000..1c4753e
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir1/file.c
@@ -0,0 +1,16 @@
+extern int dir2;
+extern int dir2_dir1;
+extern int dir3;
+extern int dir3_dir1;
+
+int main(void) {
+ if (dir2 != 20)
+ return 1;
+ if (dir2_dir1 != 21)
+ return 1;
+ if (dir3 != 30)
+ return 1;
+ if (dir3_dir1 != 31)
+ return 1;
+ return 0;
+}
diff --git a/test cases/common/151 duplicate source names/dir1/meson.build b/test cases/common/151 duplicate source names/dir1/meson.build
new file mode 100644
index 0000000..00bc85d
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir1/meson.build
@@ -0,0 +1 @@
+sources += files('file.c')
diff --git a/test cases/common/151 duplicate source names/dir2/dir1/file.c b/test cases/common/151 duplicate source names/dir2/dir1/file.c
new file mode 100644
index 0000000..5aac8e5
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir2/dir1/file.c
@@ -0,0 +1 @@
+int dir2_dir1 = 21;
diff --git a/test cases/common/151 duplicate source names/dir2/file.c b/test cases/common/151 duplicate source names/dir2/file.c
new file mode 100644
index 0000000..6cf8d66
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir2/file.c
@@ -0,0 +1 @@
+int dir2 = 20;
diff --git a/test cases/common/151 duplicate source names/dir2/meson.build b/test cases/common/151 duplicate source names/dir2/meson.build
new file mode 100644
index 0000000..f116a02
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir2/meson.build
@@ -0,0 +1 @@
+sources += files('file.c', 'dir1/file.c')
diff --git a/test cases/common/151 duplicate source names/dir3/dir1/file.c b/test cases/common/151 duplicate source names/dir3/dir1/file.c
new file mode 100644
index 0000000..04667c2
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir3/dir1/file.c
@@ -0,0 +1 @@
+int dir3_dir1 = 31;
diff --git a/test cases/common/151 duplicate source names/dir3/file.c b/test cases/common/151 duplicate source names/dir3/file.c
new file mode 100644
index 0000000..d16d0a8
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir3/file.c
@@ -0,0 +1 @@
+int dir3 = 30;
diff --git a/test cases/common/151 duplicate source names/dir3/meson.build b/test cases/common/151 duplicate source names/dir3/meson.build
new file mode 100644
index 0000000..70ddbf2
--- /dev/null
+++ b/test cases/common/151 duplicate source names/dir3/meson.build
@@ -0,0 +1 @@
+lib = static_library('lib', 'file.c', 'dir1/file.c')
diff --git a/test cases/common/151 duplicate source names/meson.build b/test cases/common/151 duplicate source names/meson.build
new file mode 100644
index 0000000..635aa8c
--- /dev/null
+++ b/test cases/common/151 duplicate source names/meson.build
@@ -0,0 +1,19 @@
+project('proj', 'c')
+
+if meson.backend() == 'xcode'
+ # Xcode gives object files unique names but only if they would clash. For example
+ # two files named lib.o instead get the following names:
+ #
+ # lib-4fbe522d8ba4cb1f1b89cc2df640a2336b92e1a5565f0a4c5a79b5b5e2969eb9.o
+ # lib-4fbe522d8ba4cb1f1b89cc2df640a2336deeff2bc2297affaadbe20f5cbfee56.o
+ #
+ # No-one has reverse engineered the naming scheme so we would access them.
+ # IF you feel up to the challenge, patches welcome.
+ error('MESON_SKIP_TEST, Xcode can not extract objs when they would have the same filename.')
+endif
+
+sources = []
+subdir('dir1')
+subdir('dir2')
+subdir('dir3')
+executable('a.out', sources : sources, objects : lib.extract_all_objects())
diff --git a/test cases/common/152 index customtarget/check_args.py b/test cases/common/152 index customtarget/check_args.py
new file mode 100644
index 0000000..8663a6f
--- /dev/null
+++ b/test cases/common/152 index customtarget/check_args.py
@@ -0,0 +1,18 @@
+#!python3
+
+import sys
+from pathlib import Path
+
+def main():
+ if len(sys.argv) != 2:
+ print(sys.argv)
+ return 1
+ if sys.argv[1] != 'gen.c':
+ print(sys.argv)
+ return 2
+ Path('foo').touch()
+
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/test cases/common/152 index customtarget/gen_sources.py b/test cases/common/152 index customtarget/gen_sources.py
new file mode 100644
index 0000000..0bdb529
--- /dev/null
+++ b/test cases/common/152 index customtarget/gen_sources.py
@@ -0,0 +1,49 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import textwrap
+
+HEADER = textwrap.dedent('''\
+ void stringify(int foo, char * buffer);
+ ''')
+
+CODE = textwrap.dedent('''\
+ #include <stdio.h>
+
+ #ifndef WORKS
+ # error "This shouldn't have been included"
+ #endif
+
+ void stringify(int foo, char * buffer) {
+ sprintf(buffer, "%i", foo);
+ }
+ ''')
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--header')
+ parser.add_argument('--code')
+ args = parser.parse_args()
+
+ with open(args.header, 'w') as f:
+ f.write(HEADER)
+
+ with open(args.code, 'w') as f:
+ f.write(CODE)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test cases/common/152 index customtarget/lib.c b/test cases/common/152 index customtarget/lib.c
new file mode 100644
index 0000000..17117d5
--- /dev/null
+++ b/test cases/common/152 index customtarget/lib.c
@@ -0,0 +1,20 @@
+/* Copyright © 2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gen.h"
+
+void func(char * buffer) {
+ stringify(1, buffer);
+}
diff --git a/test cases/common/152 index customtarget/meson.build b/test cases/common/152 index customtarget/meson.build
new file mode 100644
index 0000000..efddfac
--- /dev/null
+++ b/test cases/common/152 index customtarget/meson.build
@@ -0,0 +1,80 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('custom_target_index', 'c', default_options : 'c_std=c89')
+
+py_mod = import('python3')
+prog_python = py_mod.find_python()
+
+gen = custom_target(
+ 'gen.[ch]',
+ input : 'gen_sources.py',
+ output : ['gen.c', 'gen.h'],
+ command : [prog_python, '@INPUT@', '--header', '@OUTPUT1@', '--code', '@OUTPUT0@'],
+)
+
+has_not_changed = false
+if is_disabler(gen)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+
+assert(has_not_changed, 'Custom target has changed.')
+
+assert(not is_disabler(gen), 'Custom target is a disabler.')
+
+lib = static_library(
+ 'libfoo',
+ ['lib.c', gen[1]],
+)
+
+has_not_changed = false
+if is_disabler(lib)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+
+assert(has_not_changed, 'Static library has changed.')
+
+assert(not is_disabler(lib), 'Static library is a disabler.')
+
+custom_target(
+ 'foo',
+ input: gen[0],
+ output: 'foo',
+ command: [find_program('check_args.py'), '@INPUT@'],
+)
+
+subdir('subdir')
+
+gen = disabler()
+
+assert(is_disabler(gen), 'Generator is not a disabler.')
+
+lib = static_library(
+ 'libfoo',
+ ['lib.c', gen[1]],
+)
+
+assert(is_disabler(lib), 'Static library is not a disabler.')
+
+if lib.found()
+ lib_disabled = false
+else
+ lib_disabled = true
+endif
+
+assert(lib_disabled, 'Static library was not disabled.')
diff --git a/test cases/common/152 index customtarget/subdir/foo.c b/test cases/common/152 index customtarget/subdir/foo.c
new file mode 100644
index 0000000..c620a11
--- /dev/null
+++ b/test cases/common/152 index customtarget/subdir/foo.c
@@ -0,0 +1,22 @@
+/* Copyright © 2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gen.h"
+
+int main(void) {
+ char buf[50];
+ stringify(10, buf);
+ return 0;
+}
diff --git a/test cases/common/152 index customtarget/subdir/meson.build b/test cases/common/152 index customtarget/subdir/meson.build
new file mode 100644
index 0000000..47bcd32
--- /dev/null
+++ b/test cases/common/152 index customtarget/subdir/meson.build
@@ -0,0 +1,19 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+foo = executable(
+ 'foo',
+ ['foo.c', gen[0], gen[1]],
+ c_args : '-DWORKS',
+)
diff --git a/test cases/common/153 wrap file should not failed/meson.build b/test cases/common/153 wrap file should not failed/meson.build
new file mode 100644
index 0000000..5448502
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/meson.build
@@ -0,0 +1,23 @@
+project('mainproj', 'c',
+ default_options : ['wrap_mode=nodownload'],
+)
+
+if not find_program('patch', required : false).found() and not find_program('git', required : false).found()
+ error('MESON_SKIP_TEST: patch/git not found.')
+endif
+
+subproject('zlib')
+foo = subproject('foo')
+bar = subproject('bar')
+
+libfoo = foo.get_variable('libfoo')
+libbar = bar.get_variable('libbar')
+
+executable('grabprog', files('src/subprojects/prog.c'))
+executable('grabprog2', files('src/subprojects/foo/prog2.c'))
+subdir('src')
+
+subproject('patchdir')
+
+exe = subproject('patchfile').get_variable('foo_exe')
+test('test_foo', exe)
diff --git a/test cases/common/153 wrap file should not failed/src/meson.build b/test cases/common/153 wrap file should not failed/src/meson.build
new file mode 100644
index 0000000..0c82165
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/src/meson.build
@@ -0,0 +1,6 @@
+executable('grabprog3', files('subprojects/prog.c'))
+executable('grabprog4', files('subprojects/foo/prog2.c'))
+
+texe = executable('testexe', files('test.c'), link_with: [libfoo, libbar])
+
+test('t1', texe)
diff --git a/test cases/common/153 wrap file should not failed/src/subprojects/foo/prog2.c b/test cases/common/153 wrap file should not failed/src/subprojects/foo/prog2.c
new file mode 100644
index 0000000..849b400
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/src/subprojects/foo/prog2.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Do not have a file layout like this in your own projects.\n");
+ printf("This is only to test that this works.\n");
+ return 0;
+}
diff --git a/test cases/common/153 wrap file should not failed/src/subprojects/prog.c b/test cases/common/153 wrap file should not failed/src/subprojects/prog.c
new file mode 100644
index 0000000..849b400
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/src/subprojects/prog.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Do not have a file layout like this in your own projects.\n");
+ printf("This is only to test that this works.\n");
+ return 0;
+}
diff --git a/test cases/common/153 wrap file should not failed/src/test.c b/test cases/common/153 wrap file should not failed/src/test.c
new file mode 100644
index 0000000..34cf991
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/src/test.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int bar_dummy_func(void);
+int dummy_func(void);
+
+int main(void) {
+ printf("Hello world %d\n", bar_dummy_func() + dummy_func());
+ return 0;
+}
diff --git a/test cases/common/153 wrap file should not failed/subprojects/.gitignore b/test cases/common/153 wrap file should not failed/subprojects/.gitignore
new file mode 100644
index 0000000..aabded6
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/.gitignore
@@ -0,0 +1,3 @@
+/foo-1.0
+/bar-1.0
+/foo-1.0-patchdir
diff --git a/test cases/common/153 wrap file should not failed/subprojects/bar-1.0/bar.c b/test cases/common/153 wrap file should not failed/subprojects/bar-1.0/bar.c
new file mode 100644
index 0000000..36dcff0
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/bar-1.0/bar.c
@@ -0,0 +1,3 @@
+int bar_dummy_func(void) {
+ return 42;
+}
diff --git a/test cases/common/153 wrap file should not failed/subprojects/bar-1.0/meson.build b/test cases/common/153 wrap file should not failed/subprojects/bar-1.0/meson.build
new file mode 100644
index 0000000..c3d9fee
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/bar-1.0/meson.build
@@ -0,0 +1,2 @@
+project('static lib bar', 'c')
+libbar = static_library('bar', 'bar.c')
diff --git a/test cases/common/153 wrap file should not failed/subprojects/bar.wrap b/test cases/common/153 wrap file should not failed/subprojects/bar.wrap
new file mode 100644
index 0000000..4e8f7e3
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/bar.wrap
@@ -0,0 +1,8 @@
+[wrap-file]
+directory = bar-1.0
+lead_directory_missing = true
+
+source_filename = bar-1.0.tar.xz
+source_hash = f0f61948530dc0d33e3028cd71a9f8ee869f6b3665960d8f41d715cf4aed6467
+
+patch_filename = bar-1.0-patch.tar.xz
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/foo.c b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/foo.c
new file mode 100644
index 0000000..267b43a
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/foo.c
@@ -0,0 +1,3 @@
+int dummy_func(void) {
+ return 42;
+}
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/meson.build b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/meson.build
new file mode 100644
index 0000000..dbaf91f
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchdir/meson.build
@@ -0,0 +1,2 @@
+project('static lib patchdir', 'c')
+libfoo = static_library('foo', 'foo.c')
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/.meson-subproject-wrap-hash.txt b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/.meson-subproject-wrap-hash.txt
new file mode 100644
index 0000000..81b251f
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/.meson-subproject-wrap-hash.txt
@@ -0,0 +1 @@
+0af7983865d151deb48307cc86e9631767501d73016dcf6193523e306caa5485
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/foo.c b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/foo.c
new file mode 100644
index 0000000..d78f25c
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/foo.c
@@ -0,0 +1,7 @@
+int dummy_func(void) {
+ return 44;
+}
+
+int main(void) {
+ return dummy_func() == 44 ? 0 : 1;
+}
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/meson.build b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/meson.build
new file mode 100644
index 0000000..ae5d800
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0-patchfile/meson.build
@@ -0,0 +1,2 @@
+project('static lib patchdir', 'c')
+foo_exe = executable('foo', 'foo.c')
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo-1.0/foo.c b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0/foo.c
new file mode 100644
index 0000000..267b43a
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0/foo.c
@@ -0,0 +1,3 @@
+int dummy_func(void) {
+ return 42;
+}
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo-1.0/meson.build b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0/meson.build
new file mode 100644
index 0000000..bcb8bf7
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo-1.0/meson.build
@@ -0,0 +1,2 @@
+project('static lib', 'c')
+libfoo = static_library('foo', 'foo.c')
diff --git a/test cases/common/153 wrap file should not failed/subprojects/foo.wrap b/test cases/common/153 wrap file should not failed/subprojects/foo.wrap
new file mode 100644
index 0000000..c67c5e5
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/foo.wrap
@@ -0,0 +1,11 @@
+[wrap-file]
+directory = foo-1.0
+
+source_url = http://something.invalid
+source_filename = foo-1.0.tar.xz
+source_hash = 9ed8f67d75e43d3be161efb6eddf30dd01995a958ca83951ea64234bac8908c1
+lead_directory_missing = true
+
+patch_url = https://something.invalid/patch
+patch_filename = foo-1.0-patch.tar.xz
+patch_hash = d0ddc5e60fdb27d808552f5ac8d0bb603ea2cba306538b4427b985535b26c9c5
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0-patch.tar.xz b/test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0-patch.tar.xz
new file mode 100644
index 0000000..e26b8e0
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0-patch.tar.xz
Binary files differ
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0.tar.xz b/test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0.tar.xz
new file mode 100644
index 0000000..37eb6cc
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagecache/foo-1.0.tar.xz
Binary files differ
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8-8-wrap.zip b/test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8-8-wrap.zip
new file mode 100644
index 0000000..421376d
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8-8-wrap.zip
@@ -0,0 +1 @@
+dummy
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8.tar.gz b/test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8.tar.gz
new file mode 100644
index 0000000..421376d
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagecache/zlib-1.2.8.tar.gz
@@ -0,0 +1 @@
+dummy
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0-patch.tar.xz b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0-patch.tar.xz
new file mode 100644
index 0000000..f257a19
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0-patch.tar.xz
Binary files differ
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0.tar.xz b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0.tar.xz
new file mode 100644
index 0000000..d90a9e8
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/bar-1.0.tar.xz
Binary files differ
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/foo-1.0/meson.build b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/foo-1.0/meson.build
new file mode 100644
index 0000000..dbaf91f
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/foo-1.0/meson.build
@@ -0,0 +1,2 @@
+project('static lib patchdir', 'c')
+libfoo = static_library('foo', 'foo.c')
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch
new file mode 100644
index 0000000..a29fb6c
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch
@@ -0,0 +1,33 @@
+From b79f6cc4a096f6c2888f73b947b652491885896a Mon Sep 17 00:00:00 2001
+From: Xavier Claessens <xavier.claessens@collabora.com>
+Date: Fri, 30 Nov 2018 14:13:47 -0500
+Subject: [PATCH] Change foo to executable
+
+---
+ foo.c | 4 ++++
+ meson.build | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/foo.c b/foo.c
+index 54f9119..468f033 100644
+--- a/foo.c
++++ b/foo.c
+@@ -1,3 +1,7 @@
+ int dummy_func(void) {
+ return 44;
+ }
++
++int main(void) {
++ return dummy_func() == 44 ? 0 : 1;
++}
+diff --git a/meson.build b/meson.build
+index 318e81d..4a281d9 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1,2 +1,2 @@
+ project('static lib patchdir', 'c')
+-libfoo = static_library('foo', 'foo.c')
++foo_exe = executable('foo', 'foo.c')
+--
+2.17.1
+
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch
new file mode 100644
index 0000000..49cf1e9
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch
@@ -0,0 +1,21 @@
+From 7001dcc738e5ae7dfa8af20ed582b9a985804f72 Mon Sep 17 00:00:00 2001
+From: Xavier Claessens <xavier.claessens@collabora.com>
+Date: Fri, 30 Nov 2018 10:15:33 -0500
+Subject: [PATCH 1/2] Change return value to 43
+
+---
+ foo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/foo.c b/foo.c
+index 019f2ba..e4577b8 100644
+--- a/foo.c
++++ b/foo.c
+@@ -1,3 +1,3 @@
+ int dummy_func(void) {
+- return 42;
++ return 43;
+ }
+--
+2.17.1
+
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch
new file mode 100644
index 0000000..4794cea
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch
@@ -0,0 +1,21 @@
+From c2da2e490b09f2e251c7f4ef7c1240acee215fec Mon Sep 17 00:00:00 2001
+From: Xavier Claessens <xavier.claessens@collabora.com>
+Date: Fri, 30 Nov 2018 10:15:47 -0500
+Subject: [PATCH 2/2] Change return value to 44
+
+---
+ foo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/foo.c b/foo.c
+index e4577b8..54f9119 100644
+--- a/foo.c
++++ b/foo.c
+@@ -1,3 +1,3 @@
+ int dummy_func(void) {
+- return 43;
++ return 44;
+ }
+--
+2.17.1
+
diff --git a/test cases/common/153 wrap file should not failed/subprojects/patchdir.wrap b/test cases/common/153 wrap file should not failed/subprojects/patchdir.wrap
new file mode 100644
index 0000000..1a2134c
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/patchdir.wrap
@@ -0,0 +1,9 @@
+[wrap-file]
+directory = foo-1.0-patchdir
+
+source_url = http://something.invalid
+source_filename = foo-1.0.tar.xz
+source_hash = 9ed8f67d75e43d3be161efb6eddf30dd01995a958ca83951ea64234bac8908c1
+lead_directory_missing = true
+
+patch_directory = foo-1.0
diff --git a/test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap b/test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap
new file mode 100644
index 0000000..3d446fe
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap
@@ -0,0 +1,14 @@
+[wrap-file]
+directory = foo-1.0-patchfile
+
+source_url = http://something.invalid
+source_filename = foo-1.0.tar.xz
+source_hash = 9ed8f67d75e43d3be161efb6eddf30dd01995a958ca83951ea64234bac8908c1
+lead_directory_missing = true
+
+patch_directory = foo-1.0
+
+diff_files =
+ patchfile/0001-Change-return-value-to-43.patch,
+ patchfile/0002-Change-return-value-to-44.patch,
+ patchfile/0001-Change-foo-to-executable.patch
diff --git a/test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/foo.c b/test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/foo.c
new file mode 100644
index 0000000..267b43a
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/foo.c
@@ -0,0 +1,3 @@
+int dummy_func(void) {
+ return 42;
+}
diff --git a/test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/meson.build b/test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/meson.build
new file mode 100644
index 0000000..70d493f
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/zlib-1.2.8/meson.build
@@ -0,0 +1,2 @@
+project('shared lib', 'c')
+library('foo', 'foo.c')
diff --git a/test cases/common/153 wrap file should not failed/subprojects/zlib.wrap b/test cases/common/153 wrap file should not failed/subprojects/zlib.wrap
new file mode 100644
index 0000000..6d5896f
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/zlib.wrap
@@ -0,0 +1,10 @@
+[wrap-file]
+directory = zlib-1.2.8
+
+source_url = http://zlib.net/fossils/zlib-1.2.8.tar.gz
+source_filename = zlib-1.2.8.tar.gz
+source_hash = 36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d
+
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/zlib/1.2.8/8/get_zip
+patch_filename = zlib-1.2.8-8-wrap.zip
+patch_hash = 17c52a0e0c59ce926d3959005d5cd8178c6c7e2c9a4a1304279a8320c955ac60
diff --git a/test cases/common/154 includedir subproj/meson.build b/test cases/common/154 includedir subproj/meson.build
new file mode 100644
index 0000000..b3de5af
--- /dev/null
+++ b/test cases/common/154 includedir subproj/meson.build
@@ -0,0 +1,9 @@
+project('include dir in subproj test', 'c')
+
+
+subproject('inctest')
+
+
+exe = executable('prog', 'prog.c')
+
+test('dummy', exe)
diff --git a/test cases/common/154 includedir subproj/prog.c b/test cases/common/154 includedir subproj/prog.c
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/test cases/common/154 includedir subproj/prog.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/154 includedir subproj/subprojects/inctest/include/incfile.h b/test cases/common/154 includedir subproj/subprojects/inctest/include/incfile.h
new file mode 100644
index 0000000..ec740da
--- /dev/null
+++ b/test cases/common/154 includedir subproj/subprojects/inctest/include/incfile.h
@@ -0,0 +1,2 @@
+
+/* file which is used in the subproject */
diff --git a/test cases/common/154 includedir subproj/subprojects/inctest/meson.build b/test cases/common/154 includedir subproj/subprojects/inctest/meson.build
new file mode 100644
index 0000000..74aabcb
--- /dev/null
+++ b/test cases/common/154 includedir subproj/subprojects/inctest/meson.build
@@ -0,0 +1,13 @@
+
+project('subproj with includedir', 'c')
+
+
+
+compile_check = '''
+#include "incfile.h"
+'''
+
+if not meson.get_compiler('c').compiles(compile_check, name : 'include in subproj',
+ include_directories: include_directories('include'))
+ error('failed')
+endif
diff --git a/test cases/common/155 subproject dir name collision/a.c b/test cases/common/155 subproject dir name collision/a.c
new file mode 100644
index 0000000..7510a1b
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/a.c
@@ -0,0 +1,13 @@
+#include<assert.h>
+char func_b(void);
+char func_c(void);
+
+int main(void) {
+ if(func_b() != 'b') {
+ return 1;
+ }
+ if(func_c() != 'c') {
+ return 2;
+ }
+ return 0;
+}
diff --git a/test cases/common/155 subproject dir name collision/custom_subproject_dir/B/b.c b/test cases/common/155 subproject dir name collision/custom_subproject_dir/B/b.c
new file mode 100644
index 0000000..4d71c0f
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/custom_subproject_dir/B/b.c
@@ -0,0 +1,20 @@
+#include<stdlib.h>
+char func_c(void);
+
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_b(void) {
+ if(func_c() != 'c') {
+ exit(3);
+ }
+ return 'b';
+}
diff --git a/test cases/common/155 subproject dir name collision/custom_subproject_dir/B/meson.build b/test cases/common/155 subproject dir name collision/custom_subproject_dir/B/meson.build
new file mode 100644
index 0000000..8f4cb02
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/custom_subproject_dir/B/meson.build
@@ -0,0 +1,4 @@
+project('B', 'c')
+C = subproject('C')
+c = C.get_variable('c')
+b = library('b', 'b.c', link_with : c)
diff --git a/test cases/common/155 subproject dir name collision/custom_subproject_dir/C/c.c b/test cases/common/155 subproject dir name collision/custom_subproject_dir/C/c.c
new file mode 100644
index 0000000..facd199
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/custom_subproject_dir/C/c.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_c(void) {
+ return 'c';
+}
diff --git a/test cases/common/155 subproject dir name collision/custom_subproject_dir/C/meson.build b/test cases/common/155 subproject dir name collision/custom_subproject_dir/C/meson.build
new file mode 100644
index 0000000..1f05f9e
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/custom_subproject_dir/C/meson.build
@@ -0,0 +1,3 @@
+project('C', 'c')
+# libc.so cannot be used, it already exists as a reserved name
+c = library('cee', 'c.c')
diff --git a/test cases/common/155 subproject dir name collision/meson.build b/test cases/common/155 subproject dir name collision/meson.build
new file mode 100644
index 0000000..5531217
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/meson.build
@@ -0,0 +1,12 @@
+project('A', 'c', subproject_dir:'custom_subproject_dir')
+
+B = subproject('B')
+b = B.get_variable('b')
+
+C = subproject('C')
+c = C.get_variable('c')
+
+subdir('other_subdir')
+
+a = executable('a', 'a.c', link_with : [b, c])
+test('a test', a)
diff --git a/test cases/common/155 subproject dir name collision/other_subdir/custom_subproject_dir/other.c b/test cases/common/155 subproject dir name collision/other_subdir/custom_subproject_dir/other.c
new file mode 100644
index 0000000..fa1953e
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/other_subdir/custom_subproject_dir/other.c
@@ -0,0 +1,19 @@
+#include<stdlib.h>
+
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_b(void) {
+ if('c' != 'c') {
+ exit(3);
+ }
+ return 'b';
+}
diff --git a/test cases/common/155 subproject dir name collision/other_subdir/meson.build b/test cases/common/155 subproject dir name collision/other_subdir/meson.build
new file mode 100644
index 0000000..37cb623
--- /dev/null
+++ b/test cases/common/155 subproject dir name collision/other_subdir/meson.build
@@ -0,0 +1 @@
+other = library('other', 'custom_subproject_dir/other.c')
diff --git a/test cases/common/156 config tool variable/meson.build b/test cases/common/156 config tool variable/meson.build
new file mode 100644
index 0000000..fc80594
--- /dev/null
+++ b/test cases/common/156 config tool variable/meson.build
@@ -0,0 +1,31 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('config tool variable', 'cpp')
+
+
+dep_llvm = dependency('llvm', method : 'config-tool', required : false)
+if not dep_llvm.found()
+ error('MESON_SKIP_TEST LLVM not installed.')
+endif
+
+includedir = dep_llvm.get_configtool_variable('includedir')
+includedir = join_paths(includedir, 'llvm')
+if host_machine.system() == 'windows'
+ cmd = run_command(['dir', includedir], check: false)
+else
+ cmd = run_command(['ls', includedir], check: false)
+endif
+
+assert(cmd.returncode() == 0, 'did not run successfully')
diff --git a/test cases/common/157 custom target subdir depend files/copyfile.py b/test cases/common/157 custom target subdir depend files/copyfile.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/common/157 custom target subdir depend files/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/157 custom target subdir depend files/meson.build b/test cases/common/157 custom target subdir depend files/meson.build
new file mode 100644
index 0000000..44f5c71
--- /dev/null
+++ b/test cases/common/157 custom target subdir depend files/meson.build
@@ -0,0 +1,7 @@
+project('custom target subdir depend files', 'c')
+
+copy = find_program('copyfile.py')
+
+subdir('subdir')
+
+executable('foo', foo_src)
diff --git a/test cases/common/157 custom target subdir depend files/subdir/dep.dat b/test cases/common/157 custom target subdir depend files/subdir/dep.dat
new file mode 100644
index 0000000..5daee49
--- /dev/null
+++ b/test cases/common/157 custom target subdir depend files/subdir/dep.dat
@@ -0,0 +1 @@
+You can depend on this file. \ No newline at end of file
diff --git a/test cases/common/157 custom target subdir depend files/subdir/foo.c.in b/test cases/common/157 custom target subdir depend files/subdir/foo.c.in
new file mode 100644
index 0000000..a867b32
--- /dev/null
+++ b/test cases/common/157 custom target subdir depend files/subdir/foo.c.in
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void) {
+ printf("foo is working.\n");
+ return 0;
+}
diff --git a/test cases/common/157 custom target subdir depend files/subdir/meson.build b/test cases/common/157 custom target subdir depend files/subdir/meson.build
new file mode 100644
index 0000000..f9d31c4
--- /dev/null
+++ b/test cases/common/157 custom target subdir depend files/subdir/meson.build
@@ -0,0 +1,6 @@
+foo_src = custom_target('foo_src',
+ depend_files : 'dep.dat',
+ input : 'foo.c.in',
+ output : 'foo.c',
+ command : [copy, '@INPUT@', '@OUTPUT@']
+)
diff --git a/test cases/common/158 disabler/meson.build b/test cases/common/158 disabler/meson.build
new file mode 100644
index 0000000..d132e2b
--- /dev/null
+++ b/test cases/common/158 disabler/meson.build
@@ -0,0 +1,153 @@
+project('dolphin option', 'c')
+
+d = disabler()
+
+full_path = d.full_path()
+assert(is_disabler(full_path), 'Method call is not a disabler')
+
+d2 = dependency(d)
+d3 = (d == d2)
+d4 = d + 0
+d5 = d2 or true
+set_variable('d6', disabler())
+
+has_not_changed = false
+if is_disabler(d)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'Disabler has changed.')
+
+assert(is_disabler(d), 'Disabler was not identified correctly.')
+assert(is_disabler(d2), 'Function laundered disabler was not identified correctly.')
+assert(is_disabler(d3), 'Disabler comparison should yield disabler.')
+assert(is_disabler(d4), 'Disabler addition should yield disabler.')
+assert(is_disabler(d5), 'Disabler logic op should yield disabler.')
+assert(is_disabler(d6), 'set_variable with a disabler should set variable to disabler.')
+
+assert(d, 'Disabler did not cause this to be skipped.')
+assert(d2, 'Function laundered disabler did not cause this to be skipped.')
+assert(d3, 'Disabler comparison should yield disabler and thus this would not be called.')
+assert(d4, 'Disabler addition should yield disabler and thus this would not be called.')
+assert(d5, 'Disabler logic op should yield disabler and thus this would not be called.')
+assert(d6, 'set_variable with a disabler did not cause this to be skipped.')
+
+number = 0
+
+if d
+ number = 1
+else
+ number = 2
+endif
+
+has_not_changed = false
+if is_disabler(number)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'Number has changed.')
+
+assert(not is_disabler(number), 'Number should not be a disabler.')
+assert(number == 0, 'Plain if handled incorrectly, value should be 0 but is @0@'.format(number))
+
+if d.found()
+ number = 1
+else
+ number = 2
+endif
+
+assert(number == 2, 'If found handled incorrectly, value should be 2 but is @0@'.format(number))
+
+dep = dependency('notfounddep', required : false, disabler : true)
+app = executable('myapp', 'notfound.c', dependencies : [dep])
+assert(is_disabler(app), 'App is not a disabler.')
+app = executable('myapp', 'notfound.c', dependencies : [[dep]])
+assert(is_disabler(app), 'App is not a disabler.')
+
+cc = meson.get_compiler('c')
+dep = cc.find_library('notfounddep', required : false, disabler : true)
+app = executable('myapp', 'notfound.c', dependencies : [dep])
+assert(is_disabler(app), 'App is not a disabler.')
+
+dep = find_program('donotfindme', required : false, disabler : true)
+app = executable('myapp', 'notfound.c', dependencies : [dep])
+assert(is_disabler(app), 'App is not a disabler.')
+
+has_not_changed = false
+if is_disabler(app)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'App has changed.')
+
+assert(not is_disabler(is_variable('d6')), 'is_variable should not return a disabler')
+assert(is_variable('d6'), 'is_variable for a disabler should return true')
+
+if_is_not_disabled = false
+if is_variable('d6')
+ if_is_not_disabled = true
+else
+ if_is_not_disabled = true
+endif
+assert(if_is_not_disabled, 'Disabler in is_variable should not skip blocks')
+
+get_d = get_variable('d6')
+assert(is_disabler(get_d), 'get_variable should yield a disabler')
+
+get_fallback_d = get_variable('nonexistant', disabler())
+assert(is_disabler(get_fallback_d), 'get_variable fallback should yield a disabler')
+
+var_true = true
+get_no_fallback_d = get_variable('var_true', disabler())
+assert(not is_disabler(get_no_fallback_d), 'get_variable should not fallback to disabler')
+assert(get_no_fallback_d, 'get_variable should yield true')
+
+assert(is_disabler(get_variable(disabler())), 'get_variable should yield a disabler')
+assert(is_disabler(get_variable(disabler(), var_true)), 'get_variable should yield a disabler')
+
+if_is_disabled = true
+if disabler()
+ if_is_disabled = false
+else
+ if_is_disabled = false
+endif
+assert(if_is_disabled, 'Disabler in "if condition" must skip both blocks')
+
+if not disabler()
+ if_is_disabled = false
+else
+ if_is_disabled = false
+endif
+assert(if_is_disabled, 'Disabler in "if not condition" must skip both blocks')
+
+if disabler() == 1
+ if_is_disabled = false
+else
+ if_is_disabled = false
+endif
+assert(if_is_disabled, 'Disabler in "if a==b" must skip both blocks')
+
+loops = 0
+disablers = 0
+foreach i : [true, disabler(), true]
+ loops += 1
+ if is_disabler(i)
+ disablers += 1
+ endif
+endforeach
+assert(loops == 3, 'Disabler in foreach array')
+assert(disablers == 1, 'Disabler in foreach array')
+
+loops = 0
+disablers = 0
+foreach k, i : {'a': true, 'b': disabler(), 'c': true}
+ loops += 1
+ if is_disabler(i)
+ disablers += 1
+ endif
+endforeach
+assert(loops == 3, 'Disabler in foreach dict')
+assert(disablers == 1, 'Disabler in foreach dict')
diff --git a/test cases/common/159 array option/meson.build b/test cases/common/159 array option/meson.build
new file mode 100644
index 0000000..034b9a5
--- /dev/null
+++ b/test cases/common/159 array option/meson.build
@@ -0,0 +1,17 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('array default options')
+
+assert(get_option('array') == ['foo', 'bar'], 'Default value for array is not equal to choices')
diff --git a/test cases/common/159 array option/meson_options.txt b/test cases/common/159 array option/meson_options.txt
new file mode 100644
index 0000000..7ed0ac1
--- /dev/null
+++ b/test cases/common/159 array option/meson_options.txt
@@ -0,0 +1,19 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+option(
+ 'array',
+ type : 'array',
+ choices : ['foo', 'bar'],
+)
diff --git a/test cases/common/16 comparison/meson.build b/test cases/common/16 comparison/meson.build
new file mode 100644
index 0000000..97cf2ca
--- /dev/null
+++ b/test cases/common/16 comparison/meson.build
@@ -0,0 +1,146 @@
+project('comparison', 'c')
+
+# Compare equality of strings
+
+var1 = 'foo'
+var2 = 'bar'
+
+if var1 == var2
+ exe1 = executable('broken', 'broken.c')
+else
+ exe1 = executable('prog1', 'prog.c')
+endif
+
+if var1 == var1
+ exe2 = executable('prog2', 'prog.c')
+else
+ exe2 = executable('broken', 'broken.c')
+endif
+
+if var1 != var2
+ exe3 = executable('prog3', 'prog.c')
+else
+ exe3 = executable('broken', 'broken.c')
+endif
+
+if var1 != var1
+ exe4 = executable('broken', 'broken.c')
+else
+ exe4 = executable('prog4', 'prog.c')
+endif
+
+test('equalfalse', exe1)
+test('equaltrue', exe2)
+test('nequaltrue', exe3)
+test('nequalfalse', exe4)
+
+# Non-equality comparisons
+
+var3 = 3
+var4 = 4
+
+if var3 < var4
+ exe5 = executable('prog5', 'prog.c')
+else
+ exe5 = executable('broken', 'broken.c')
+endif
+
+if var3 < var3
+ exe6 = executable('broken', 'broken.c')
+else
+ exe6 = executable('prog6', 'prog.c')
+endif
+
+if var4 > var3
+ exe7 = executable('prog7', 'prog.c')
+else
+ exe7 = executable('broken', 'broken.c')
+endif
+
+if var3 > var3
+ exe8 = executable('broken', 'broken.c')
+else
+ exe8 = executable('prog8', 'prog.c')
+endif
+
+if var4 <= var3
+ exe9 = executable('broken', 'broken.c')
+else
+ exe9 = executable('prog9', 'prog.c')
+endif
+
+if var3 <= var3
+ exe10 = executable('prog10', 'prog.c')
+else
+ exe10 = executable('broken', 'broken.c')
+endif
+
+if var3 >= var4
+ exe11 = executable('broken', 'broken.c')
+else
+ exe11 = executable('prog11', 'prog.c')
+endif
+
+if var3 >= var3
+ exe12 = executable('prog12', 'prog.c')
+else
+ exe12 = executable('broken', 'broken.c')
+endif
+
+test('lttrue', exe5)
+test('ltfalse', exe6)
+test('gttrue', exe7)
+test('gtfalse', exe8)
+test('lefalse', exe9)
+test('letrue', exe10)
+test('gefalse', exe11)
+test('getrue', exe12)
+
+# Non-elementary type comparisons
+
+if exe1 == exe2
+ exe13 = executable('broken', 'broken.c')
+else
+ exe13 = executable('prog13', 'prog.c')
+endif
+
+if exe1 == exe1
+ exe14 = executable('prog14', 'prog.c')
+else
+ exe14 = executable('broken', 'broken.c')
+endif
+
+if exe1 != exe2
+ exe15 = executable('prog15', 'prog.c')
+else
+ exe15 = executable('broken', 'broken.c')
+endif
+
+if exe1 != exe1
+ exe16 = executable('broken', 'broken.c')
+else
+ exe16 = executable('prog16', 'prog.c')
+endif
+
+test('equalfalse', exe13)
+test('equaltrue', exe14)
+test('nequaltrue', exe15)
+test('nequalfalse', exe16)
+
+# "in" and "not in" operators
+
+assert(1 in [1, 2], '''1 should be in [1, 2]''')
+assert(3 not in [1, 2], '''3 shouldn't be in [1, 2]''')
+assert(not (3 in [1, 2]), '''3 shouldn't be in [1, 2]''')
+
+assert('b' in ['a', 'b'], ''''b' should be in ['a', 'b']''')
+assert('c' not in ['a', 'b'], ''''c' shouldn't be in ['a', 'b']''')
+
+assert(exe1 in [exe1, exe2], ''''exe1 should be in [exe1, exe2]''')
+assert(exe3 not in [exe1, exe2], ''''exe3 shouldn't be in [exe1, exe2]''')
+
+assert('a' in {'a': 'b'}, '''1 should be in {'a': 'b'}''')
+assert('b' not in {'a': 'b'}, '''1 should be in {'a': 'b'}''')
+
+assert('a' in 'abc')
+assert('b' not in 'def')
diff --git a/test cases/common/16 comparison/prog.c b/test cases/common/16 comparison/prog.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/16 comparison/prog.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/160 custom target template substitution/checkcopy.py b/test cases/common/160 custom target template substitution/checkcopy.py
new file mode 100644
index 0000000..ab9f436
--- /dev/null
+++ b/test cases/common/160 custom target template substitution/checkcopy.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+if '@INPUT1@' in sys.argv[1]:
+ shutil.copyfile(sys.argv[2], sys.argv[3])
+else:
+ sys.exit('String @INPUT1@ not found in "{}"'.format(sys.argv[1]))
diff --git a/test cases/common/160 custom target template substitution/foo.c.in b/test cases/common/160 custom target template substitution/foo.c.in
new file mode 100644
index 0000000..a867b32
--- /dev/null
+++ b/test cases/common/160 custom target template substitution/foo.c.in
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void) {
+ printf("foo is working.\n");
+ return 0;
+}
diff --git a/test cases/common/160 custom target template substitution/meson.build b/test cases/common/160 custom target template substitution/meson.build
new file mode 100644
index 0000000..737408e
--- /dev/null
+++ b/test cases/common/160 custom target template substitution/meson.build
@@ -0,0 +1,17 @@
+project('custom target template substitution', 'c')
+
+check = find_program('checkcopy.py')
+
+config = configuration_data()
+
+config_file = configure_file(configuration : config, output : 'x@IN')
+
+# Check that substitution does not find @FOO@ and then misses @INPUT0@.
+# Check the resulting x@INPUT1@ is not replaced.
+foo = custom_target('runcheck',
+ input : [config_file, 'foo.c.in'],
+ output : 'foo.c',
+ command : [check, '-D@FOO@INPUT0@PUT1@', '@INPUT1@', '@OUTPUT@']
+)
+
+executable('foo', foo)
diff --git a/test cases/common/161 not-found dependency/meson.build b/test cases/common/161 not-found dependency/meson.build
new file mode 100644
index 0000000..02072b6
--- /dev/null
+++ b/test cases/common/161 not-found dependency/meson.build
@@ -0,0 +1,14 @@
+project('dep-test', 'c')
+
+dep = dependency('', required:false)
+if dep.found()
+ error('not-found dependency was found')
+endif
+
+assert(dep.type_name() == 'not-found', 'dependency should be of type "not-found" not ' + dep.type_name())
+
+library('testlib', 'testlib.c', dependencies: [dep])
+subdir('sub', if_found: dep)
+
+subdep = dependency('', fallback: ['trivial', 'trivial_dep'])
+missing = dependency('', fallback: ['missing', 'missing_dep'], required: false)
diff --git a/test cases/common/161 not-found dependency/sub/meson.build b/test cases/common/161 not-found dependency/sub/meson.build
new file mode 100644
index 0000000..2a33cae
--- /dev/null
+++ b/test cases/common/161 not-found dependency/sub/meson.build
@@ -0,0 +1 @@
+error('should be disabled by subdir(if_found:)')
diff --git a/test cases/common/161 not-found dependency/subprojects/trivial/meson.build b/test cases/common/161 not-found dependency/subprojects/trivial/meson.build
new file mode 100644
index 0000000..8769c70
--- /dev/null
+++ b/test cases/common/161 not-found dependency/subprojects/trivial/meson.build
@@ -0,0 +1,3 @@
+project('trivial subproject', 'c')
+trivial_lib = static_library('trivial', 'trivial.c', install: false)
+trivial_dep = declare_dependency(link_with: trivial_lib)
diff --git a/test cases/common/161 not-found dependency/subprojects/trivial/trivial.c b/test cases/common/161 not-found dependency/subprojects/trivial/trivial.c
new file mode 100644
index 0000000..cb0c02f
--- /dev/null
+++ b/test cases/common/161 not-found dependency/subprojects/trivial/trivial.c
@@ -0,0 +1,3 @@
+int subfunc(void) {
+ return 42;
+}
diff --git a/test cases/common/161 not-found dependency/testlib.c b/test cases/common/161 not-found dependency/testlib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/161 not-found dependency/testlib.c
diff --git a/test cases/common/162 subdir if_found/meson.build b/test cases/common/162 subdir if_found/meson.build
new file mode 100644
index 0000000..05be94f
--- /dev/null
+++ b/test cases/common/162 subdir if_found/meson.build
@@ -0,0 +1,11 @@
+project('subdir if found')
+
+found_dep = declare_dependency()
+not_found_dep = dependency('nonexisting', required : false)
+
+subdir('nonexisting_dir', if_found : not_found_dep)
+
+variable = 3
+
+subdir('subdir', if_found : found_dep)
+assert(variable == 5, 'Subdir was not properly entered.')
diff --git a/test cases/common/162 subdir if_found/subdir/meson.build b/test cases/common/162 subdir if_found/subdir/meson.build
new file mode 100644
index 0000000..1030e25
--- /dev/null
+++ b/test cases/common/162 subdir if_found/subdir/meson.build
@@ -0,0 +1 @@
+variable = 5
diff --git a/test cases/common/163 default options prefix dependent defaults/meson.build b/test cases/common/163 default options prefix dependent defaults/meson.build
new file mode 100644
index 0000000..ee80192
--- /dev/null
+++ b/test cases/common/163 default options prefix dependent defaults/meson.build
@@ -0,0 +1 @@
+project('default options prefix dependent defaults ', default_options : ['sharedstatedir=/sharedstate', 'prefix=/usr'])
diff --git a/test cases/common/164 dependency factory/meson.build b/test cases/common/164 dependency factory/meson.build
new file mode 100644
index 0000000..9488cd4
--- /dev/null
+++ b/test cases/common/164 dependency factory/meson.build
@@ -0,0 +1,66 @@
+project('dependency factory', 'c', meson_version : '>=0.53')
+
+dep = dependency('gl', method: 'pkg-config', required: false)
+if dep.found()
+ assert(dep.type_name() == 'pkgconfig')
+ dep.get_pkgconfig_variable('prefix')
+endif
+
+dep = dependency('SDL2', method: 'pkg-config', required: false)
+if dep.found()
+ assert(dep.type_name() == 'pkgconfig')
+ dep.get_pkgconfig_variable('prefix')
+endif
+
+dep = dependency('SDL2', method: 'config-tool', required: false)
+if dep.found()
+ assert(dep.type_name() == 'config-tool')
+ dep.get_configtool_variable('prefix')
+endif
+
+dep = dependency('Vulkan', method: 'pkg-config', required: false)
+if dep.found()
+ assert(dep.type_name() == 'pkgconfig')
+ dep.get_pkgconfig_variable('prefix')
+endif
+
+dep = dependency('pcap', method: 'pkg-config', required: false)
+if dep.found()
+ assert(dep.type_name() == 'pkgconfig')
+ dep.get_pkgconfig_variable('prefix')
+endif
+
+dep = dependency('pcap', method: 'config-tool', required: false)
+if dep.found()
+ assert(dep.type_name() == 'config-tool')
+ dep.get_configtool_variable('prefix')
+endif
+
+dep = dependency('cups', method: 'pkg-config', required: false)
+if dep.found()
+ assert(dep.type_name() == 'pkgconfig')
+ dep.get_pkgconfig_variable('prefix')
+endif
+
+dep = dependency('cups', method: 'config-tool', required: false)
+if dep.found()
+ assert(dep.type_name() == 'config-tool')
+ dep.get_configtool_variable('prefix')
+endif
+
+dep = dependency('libwmf', method: 'pkg-config', required: false)
+if dep.found()
+ assert(dep.type_name() == 'pkgconfig')
+ dep.get_pkgconfig_variable('prefix')
+endif
+
+dep = dependency('libwmf', method: 'config-tool', required: false)
+if dep.found()
+ assert(dep.type_name() == 'config-tool')
+ dep.get_configtool_variable('prefix')
+endif
+
+dep = dependency('boost', method: 'system', required: false)
+if dep.found()
+ assert(dep.type_name() == 'system')
+endif
diff --git a/test cases/common/165 get project license/bar.c b/test cases/common/165 get project license/bar.c
new file mode 100644
index 0000000..f1bd822
--- /dev/null
+++ b/test cases/common/165 get project license/bar.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I'm a main project bar.\n");
+ return 0;
+}
diff --git a/test cases/common/165 get project license/meson.build b/test cases/common/165 get project license/meson.build
new file mode 100644
index 0000000..e7e9deb
--- /dev/null
+++ b/test cases/common/165 get project license/meson.build
@@ -0,0 +1,8 @@
+project('bar', 'c', license: 'Apache-2.0')
+
+executable('bar', 'bar.c')
+
+license = meson.project_license()[0]
+if license != 'Apache-2.0'
+ error('The license should be Apache-2.0, but it is: ' + license)
+endif
diff --git a/test cases/common/166 yield/meson.build b/test cases/common/166 yield/meson.build
new file mode 100644
index 0000000..e8f2106
--- /dev/null
+++ b/test cases/common/166 yield/meson.build
@@ -0,0 +1,7 @@
+project('yield_options')
+
+subproject('sub')
+
+assert(get_option('unshared_option') == 'one', 'Unshared option has wrong value in superproject.')
+assert(get_option('shared_option') == 'two', 'Shared option has wrong value in superproject..')
+assert(get_option('wrongtype_option') == 'three', 'Wrongtype option has wrong value in superproject..')
diff --git a/test cases/common/166 yield/meson_options.txt b/test cases/common/166 yield/meson_options.txt
new file mode 100644
index 0000000..9f58fbb
--- /dev/null
+++ b/test cases/common/166 yield/meson_options.txt
@@ -0,0 +1,3 @@
+option('unshared_option', type : 'string', value : 'one')
+option('shared_option', type : 'string', value : 'two')
+option('wrongtype_option', type : 'string', value : 'three')
diff --git a/test cases/common/166 yield/subprojects/sub/meson.build b/test cases/common/166 yield/subprojects/sub/meson.build
new file mode 100644
index 0000000..1c29d86
--- /dev/null
+++ b/test cases/common/166 yield/subprojects/sub/meson.build
@@ -0,0 +1,5 @@
+project('subbie')
+
+assert(get_option('unshared_option') == 'three', 'Unshared option has wrong value in subproject.')
+assert(get_option('shared_option') == 'two', 'Shared option has wrong value in subproject.')
+assert(get_option('wrongtype_option') == true, 'Wrongtype option has wrong value in subproject.')
diff --git a/test cases/common/166 yield/subprojects/sub/meson_options.txt b/test cases/common/166 yield/subprojects/sub/meson_options.txt
new file mode 100644
index 0000000..101122e
--- /dev/null
+++ b/test cases/common/166 yield/subprojects/sub/meson_options.txt
@@ -0,0 +1,3 @@
+option('unshared_option', type : 'string', value : 'three', yield : false)
+option('shared_option', type : 'string', value : 'four', yield : true)
+option('wrongtype_option', type : 'boolean', value : true, yield : true)
diff --git a/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/a.c b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/a.c
new file mode 100644
index 0000000..102041e
--- /dev/null
+++ b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/a.c
@@ -0,0 +1,14 @@
+int func2(void);
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func(void) { return func2(); }
diff --git a/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/meson.build b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/meson.build
new file mode 100644
index 0000000..1014db1
--- /dev/null
+++ b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/meson.build
@@ -0,0 +1,4 @@
+project('alpha project', 'c', subproject_dir: 'var/subprojects')
+
+b = subproject('beta')
+l = library('a', 'a.c', link_with : b.get_variable('lb'))
diff --git a/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/var/subprojects/wrap_files_might_be_here b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/var/subprojects/wrap_files_might_be_here
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/alpha/var/subprojects/wrap_files_might_be_here
@@ -0,0 +1 @@
+
diff --git a/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/b.c b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/b.c
new file mode 100644
index 0000000..8c07177
--- /dev/null
+++ b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/b.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func2(void) {
+ return 42;
+}
diff --git a/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/meson.build b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/meson.build
new file mode 100644
index 0000000..1720d3e
--- /dev/null
+++ b/test cases/common/167 subproject nested subproject dirs/contrib/subprojects/beta/meson.build
@@ -0,0 +1,4 @@
+project('beta project', 'c')
+
+lb = shared_library('b', 'b.c')
+notfound = dependency('', required : false)
diff --git a/test cases/common/167 subproject nested subproject dirs/meson.build b/test cases/common/167 subproject nested subproject dirs/meson.build
new file mode 100644
index 0000000..875eed3
--- /dev/null
+++ b/test cases/common/167 subproject nested subproject dirs/meson.build
@@ -0,0 +1,11 @@
+project('gamma project', 'c', subproject_dir: 'contrib/subprojects')
+
+a = subproject('alpha')
+lib = a.get_variable('l')
+
+# Ensure that the dependency version is not checked for a not-found dependency
+notfound = dependency('', version : '>=1.0', required : false,
+ fallback : ['beta', 'notfound'])
+
+exe = executable('prog', 'prog.c', link_with : lib)
+test('basic', exe)
diff --git a/test cases/common/167 subproject nested subproject dirs/prog.c b/test cases/common/167 subproject nested subproject dirs/prog.c
new file mode 100644
index 0000000..27162c5
--- /dev/null
+++ b/test cases/common/167 subproject nested subproject dirs/prog.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func() == 42 ? 0 : 1;
+}
diff --git a/test cases/common/168 preserve gendir/base.inp b/test cases/common/168 preserve gendir/base.inp
new file mode 100644
index 0000000..df967b9
--- /dev/null
+++ b/test cases/common/168 preserve gendir/base.inp
@@ -0,0 +1 @@
+base
diff --git a/test cases/common/168 preserve gendir/com/mesonbuild/subbie.inp b/test cases/common/168 preserve gendir/com/mesonbuild/subbie.inp
new file mode 100644
index 0000000..df0f4e9
--- /dev/null
+++ b/test cases/common/168 preserve gendir/com/mesonbuild/subbie.inp
@@ -0,0 +1 @@
+subbie
diff --git a/test cases/common/168 preserve gendir/genprog.py b/test cases/common/168 preserve gendir/genprog.py
new file mode 100755
index 0000000..681c43a
--- /dev/null
+++ b/test cases/common/168 preserve gendir/genprog.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+import os, sys, argparse
+
+h_templ = '''#pragma once
+
+int %s(void);
+'''
+
+c_templ = '''#include"%s.h"
+
+int %s(void) {
+ return 0;
+}
+'''
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--searchdir', required=True)
+parser.add_argument('--outdir', required=True)
+parser.add_argument('ifiles', nargs='+')
+
+options = parser.parse_args()
+
+searchdir = options.searchdir
+outdir = options.outdir
+ifiles = options.ifiles
+
+rel_ofiles = []
+
+for ifile in ifiles:
+ if not ifile.startswith(options.searchdir):
+ sys.exit(f'Input file {ifile} does not start with search dir {searchdir}.')
+ rel_ofile = ifile[len(searchdir):]
+ if rel_ofile[0] == '/' or rel_ofile[0] == '\\':
+ rel_ofile = rel_ofile[1:]
+ rel_ofiles.append(os.path.splitext(rel_ofile)[0])
+
+ofile_bases = [os.path.join(outdir, i) for i in rel_ofiles]
+
+for i, ifile_name in enumerate(ifiles):
+ proto_name = open(ifile_name).readline().strip()
+ h_out = ofile_bases[i] + '.h'
+ c_out = ofile_bases[i] + '.c'
+ os.makedirs(os.path.split(ofile_bases[i])[0], exist_ok=True)
+ open(h_out, 'w').write(h_templ % (proto_name))
+ open(c_out, 'w').write(c_templ % (proto_name, proto_name))
diff --git a/test cases/common/168 preserve gendir/meson.build b/test cases/common/168 preserve gendir/meson.build
new file mode 100644
index 0000000..ce219f0
--- /dev/null
+++ b/test cases/common/168 preserve gendir/meson.build
@@ -0,0 +1,13 @@
+project('preserve subdir', 'c')
+
+gprog = find_program('genprog.py')
+
+gen = generator(gprog, \
+ output : ['@BASENAME@.c', '@BASENAME@.h'],
+ arguments : ['--searchdir=@CURRENT_SOURCE_DIR@', '--outdir=@BUILD_DIR@', '@INPUT@'])
+
+generated = gen.process('base.inp', 'com/mesonbuild/subbie.inp',
+ preserve_path_from : meson.current_source_dir())
+
+e = executable('testprog', 'testprog.c', generated)
+test('testprog', e)
diff --git a/test cases/common/168 preserve gendir/testprog.c b/test cases/common/168 preserve gendir/testprog.c
new file mode 100644
index 0000000..b6a9926
--- /dev/null
+++ b/test cases/common/168 preserve gendir/testprog.c
@@ -0,0 +1,6 @@
+#include"base.h"
+#include"com/mesonbuild/subbie.h"
+
+int main(void) {
+ return base() + subbie();
+}
diff --git a/test cases/common/169 source in dep/bar.cpp b/test cases/common/169 source in dep/bar.cpp
new file mode 100644
index 0000000..2ea623b
--- /dev/null
+++ b/test cases/common/169 source in dep/bar.cpp
@@ -0,0 +1,5 @@
+extern "C" int foo(void);
+
+int main(void) {
+ return foo() != 42;
+}
diff --git a/test cases/common/169 source in dep/foo.c b/test cases/common/169 source in dep/foo.c
new file mode 100644
index 0000000..c1be8d0
--- /dev/null
+++ b/test cases/common/169 source in dep/foo.c
@@ -0,0 +1,3 @@
+int foo(void) {
+ return 42;
+}
diff --git a/test cases/common/169 source in dep/generated/funname b/test cases/common/169 source in dep/generated/funname
new file mode 100644
index 0000000..79f3c86
--- /dev/null
+++ b/test cases/common/169 source in dep/generated/funname
@@ -0,0 +1 @@
+my_wonderful_function
diff --git a/test cases/common/169 source in dep/generated/genheader.py b/test cases/common/169 source in dep/generated/genheader.py
new file mode 100755
index 0000000..489db23
--- /dev/null
+++ b/test cases/common/169 source in dep/generated/genheader.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+
+import sys
+
+ifile = sys.argv[1]
+ofile = sys.argv[2]
+
+templ = '''#pragma once
+
+int %s(void) {
+ return 42;
+}
+'''
+
+funname = open(ifile).readline().strip()
+
+open(ofile, 'w').write(templ % funname)
diff --git a/test cases/common/169 source in dep/generated/main.c b/test cases/common/169 source in dep/generated/main.c
new file mode 100644
index 0000000..1ab980a
--- /dev/null
+++ b/test cases/common/169 source in dep/generated/main.c
@@ -0,0 +1,5 @@
+#include"funheader.h"
+
+int main(void) {
+ return my_wonderful_function() != 42;
+}
diff --git a/test cases/common/169 source in dep/generated/meson.build b/test cases/common/169 source in dep/generated/meson.build
new file mode 100644
index 0000000..fade382
--- /dev/null
+++ b/test cases/common/169 source in dep/generated/meson.build
@@ -0,0 +1,12 @@
+fp = find_program('genheader.py')
+
+genh = custom_target('genh',
+ input : 'funname',
+ output : 'funheader.h',
+ command : [fp, '@INPUT@', '@OUTPUT@'])
+
+dep = declare_dependency(sources : [genh])
+
+e = executable('genuser', 'main.c',
+ dependencies : dep)
+test('genuser', e)
diff --git a/test cases/common/169 source in dep/meson.build b/test cases/common/169 source in dep/meson.build
new file mode 100644
index 0000000..7111ba1
--- /dev/null
+++ b/test cases/common/169 source in dep/meson.build
@@ -0,0 +1,8 @@
+project('foo', 'c', 'cpp')
+
+dep = declare_dependency(sources : 'foo.c')
+
+executable('bar', 'bar.cpp',
+ dependencies : dep)
+
+subdir('generated')
diff --git a/test cases/common/17 array/func.c b/test cases/common/17 array/func.c
new file mode 100644
index 0000000..a324dca
--- /dev/null
+++ b/test cases/common/17 array/func.c
@@ -0,0 +1 @@
+int func(void) { return 0; }
diff --git a/test cases/common/17 array/meson.build b/test cases/common/17 array/meson.build
new file mode 100644
index 0000000..0d17374
--- /dev/null
+++ b/test cases/common/17 array/meson.build
@@ -0,0 +1,8 @@
+project('array test', 'c')
+
+arr = [
+ 'func.c',
+ 'prog.c']
+
+exe = executable('prog', sources : arr)
+test('arr test', exe)
diff --git a/test cases/common/17 array/prog.c b/test cases/common/17 array/prog.c
new file mode 100644
index 0000000..f794e1b
--- /dev/null
+++ b/test cases/common/17 array/prog.c
@@ -0,0 +1,3 @@
+extern int func(void);
+
+int main(void) { return func(); }
diff --git a/test cases/common/170 generator link whole/export.h b/test cases/common/170 generator link whole/export.h
new file mode 100644
index 0000000..f4f6f45
--- /dev/null
+++ b/test cases/common/170 generator link whole/export.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#if defined BUILDING_EMBEDDED
+ #define DLL_PUBLIC
+#elif defined _WIN32 || defined __CYGWIN__
+ #if defined BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
diff --git a/test cases/common/170 generator link whole/generator.py b/test cases/common/170 generator link whole/generator.py
new file mode 100755
index 0000000..18a6cc2
--- /dev/null
+++ b/test cases/common/170 generator link whole/generator.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+import os
+import os.path
+import sys
+
+
+def main():
+ name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
+ out = sys.argv[2]
+ hname = os.path.join(out, name + '.h')
+ cname = os.path.join(out, name + '.c')
+ print(os.getcwd(), hname)
+ with open(hname, 'w') as hfile:
+ hfile.write('''
+#pragma once
+#include "export.h"
+int DLL_PUBLIC {name}(void);
+'''.format(name=name))
+ with open(cname, 'w') as cfile:
+ cfile.write('''
+#include "{name}.h"
+int {name}(void) {{
+ return {size};
+}}
+'''.format(name=name, size=len(name)))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test cases/common/170 generator link whole/main.c b/test cases/common/170 generator link whole/main.c
new file mode 100644
index 0000000..7605022
--- /dev/null
+++ b/test cases/common/170 generator link whole/main.c
@@ -0,0 +1,11 @@
+#include "meson_test_function.h"
+
+#include <stdio.h>
+
+int main(void) {
+ if (meson_test_function() != 19) {
+ printf("Bad meson_test_function()\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/170 generator link whole/meson.build b/test cases/common/170 generator link whole/meson.build
new file mode 100644
index 0000000..f5d3e58
--- /dev/null
+++ b/test cases/common/170 generator link whole/meson.build
@@ -0,0 +1,62 @@
+project('generator link_whole', 'c')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: whole-archive not supported in Xcode. Patches welcome.')
+endif
+
+# This just generates foo.h and foo.c with int foo() defined.
+gen_py = find_program('generator.py')
+gen = generator(gen_py,
+ output: ['@BASENAME@.h', '@BASENAME@.c'],
+ arguments : ['@INPUT@', '@BUILD_DIR@'])
+
+# Test 1: link directly into executable
+srcs = gen.process('meson_test_function.tmpl')
+exe = executable('exe1', [srcs, 'main.c'], c_args : '-DBUILDING_EMBEDDED')
+test('test1', exe)
+
+# Test 2: link into shared library and access from executable
+srcs = gen.process('meson_test_function.tmpl')
+shlib2 = shared_library('shlib2', [srcs], c_args : '-DBUILDING_DLL')
+exe = executable('exe2', 'main.c',
+ link_with : shlib2,
+ include_directories : shlib2.private_dir_include(),
+)
+test('test2', exe)
+
+# Test 3: link into static library and access from executable
+srcs = gen.process('meson_test_function.tmpl')
+stlib3 = static_library('stlib3', [srcs], c_args : '-DBUILDING_EMBEDDED')
+exe = executable('exe3', 'main.c',
+ c_args : '-DBUILDING_EMBEDDED',
+ link_with : stlib3,
+ include_directories : stlib3.private_dir_include(),
+)
+test('test3', exe)
+
+# Test 4: link into static library, link into shared
+# and access from executable. To make sure static_library
+# is not dropped use pull_meson_test_function helper.
+srcs = gen.process('meson_test_function.tmpl')
+stlib4 = static_library('stlib4', [srcs], c_args : '-DBUILDING_DLL')
+shlib4 = shared_library('shlib4', 'pull_meson_test_function.c',
+ c_args : '-DBUILDING_DLL',
+ link_with : stlib4,
+ include_directories : stlib4.private_dir_include(),
+)
+exe = executable('exe4', 'main.c',
+ link_with : shlib4,
+ include_directories : stlib4.private_dir_include(),
+)
+test('test4', exe)
+
+# Test 5: link into static library, link_whole into shared
+# and access from executable
+srcs = gen.process('meson_test_function.tmpl')
+stlib5 = static_library('stlib5', [srcs], c_args : '-DBUILDING_DLL')
+shlib5 = shared_library('shlib5', link_whole : stlib5)
+exe = executable('exe5', 'main.c',
+ link_with : shlib5,
+ include_directories : stlib5.private_dir_include(),
+)
+test('test5', exe)
diff --git a/test cases/common/170 generator link whole/meson_test_function.tmpl b/test cases/common/170 generator link whole/meson_test_function.tmpl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/170 generator link whole/meson_test_function.tmpl
diff --git a/test cases/common/170 generator link whole/pull_meson_test_function.c b/test cases/common/170 generator link whole/pull_meson_test_function.c
new file mode 100644
index 0000000..23d24ac
--- /dev/null
+++ b/test cases/common/170 generator link whole/pull_meson_test_function.c
@@ -0,0 +1,6 @@
+#include "export.h"
+#include "meson_test_function.h"
+
+int DLL_PUBLIC function_puller(void) {
+ return meson_test_function();
+}
diff --git a/test cases/common/171 initial c_args/meson.build b/test cases/common/171 initial c_args/meson.build
new file mode 100644
index 0000000..638f8c2
--- /dev/null
+++ b/test cases/common/171 initial c_args/meson.build
@@ -0,0 +1,7 @@
+project('options', 'c')
+
+# Test passing c_args and c_link_args options from the command line.
+assert(get_option('c_args') == ['-funroll-loops'],
+ 'Incorrect value for c_args option.')
+assert(get_option('c_link_args') == ['-Dtest_harmless_but_useless_link_arg'],
+ 'Incorrect value for c_link_args option.')
diff --git a/test cases/common/171 initial c_args/test.json b/test cases/common/171 initial c_args/test.json
new file mode 100644
index 0000000..f9b73a4
--- /dev/null
+++ b/test cases/common/171 initial c_args/test.json
@@ -0,0 +1,8 @@
+{
+ "matrix": {
+ "options": {
+ "c_args": [{ "val": "-funroll-loops" }],
+ "c_link_args": [{ "val": "-Dtest_harmless_but_useless_link_arg" }]
+ }
+ }
+}
diff --git a/test cases/common/172 identical target name in subproject flat layout/foo.c b/test cases/common/172 identical target name in subproject flat layout/foo.c
new file mode 100644
index 0000000..ed42789
--- /dev/null
+++ b/test cases/common/172 identical target name in subproject flat layout/foo.c
@@ -0,0 +1 @@
+int meson_test_main_foo(void) { return 10; }
diff --git a/test cases/common/172 identical target name in subproject flat layout/main.c b/test cases/common/172 identical target name in subproject flat layout/main.c
new file mode 100644
index 0000000..6f02aeb
--- /dev/null
+++ b/test cases/common/172 identical target name in subproject flat layout/main.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int meson_test_main_foo(void);
+int meson_test_subproj_foo(void);
+
+int main(void) {
+ if (meson_test_main_foo() != 10) {
+ printf("Failed meson_test_main_foo\n");
+ return 1;
+ }
+ if (meson_test_subproj_foo() != 20) {
+ printf("Failed meson_test_subproj_foo\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/172 identical target name in subproject flat layout/meson.build b/test cases/common/172 identical target name in subproject flat layout/meson.build
new file mode 100644
index 0000000..ce1d4b8
--- /dev/null
+++ b/test cases/common/172 identical target name in subproject flat layout/meson.build
@@ -0,0 +1,15 @@
+project('subproject targets', 'c')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: many targets with the same name not supported in Xcode. Patches welcome.')
+endif
+
+# Idea behind this test is to create targets with identical name
+# but different output files. We can do this by choosing different
+# name_prefix of libraries. Target id does not depend on name_prefix.
+
+main_foo = static_library('foo', 'foo.c', name_prefix : 'main')
+subproj_foo = subproject('subproj').get_variable('foo')
+
+exe = executable('prog', 'main.c', link_with : [main_foo, subproj_foo])
+test('main test', exe)
diff --git a/test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/foo.c b/test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/foo.c
new file mode 100644
index 0000000..f334292
--- /dev/null
+++ b/test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/foo.c
@@ -0,0 +1 @@
+int meson_test_subproj_foo(void) { return 20; }
diff --git a/test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/meson.build b/test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/meson.build
new file mode 100644
index 0000000..c927194
--- /dev/null
+++ b/test cases/common/172 identical target name in subproject flat layout/subprojects/subproj/meson.build
@@ -0,0 +1,3 @@
+project('subproj', 'c')
+
+foo = static_library('foo', 'foo.c', name_prefix : 'subproj')
diff --git a/test cases/common/173 as-needed/config.h b/test cases/common/173 as-needed/config.h
new file mode 100644
index 0000000..b8fb60f
--- /dev/null
+++ b/test cases/common/173 as-needed/config.h
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #if defined BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
diff --git a/test cases/common/173 as-needed/libA.cpp b/test cases/common/173 as-needed/libA.cpp
new file mode 100644
index 0000000..5f45bc0
--- /dev/null
+++ b/test cases/common/173 as-needed/libA.cpp
@@ -0,0 +1,7 @@
+#define BUILDING_DLL
+
+#include "libA.h"
+
+namespace meson_test_as_needed {
+ DLL_PUBLIC bool linked = false;
+}
diff --git a/test cases/common/173 as-needed/libA.h b/test cases/common/173 as-needed/libA.h
new file mode 100644
index 0000000..8e76d22
--- /dev/null
+++ b/test cases/common/173 as-needed/libA.h
@@ -0,0 +1,5 @@
+#include "config.h"
+
+namespace meson_test_as_needed {
+ DLL_PUBLIC extern bool linked;
+}
diff --git a/test cases/common/173 as-needed/libB.cpp b/test cases/common/173 as-needed/libB.cpp
new file mode 100644
index 0000000..a872394
--- /dev/null
+++ b/test cases/common/173 as-needed/libB.cpp
@@ -0,0 +1,19 @@
+#include "libA.h"
+
+#undef DLL_PUBLIC
+#define BUILDING_DLL
+#include "config.h"
+
+namespace meson_test_as_needed {
+ namespace {
+ bool set_linked() {
+ linked = true;
+ return true;
+ }
+ bool stub = set_linked();
+ }
+
+ DLL_PUBLIC int libB_unused_func() {
+ return 0;
+ }
+}
diff --git a/test cases/common/173 as-needed/main.cpp b/test cases/common/173 as-needed/main.cpp
new file mode 100644
index 0000000..a893431
--- /dev/null
+++ b/test cases/common/173 as-needed/main.cpp
@@ -0,0 +1,7 @@
+#include <cstdlib>
+
+#include "libA.h"
+
+int main(void) {
+ return !meson_test_as_needed::linked ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/test cases/common/173 as-needed/meson.build b/test cases/common/173 as-needed/meson.build
new file mode 100644
index 0000000..3b54aaa
--- /dev/null
+++ b/test cases/common/173 as-needed/meson.build
@@ -0,0 +1,13 @@
+project('as-needed test', 'cpp')
+
+# Idea behind this test is to have -Wl,--as-needed prune
+# away unneeded linkages, which would otherwise cause global
+# static initialiser side-effects to set a boolean to true.
+
+# Credits for portable ISO C++ idea go to sarum9in
+
+libA = library('A', 'libA.cpp')
+libB = library('B', 'libB.cpp', link_with : libA)
+
+main_exe = executable('C', 'main.cpp', link_with : [libA, libB])
+test('main test', main_exe)
diff --git a/test cases/common/174 ndebug if-release enabled/main.c b/test cases/common/174 ndebug if-release enabled/main.c
new file mode 100644
index 0000000..984ebca
--- /dev/null
+++ b/test cases/common/174 ndebug if-release enabled/main.c
@@ -0,0 +1,15 @@
+#include <assert.h>
+#include <stdlib.h>
+
+int meson_test_side_effect = EXIT_FAILURE;
+
+int meson_test_set_side_effect(void) {
+ meson_test_side_effect = EXIT_SUCCESS;
+ return 1;
+}
+
+int main(void) {
+ // meson_test_side_effect is set only if assert is executed
+ assert(meson_test_set_side_effect());
+ return meson_test_side_effect;
+}
diff --git a/test cases/common/174 ndebug if-release enabled/meson.build b/test cases/common/174 ndebug if-release enabled/meson.build
new file mode 100644
index 0000000..be26375
--- /dev/null
+++ b/test cases/common/174 ndebug if-release enabled/meson.build
@@ -0,0 +1,7 @@
+project('ndebug enabled', 'c',
+ default_options : [
+ 'buildtype=debugoptimized',
+ 'b_ndebug=if-release',
+ ])
+
+test('exe', executable('main', 'main.c'))
diff --git a/test cases/common/175 ndebug if-release disabled/main.c b/test cases/common/175 ndebug if-release disabled/main.c
new file mode 100644
index 0000000..cb3ec3f
--- /dev/null
+++ b/test cases/common/175 ndebug if-release disabled/main.c
@@ -0,0 +1,7 @@
+#include <assert.h>
+#include <stdlib.h>
+
+int main(void) {
+ assert(0);
+ return EXIT_SUCCESS;
+}
diff --git a/test cases/common/175 ndebug if-release disabled/meson.build b/test cases/common/175 ndebug if-release disabled/meson.build
new file mode 100644
index 0000000..a9a79ea
--- /dev/null
+++ b/test cases/common/175 ndebug if-release disabled/meson.build
@@ -0,0 +1,7 @@
+project('ndebug disabled', 'c',
+ default_options : [
+ 'buildtype=release',
+ 'b_ndebug=if-release',
+ ])
+
+test('exe', executable('main', 'main.c'))
diff --git a/test cases/common/176 subproject version/meson.build b/test cases/common/176 subproject version/meson.build
new file mode 100644
index 0000000..b98f0cb
--- /dev/null
+++ b/test cases/common/176 subproject version/meson.build
@@ -0,0 +1,9 @@
+project('subproject version',
+ version : '2.3.4',
+ license: 'mylicense')
+
+subproject('a')
+
+liba_dep = dependency('a',
+ fallback: ['a', 'liba_dep'],
+ version: ['>= 0.30.0', '!= 0.99.0'])
diff --git a/test cases/common/176 subproject version/subprojects/a/meson.build b/test cases/common/176 subproject version/subprojects/a/meson.build
new file mode 100644
index 0000000..aeb85af
--- /dev/null
+++ b/test cases/common/176 subproject version/subprojects/a/meson.build
@@ -0,0 +1,5 @@
+project('mysubproject',
+ version : '1.0.0',
+ license : 'sublicense')
+
+liba_dep = declare_dependency (version : '1.0.0')
diff --git a/test cases/common/177 subdir_done/meson.build b/test cases/common/177 subdir_done/meson.build
new file mode 100644
index 0000000..62346a2
--- /dev/null
+++ b/test cases/common/177 subdir_done/meson.build
@@ -0,0 +1,11 @@
+# Should run, even though main.cpp does not exist and we call error in the last line.
+# subdir_done jumps to end, so both lines are not executed.
+
+project('example exit')
+
+if true
+ subdir_done()
+endif
+
+executable('main', 'main.cpp')
+error('Unreachable')
diff --git a/test cases/common/178 bothlibraries/dummy.py b/test cases/common/178 bothlibraries/dummy.py
new file mode 100644
index 0000000..9e838ba
--- /dev/null
+++ b/test cases/common/178 bothlibraries/dummy.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+from pathlib import Path
+import sys
+
+if __name__ == '__main__':
+ Path(sys.argv[1]).write_text('Hello World\n')
+ raise SystemExit(0)
diff --git a/test cases/common/178 bothlibraries/foo.cpp b/test cases/common/178 bothlibraries/foo.cpp
new file mode 100644
index 0000000..a705cbc
--- /dev/null
+++ b/test cases/common/178 bothlibraries/foo.cpp
@@ -0,0 +1,11 @@
+#include <memory>
+#include "mylib.h"
+
+extern "C" {
+ DO_EXPORT int foo(void);
+}
+
+int foo(void) {
+ auto bptr = std::make_shared<int>(0);
+ return *bptr;
+}
diff --git a/test cases/common/178 bothlibraries/libfile.c b/test cases/common/178 bothlibraries/libfile.c
new file mode 100644
index 0000000..f5e228e
--- /dev/null
+++ b/test cases/common/178 bothlibraries/libfile.c
@@ -0,0 +1,7 @@
+#include "mylib.h"
+
+DO_EXPORT int retval = 42;
+
+DO_EXPORT int func(void) {
+ return retval;
+}
diff --git a/test cases/common/178 bothlibraries/main.c b/test cases/common/178 bothlibraries/main.c
new file mode 100644
index 0000000..8237bae
--- /dev/null
+++ b/test cases/common/178 bothlibraries/main.c
@@ -0,0 +1,8 @@
+#include "mylib.h"
+
+DO_IMPORT int func(void);
+DO_IMPORT int retval;
+
+int main(void) {
+ return func() == retval ? 0 : 1;
+}
diff --git a/test cases/common/178 bothlibraries/main2.c b/test cases/common/178 bothlibraries/main2.c
new file mode 100644
index 0000000..e1f4bf8
--- /dev/null
+++ b/test cases/common/178 bothlibraries/main2.c
@@ -0,0 +1,9 @@
+#include "mylib.h"
+
+DO_IMPORT int func(void);
+DO_IMPORT int foo(void);
+DO_IMPORT int retval;
+
+int main(void) {
+ return func() + foo() == retval ? 0 : 1;
+}
diff --git a/test cases/common/178 bothlibraries/meson.build b/test cases/common/178 bothlibraries/meson.build
new file mode 100644
index 0000000..bb3a2bc
--- /dev/null
+++ b/test cases/common/178 bothlibraries/meson.build
@@ -0,0 +1,62 @@
+project('both libraries linking test', 'c', 'cpp')
+
+both_libs = both_libraries('mylib', 'libfile.c')
+dep = declare_dependency(link_with: both_libs)
+exe_shared = executable('prog-shared', 'main.c', link_with : both_libs.get_shared_lib())
+exe_static = executable('prog-static', 'main.c',
+ c_args : ['-DSTATIC_COMPILATION'],
+ link_with : both_libs.get_static_lib())
+exe_both = executable('prog-both', 'main.c', link_with : both_libs)
+exe_dep = executable('prog-dep', 'main.c', dependencies : [dep])
+
+# Try using it in a custom_target
+custom_target('tgt_a',
+ command: [
+ find_program('./dummy.py'),
+ '@OUTPUT@',
+ both_libs,
+ ],
+ output: ['hello1.txt'],
+ input: [both_libs],
+)
+
+test('runtest-shared', exe_shared)
+test('runtest-static', exe_static)
+test('runtest-both', exe_both)
+test('runtest-dep', exe_dep)
+
+# Same as above, but using build_target()
+both_libs2 = build_target('mylib2', 'libfile.c', target_type: 'both_libraries')
+exe_shared2 = executable('prog-shared2', 'main.c',
+ link_with : both_libs2.get_shared_lib())
+exe_static2 = executable('prog-static2', 'main.c',
+ c_args : ['-DSTATIC_COMPILATION'],
+ link_with : both_libs2.get_static_lib())
+exe_both2 = executable('prog-both2', 'main.c', link_with : both_libs2)
+
+# Test {set,get}_variable
+set_variable('both_libs2', both_libs)
+both_libs3 = get_variable('both_libs')
+
+# Ensure that calling the build target methods also works
+assert(both_libs.name() == 'mylib')
+assert(both_libs2.name() == 'mylib')
+assert(both_libs3.name() == 'mylib')
+assert(both_libs2.get_shared_lib().name() == 'mylib')
+assert(both_libs3.get_static_lib().name() == 'mylib')
+
+test('runtest-shared-2', exe_shared2)
+test('runtest-static-2', exe_static2)
+test('runtest-both-2', exe_both2)
+
+# Regression test: libccpp has both C and C++ sources. The executable only has
+# C sources. It should still link using the C++ compiler. When using
+# both_libraries the static has no sources and thus no compilers, resulting in
+# the executable linking using the C compiler.
+# https://github.com/Netflix/vmaf/issues/1107
+libccpp = both_libraries('ccpp', 'foo.cpp', 'libfile.c')
+exe = executable('prog-ccpp', 'main2.c',
+ link_with: libccpp.get_static_lib(),
+ c_args : ['-DSTATIC_COMPILATION'],
+)
+test('runtest-ccpp', exe)
diff --git a/test cases/common/178 bothlibraries/mylib.h b/test cases/common/178 bothlibraries/mylib.h
new file mode 100644
index 0000000..1038a01
--- /dev/null
+++ b/test cases/common/178 bothlibraries/mylib.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#ifdef _WIN32
+ #ifdef STATIC_COMPILATION
+ #define DO_IMPORT extern
+ #else
+ #define DO_IMPORT __declspec(dllimport)
+ #endif
+ #define DO_EXPORT __declspec(dllexport)
+#else
+ #define DO_IMPORT extern
+ #define DO_EXPORT
+#endif
diff --git a/test cases/common/179 escape and unicode/file.c.in b/test cases/common/179 escape and unicode/file.c.in
new file mode 100644
index 0000000..5dd6e50
--- /dev/null
+++ b/test cases/common/179 escape and unicode/file.c.in
@@ -0,0 +1,5 @@
+#include<stdio.h>
+const char* does_it_work(void) {
+ printf("{NAME}\n");
+ return "yes it does";
+}
diff --git a/test cases/common/179 escape and unicode/file.py b/test cases/common/179 escape and unicode/file.py
new file mode 100644
index 0000000..40fa7ca
--- /dev/null
+++ b/test cases/common/179 escape and unicode/file.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+
+import sys
+import os
+
+with open(sys.argv[1]) as fh:
+ content = fh.read().replace("{NAME}", sys.argv[2])
+
+with open(os.path.join(sys.argv[3]), 'w', errors='replace') as fh:
+ fh.write(content)
diff --git a/test cases/common/179 escape and unicode/find.py b/test cases/common/179 escape and unicode/find.py
new file mode 100644
index 0000000..34a3eb8
--- /dev/null
+++ b/test cases/common/179 escape and unicode/find.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+for fh in os.listdir('.'):
+ if os.path.isfile(fh):
+ if fh.endswith('.c'):
+ sys.stdout.write(fh + '\0')
diff --git a/test cases/common/179 escape and unicode/fun.c b/test cases/common/179 escape and unicode/fun.c
new file mode 100644
index 0000000..c5634d8
--- /dev/null
+++ b/test cases/common/179 escape and unicode/fun.c
@@ -0,0 +1,3 @@
+int a_fun(void) {
+ return 1;
+}
diff --git a/test cases/common/179 escape and unicode/main.c b/test cases/common/179 escape and unicode/main.c
new file mode 100644
index 0000000..6137ad7
--- /dev/null
+++ b/test cases/common/179 escape and unicode/main.c
@@ -0,0 +1,12 @@
+#include <string.h>
+
+const char* does_it_work(void);
+
+int a_fun(void);
+
+int main(void) {
+ if(strcmp(does_it_work(), "yes it does") != 0) {
+ return -a_fun();
+ }
+ return 0;
+}
diff --git a/test cases/common/179 escape and unicode/meson.build b/test cases/common/179 escape and unicode/meson.build
new file mode 100644
index 0000000..46c99d3
--- /dev/null
+++ b/test cases/common/179 escape and unicode/meson.build
@@ -0,0 +1,38 @@
+project('180 escape', 'c')
+
+gen = generator(find_program('file.py'), arguments:['@INPUT@', 'erd\u0151', '@OUTPUT@'], output: '@BASENAME@')
+
+gen_file = gen.process('file.c.in')
+
+find_file_list = run_command(find_program('find.py'), check: true)
+assert(find_file_list.returncode() == 0, 'Didn\'t find any files.')
+
+# Strings should support both octal \ooo and hex \xhh encodings
+
+found_files_oct = []
+foreach l : find_file_list.stdout().strip('\0').split('\000')
+ found_files_oct += [files(l)]
+endforeach
+
+test('first', executable('first', found_files_oct + [gen_file]))
+
+found_files_hex = []
+foreach l : find_file_list.stdout().strip('\x00').split('\x00')
+ found_files_hex += [files(l)]
+endforeach
+
+test('second', executable('second', found_files_hex + [gen_file]))
+
+# Unrecognized and malformed escape sequences are literal
+
+malformed = [
+ [ '\c', 'c' ],
+ [ '\Uabcdefghi', 'Uabcdefghi'],
+ [ '\u123 ', 'u123 '],
+ [ '\xqr', 'xqr'],
+]
+
+foreach m : malformed
+ assert(m[0].endswith(m[1]), 'bad escape sequence had unexpected end')
+ assert(m[0].startswith('\\'), 'bad escape sequence had unexpected start')
+endforeach
diff --git a/test cases/common/18 includedir/include/func.h b/test cases/common/18 includedir/include/func.h
new file mode 100644
index 0000000..647b72f
--- /dev/null
+++ b/test cases/common/18 includedir/include/func.h
@@ -0,0 +1,6 @@
+#ifndef FUNC_H__
+#define FUNC_H__
+
+int func(void);
+
+#endif
diff --git a/test cases/common/18 includedir/meson.build b/test cases/common/18 includedir/meson.build
new file mode 100644
index 0000000..17eec0e
--- /dev/null
+++ b/test cases/common/18 includedir/meson.build
@@ -0,0 +1,4 @@
+project('include dir test', 'c')
+
+inc = include_directories('include')
+subdir('src')
diff --git a/test cases/common/18 includedir/src/func.c b/test cases/common/18 includedir/src/func.c
new file mode 100644
index 0000000..215beff
--- /dev/null
+++ b/test cases/common/18 includedir/src/func.c
@@ -0,0 +1,5 @@
+#include "func.h"
+
+int func(void) {
+ return 0;
+}
diff --git a/test cases/common/18 includedir/src/meson.build b/test cases/common/18 includedir/src/meson.build
new file mode 100644
index 0000000..30d2e0c
--- /dev/null
+++ b/test cases/common/18 includedir/src/meson.build
@@ -0,0 +1,5 @@
+exe = executable('prog', 'prog.c', 'func.c', include_directories : inc)
+test('inc test', exe)
+
+exe2 = executable('prog2', 'prog.c', 'func.c', include_directories : [['../include']])
+test('inc test 2', exe2)
diff --git a/test cases/common/18 includedir/src/prog.c b/test cases/common/18 includedir/src/prog.c
new file mode 100644
index 0000000..ce4dd67
--- /dev/null
+++ b/test cases/common/18 includedir/src/prog.c
@@ -0,0 +1,5 @@
+#include "func.h"
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/180 has link arg/meson.build b/test cases/common/180 has link arg/meson.build
new file mode 100644
index 0000000..6bfbd59
--- /dev/null
+++ b/test cases/common/180 has link arg/meson.build
@@ -0,0 +1,47 @@
+project('has link arg', 'c', 'cpp')
+
+cc = meson.get_compiler('c')
+cpp = meson.get_compiler('cpp')
+
+if cc.get_argument_syntax() == 'msvc'
+ is_arg = '/OPT:REF'
+ useless = '/DEBUG'
+ isnt_arg = '/iambroken'
+else
+ is_arg = '-Wl,-L/tmp'
+ useless = '-Wl,-L/usr'
+ isnt_arg = '-Wl,-iambroken'
+endif
+
+assert(cc.has_link_argument(is_arg), 'Arg that should have worked does not work.')
+assert(cpp.has_link_argument(is_arg), 'Arg that should have worked does not work.')
+
+if cc.get_id() != 'pgi'
+assert(not cc.has_link_argument(isnt_arg), 'Arg that should be broken is not.')
+assert(not cpp.has_link_argument(isnt_arg), 'Arg that should be broken is not.')
+
+assert(cc.get_supported_link_arguments([is_arg, isnt_arg, useless]) == [is_arg, useless], 'Arg filtering returned different result.')
+assert(cpp.get_supported_link_arguments([is_arg, isnt_arg, useless]) == [is_arg, useless], 'Arg filtering returned different result.')
+
+# Have useless at the end to ensure that the search goes from front to back.
+l1 = cc.first_supported_link_argument([isnt_arg, is_arg, isnt_arg, useless])
+l2 = cc.first_supported_link_argument(isnt_arg, isnt_arg, isnt_arg)
+
+assert(l1.length() == 1, 'First supported returned wrong result.')
+assert(l1.get(0) == is_arg, 'First supported returned wrong argument.')
+assert(l2.length() == 0, 'First supported did not return empty array.')
+
+l1 = cpp.first_supported_link_argument([isnt_arg, is_arg, isnt_arg, useless])
+l2 = cpp.first_supported_link_argument(isnt_arg, isnt_arg, isnt_arg)
+
+assert(l1.length() == 1, 'First supported returned wrong result.')
+assert(l1.get(0) == is_arg, 'First supported returned wrong argument.')
+assert(l2.length() == 0, 'First supported did not return empty array.')
+
+assert(not cc.has_multi_link_arguments([isnt_arg, is_arg]), 'Arg that should be broken is not.')
+
+assert(not cc.has_link_argument('-Wl,-z,nodelete42'), 'Did not detect wrong -z linker argument')
+endif
+
+assert(cc.has_multi_link_arguments(is_arg), 'Arg that should have worked does not work.')
+assert(cc.has_multi_link_arguments([useless, is_arg]), 'Arg that should have worked does not work.')
diff --git a/test cases/common/181 same target name flat layout/foo.c b/test cases/common/181 same target name flat layout/foo.c
new file mode 100644
index 0000000..ed42789
--- /dev/null
+++ b/test cases/common/181 same target name flat layout/foo.c
@@ -0,0 +1 @@
+int meson_test_main_foo(void) { return 10; }
diff --git a/test cases/common/181 same target name flat layout/main.c b/test cases/common/181 same target name flat layout/main.c
new file mode 100644
index 0000000..6f02aeb
--- /dev/null
+++ b/test cases/common/181 same target name flat layout/main.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int meson_test_main_foo(void);
+int meson_test_subproj_foo(void);
+
+int main(void) {
+ if (meson_test_main_foo() != 10) {
+ printf("Failed meson_test_main_foo\n");
+ return 1;
+ }
+ if (meson_test_subproj_foo() != 20) {
+ printf("Failed meson_test_subproj_foo\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/181 same target name flat layout/meson.build b/test cases/common/181 same target name flat layout/meson.build
new file mode 100644
index 0000000..cfad2c2
--- /dev/null
+++ b/test cases/common/181 same target name flat layout/meson.build
@@ -0,0 +1,15 @@
+project('subdir targets', 'c')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: many targets with the same name not supported in Xcode. Patches welcome.')
+endif
+
+# Idea behind this test is to create targets with identical name
+# but different output files. We can do this by choosing different
+# name_prefix of libraries. Target id does not depend on name_prefix.
+
+main_foo = static_library('foo', 'foo.c', name_prefix : 'main')
+subdir('subdir') # defines subdir_foo
+
+exe = executable('prog', 'main.c', link_with : [main_foo, subdir_foo])
+test('main test', exe)
diff --git a/test cases/common/181 same target name flat layout/subdir/foo.c b/test cases/common/181 same target name flat layout/subdir/foo.c
new file mode 100644
index 0000000..f334292
--- /dev/null
+++ b/test cases/common/181 same target name flat layout/subdir/foo.c
@@ -0,0 +1 @@
+int meson_test_subproj_foo(void) { return 20; }
diff --git a/test cases/common/181 same target name flat layout/subdir/meson.build b/test cases/common/181 same target name flat layout/subdir/meson.build
new file mode 100644
index 0000000..223a5ef
--- /dev/null
+++ b/test cases/common/181 same target name flat layout/subdir/meson.build
@@ -0,0 +1 @@
+subdir_foo = static_library('foo', 'foo.c', name_prefix : 'subdir')
diff --git a/test cases/common/182 find override/meson.build b/test cases/common/182 find override/meson.build
new file mode 100644
index 0000000..8dcbac7
--- /dev/null
+++ b/test cases/common/182 find override/meson.build
@@ -0,0 +1,25 @@
+project('find program override', 'c')
+
+gencodegen = find_program('gencodegen', required : false)
+six_prog = find_program('six_meson_exe', required : false)
+
+assert(not gencodegen.found(), 'gencodegen is an internal program, should not be found')
+assert(not six_prog.found(), 'six_meson_exe is an internal program, should not be found')
+
+# Test the check-if-found-else-override workflow
+if not gencodegen.found()
+ subdir('subdir')
+endif
+
+subdir('otherdir')
+
+tool = find_program('sometool')
+assert(tool.found())
+assert(tool.full_path() != '')
+assert(tool.full_path() == tool.path())
+
+# six_meson_exe is an overritten project executable
+six_prog = find_program('six_meson_exe')
+assert(six_prog.found())
+assert(six_prog.full_path() != '')
+assert(six_prog.full_path() == six_prog.path())
diff --git a/test cases/common/182 find override/otherdir/main.c b/test cases/common/182 find override/otherdir/main.c
new file mode 100644
index 0000000..5fb6371
--- /dev/null
+++ b/test cases/common/182 find override/otherdir/main.c
@@ -0,0 +1,5 @@
+int be_seeing_you(void);
+
+int main(void) {
+ return be_seeing_you() == 6 ? 0 : 1;
+}
diff --git a/test cases/common/182 find override/otherdir/main2.c b/test cases/common/182 find override/otherdir/main2.c
new file mode 100644
index 0000000..80a3009
--- /dev/null
+++ b/test cases/common/182 find override/otherdir/main2.c
@@ -0,0 +1,5 @@
+int number_returner(void);
+
+int main(void) {
+ return number_returner() == 100 ? 0 : 1;
+}
diff --git a/test cases/common/182 find override/otherdir/meson.build b/test cases/common/182 find override/otherdir/meson.build
new file mode 100644
index 0000000..7deff40
--- /dev/null
+++ b/test cases/common/182 find override/otherdir/meson.build
@@ -0,0 +1,30 @@
+gen = find_program('codegen') # Should use overridden value set in "subdir".
+
+src = custom_target('arrival',
+ input : 'source.desc',
+ output : 'file.c',
+ command : [gen, '@INPUT@', '@OUTPUT@']
+ )
+
+e = executable('six', 'main.c', src)
+
+test('six', e)
+
+# Override stuff with an executables
+meson.override_find_program('six_meson_exe', e)
+
+
+# The same again, but this time with a program that was generated
+# with configure_file.
+
+gen = find_program('gencodegen')
+
+src = custom_target('hundred',
+ input : 'source2.desc',
+ output : 'file2.c',
+ command : [gen, '@INPUT@', '@OUTPUT@']
+ )
+
+e = executable('hundred', 'main2.c', src)
+
+test('hundred', e)
diff --git a/test cases/common/182 find override/otherdir/source.desc b/test cases/common/182 find override/otherdir/source.desc
new file mode 100644
index 0000000..8b19c9c
--- /dev/null
+++ b/test cases/common/182 find override/otherdir/source.desc
@@ -0,0 +1 @@
+be_seeing_you
diff --git a/test cases/common/182 find override/otherdir/source2.desc b/test cases/common/182 find override/otherdir/source2.desc
new file mode 100644
index 0000000..965f868
--- /dev/null
+++ b/test cases/common/182 find override/otherdir/source2.desc
@@ -0,0 +1 @@
+number_returner
diff --git a/test cases/common/182 find override/subdir/converter.py b/test cases/common/182 find override/subdir/converter.py
new file mode 100755
index 0000000..efe0464
--- /dev/null
+++ b/test cases/common/182 find override/subdir/converter.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import sys
+import pathlib
+
+[ifilename, ofilename] = sys.argv[1:3]
+
+ftempl = '''int %s(void) {
+ return 6;
+}
+'''
+
+d = pathlib.Path(ifilename).read_text().split('\n')[0].strip()
+
+pathlib.Path(ofilename).write_text(ftempl % d)
diff --git a/test cases/common/182 find override/subdir/gencodegen.py.in b/test cases/common/182 find override/subdir/gencodegen.py.in
new file mode 100755
index 0000000..78ebb2f
--- /dev/null
+++ b/test cases/common/182 find override/subdir/gencodegen.py.in
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import sys
+import pathlib
+
+[ifilename, ofilename] = sys.argv[1:3]
+
+ftempl = '''int %s(void) {
+ return @NUMBER@;
+}
+'''
+
+d = pathlib.Path(ifilename).read_text().split('\n')[0].strip()
+
+pathlib.Path(ofilename).write_text(ftempl % d)
diff --git a/test cases/common/182 find override/subdir/meson.build b/test cases/common/182 find override/subdir/meson.build
new file mode 100644
index 0000000..e5de34d
--- /dev/null
+++ b/test cases/common/182 find override/subdir/meson.build
@@ -0,0 +1,14 @@
+x = find_program('converter.py')
+
+meson.override_find_program('codegen', x)
+
+# Override a command with a generated script
+
+cdata = configuration_data()
+
+cdata.set('NUMBER', 100)
+numprog = configure_file(input : 'gencodegen.py.in',
+ output : 'gencodegen.py',
+ configuration : cdata)
+
+meson.override_find_program('gencodegen', numprog)
diff --git a/test cases/common/182 find override/subprojects/sub.wrap b/test cases/common/182 find override/subprojects/sub.wrap
new file mode 100644
index 0000000..17aa332
--- /dev/null
+++ b/test cases/common/182 find override/subprojects/sub.wrap
@@ -0,0 +1,5 @@
+[wrap-file]
+directory = sub
+
+[provide]
+program_names = sometool
diff --git a/test cases/common/182 find override/subprojects/sub/meson.build b/test cases/common/182 find override/subprojects/sub/meson.build
new file mode 100644
index 0000000..640f270
--- /dev/null
+++ b/test cases/common/182 find override/subprojects/sub/meson.build
@@ -0,0 +1,4 @@
+project('tools')
+
+exe = find_program('gencodegen')
+meson.override_find_program('sometool', exe)
diff --git a/test cases/common/183 partial dependency/declare_dependency/headers/foo.c b/test cases/common/183 partial dependency/declare_dependency/headers/foo.c
new file mode 100644
index 0000000..215112c
--- /dev/null
+++ b/test cases/common/183 partial dependency/declare_dependency/headers/foo.c
@@ -0,0 +1,16 @@
+/* Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#error "Included C sources that shouldn't be."
diff --git a/test cases/common/183 partial dependency/declare_dependency/headers/foo.h b/test cases/common/183 partial dependency/declare_dependency/headers/foo.h
new file mode 100644
index 0000000..28c81c9
--- /dev/null
+++ b/test cases/common/183 partial dependency/declare_dependency/headers/foo.h
@@ -0,0 +1,16 @@
+/* Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+int foo(void);
diff --git a/test cases/common/183 partial dependency/declare_dependency/main.c b/test cases/common/183 partial dependency/declare_dependency/main.c
new file mode 100644
index 0000000..057b713
--- /dev/null
+++ b/test cases/common/183 partial dependency/declare_dependency/main.c
@@ -0,0 +1,25 @@
+/* Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "foo.h"
+
+int main(void) {
+ int a = foo();
+ if (a == 1) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
diff --git a/test cases/common/183 partial dependency/declare_dependency/meson.build b/test cases/common/183 partial dependency/declare_dependency/meson.build
new file mode 100644
index 0000000..3783f66
--- /dev/null
+++ b/test cases/common/183 partial dependency/declare_dependency/meson.build
@@ -0,0 +1,32 @@
+# Copyright © 2018 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+dec_sub_dep = declare_dependency(
+ include_directories : include_directories('headers'),
+)
+
+dec_dep = declare_dependency(
+ sources : files('headers/foo.c'),
+ dependencies : dec_sub_dep,
+)
+
+sub_dep = dec_dep.partial_dependency(includes : true)
+
+dec_exe = executable(
+ 'declare_dep',
+ files('main.c', 'other.c'),
+ dependencies : sub_dep,
+)
+
+test('Declare Dependency', dec_exe)
diff --git a/test cases/common/183 partial dependency/declare_dependency/other.c b/test cases/common/183 partial dependency/declare_dependency/other.c
new file mode 100644
index 0000000..b1e199e
--- /dev/null
+++ b/test cases/common/183 partial dependency/declare_dependency/other.c
@@ -0,0 +1,20 @@
+/* Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "foo.h"
+
+int foo(void) {
+ return 1;
+}
diff --git a/test cases/common/183 partial dependency/meson.build b/test cases/common/183 partial dependency/meson.build
new file mode 100644
index 0000000..e908487
--- /dev/null
+++ b/test cases/common/183 partial dependency/meson.build
@@ -0,0 +1,17 @@
+# Copyright © 2018 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('partial dependency', ['c', 'cpp'])
+
+subdir('declare_dependency')
diff --git a/test cases/common/184 openmp/main.c b/test cases/common/184 openmp/main.c
new file mode 100644
index 0000000..cc81f48
--- /dev/null
+++ b/test cases/common/184 openmp/main.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <omp.h>
+
+int main(void) {
+#ifdef _OPENMP
+ if (omp_get_max_threads() == 2) {
+ return 0;
+ } else {
+ printf("Max threads is %d not 2.\n", omp_get_max_threads());
+ return 1;
+ }
+#else
+ printf("_OPENMP is not defined; is OpenMP compilation working?\n");
+ return 1;
+#endif
+}
diff --git a/test cases/common/184 openmp/main.cpp b/test cases/common/184 openmp/main.cpp
new file mode 100644
index 0000000..b12be3f
--- /dev/null
+++ b/test cases/common/184 openmp/main.cpp
@@ -0,0 +1,16 @@
+#include <iostream>
+#include <omp.h>
+
+int main(void) {
+#ifdef _OPENMP
+ if (omp_get_max_threads() == 2) {
+ return 0;
+ } else {
+ std::cout << "Max threads is " << omp_get_max_threads() << " not 2." << std::endl;
+ return 1;
+ }
+#else
+ printf("_OPENMP is not defined; is OpenMP compilation working?\n");
+ return 1;
+#endif
+}
diff --git a/test cases/common/184 openmp/main.f90 b/test cases/common/184 openmp/main.f90
new file mode 100644
index 0000000..d80f90f
--- /dev/null
+++ b/test cases/common/184 openmp/main.f90
@@ -0,0 +1,9 @@
+use, intrinsic :: iso_fortran_env, only: stderr=>error_unit
+use omp_lib
+
+if (omp_get_max_threads() /= 2) then
+ write(stderr, *) 'Max Fortran threads is', omp_get_max_threads(), 'not 2.'
+ stop 1
+endif
+
+end program
diff --git a/test cases/common/184 openmp/meson.build b/test cases/common/184 openmp/meson.build
new file mode 100644
index 0000000..a1154c2
--- /dev/null
+++ b/test cases/common/184 openmp/meson.build
@@ -0,0 +1,58 @@
+project('openmp', 'c')
+
+cc = meson.get_compiler('c')
+if cc.get_id() == 'gcc' and cc.version().version_compare('<4.2.0')
+ error('MESON_SKIP_TEST gcc is too old to support OpenMP.')
+endif
+if cc.get_id() == 'clang' and cc.version().version_compare('<3.7.0')
+ error('MESON_SKIP_TEST clang is too old to support OpenMP.')
+endif
+if cc.get_id() == 'msvc' and cc.version().version_compare('<17')
+ error('MESON_SKIP_TEST msvc is too old to support OpenMP.')
+endif
+if cc.get_id() == 'clang-cl'
+ error('MESON_SKIP_TEST clang-cl does not support OpenMP.')
+endif
+if cc.get_id() == 'clang' and host_machine.system() == 'windows'
+ error('MESON_SKIP_TEST Windows clang does not support OpenMP.')
+endif
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST macOS does not support OpenMP.')
+endif
+
+openmp = dependency('openmp')
+env = environment()
+env.set('OMP_NUM_THREADS', '2')
+
+exec = executable('exec',
+ 'main.c',
+ dependencies : [openmp])
+test('OpenMP C', exec, env : env)
+
+if not(build_machine.system() == 'windows' and cc.get_id() == 'pgi')
+ if add_languages('cpp', required : false)
+ execpp = executable('execpp',
+ 'main.cpp',
+ dependencies : [openmp])
+ test('OpenMP C++', execpp, env : env)
+ endif
+endif
+
+if add_languages('fortran', required : false)
+ # Mixing compilers (msvc/clang with gfortran) does not seem to work on Windows.
+ if build_machine.system() != 'windows' or cc.get_id() == 'gnu'
+ exef = executable('exef',
+ 'main.f90',
+ dependencies : [openmp])
+ test('OpenMP Fortran', exef, env : env)
+
+ openmp_f = dependency('openmp', language : 'fortran')
+ exe_f = executable('exe_f',
+ 'main.f90',
+ dependencies : [openmp_f])
+ test('OpenMP Fortran-specific', exe_f, env : env)
+ endif
+endif
+
+# Check we can apply a version constraint
+dependency('openmp', version: '>=@0@'.format(openmp.version()))
diff --git a/test cases/common/185 same target name/file.c b/test cases/common/185 same target name/file.c
new file mode 100644
index 0000000..9180030
--- /dev/null
+++ b/test cases/common/185 same target name/file.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 0;
+}
diff --git a/test cases/common/185 same target name/meson.build b/test cases/common/185 same target name/meson.build
new file mode 100644
index 0000000..4e585d5
--- /dev/null
+++ b/test cases/common/185 same target name/meson.build
@@ -0,0 +1,4 @@
+project('same name', 'c')
+
+static_library('foo', 'file.c')
+subdir('sub')
diff --git a/test cases/common/185 same target name/sub/file2.c b/test cases/common/185 same target name/sub/file2.c
new file mode 100644
index 0000000..3d1a1c3
--- /dev/null
+++ b/test cases/common/185 same target name/sub/file2.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 5;
+}
diff --git a/test cases/common/185 same target name/sub/meson.build b/test cases/common/185 same target name/sub/meson.build
new file mode 100644
index 0000000..610a4a3
--- /dev/null
+++ b/test cases/common/185 same target name/sub/meson.build
@@ -0,0 +1 @@
+static_library('foo', 'file2.c')
diff --git a/test cases/common/186 test depends/gen.py b/test cases/common/186 test depends/gen.py
new file mode 100755
index 0000000..ee4ed98
--- /dev/null
+++ b/test cases/common/186 test depends/gen.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import sys
+
+
+def main():
+ with open(sys.argv[1], 'w') as out:
+ out.write(sys.argv[2])
+ out.write('\n')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test cases/common/186 test depends/main.c b/test cases/common/186 test depends/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/186 test depends/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/186 test depends/meson.build b/test cases/common/186 test depends/meson.build
new file mode 100644
index 0000000..888c451
--- /dev/null
+++ b/test cases/common/186 test depends/meson.build
@@ -0,0 +1,26 @@
+project('test depends', 'c')
+
+gen = find_program('gen.py')
+
+custom_dep = custom_target('custom_dep',
+ build_by_default : false,
+ output : 'custom_dep.txt',
+ command : [gen, '@OUTPUT@', 'custom_dep'],
+)
+
+exe_dep = executable('exe_dep', 'main.c',
+ build_by_default : false,
+)
+
+test_prog = find_program('test.py')
+test('string dependencies', test_prog,
+ args : [
+ # This is declared for convenience,
+ # real use case might have some obscure method
+ # to find these dependencies, e.g. automatic plugin loading.
+ 'custom_dep.txt',
+ exe_dep.full_path(),
+ ],
+ depends : [custom_dep, exe_dep],
+ workdir : meson.current_build_dir(),
+)
diff --git a/test cases/common/186 test depends/test.py b/test cases/common/186 test depends/test.py
new file mode 100755
index 0000000..5b9f65c
--- /dev/null
+++ b/test cases/common/186 test depends/test.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import os
+import os.path
+import sys
+
+
+def main():
+ print('Looking in:', os.getcwd())
+ not_found = list()
+ for f in sys.argv[1:]:
+ if not os.path.exists(f):
+ not_found.append(f)
+ if not_found:
+ print('Not found:', ', '.join(not_found))
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test cases/common/187 args flattening/meson.build b/test cases/common/187 args flattening/meson.build
new file mode 100644
index 0000000..61d77e4
--- /dev/null
+++ b/test cases/common/187 args flattening/meson.build
@@ -0,0 +1,25 @@
+project('args flattening')
+
+arr = get_variable('does-not-exist', ['bar', 'baz'])
+assert(arr == ['bar', 'baz'], 'get_variable with array fallback is broken')
+
+set_variable('arr', ['bar', 'baz'])
+assert(arr == ['bar', 'baz'], 'set_variable(array) is broken')
+
+arr = meson.get_cross_property('does-not-exist', ['bar', 'baz'])
+assert(arr == ['bar', 'baz'], 'meson.get_cross_property with array fallback is broken')
+
+arr = meson.get_external_property('does-not-exist', ['bar', 'baz'])
+assert(arr == ['bar', 'baz'], 'meson.get_external_property with array fallback is broken')
+
+arr = meson.get_external_property('does-not-exist', ['bar', 'baz'], native: true)
+assert(arr == ['bar', 'baz'], 'meson.get_external_property native:true with array fallback is broken')
+
+arr = meson.get_external_property('does-not-exist', ['bar', 'baz'], native: false)
+assert(arr == ['bar', 'baz'], 'meson.get_external_property native:false with array fallback is broken')
+
+# Test deprecated behaviour
+
+conf = configuration_data()
+conf.set(['foo', 'bar'])
+message(conf.get('foo'))
diff --git a/test cases/common/188 dict/meson.build b/test cases/common/188 dict/meson.build
new file mode 100644
index 0000000..2f4c4c9
--- /dev/null
+++ b/test cases/common/188 dict/meson.build
@@ -0,0 +1,82 @@
+project('dict test', 'c')
+
+dict = {'foo' : 'bar',
+ 'baz' : 'foo',
+ 'foo bar': 'baz'}
+
+exe = executable('prog', sources : ['prog.c'])
+
+i = 0
+
+foreach key, value : dict
+ test('dict test @0@'.format(key), exe,
+ args : [dict[key], value])
+ i += 1
+endforeach
+
+assert(i == 3, 'There should be three elements in that dictionary')
+
+empty_dict = {}
+
+foreach key, value : empty_dict
+ assert(false, 'This dict should be empty')
+endforeach
+
+d1 = empty_dict + {'a' : 'b'}
+assert(d1 == {'a' : 'b'}, 'dict addition is not working')
+
+d2 = d1 + {'a' : 'b2', 'c' : 'd'}
+assert(d2 == {'a' : 'b2', 'c' : 'd'}, 'dict addition is not working')
+assert(d1 == {'a' : 'b'}, 'dict should be immutable')
+
+d3 = d2
+d3 += {'e' : 'f'}
+assert(d3 == {'a' : 'b2', 'c' : 'd', 'e' : 'f'}, 'dict plusassign is not working')
+assert(d2 == {'a' : 'b2', 'c' : 'd'}, 'dict should be immutable')
+
+dict1 = {}
+
+# A variable to be used as a key
+testkey1 = 'myKey1'
+testkey2 = 'myKey2'
+
+# Add new entry using the variable
+dict1 += {testkey1 : 'myValue'}
+dict1 += {testkey2 : 42}
+
+# Test that the stored values are correct
+assert(dict1[testkey1] == 'myValue',
+ 'Incorrect string value retrieved from dictionary - variable key')
+assert(dict1['myKey1'] == 'myValue',
+ 'Incorrect string value retrieved from dictionary - literal key')
+assert(dict1[testkey2] == 42,
+ 'Incorrect int value retrieved from dictionary - variable key')
+assert(dict1['myKey2'] == 42,
+ 'Incorrect int value retrieved from dictionary - literal key')
+
+d = {testkey1 : 1}
+assert(d[testkey1] == 1,
+ 'Incorrect int value retrieved from dictionary - variable key')
+assert(d['myKey1'] == 1,
+ 'Incorrect int value retrieved from dictionary - literal key')
+
+d = {'1' / '2' : 1, join_paths('a', 'b') : 2}
+k1 = '1' / '2'
+k2 = join_paths('a', 'b')
+assert(d[k1] == 1, 'Incorrect expression evaluation in dictionary key')
+assert(d[k2] == 2, 'Incorrect expression evaluation in dictionary key')
+
+d = {'a' + 'b' : 1}
+assert(d['a' + 'b'] == 1, 'Incorrect expression evaluation in dictionary key')
+assert(d['ab'] == 1, 'Incorrect expression evaluation in dictionary key')
+
+# Complex types
+d = {
+ 'sanity': 1,
+ 'host': host_machine,
+ 'meson': meson,
+}
+
+assert(d['sanity'] == 1)
+assert(not is_disabler(d['meson']))
+assert(not is_disabler(d['host']))
diff --git a/test cases/common/188 dict/prog.c b/test cases/common/188 dict/prog.c
new file mode 100644
index 0000000..bf0999d
--- /dev/null
+++ b/test cases/common/188 dict/prog.c
@@ -0,0 +1,8 @@
+#include <string.h>
+
+int main(int argc, char **argv) {
+ if (argc != 3)
+ return 1;
+
+ return strcmp(argv[1], argv[2]);
+}
diff --git a/test cases/common/189 check header/meson.build b/test cases/common/189 check header/meson.build
new file mode 100644
index 0000000..98b395d
--- /dev/null
+++ b/test cases/common/189 check header/meson.build
@@ -0,0 +1,48 @@
+project('check header', 'c', 'cpp')
+
+host_system = host_machine.system()
+
+non_existent_header = 'ouagadougou.h'
+
+# Copy it into the builddir to ensure that it isn't found even if it's there
+configure_file(input : non_existent_header,
+ output : non_existent_header,
+ copy: true)
+
+fallback = ''
+
+foreach comp : [meson.get_compiler('c'), meson.get_compiler('cpp')]
+ assert(comp.check_header('stdio.h', prefix : fallback), 'Stdio missing.')
+
+ # stdio.h doesn't actually need stdlib.h, but just test that setting the
+ # prefix does not result in an error.
+ assert(comp.check_header('stdio.h', prefix : '#include <stdlib.h>' + fallback),
+ 'Stdio missing.')
+
+ # Test that check_header behaves differently than has_header. The second
+ # check without windows.h will fail with check_header.
+ # We only do this check on MSVC because MinGW often defines its own wrappers
+ # that pre-include windows.h
+ if comp.get_id() == 'msvc'
+ assert(comp.check_header('XInput.h', prefix : '#include <windows.h>' + fallback),
+ 'XInput.h should not be missing on Windows')
+ assert(not comp.check_header('XInput.h'), 'XInput.h needs windows.h')
+ endif
+
+ # Test that the following GCC bug doesn't happen:
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80005
+ # https://github.com/mesonbuild/meson/issues/1458
+ if host_system == 'linux'
+ assert(comp.check_header('linux/socket.h', prefix : fallback),
+ 'Could not find <linux/socket.h>')
+ if comp.has_header('intrin.h', prefix : fallback)
+ assert(not comp.check_header('intrin.h'),
+ 'intrin.h should not be usable on linux')
+ endif
+ endif
+
+ # This header exists in the source and the builddir, but we still must not
+ # find it since we are looking in the system directories.
+ assert(not comp.check_header(non_existent_header, prefix : fallback),
+ 'Found non-existent header.')
+endforeach
diff --git a/test cases/common/189 check header/ouagadougou.h b/test cases/common/189 check header/ouagadougou.h
new file mode 100644
index 0000000..2f76c49
--- /dev/null
+++ b/test cases/common/189 check header/ouagadougou.h
@@ -0,0 +1 @@
+#define OMG_THIS_SHOULDNT_BE_FOUND
diff --git a/test cases/common/19 header in file list/header.h b/test cases/common/19 header in file list/header.h
new file mode 100644
index 0000000..354499a
--- /dev/null
+++ b/test cases/common/19 header in file list/header.h
@@ -0,0 +1 @@
+#include<stdio.h>
diff --git a/test cases/common/19 header in file list/meson.build b/test cases/common/19 header in file list/meson.build
new file mode 100644
index 0000000..79eec8d
--- /dev/null
+++ b/test cases/common/19 header in file list/meson.build
@@ -0,0 +1,14 @@
+project('header in file list', 'c')
+
+cc_id = meson.get_compiler('c').get_id()
+cc_ver = meson.get_compiler('c').version()
+
+if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08'))
+ # ICC and LCC <= 1.23.08 do not escape spaces in paths in the dependency file, so Ninja
+ # (correctly) thinks that the rule has multiple outputs and errors out:
+ # 'depfile has multiple output paths'
+ error('MESON_SKIP_TEST: Skipping test because your compiler is known to generate broken dependency files')
+endif
+
+exe = executable('prog', 'prog.c', 'header.h')
+test('basic', exe)
diff --git a/test cases/common/19 header in file list/prog.c b/test cases/common/19 header in file list/prog.c
new file mode 100644
index 0000000..97acb3f
--- /dev/null
+++ b/test cases/common/19 header in file list/prog.c
@@ -0,0 +1,3 @@
+#include "header.h"
+
+int main(void) { return 0; }
diff --git a/test cases/common/190 install_mode/config.h.in b/test cases/common/190 install_mode/config.h.in
new file mode 100644
index 0000000..14a1558
--- /dev/null
+++ b/test cases/common/190 install_mode/config.h.in
@@ -0,0 +1,5 @@
+#define MESSAGE "@var@"
+#define OTHER "@other@" "@second@" "@empty@"
+
+#mesondefine BE_TRUE
+#mesondefine SHOULD_BE_UNDEF
diff --git a/test cases/common/190 install_mode/data_source.txt b/test cases/common/190 install_mode/data_source.txt
new file mode 100644
index 0000000..0c23cc0
--- /dev/null
+++ b/test cases/common/190 install_mode/data_source.txt
@@ -0,0 +1 @@
+This is a text only input file.
diff --git a/test cases/common/190 install_mode/foo.1 b/test cases/common/190 install_mode/foo.1
new file mode 100644
index 0000000..647c097
--- /dev/null
+++ b/test cases/common/190 install_mode/foo.1
@@ -0,0 +1 @@
+this is a man page of foo.1 its contents are irrelevant
diff --git a/test cases/common/190 install_mode/meson.build b/test cases/common/190 install_mode/meson.build
new file mode 100644
index 0000000..e877ba7
--- /dev/null
+++ b/test cases/common/190 install_mode/meson.build
@@ -0,0 +1,60 @@
+project('install_mode test', 'c',
+ default_options : ['install_umask=027', 'libdir=libtest'])
+
+if build_machine.system() == 'windows'
+ error('MESON_SKIP_TEST: install_mode test requires a Unix-like OS')
+endif
+
+# confirm no regressions in install_data
+install_data('runscript.sh',
+ install_dir : get_option('bindir'),
+ install_mode : ['rwxr-sr-x', 'root', 0])
+
+# confirm no regressions in install_subdir
+install_subdir('sub1',
+ install_dir : 'share',
+ install_mode : ['rwxr-x--t', 'root'])
+
+install_subdir('sub2',
+ install_dir : 'share')
+
+# test install_mode in configure_file
+conf = configuration_data()
+conf.set('var', 'mystring')
+conf.set('other', 'string 2')
+conf.set('second', ' bonus')
+conf.set('BE_TRUE', true)
+configure_file(input : 'config.h.in',
+ output : 'config.h',
+ configuration : conf,
+ install_dir : 'include',
+ install_mode : 'rw-rwSr--')
+
+# test install_mode in custom_target
+custom_target('bindat',
+ output : 'data.dat',
+ input : 'data_source.txt',
+ command : ['cp', '@INPUT@', '@OUTPUT@'],
+ install : true,
+ install_dir : 'subdir',
+ install_mode : 'rw-rwSr--')
+
+# test install_mode in install_headers
+install_headers('rootdir.h',
+ install_mode : 'r--r--r-T')
+
+# test install_mode in install_man
+install_man('foo.1',
+ install_mode : 'r--r--r-T')
+
+# test install_mode in executable
+executable('trivialprog',
+ sources : 'trivial.c',
+ install : true,
+ build_rpath: meson.current_build_dir(),
+ install_mode : ['rwxr-sr-x', 'root', 'root'])
+
+# test install_mode in static_library
+static_library('stat', 'stat.c',
+ install : true,
+ install_mode : ['rw---Sr--'])
diff --git a/test cases/common/190 install_mode/rootdir.h b/test cases/common/190 install_mode/rootdir.h
new file mode 100644
index 0000000..72fb132
--- /dev/null
+++ b/test cases/common/190 install_mode/rootdir.h
@@ -0,0 +1,3 @@
+/* This header goes to include dir root. */
+
+int root_func();
diff --git a/test cases/common/190 install_mode/runscript.sh b/test cases/common/190 install_mode/runscript.sh
new file mode 100644
index 0000000..8bc5ca6
--- /dev/null
+++ b/test cases/common/190 install_mode/runscript.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "Runscript"
diff --git a/test cases/common/190 install_mode/stat.c b/test cases/common/190 install_mode/stat.c
new file mode 100644
index 0000000..4825cef
--- /dev/null
+++ b/test cases/common/190 install_mode/stat.c
@@ -0,0 +1 @@
+int func(void) { return 933; }
diff --git a/test cases/common/190 install_mode/sub1/second.dat b/test cases/common/190 install_mode/sub1/second.dat
new file mode 100644
index 0000000..48857a8
--- /dev/null
+++ b/test cases/common/190 install_mode/sub1/second.dat
@@ -0,0 +1 @@
+Test that multiple install_subdirs meld their results. \ No newline at end of file
diff --git a/test cases/common/190 install_mode/sub2/stub b/test cases/common/190 install_mode/sub2/stub
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/190 install_mode/sub2/stub
diff --git a/test cases/common/190 install_mode/test.json b/test cases/common/190 install_mode/test.json
new file mode 100644
index 0000000..a58caa1
--- /dev/null
+++ b/test cases/common/190 install_mode/test.json
@@ -0,0 +1,22 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/runscript.sh"},
+ {"type": "exe", "file": "usr/bin/trivialprog"},
+ {"type": "pdb", "file": "usr/bin/trivialprog"},
+ {"type": "file", "file": "usr/include/config.h"},
+ {"type": "file", "file": "usr/include/rootdir.h"},
+ {"type": "file", "file": "usr/libtest/libstat.a"},
+ {"type": "file", "file": "usr/share/man/man1/foo.1"},
+ {"type": "file", "file": "usr/share/sub1/second.dat"},
+ {"type": "file", "file": "usr/share/sub2/stub"},
+ {"type": "file", "file": "usr/subdir/data.dat"}
+ ],
+ "do_not_set_opts": ["libdir"],
+ "stdout": [
+ {
+ "line": ".* DEPRECATION: install_mode with the sticky bit on a file",
+ "match": "re",
+ "count": 3
+ }
+ ]
+}
diff --git a/test cases/common/190 install_mode/trivial.c b/test cases/common/190 install_mode/trivial.c
new file mode 100644
index 0000000..96612d4
--- /dev/null
+++ b/test cases/common/190 install_mode/trivial.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Trivial test is working.\n");
+ return 0;
+}
diff --git a/test cases/common/191 subproject array version/meson.build b/test cases/common/191 subproject array version/meson.build
new file mode 100644
index 0000000..4e5aebf
--- /dev/null
+++ b/test cases/common/191 subproject array version/meson.build
@@ -0,0 +1,3 @@
+project('master')
+
+x = subproject('foo', version : ['>=1.0.0', '<2.0'])
diff --git a/test cases/common/191 subproject array version/subprojects/foo/meson.build b/test cases/common/191 subproject array version/subprojects/foo/meson.build
new file mode 100644
index 0000000..615ee92
--- /dev/null
+++ b/test cases/common/191 subproject array version/subprojects/foo/meson.build
@@ -0,0 +1 @@
+project('foo', version : '1.0.0')
diff --git a/test cases/common/192 feature option/meson.build b/test cases/common/192 feature option/meson.build
new file mode 100644
index 0000000..b5e26fa
--- /dev/null
+++ b/test cases/common/192 feature option/meson.build
@@ -0,0 +1,62 @@
+project('feature user option', 'c')
+
+feature_opts = get_option('auto_features')
+required_opt = get_option('required')
+optional_opt = get_option('optional')
+disabled_opt = get_option('disabled')
+
+assert(not feature_opts.enabled(), 'Should be auto option')
+assert(not feature_opts.disabled(), 'Should be auto option')
+assert(feature_opts.auto(), 'Should be auto option')
+assert(feature_opts.allowed(), 'Should be auto option')
+
+assert(required_opt.enabled(), 'Should be enabled option')
+assert(not required_opt.disabled(), 'Should be enabled option')
+assert(not required_opt.auto(), 'Should be enabled option')
+assert(required_opt.allowed(), 'Should be enabled option')
+assert(required_opt.require(true, error_message: 'xyz').enabled(), 'Should be enabled option')
+assert(required_opt.disable_auto_if(true).enabled(), 'Should be enabled option')
+assert(required_opt.disable_auto_if(false).enabled(), 'Should be enabled option')
+
+assert(not optional_opt.enabled(), 'Should be auto option')
+assert(not optional_opt.disabled(), 'Should be auto option')
+assert(optional_opt.auto(), 'Should be auto option')
+assert(optional_opt.allowed(), 'Should be auto option')
+assert(optional_opt.require(true).auto(), 'Should be auto option')
+assert(optional_opt.require(false, error_message: 'xyz').disabled(), 'Should be disabled auto option')
+assert(optional_opt.disable_auto_if(true).disabled(), 'Should be disabled auto option')
+assert(optional_opt.disable_auto_if(false).auto(), 'Should be auto option')
+
+assert(not disabled_opt.enabled(), 'Should be disabled option')
+assert(disabled_opt.disabled(), 'Should be disabled option')
+assert(not disabled_opt.auto(), 'Should be disabled option')
+assert(not disabled_opt.allowed(), 'Should be disabled option')
+assert(disabled_opt.require(true).disabled(), 'Should be disabled option')
+assert(disabled_opt.require(false, error_message: 'xyz').disabled(), 'Should be disabled option')
+assert(disabled_opt.disable_auto_if(true).disabled(), 'Should be disabled option')
+assert(disabled_opt.disable_auto_if(false).disabled(), 'Should be disabled option')
+
+dep = dependency('threads', required : required_opt)
+assert(dep.found(), 'Should find required "threads" dep')
+
+dep = dependency('threads', required : optional_opt)
+assert(dep.found(), 'Should find optional "threads" dep')
+
+dep = dependency('threads', required : disabled_opt)
+assert(not dep.found(), 'Should not find disabled "threads" dep')
+
+dep = dependency('notfounddep', required : optional_opt)
+assert(not dep.found(), 'Should not find optional "notfounddep" dep')
+
+dep = dependency('notfounddep', required : disabled_opt)
+assert(not dep.found(), 'Should not find disabled "notfounddep" dep')
+
+cc = meson.get_compiler('c')
+lib = cc.find_library('m', required : disabled_opt)
+assert(not lib.found(), 'Should not find "m" library')
+
+cp = find_program('cp', required : disabled_opt)
+assert(not cp.found(), 'Should not find "cp" program')
+
+found = add_languages('cpp', required : disabled_opt)
+assert(not found, 'Should not find "cpp" language')
diff --git a/test cases/common/192 feature option/meson_options.txt b/test cases/common/192 feature option/meson_options.txt
new file mode 100644
index 0000000..063a35f
--- /dev/null
+++ b/test cases/common/192 feature option/meson_options.txt
@@ -0,0 +1,3 @@
+option('required', type : 'feature', value : 'enabled', description : 'An required feature')
+option('optional', type : 'feature', value : 'auto', description : 'An optional feature')
+option('disabled', type : 'feature', value : 'disabled', description : 'A disabled feature')
diff --git a/test cases/common/193 feature option disabled/meson.build b/test cases/common/193 feature option disabled/meson.build
new file mode 100644
index 0000000..65d4d71
--- /dev/null
+++ b/test cases/common/193 feature option disabled/meson.build
@@ -0,0 +1,23 @@
+project('feature user option',
+ default_options : ['auto_features=disabled'])
+
+feature_opts = get_option('auto_features')
+required_opt = get_option('required')
+optional_opt = get_option('optional')
+disabled_opt = get_option('disabled')
+
+assert(not feature_opts.enabled(), 'Should be disabled option')
+assert(feature_opts.disabled(), 'Should be disabled option')
+assert(not feature_opts.auto(), 'Should be disabled option')
+
+assert(required_opt.enabled(), 'Should be enabled option')
+assert(not required_opt.disabled(), 'Should be enabled option')
+assert(not required_opt.auto(), 'Should be enabled option')
+
+assert(not optional_opt.enabled(), 'Auto feature should be disabled')
+assert(optional_opt.disabled(), 'Auto feature should be disabled')
+assert(not optional_opt.auto(), 'Auto feature should be disabled')
+
+assert(not disabled_opt.enabled(), 'Should be disabled option')
+assert(disabled_opt.disabled(), 'Should be disabled option')
+assert(not disabled_opt.auto(), 'Should be disabled option')
diff --git a/test cases/common/193 feature option disabled/meson_options.txt b/test cases/common/193 feature option disabled/meson_options.txt
new file mode 100644
index 0000000..063a35f
--- /dev/null
+++ b/test cases/common/193 feature option disabled/meson_options.txt
@@ -0,0 +1,3 @@
+option('required', type : 'feature', value : 'enabled', description : 'An required feature')
+option('optional', type : 'feature', value : 'auto', description : 'An optional feature')
+option('disabled', type : 'feature', value : 'disabled', description : 'A disabled feature')
diff --git a/test cases/common/194 static threads/lib1.c b/test cases/common/194 static threads/lib1.c
new file mode 100644
index 0000000..1aa786c
--- /dev/null
+++ b/test cases/common/194 static threads/lib1.c
@@ -0,0 +1,13 @@
+#if defined _WIN32
+#include<windows.h>
+#else
+#include<pthread.h>
+#endif
+
+void *f(void) {
+#if defined _WIN32
+ return CreateThread;
+#else
+ return pthread_create;
+#endif
+}
diff --git a/test cases/common/194 static threads/lib2.c b/test cases/common/194 static threads/lib2.c
new file mode 100644
index 0000000..e988814
--- /dev/null
+++ b/test cases/common/194 static threads/lib2.c
@@ -0,0 +1,5 @@
+extern void *f(void);
+
+void *g(void) {
+ return f();
+}
diff --git a/test cases/common/194 static threads/meson.build b/test cases/common/194 static threads/meson.build
new file mode 100644
index 0000000..4279200
--- /dev/null
+++ b/test cases/common/194 static threads/meson.build
@@ -0,0 +1,13 @@
+project('threads', 'c')
+
+thread_dep = dependency('threads')
+
+
+lib1 = static_library('lib1', 'lib1.c',
+ dependencies : thread_dep)
+
+lib2 = static_library('lib2', 'lib2.c',
+ link_with : lib1)
+
+executable('prog', 'prog.c',
+ link_with : lib2)
diff --git a/test cases/common/194 static threads/prog.c b/test cases/common/194 static threads/prog.c
new file mode 100644
index 0000000..14a7c76
--- /dev/null
+++ b/test cases/common/194 static threads/prog.c
@@ -0,0 +1,6 @@
+extern void *g(void);
+
+int main(void) {
+ g();
+ return 0;
+}
diff --git a/test cases/common/195 generator in subdir/com/mesonbuild/genprog.py b/test cases/common/195 generator in subdir/com/mesonbuild/genprog.py
new file mode 100644
index 0000000..681c43a
--- /dev/null
+++ b/test cases/common/195 generator in subdir/com/mesonbuild/genprog.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+import os, sys, argparse
+
+h_templ = '''#pragma once
+
+int %s(void);
+'''
+
+c_templ = '''#include"%s.h"
+
+int %s(void) {
+ return 0;
+}
+'''
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--searchdir', required=True)
+parser.add_argument('--outdir', required=True)
+parser.add_argument('ifiles', nargs='+')
+
+options = parser.parse_args()
+
+searchdir = options.searchdir
+outdir = options.outdir
+ifiles = options.ifiles
+
+rel_ofiles = []
+
+for ifile in ifiles:
+ if not ifile.startswith(options.searchdir):
+ sys.exit(f'Input file {ifile} does not start with search dir {searchdir}.')
+ rel_ofile = ifile[len(searchdir):]
+ if rel_ofile[0] == '/' or rel_ofile[0] == '\\':
+ rel_ofile = rel_ofile[1:]
+ rel_ofiles.append(os.path.splitext(rel_ofile)[0])
+
+ofile_bases = [os.path.join(outdir, i) for i in rel_ofiles]
+
+for i, ifile_name in enumerate(ifiles):
+ proto_name = open(ifile_name).readline().strip()
+ h_out = ofile_bases[i] + '.h'
+ c_out = ofile_bases[i] + '.c'
+ os.makedirs(os.path.split(ofile_bases[i])[0], exist_ok=True)
+ open(h_out, 'w').write(h_templ % (proto_name))
+ open(c_out, 'w').write(c_templ % (proto_name, proto_name))
diff --git a/test cases/common/195 generator in subdir/com/mesonbuild/meson.build b/test cases/common/195 generator in subdir/com/mesonbuild/meson.build
new file mode 100644
index 0000000..4808743
--- /dev/null
+++ b/test cases/common/195 generator in subdir/com/mesonbuild/meson.build
@@ -0,0 +1,10 @@
+gprog = find_program('genprog.py')
+
+gen = generator(gprog, \
+ output : ['@BASENAME@.c', '@BASENAME@.h'],
+ arguments : ['--searchdir=@CURRENT_SOURCE_DIR@', '--outdir=@BUILD_DIR@', '@INPUT@'])
+
+generated = gen.process('subbie.inp')
+
+e = executable('testprog', 'testprog.c', generated)
+test('testprog', e)
diff --git a/test cases/common/195 generator in subdir/com/mesonbuild/subbie.inp b/test cases/common/195 generator in subdir/com/mesonbuild/subbie.inp
new file mode 100644
index 0000000..df0f4e9
--- /dev/null
+++ b/test cases/common/195 generator in subdir/com/mesonbuild/subbie.inp
@@ -0,0 +1 @@
+subbie
diff --git a/test cases/common/195 generator in subdir/com/mesonbuild/testprog.c b/test cases/common/195 generator in subdir/com/mesonbuild/testprog.c
new file mode 100644
index 0000000..7a7cdf7
--- /dev/null
+++ b/test cases/common/195 generator in subdir/com/mesonbuild/testprog.c
@@ -0,0 +1,5 @@
+#include"subbie.h"
+
+int main(void) {
+ return subbie();
+}
diff --git a/test cases/common/195 generator in subdir/meson.build b/test cases/common/195 generator in subdir/meson.build
new file mode 100644
index 0000000..9b8eb7c
--- /dev/null
+++ b/test cases/common/195 generator in subdir/meson.build
@@ -0,0 +1,3 @@
+project('generator in subdir', 'c')
+
+subdir('com/mesonbuild')
diff --git a/test cases/common/196 subproject with features/meson.build b/test cases/common/196 subproject with features/meson.build
new file mode 100644
index 0000000..5bdfefb
--- /dev/null
+++ b/test cases/common/196 subproject with features/meson.build
@@ -0,0 +1,17 @@
+project('proj', 'c')
+
+auto_subproj = subproject('sub', required: get_option('use-subproject'))
+assert(auto_subproj.found(), 'Subproject should always be buildable and thus found')
+
+auto_dep = dependency('', fallback: ['sub', 'libSub'], required: true)
+assert(auto_dep.found() == true, 'Subproject is required and foundable, dependency should be found.')
+
+disabled_subproj = subproject('disabled_sub', required: get_option('disabled-subproject'))
+assert(disabled_subproj.found() == false, 'Disabled subproject should be NOT found')
+
+disabled_dep = dependency('', fallback: ['disabled_sub', 'libSub'], required: false)
+assert(disabled_dep.found() == false, 'Subprojetc was disabled, it should never be built.')
+nothing = executable('nothing', 'nothing.c', dependencies: [disabled_dep])
+
+subproj_with_missing_dep = subproject('auto_sub_with_missing_dep', required: get_option('auto-sub-with-missing-dep'))
+assert(subproj_with_missing_dep.found() == false, 'Subproject with required=auto and missing dependency should be NOT found')
diff --git a/test cases/common/196 subproject with features/meson_options.txt b/test cases/common/196 subproject with features/meson_options.txt
new file mode 100644
index 0000000..a46e5fb
--- /dev/null
+++ b/test cases/common/196 subproject with features/meson_options.txt
@@ -0,0 +1,3 @@
+option('use-subproject', type : 'feature', value : 'auto')
+option('disabled-subproject', type : 'feature', value : 'disabled')
+option('auto-sub-with-missing-dep', type : 'feature', value : 'auto')
diff --git a/test cases/common/196 subproject with features/nothing.c b/test cases/common/196 subproject with features/nothing.c
new file mode 100644
index 0000000..58fe692
--- /dev/null
+++ b/test cases/common/196 subproject with features/nothing.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/test cases/common/196 subproject with features/subprojects/auto_sub_with_missing_dep/meson.build b/test cases/common/196 subproject with features/subprojects/auto_sub_with_missing_dep/meson.build
new file mode 100644
index 0000000..fa6b011
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/auto_sub_with_missing_dep/meson.build
@@ -0,0 +1,3 @@
+project('sub', 'c')
+
+dependency('no_way_this_exists', required: true) \ No newline at end of file
diff --git a/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/meson.build b/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/meson.build
new file mode 100644
index 0000000..933001a
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/meson.build
@@ -0,0 +1,3 @@
+lib = static_library('sub', 'sub.c')
+
+libSub = declare_dependency(include_directories: include_directories('.'), link_with: lib) \ No newline at end of file
diff --git a/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.c b/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.c
new file mode 100644
index 0000000..e748ac7
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.c
@@ -0,0 +1,5 @@
+#include "sub.h"
+
+int sub(void) {
+ return 0;
+}
diff --git a/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.h b/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.h
new file mode 100644
index 0000000..f1ab0e1
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/disabled_sub/lib/sub.h
@@ -0,0 +1,6 @@
+#ifndef SUB_H
+#define SUB_H
+
+int sub();
+
+#endif
diff --git a/test cases/common/196 subproject with features/subprojects/disabled_sub/meson.build b/test cases/common/196 subproject with features/subprojects/disabled_sub/meson.build
new file mode 100644
index 0000000..65fef03
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/disabled_sub/meson.build
@@ -0,0 +1,3 @@
+project('disabled_sub', 'c')
+
+subdir('lib') \ No newline at end of file
diff --git a/test cases/common/196 subproject with features/subprojects/sub/lib/meson.build b/test cases/common/196 subproject with features/subprojects/sub/lib/meson.build
new file mode 100644
index 0000000..731d22b
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/sub/lib/meson.build
@@ -0,0 +1,2 @@
+lib = static_library('sub', 'sub.c')
+libSub = declare_dependency(include_directories: include_directories('.'), link_with: lib)
diff --git a/test cases/common/196 subproject with features/subprojects/sub/lib/sub.c b/test cases/common/196 subproject with features/subprojects/sub/lib/sub.c
new file mode 100644
index 0000000..768ed36
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/sub/lib/sub.c
@@ -0,0 +1,5 @@
+#include "sub.h"
+
+int sub(void) {
+ return 0;
+}
diff --git a/test cases/common/196 subproject with features/subprojects/sub/lib/sub.h b/test cases/common/196 subproject with features/subprojects/sub/lib/sub.h
new file mode 100644
index 0000000..2b59a3a
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/sub/lib/sub.h
@@ -0,0 +1,6 @@
+#ifndef SUB_H
+#define SUB_H
+
+int sub(void);
+
+#endif
diff --git a/test cases/common/196 subproject with features/subprojects/sub/meson.build b/test cases/common/196 subproject with features/subprojects/sub/meson.build
new file mode 100644
index 0000000..31882ac
--- /dev/null
+++ b/test cases/common/196 subproject with features/subprojects/sub/meson.build
@@ -0,0 +1,3 @@
+project('sub', 'c')
+
+subdir('lib') \ No newline at end of file
diff --git a/test cases/common/197 function attributes/meson.build b/test cases/common/197 function attributes/meson.build
new file mode 100644
index 0000000..4d43ecd
--- /dev/null
+++ b/test cases/common/197 function attributes/meson.build
@@ -0,0 +1,119 @@
+# Copyright © 2017-2018 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('gcc func attributes', ['c', 'cpp'])
+
+# For msvc these will fail because msvc doesn't support __attribute__, for
+# Clang and GCC, they should pass.
+c = meson.get_compiler('c')
+cpp = meson.get_compiler('cpp')
+
+if c.get_id() == 'pgi'
+ error('MESON_SKIP_TEST: PGI supports its own set of features, will need a separate list for PGI to test it.')
+endif
+
+expected_result = not ['msvc', 'clang-cl', 'intel-cl'].contains(c.get_id())
+
+# Q: Why is ifunc not in this list or any of the below lists?
+# A: It's too damn hard to figure out if you actually support it, since it
+# requires both compiler and libc support, and there isn't a good way to
+# figure that out except by running the code we're trying to test.
+attributes = [
+ 'aligned',
+ 'always_inline',
+ 'cold',
+ 'const',
+ 'constructor',
+ 'constructor_priority',
+ 'deprecated',
+ 'destructor',
+ 'flatten',
+ 'format',
+ 'format_arg',
+ 'gnu_inline',
+ 'hot',
+ 'malloc',
+ 'noinline',
+ 'nonnull',
+ 'noreturn',
+ 'nothrow',
+ 'pure',
+ 'section',
+ 'sentinel',
+ 'unused',
+ 'used',
+ 'warn_unused_result',
+ 'weak',
+]
+
+if c.get_id() != 'intel'
+ # not supported by icc as of 19.0.0
+ attributes += 'weakref'
+endif
+
+# These are unsupported on darwin with apple clang 9.1.0
+if host_machine.system() != 'darwin'
+ attributes += 'alias'
+ attributes += 'visibility'
+ attributes += 'alloc_size'
+endif
+
+if ['gcc', 'intel'].contains(c.get_id())
+ # not supported by clang as of 5.0.0 (at least up to 6.0.1)
+ attributes += 'artificial'
+ attributes += 'error'
+ attributes += 'externally_visible'
+ attributes += 'leaf'
+ attributes += 'noclone'
+ attributes += 'optimize'
+ attributes += 'warning'
+
+ if c.get_id() == 'gcc' and c.version().version_compare('>= 7.0.0')
+ attributes += 'fallthrough'
+ endif
+
+ # XXX(arsen): limited to clang 13+ even though gcc 11 has it, since gcc
+ # detects support for it at compile time based on binutils version
+ if c.get_id() == 'clang' and c.version().version_compare('>= 13.0.0')
+ attributes += 'retain'
+ endif
+endif
+
+if get_option('mode') == 'single'
+ foreach a : attributes
+ x = c.has_function_attribute(a)
+ assert(x == expected_result, '@0@: @1@'.format(c.get_id(), a))
+ x = cpp.has_function_attribute(a)
+ assert(x == expected_result, '@0@: @1@'.format(cpp.get_id(), a))
+ endforeach
+
+ win_expect = ['windows', 'cygwin'].contains(host_machine.system())
+ foreach a : ['dllexport', 'dllimport']
+ assert(c.has_function_attribute(a) == win_expect,
+ '@0@: @1@'.format(c.get_id(), a))
+ assert(cpp.has_function_attribute(a) == win_expect,
+ '@0@: @1@'.format(cpp.get_id(), a))
+ endforeach
+else
+ if not ['msvc', 'clang-cl', 'intel-cl'].contains(c.get_id())
+ multi_expected = attributes
+ else
+ multi_expected = []
+ endif
+
+ multi_check = c.get_supported_function_attributes(attributes)
+ assert(multi_check == multi_expected, 'get_supported_function_arguments works (C)')
+ multi_check = cpp.get_supported_function_attributes(attributes)
+ assert(multi_check == multi_expected, 'get_supported_function_arguments works (C++)')
+endif
diff --git a/test cases/common/197 function attributes/meson_options.txt b/test cases/common/197 function attributes/meson_options.txt
new file mode 100644
index 0000000..4a1d87c
--- /dev/null
+++ b/test cases/common/197 function attributes/meson_options.txt
@@ -0,0 +1,7 @@
+option(
+ 'mode',
+ type : 'combo',
+ choices : ['single', 'parallel'],
+ value : 'single',
+ description : 'Test the one at a time function or many at a time function.'
+)
diff --git a/test cases/common/197 function attributes/test.json b/test cases/common/197 function attributes/test.json
new file mode 100644
index 0000000..d06a24a
--- /dev/null
+++ b/test cases/common/197 function attributes/test.json
@@ -0,0 +1,10 @@
+{
+ "matrix": {
+ "options": {
+ "mode": [
+ { "val": "single" },
+ { "val": "parallel" }
+ ]
+ }
+ }
+}
diff --git a/test cases/common/198 broken subproject/meson.build b/test cases/common/198 broken subproject/meson.build
new file mode 100644
index 0000000..e3a6cae
--- /dev/null
+++ b/test cases/common/198 broken subproject/meson.build
@@ -0,0 +1,2 @@
+project('test broken subproject')
+subproject('broken', required : false)
diff --git a/test cases/common/198 broken subproject/subprojects/broken/broken.c b/test cases/common/198 broken subproject/subprojects/broken/broken.c
new file mode 100644
index 0000000..a9fc4b1
--- /dev/null
+++ b/test cases/common/198 broken subproject/subprojects/broken/broken.c
@@ -0,0 +1 @@
+#error This must not compile
diff --git a/test cases/common/198 broken subproject/subprojects/broken/meson.build b/test cases/common/198 broken subproject/subprojects/broken/meson.build
new file mode 100644
index 0000000..2d64fde
--- /dev/null
+++ b/test cases/common/198 broken subproject/subprojects/broken/meson.build
@@ -0,0 +1,4 @@
+project('broken', 'c')
+
+executable('app', 'broken.c')
+assert(false, 'This subproject must fail')
diff --git a/test cases/common/199 argument syntax/meson.build b/test cases/common/199 argument syntax/meson.build
new file mode 100644
index 0000000..b97ca74
--- /dev/null
+++ b/test cases/common/199 argument syntax/meson.build
@@ -0,0 +1,19 @@
+project(
+ 'argument syntax',
+ ['c'],
+)
+
+cc = meson.get_compiler('c')
+
+if ['gcc', 'lcc', 'clang', 'intel'].contains(cc.get_id())
+ expected = 'gcc'
+elif ['msvc', 'clang-cl', 'intel-cl'].contains(cc.get_id())
+ expected = 'msvc'
+else
+ # It's possible that other compilers end up here that shouldn't
+ expected = 'other'
+endif
+
+assert(cc.get_argument_syntax() == expected,
+ 'Wrong output for compiler @0@. expected @1@ but got @2@'.format(
+ cc.get_id(), expected, cc.get_argument_syntax()))
diff --git a/test cases/common/2 cpp/VERSIONFILE b/test cases/common/2 cpp/VERSIONFILE
new file mode 100644
index 0000000..3eefcb9
--- /dev/null
+++ b/test cases/common/2 cpp/VERSIONFILE
@@ -0,0 +1 @@
+1.0.0
diff --git a/test cases/common/2 cpp/cpp.C b/test cases/common/2 cpp/cpp.C
new file mode 100644
index 0000000..d3df476
--- /dev/null
+++ b/test cases/common/2 cpp/cpp.C
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(void) {
+ std::cout << "C++ seems to be working." << std::endl;
+ return 0;
+}
diff --git a/test cases/common/2 cpp/meson.build b/test cases/common/2 cpp/meson.build
new file mode 100644
index 0000000..2962681
--- /dev/null
+++ b/test cases/common/2 cpp/meson.build
@@ -0,0 +1,41 @@
+project('c++ test', 'cpp', version: files('VERSIONFILE'))
+
+cpp = meson.get_compiler('cpp')
+if cpp.get_id() == 'intel'
+ # Error out if the -std=xxx option is incorrect
+ add_project_arguments('-diag-error', '10159', language : 'cpp')
+elif cpp.get_id() == 'intel-cl'
+ add_project_arguments('/Qdiag-error:10159', language : 'cpp')
+endif
+
+exe = executable('trivialprog', 'trivial.cc', extra_files : 'something.txt')
+test('runtest', exe)
+
+has_not_changed = false
+if is_disabler(exe)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'Executable has changed.')
+
+assert(not is_disabler(exe), 'Executable is a disabler.')
+
+exe = executable('trivialprog', 'trivial.cc', extra_files : disabler())
+
+assert(is_disabler(exe), 'Executable is not a disabler.')
+
+if exe.found()
+ exe_disabled = false
+else
+ exe_disabled = true
+endif
+
+assert(exe_disabled, 'Executable was not disabled.')
+
+if cpp.get_id() == 'msvc'
+ exe = executable('cppprog', 'cpp.C', cpp_args : '/TP')
+else
+ exe = executable('cppprog', 'cpp.C')
+endif
+test('cpptest', exe)
diff --git a/test cases/common/2 cpp/something.txt b/test cases/common/2 cpp/something.txt
new file mode 100644
index 0000000..9f6cc91
--- /dev/null
+++ b/test cases/common/2 cpp/something.txt
@@ -0,0 +1 @@
+This file is only here so it shows up in IDEs as part of this target.
diff --git a/test cases/common/2 cpp/trivial.cc b/test cases/common/2 cpp/trivial.cc
new file mode 100644
index 0000000..d3df476
--- /dev/null
+++ b/test cases/common/2 cpp/trivial.cc
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(void) {
+ std::cout << "C++ seems to be working." << std::endl;
+ return 0;
+}
diff --git a/test cases/common/20 global arg/meson.build b/test cases/common/20 global arg/meson.build
new file mode 100644
index 0000000..2a1c736
--- /dev/null
+++ b/test cases/common/20 global arg/meson.build
@@ -0,0 +1,16 @@
+project('global arg test', 'cpp', 'c')
+
+add_global_arguments('-DMYTHING', language : 'c')
+add_global_arguments('-DMYCPPTHING', language : 'cpp')
+add_global_arguments('-DGLOBAL_HOST', language : 'c')
+
+build_c_args = ['-DARG_BUILD']
+c_args = ['-DARG_HOST']
+
+add_global_arguments('-DMYCANDCPPTHING', language: ['c', 'cpp'])
+
+exe2 = executable('prog2', 'prog.c', c_args : c_args)
+exe3 = executable('prog3', 'prog.cc')
+
+test('prog2', exe2)
+test('prog3', exe3)
diff --git a/test cases/common/20 global arg/prog.c b/test cases/common/20 global arg/prog.c
new file mode 100644
index 0000000..2a71236
--- /dev/null
+++ b/test cases/common/20 global arg/prog.c
@@ -0,0 +1,43 @@
+#ifndef MYTHING
+ #error "Global argument not set"
+#endif
+
+#ifdef MYCPPTHING
+ #error "Wrong global argument set"
+#endif
+
+#ifndef MYCANDCPPTHING
+ #error "Global argument not set"
+#endif
+
+#if !defined(GLOBAL_HOST) && !defined(GLOBAL_BUILD)
+ #error "Neither global_host nor glogal_build is set."
+#endif
+
+#if defined(GLOBAL_HOST) && defined(GLOBAL_BUILD)
+ #error "Both global build and global host set."
+#endif
+
+#ifdef GLOBAL_BUILD
+ #ifndef ARG_BUILD
+ #error "Global is build but arg_build is not set."
+ #endif
+
+ #ifdef ARG_HOST
+ #error "Global is build but arg host is set."
+ #endif
+#endif
+
+#ifdef GLOBAL_HOST
+ #ifndef ARG_HOST
+ #error "Global is host but arg_host is not set."
+ #endif
+
+ #ifdef ARG_BUILD
+ #error "Global is host but arg_build is set."
+ #endif
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/20 global arg/prog.cc b/test cases/common/20 global arg/prog.cc
new file mode 100644
index 0000000..5c32209
--- /dev/null
+++ b/test cases/common/20 global arg/prog.cc
@@ -0,0 +1,15 @@
+#ifdef MYTHING
+#error "Wrong global argument set"
+#endif
+
+#ifndef MYCPPTHING
+#error "Global argument not set"
+#endif
+
+#ifndef MYCANDCPPTHING
+#error "Global argument not set"
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/200 install name_prefix name_suffix/libfile.c b/test cases/common/200 install name_prefix name_suffix/libfile.c
new file mode 100644
index 0000000..91489b2
--- /dev/null
+++ b/test cases/common/200 install name_prefix name_suffix/libfile.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func(void) {
+ return 0;
+}
diff --git a/test cases/common/200 install name_prefix name_suffix/meson.build b/test cases/common/200 install name_prefix name_suffix/meson.build
new file mode 100644
index 0000000..044f915
--- /dev/null
+++ b/test cases/common/200 install name_prefix name_suffix/meson.build
@@ -0,0 +1,13 @@
+project('library with name_prefix name_suffix test', 'c')
+
+shared_library('foo', 'libfile.c', name_prefix: '', install : true)
+static_library('bar', 'libfile.c', name_prefix: '', install : true)
+
+shared_library('baz', 'libfile.c', name_suffix: 'cheese', install : true)
+static_library('qux', 'libfile.c', name_suffix: 'cheese', install : true)
+
+shared_library('corge', 'libfile.c', name_prefix: 'bow', name_suffix: 'stern', install : true)
+static_library('grault', 'libfile.c', name_prefix: 'bow', name_suffix: 'stern', install : true)
+
+# exercise default name_prefix and name_suffix
+shared_library('garply', 'libfile.c', name_prefix: [], name_suffix: [], install : true)
diff --git a/test cases/common/200 install name_prefix name_suffix/test.json b/test cases/common/200 install name_prefix name_suffix/test.json
new file mode 100644
index 0000000..b92a985
--- /dev/null
+++ b/test cases/common/200 install name_prefix name_suffix/test.json
@@ -0,0 +1,19 @@
+{
+ "installed": [
+ {"type": "pdb", "file": "usr/bin/baz"},
+ {"type": "pdb", "file": "usr/bin/bowcorge"},
+ {"type": "pdb", "file": "usr/bin/foo"},
+ {"type": "expr", "file": "usr/?lib/bowcorge.stern"},
+ {"type": "expr", "file": "usr/lib/?libbaz.cheese"},
+ {"type": "file", "file": "usr/lib/bar.a"},
+ {"type": "implib", "file": "usr/lib/bowcorge"},
+ {"type": "file", "file": "usr/lib/bowgrault.stern"},
+ {"type": "implib", "file": "usr/lib/foo"},
+ {"type": "expr", "file": "usr/lib/foo?so"},
+ {"type": "implib", "file": "usr/lib/libbaz"},
+ {"type": "file", "file": "usr/lib/libqux.cheese"},
+ {"type": "expr", "file": "usr/?lib/libgarply?so"},
+ {"type": "implib", "file": "usr/lib/libgarply"},
+ {"type": "pdb", "file": "usr/bin/garply"}
+ ]
+}
diff --git a/test cases/common/201 kwarg entry/inc/prog.h b/test cases/common/201 kwarg entry/inc/prog.h
new file mode 100644
index 0000000..665521d
--- /dev/null
+++ b/test cases/common/201 kwarg entry/inc/prog.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define MESSAGE "Hello there.\n"
diff --git a/test cases/common/201 kwarg entry/meson.build b/test cases/common/201 kwarg entry/meson.build
new file mode 100644
index 0000000..564ec37
--- /dev/null
+++ b/test cases/common/201 kwarg entry/meson.build
@@ -0,0 +1,7 @@
+project('kwarg', 'c')
+
+default_kwargs = {'install': true,
+ 'include_directories': include_directories('inc')}
+
+executable('prog', 'prog.c',
+ kwargs: default_kwargs)
diff --git a/test cases/common/201 kwarg entry/prog.c b/test cases/common/201 kwarg entry/prog.c
new file mode 100644
index 0000000..2eec26b
--- /dev/null
+++ b/test cases/common/201 kwarg entry/prog.c
@@ -0,0 +1,7 @@
+#include<prog.h>
+#include<stdio.h>
+
+int main(void) {
+ printf(MESSAGE);
+ return 0;
+}
diff --git a/test cases/common/201 kwarg entry/test.json b/test cases/common/201 kwarg entry/test.json
new file mode 100644
index 0000000..135300d
--- /dev/null
+++ b/test cases/common/201 kwarg entry/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/common/202 custom target build by default/docgen.py b/test cases/common/202 custom target build by default/docgen.py
new file mode 100644
index 0000000..f343f21
--- /dev/null
+++ b/test cases/common/202 custom target build by default/docgen.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+out = sys.argv[1]
+
+os.mkdir(out)
+
+for name in ('a', 'b', 'c'):
+ with open(os.path.join(out, name + '.txt'), 'w') as f:
+ f.write(name)
diff --git a/test cases/common/202 custom target build by default/meson.build b/test cases/common/202 custom target build by default/meson.build
new file mode 100644
index 0000000..53f0fe6
--- /dev/null
+++ b/test cases/common/202 custom target build by default/meson.build
@@ -0,0 +1,10 @@
+project('custom-target-dir-install')
+
+docgen = find_program('docgen.py')
+
+custom_target('docgen',
+ output : 'html',
+ command : [docgen, '@OUTPUT@'],
+ install : true,
+ build_by_default : false,
+ install_dir : join_paths(get_option('datadir'), 'doc/testpkgname'))
diff --git a/test cases/common/202 custom target build by default/test.json b/test cases/common/202 custom target build by default/test.json
new file mode 100644
index 0000000..df8bcb9
--- /dev/null
+++ b/test cases/common/202 custom target build by default/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+
+ ]
+}
diff --git a/test cases/common/203 find_library and headers/foo.h b/test cases/common/203 find_library and headers/foo.h
new file mode 100644
index 0000000..014e06e
--- /dev/null
+++ b/test cases/common/203 find_library and headers/foo.h
@@ -0,0 +1 @@
+#define VAL 42
diff --git a/test cases/common/203 find_library and headers/meson.build b/test cases/common/203 find_library and headers/meson.build
new file mode 100644
index 0000000..bcd71f1
--- /dev/null
+++ b/test cases/common/203 find_library and headers/meson.build
@@ -0,0 +1,23 @@
+project('find library and headers', 'c')
+
+cc = meson.get_compiler('c')
+
+if not cc.find_library('z', required : false).found()
+ error('MESON_SKIP_TEST: zlib not found.')
+endif
+
+lib = cc.find_library('z',
+ has_headers : 'foo.h',
+ required : false)
+assert(not lib.found(), 'Header should be missing')
+
+lib = cc.find_library('z',
+ has_headers : 'foo.h',
+ header_include_directories : include_directories('.'))
+assert(lib.found(), 'Header should be found')
+
+lib = cc.find_library('z',
+ has_headers : ['foo.h', 'bar.h'],
+ header_include_directories : include_directories('.'),
+ required : false)
+assert(not lib.found(), 'One header should be missing')
diff --git a/test cases/common/204 line continuation/meson.build b/test cases/common/204 line continuation/meson.build
new file mode 100644
index 0000000..16c72f9
--- /dev/null
+++ b/test cases/common/204 line continuation/meson.build
@@ -0,0 +1,17 @@
+project('line continuation')
+
+a = 1
+b = 2
+
+c = a \
++b
+assert(c == 3, 'Line continuation is not working')
+
+d = a + \
+ b
+assert(d == 3, 'Line continuation is not working')
+
+if a == 1 and \
+ b == 3
+ error('Line continuation in "if" condition is not working')
+endif
diff --git a/test cases/common/205 native file path override/main.cpp b/test cases/common/205 native file path override/main.cpp
new file mode 100644
index 0000000..91bc809
--- /dev/null
+++ b/test cases/common/205 native file path override/main.cpp
@@ -0,0 +1,5 @@
+#include <iostream>
+
+int main(void) {
+ std::cout << "Hello world!" << std::endl;
+}
diff --git a/test cases/common/205 native file path override/meson.build b/test cases/common/205 native file path override/meson.build
new file mode 100644
index 0000000..142ca1c
--- /dev/null
+++ b/test cases/common/205 native file path override/meson.build
@@ -0,0 +1,7 @@
+project('native file install dir override', 'cpp')
+
+if meson.is_cross_build()
+ error('MESON_SKIP_TEST cannot test native build rules in cross build')
+endif
+
+executable('main', 'main.cpp', install : true)
diff --git a/test cases/common/205 native file path override/nativefile.ini b/test cases/common/205 native file path override/nativefile.ini
new file mode 100644
index 0000000..1c295c7
--- /dev/null
+++ b/test cases/common/205 native file path override/nativefile.ini
@@ -0,0 +1,2 @@
+[paths]
+bindir = 'custom_bindir'
diff --git a/test cases/common/205 native file path override/test.json b/test cases/common/205 native file path override/test.json
new file mode 100644
index 0000000..7954c8e
--- /dev/null
+++ b/test cases/common/205 native file path override/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/custom_bindir/main"},
+ {"type": "pdb", "file": "usr/custom_bindir/main"}
+ ]
+}
diff --git a/test cases/common/206 tap tests/cat.c b/test cases/common/206 tap tests/cat.c
new file mode 100644
index 0000000..4b92010
--- /dev/null
+++ b/test cases/common/206 tap tests/cat.c
@@ -0,0 +1,26 @@
+#include <errno.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ char buf[1024];
+ size_t len;
+ FILE *fh;
+
+ if (argc != 2) {
+ fprintf(stderr, "Incorrect number of arguments, got %i\n", argc);
+ return 1;
+ }
+ fh = fopen(argv[1], "r");
+ if (fh == NULL) {
+ fprintf(stderr, "Opening %s: errno=%i\n", argv[1], errno);
+ return 1;
+ }
+ do {
+ len = fread(buf, 1, sizeof(buf), fh);
+ if (len > 0) {
+ fwrite(buf, 1, len, stdout);
+ }
+ } while (len > 0);
+ fclose(fh);
+ return 0;
+}
diff --git a/test cases/common/206 tap tests/issue7515.txt b/test cases/common/206 tap tests/issue7515.txt
new file mode 100644
index 0000000..ca85637
--- /dev/null
+++ b/test cases/common/206 tap tests/issue7515.txt
@@ -0,0 +1,27 @@
+1..26
+ok 1 Gtk overrides UI template sets up internal and public template children
+ok 2 Gtk overrides UI template sets up public template children with the correct widgets
+ok 3 Gtk overrides UI template sets up internal template children with the correct widgets
+ok 4 Gtk overrides UI template connects template callbacks to the correct handler
+ok 5 Gtk overrides UI template binds template callbacks to the correct object
+ok 6 Gtk overrides UI template from resource sets up internal and public template children
+ok 7 Gtk overrides UI template from resource sets up public template children with the correct widgets
+ok 8 Gtk overrides UI template from resource sets up internal template children with the correct widgets
+ok 9 Gtk overrides UI template from resource connects template callbacks to the correct handler
+ok 10 Gtk overrides UI template from resource binds template callbacks to the correct object
+ok 11 Gtk overrides UI template from file sets up internal and public template children
+ok 12 Gtk overrides UI template from file sets up public template children with the correct widgets
+ok 13 Gtk overrides UI template from file sets up internal template children with the correct widgets
+ok 14 Gtk overrides UI template from file connects template callbacks to the correct handler
+ok 15 Gtk overrides UI template from file binds template callbacks to the correct object
+ok 16 Gtk overrides Class inheriting from template class sets up internal and public template children # SKIP pending
+ok 17 Gtk overrides Class inheriting from template class sets up public template children with the correct widgets # SKIP pending
+ok 18 Gtk overrides Class inheriting from template class sets up internal template children with the correct widgets # SKIP pending
+ok 19 Gtk overrides Class inheriting from template class connects template callbacks to the correct handler # SKIP pending
+ok 20 Gtk overrides Class inheriting from template class binds template callbacks to the correct object # SKIP pending
+ok 21 Gtk overrides sets CSS names on classes
+ok 22 Gtk overrides avoid crashing when GTK vfuncs are called in garbage collection
+ok 23 Gtk overrides accepts string in place of GdkAtom
+ok 24 Gtk overrides accepts null in place of GdkAtom as GDK_NONE
+ok 25 Gtk overrides uses the correct GType for null child properties
+ok 26 Gtk overrides can create a Gtk.TreeIter with accessible stamp field
diff --git a/test cases/common/206 tap tests/meson.build b/test cases/common/206 tap tests/meson.build
new file mode 100644
index 0000000..54f4e41
--- /dev/null
+++ b/test cases/common/206 tap tests/meson.build
@@ -0,0 +1,14 @@
+project('test features', 'c')
+
+tester = executable('tester', 'tester.c')
+cat = executable('cat', 'cat.c')
+test('pass', tester, args : ['ok'], protocol: 'tap')
+test('fail', tester, args : ['not ok'], should_fail: true, protocol: 'tap')
+test('xfail', tester, args : ['not ok # todo'], protocol: 'tap')
+test('xpass', tester, args : ['ok # todo'], should_fail: true, protocol: 'tap')
+test('skip', tester, args : ['ok # skip'], protocol: 'tap')
+test('partially skipped', tester, args : ['ok 1\nok 2 # skip'], suite: ['verbose'], protocol: 'tap', verbose: true)
+test('partially skipped (real-world example)', cat, args : [files('issue7515.txt')], protocol: 'tap')
+test('skip comment', tester, args : ['ok # Skipped: with a comment'], protocol: 'tap')
+test('skip failure', tester, args : ['not ok # skip'], should_fail: true, protocol: 'tap')
+test('no tests', tester, args : ['1..0 # skip'], protocol: 'tap')
diff --git a/test cases/common/206 tap tests/tester.c b/test cases/common/206 tap tests/tester.c
new file mode 100644
index 0000000..ac582e7
--- /dev/null
+++ b/test cases/common/206 tap tests/tester.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "Incorrect number of arguments, got %i\n", argc);
+ return 1;
+ }
+ puts(argv[1]);
+ return 0;
+}
diff --git a/test cases/common/207 warning level 0/main.cpp b/test cases/common/207 warning level 0/main.cpp
new file mode 100644
index 0000000..954d9ce
--- /dev/null
+++ b/test cases/common/207 warning level 0/main.cpp
@@ -0,0 +1,12 @@
+#include <iostream>
+
+#define PROJECT_NAME "demo"
+
+int main(int argc, char **argv) {
+ if(argc != 1) {
+ std::cout << argv[0] << "takes no arguments.\n";
+ return 1;
+ }
+ std::cout << "This is project " << PROJECT_NAME << ".\n";
+ return 0;
+}
diff --git a/test cases/common/207 warning level 0/meson.build b/test cases/common/207 warning level 0/meson.build
new file mode 100644
index 0000000..f2bd339
--- /dev/null
+++ b/test cases/common/207 warning level 0/meson.build
@@ -0,0 +1,3 @@
+project('warning_level', 'cpp', default_options : ['warning_level=0'])
+
+exe = executable('main', 'main.cpp', install : false)
diff --git a/test cases/common/208 link custom/custom_stlib.py b/test cases/common/208 link custom/custom_stlib.py
new file mode 100755
index 0000000..6a090f3
--- /dev/null
+++ b/test cases/common/208 link custom/custom_stlib.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+
+import shutil, sys, subprocess, argparse, pathlib
+import platform
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument('--private-dir', required=True)
+parser.add_argument('-o', required=True)
+parser.add_argument('cmparr', nargs='+')
+
+contents = '''#include<stdio.h>
+
+void flob(void) {
+ printf("Now flobbing.\\n");
+}
+'''
+
+def get_pic_args():
+ platname = platform.system().lower()
+ if platname in ['windows', 'darwin'] or sys.platform == 'cygwin':
+ return []
+ return ['-fPIC']
+
+def generate_lib_gnulike(outfile, c_file, private_dir, compiler_array):
+ if shutil.which('ar'):
+ static_linker = 'ar'
+ elif shutil.which('llvm-ar'):
+ static_linker = 'llvm-ar'
+ elif shutil.which('gcc-ar'):
+ static_linker = 'gcc-ar'
+ else:
+ sys.exit('Could not detect a static linker.')
+ o_file = c_file.with_suffix('.o')
+ compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', str(o_file), str(c_file)]
+ compile_cmd += get_pic_args()
+ subprocess.check_call(compile_cmd)
+ out_file = pathlib.Path(outfile)
+ if out_file.exists():
+ out_file.unlink()
+ link_cmd = [static_linker, 'csr', outfile, str(o_file)]
+ subprocess.check_call(link_cmd)
+ return 0
+
+
+def generate_lib_msvc(outfile, c_file, private_dir, compiler_array):
+ static_linker = 'lib'
+ o_file = c_file.with_suffix('.obj')
+ compile_cmd = compiler_array + ['/MDd',
+ '/nologo',
+ '/ZI',
+ '/Ob0',
+ '/Od',
+ '/c',
+ '/Fo' + str(o_file),
+ str(c_file)]
+ subprocess.check_call(compile_cmd)
+ out_file = pathlib.Path(outfile)
+ if out_file.exists():
+ out_file.unlink()
+ link_cmd = [static_linker,
+ '/nologo',
+ '/OUT:' + str(outfile),
+ str(o_file)]
+ subprocess.check_call(link_cmd)
+ return 0
+
+def generate_lib(outfile, private_dir, compiler_array):
+ private_dir = pathlib.Path(private_dir)
+ if not private_dir.exists():
+ private_dir.mkdir()
+ c_file = private_dir / 'flob.c'
+ c_file.write_text(contents)
+ for i in compiler_array:
+ if (i.endswith('cl') or i.endswith('cl.exe')) and 'clang-cl' not in i:
+ return generate_lib_msvc(outfile, c_file, private_dir, compiler_array)
+ return generate_lib_gnulike(outfile, c_file, private_dir, compiler_array)
+
+if __name__ == '__main__':
+ options = parser.parse_args()
+ sys.exit(generate_lib(options.o, options.private_dir, options.cmparr))
diff --git a/test cases/common/208 link custom/custom_target.c b/test cases/common/208 link custom/custom_target.c
new file mode 100644
index 0000000..1bbe82c
--- /dev/null
+++ b/test cases/common/208 link custom/custom_target.c
@@ -0,0 +1,6 @@
+void outer_lib_func(void);
+
+int main(void) {
+ outer_lib_func();
+ return 0;
+}
diff --git a/test cases/common/208 link custom/custom_target.py b/test cases/common/208 link custom/custom_target.py
new file mode 100644
index 0000000..c246344
--- /dev/null
+++ b/test cases/common/208 link custom/custom_target.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import shutil, sys
+
+if __name__ == '__main__':
+ shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/208 link custom/dummy.c b/test cases/common/208 link custom/dummy.c
new file mode 100644
index 0000000..53a4a40
--- /dev/null
+++ b/test cases/common/208 link custom/dummy.c
@@ -0,0 +1 @@
+void inner_lib_func(void) {} \ No newline at end of file
diff --git a/test cases/common/208 link custom/lib.c b/test cases/common/208 link custom/lib.c
new file mode 100644
index 0000000..585b6c9
--- /dev/null
+++ b/test cases/common/208 link custom/lib.c
@@ -0,0 +1,7 @@
+void flob(void);
+
+int foo(void)
+{
+ flob();
+ return 0;
+}
diff --git a/test cases/common/208 link custom/meson.build b/test cases/common/208 link custom/meson.build
new file mode 100644
index 0000000..4d4f655
--- /dev/null
+++ b/test cases/common/208 link custom/meson.build
@@ -0,0 +1,86 @@
+project('linkcustom', 'c')
+
+# This would require passing the static linker to the build script or having
+# it detect it by itself. I'm too lazy to implement it now and it is not
+# really needed for testing that custom targets work. It is the responsibility
+# of the custom target to produce things in the correct format.
+assert(not meson.is_cross_build(),
+ 'MESON_SKIP_TEST cross checking not implemented.')
+
+cc = meson.get_compiler('c')
+genprog = find_program('custom_stlib.py')
+
+clib = custom_target('linkcustom',
+ output: 'libflob.a',
+ command: [genprog,
+ '-o', '@OUTPUT@',
+ '--private-dir', '@PRIVATE_DIR@'] + cc.cmd_array())
+
+# custom_target tests
+
+exe = executable('prog', 'prog.c', link_with: clib)
+test('linkcustom', exe)
+
+d = declare_dependency(link_with: clib)
+
+exe2 = executable('prog2', 'prog.c', dependencies: d)
+test('linkcustom2', exe2)
+
+# Link whole tests
+
+if meson.backend() == 'xcode'
+ message('Xcode does not support link whole so skipping.')
+else
+ exe3 = executable('prog3', 'prog.c', link_whole: clib)
+ test('linkwhole', exe)
+
+ d2 = declare_dependency(link_whole: clib)
+
+ exe4 = executable('prog4', 'prog.c', dependencies: d2)
+ test('linkwhole2', exe2)
+endif
+
+# custom_target[i] tests
+
+exe_i = executable('prog_i', 'prog.c', link_with: clib[0])
+test('linkcustom', exe_i)
+
+d_i = declare_dependency(link_with: clib[0])
+
+exe2_i = executable('prog2_i', 'prog.c', dependencies: d_i)
+test('linkcustom2_i', exe2_i)
+
+# Link whole tests
+
+if meson.backend() == 'xcode'
+ message('Xcode does not support link whole so skipping.')
+else
+ shared_library('lib1', 'lib.c', link_whole: clib)
+
+ exe3_i = executable('prog3_i', 'prog.c', link_whole: clib[0])
+ test('linkwhole', exe)
+
+ d2_i = declare_dependency(link_whole: clib[0])
+
+ exe4_i = executable('prog4_i', 'prog.c', dependencies: d2_i)
+ test('linkwhole2_i', exe2_i)
+endif
+
+# Link with custom target
+
+dummy = static_library('dummy', 'dummy.c')
+
+custom_prog = find_program('custom_target.py')
+t = custom_target('custom', input: dummy, output: 'libcustom.a', command: [custom_prog, '@INPUT@', '@OUTPUT@'])
+
+dep1 = declare_dependency(link_with: t)
+dep2 = declare_dependency(link_with: t[0])
+
+lib1 = static_library('lib1', 'outerlib.c', dependencies: dep1)
+lib2 = static_library('lib2', 'outerlib.c', dependencies: dep2)
+
+exe1 = executable('exe1', 'custom_target.c', link_with: lib1)
+test('custom_target_1', exe1)
+
+exe1_2 = executable('exe1_2', 'custom_target.c', link_with: lib2)
+test('custom_target_2', exe2) \ No newline at end of file
diff --git a/test cases/common/208 link custom/outerlib.c b/test cases/common/208 link custom/outerlib.c
new file mode 100644
index 0000000..6861f8d
--- /dev/null
+++ b/test cases/common/208 link custom/outerlib.c
@@ -0,0 +1,3 @@
+void inner_lib_func(void);
+
+void outer_lib_func(void) { inner_lib_func(); } \ No newline at end of file
diff --git a/test cases/common/208 link custom/prog.c b/test cases/common/208 link custom/prog.c
new file mode 100644
index 0000000..efecbef
--- /dev/null
+++ b/test cases/common/208 link custom/prog.c
@@ -0,0 +1,6 @@
+void flob(void);
+
+int main(void) {
+ flob();
+ return 0;
+}
diff --git a/test cases/common/209 link custom_i single from multiple/generate_conflicting_stlibs.py b/test cases/common/209 link custom_i single from multiple/generate_conflicting_stlibs.py
new file mode 100644
index 0000000..42d6631
--- /dev/null
+++ b/test cases/common/209 link custom_i single from multiple/generate_conflicting_stlibs.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+
+import shutil, sys, subprocess, argparse, pathlib
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument('--private-dir', required=True)
+parser.add_argument('-o', nargs='+', required=True)
+parser.add_argument('cmparr', nargs='+')
+
+contents = ['''
+int flob() {
+ return 0;
+}
+''', '''
+int flob() {
+ return 1;
+}
+''']
+
+def generate_lib_gnulike(outfile, c_file, private_dir, compiler_array):
+ if shutil.which('ar'):
+ static_linker = 'ar'
+ elif shutil.which('llvm-ar'):
+ static_linker = 'llvm-ar'
+ elif shutil.which('gcc-ar'):
+ static_linker = 'gcc-ar'
+ else:
+ sys.exit('Could not detect a static linker.')
+ o_file = c_file.with_suffix('.o')
+ compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', str(o_file), str(c_file)]
+ subprocess.check_call(compile_cmd)
+ out_file = pathlib.Path(outfile)
+ if out_file.exists():
+ out_file.unlink()
+ link_cmd = [static_linker, 'csr', outfile, str(o_file)]
+ subprocess.check_call(link_cmd)
+ return 0
+
+
+def generate_lib_msvc(outfile, c_file, private_dir, compiler_array):
+ static_linker = 'lib'
+ o_file = c_file.with_suffix('.obj')
+ compile_cmd = compiler_array + ['/MDd',
+ '/nologo',
+ '/ZI',
+ '/Ob0',
+ '/Od',
+ '/c',
+ '/Fo' + str(o_file),
+ str(c_file)]
+ subprocess.check_call(compile_cmd)
+ out_file = pathlib.Path(outfile)
+ if out_file.exists():
+ out_file.unlink()
+ link_cmd = [static_linker,
+ '/nologo',
+ '/OUT:' + str(outfile),
+ str(o_file)]
+ subprocess.check_call(link_cmd)
+ return 0
+
+def generate_lib(outfiles, private_dir, compiler_array):
+ private_dir = pathlib.Path(private_dir)
+ if not private_dir.exists():
+ private_dir.mkdir()
+
+ for i, content in enumerate(contents):
+ c_file = private_dir / ('flob_' + str(i + 1) + '.c')
+ c_file.write_text(content)
+ outfile = outfiles[i]
+
+ cl_found = False
+ for cl_arg in compiler_array:
+ if (cl_arg.endswith('cl') or cl_arg.endswith('cl.exe')) and 'clang-cl' not in cl_arg:
+ ret = generate_lib_msvc(outfile, c_file, private_dir, compiler_array)
+ if ret > 0:
+ return ret
+ else:
+ cl_found = True
+ break
+ if not cl_found:
+ ret = generate_lib_gnulike(outfile, c_file, private_dir, compiler_array)
+ if ret > 0:
+ return ret
+ return 0
+
+if __name__ == '__main__':
+ options = parser.parse_args()
+ sys.exit(generate_lib(options.o, options.private_dir, options.cmparr))
diff --git a/test cases/common/209 link custom_i single from multiple/meson.build b/test cases/common/209 link custom_i single from multiple/meson.build
new file mode 100644
index 0000000..7aadb17
--- /dev/null
+++ b/test cases/common/209 link custom_i single from multiple/meson.build
@@ -0,0 +1,42 @@
+project('linkcustom', 'c')
+
+# This would require passing the static linker to the build script or having
+# it detect it by itself. I'm too lazy to implement it now and it is not
+# really needed for testing that custom targets work. It is the responsibility
+# of the custom target to produce things in the correct format.
+assert(not meson.is_cross_build(),
+ 'MESON_SKIP_TEST cross checking not implemented.')
+
+cc = meson.get_compiler('c')
+genprog = find_program('generate_conflicting_stlibs.py')
+
+clib = custom_target('linkcustom',
+ output: ['libflob_1.a', 'libflob_2.a'],
+ command: [genprog,
+ '-o', '@OUTPUT@',
+ '--private-dir', '@PRIVATE_DIR@'] + cc.cmd_array())
+
+clib_2 = clib[1]
+
+exe = executable('prog', 'prog.c', link_with: clib_2)
+test('linkcustom', exe)
+
+d = declare_dependency(link_with: clib_2)
+
+exe2 = executable('prog2', 'prog.c', dependencies: d)
+test('linkcustom2', exe2)
+
+# Link whole tests
+
+if meson.backend() == 'xcode'
+ message('Xcode does not support link whole so skipping.')
+ subdir_done()
+endif
+
+exe3 = executable('prog3', 'prog.c', link_whole: clib_2)
+test('linkwhole', exe)
+
+d2 = declare_dependency(link_whole: clib_2)
+
+exe4 = executable('prog4', 'prog.c', dependencies: d2)
+test('linkwhole2', exe2)
diff --git a/test cases/common/209 link custom_i single from multiple/prog.c b/test cases/common/209 link custom_i single from multiple/prog.c
new file mode 100644
index 0000000..040672a
--- /dev/null
+++ b/test cases/common/209 link custom_i single from multiple/prog.c
@@ -0,0 +1,5 @@
+int flob(void);
+
+int main(void) {
+ return (flob() == 1 ? 0 : 1);
+}
diff --git a/test cases/common/21 target arg/func.c b/test cases/common/21 target arg/func.c
new file mode 100644
index 0000000..8c0659e
--- /dev/null
+++ b/test cases/common/21 target arg/func.c
@@ -0,0 +1,9 @@
+#ifndef CTHING
+#error "Local argument not set"
+#endif
+
+#ifdef CPPTHING
+#error "Wrong local argument set"
+#endif
+
+int func(void) { return 0; }
diff --git a/test cases/common/21 target arg/func2.c b/test cases/common/21 target arg/func2.c
new file mode 100644
index 0000000..1897cf7
--- /dev/null
+++ b/test cases/common/21 target arg/func2.c
@@ -0,0 +1,9 @@
+#ifdef CTHING
+#error "Local C argument set in wrong target"
+#endif
+
+#ifdef CPPTHING
+#error "Local CPP argument set in wrong target"
+#endif
+
+int func(void) { return 0; }
diff --git a/test cases/common/21 target arg/meson.build b/test cases/common/21 target arg/meson.build
new file mode 100644
index 0000000..11ac006
--- /dev/null
+++ b/test cases/common/21 target arg/meson.build
@@ -0,0 +1,9 @@
+project('local arg test', 'cpp', 'c')
+
+exe1 = executable('prog', 'prog.cc', 'func.c', \
+c_args : '-DCTHING', \
+cpp_args : '-DCPPTHING')
+exe2 = executable('prog2', 'prog2.cc', 'func2.c')
+
+test('prog1', exe1)
+test('prog2', exe2)
diff --git a/test cases/common/21 target arg/prog.cc b/test cases/common/21 target arg/prog.cc
new file mode 100644
index 0000000..23028af
--- /dev/null
+++ b/test cases/common/21 target arg/prog.cc
@@ -0,0 +1,13 @@
+#ifdef CTHING
+#error "Wrong local argument set"
+#endif
+
+#ifndef CPPTHING
+#error "Local argument not set"
+#endif
+
+extern "C" int func();
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/21 target arg/prog2.cc b/test cases/common/21 target arg/prog2.cc
new file mode 100644
index 0000000..e2ffe62
--- /dev/null
+++ b/test cases/common/21 target arg/prog2.cc
@@ -0,0 +1,13 @@
+#ifdef CTHING
+#error "Local C argument set in wrong target"
+#endif
+
+#ifdef CPPTHING
+#error "Local CPP argument set in wrong target"
+#endif
+
+extern "C" int func();
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/210 link custom_i multiple from multiple/generate_stlibs.py b/test cases/common/210 link custom_i multiple from multiple/generate_stlibs.py
new file mode 100644
index 0000000..5292006
--- /dev/null
+++ b/test cases/common/210 link custom_i multiple from multiple/generate_stlibs.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python3
+
+import shutil, sys, subprocess, argparse, pathlib
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument('--private-dir', required=True)
+parser.add_argument('-o', nargs='+', required=True)
+parser.add_argument('cmparr', nargs='+')
+
+contents = ['''#include<stdio.h>
+
+void flob_1() {
+ printf("Now flobbing #1.\\n");
+}
+''', '''#include<stdio.h>
+
+void flob_2() {
+ printf("Now flobbing #2.\\n");
+}
+''']
+
+def generate_lib_gnulike(outfile, c_file, private_dir, compiler_array):
+ if shutil.which('ar'):
+ static_linker = 'ar'
+ elif shutil.which('llvm-ar'):
+ static_linker = 'llvm-ar'
+ elif shutil.which('gcc-ar'):
+ static_linker = 'gcc-ar'
+ else:
+ sys.exit('Could not detect a static linker.')
+ o_file = c_file.with_suffix('.o')
+ compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', str(o_file), str(c_file)]
+ subprocess.check_call(compile_cmd)
+ out_file = pathlib.Path(outfile)
+ if out_file.exists():
+ out_file.unlink()
+ link_cmd = [static_linker, 'csr', outfile, str(o_file)]
+ subprocess.check_call(link_cmd)
+ return 0
+
+
+def generate_lib_msvc(outfile, c_file, private_dir, compiler_array):
+ static_linker = 'lib'
+ o_file = c_file.with_suffix('.obj')
+ compile_cmd = compiler_array + ['/MDd',
+ '/nologo',
+ '/ZI',
+ '/Ob0',
+ '/Od',
+ '/c',
+ '/Fo' + str(o_file),
+ str(c_file)]
+ subprocess.check_call(compile_cmd)
+ out_file = pathlib.Path(outfile)
+ if out_file.exists():
+ out_file.unlink()
+ link_cmd = [static_linker,
+ '/nologo',
+ '/OUT:' + str(outfile),
+ str(o_file)]
+ subprocess.check_call(link_cmd)
+ return 0
+
+def generate_lib(outfiles, private_dir, compiler_array):
+ private_dir = pathlib.Path(private_dir)
+ if not private_dir.exists():
+ private_dir.mkdir()
+
+ for i, content in enumerate(contents):
+ c_file = private_dir / ('flob_' + str(i + 1) + '.c')
+ c_file.write_text(content)
+ outfile = outfiles[i]
+
+ cl_found = False
+ for cl_arg in compiler_array:
+ if (cl_arg.endswith('cl') or cl_arg.endswith('cl.exe')) and 'clang-cl' not in cl_arg:
+ ret = generate_lib_msvc(outfile, c_file, private_dir, compiler_array)
+ if ret > 0:
+ return ret
+ else:
+ cl_found = True
+ break
+ if not cl_found:
+ ret = generate_lib_gnulike(outfile, c_file, private_dir, compiler_array)
+ if ret > 0:
+ return ret
+ return 0
+
+if __name__ == '__main__':
+ options = parser.parse_args()
+ sys.exit(generate_lib(options.o, options.private_dir, options.cmparr))
diff --git a/test cases/common/210 link custom_i multiple from multiple/meson.build b/test cases/common/210 link custom_i multiple from multiple/meson.build
new file mode 100644
index 0000000..ede059e
--- /dev/null
+++ b/test cases/common/210 link custom_i multiple from multiple/meson.build
@@ -0,0 +1,42 @@
+project('linkcustom', 'c')
+
+# This would require passing the static linker to the build script or having
+# it detect it by itself. I'm too lazy to implement it now and it is not
+# really needed for testing that custom targets work. It is the responsibility
+# of the custom target to produce things in the correct format.
+assert(not meson.is_cross_build(),
+ 'MESON_SKIP_TEST cross checking not implemented.')
+
+cc = meson.get_compiler('c')
+genprog = find_program('generate_stlibs.py')
+
+clib = custom_target('linkcustom',
+ output: ['libflob_1.a', 'libflob_2.a'],
+ command: [genprog,
+ '-o', '@OUTPUT@',
+ '--private-dir', '@PRIVATE_DIR@'] + cc.cmd_array())
+
+clibs = [clib[0], clib[1]]
+
+exe = executable('prog', 'prog.c', link_with: clibs)
+test('linkcustom', exe)
+
+d = declare_dependency(link_with: clibs)
+
+exe2 = executable('prog2', 'prog.c', dependencies: d)
+test('linkcustom2', exe2)
+
+# Link whole tests
+
+if meson.backend() == 'xcode'
+ message('Xcode does not support link whole so skipping.')
+ subdir_done()
+endif
+
+exe3 = executable('prog3', 'prog.c', link_whole: clibs)
+test('linkwhole', exe)
+
+d2 = declare_dependency(link_whole: clibs)
+
+exe4 = executable('prog4', 'prog.c', dependencies: d2)
+test('linkwhole2', exe2)
diff --git a/test cases/common/210 link custom_i multiple from multiple/prog.c b/test cases/common/210 link custom_i multiple from multiple/prog.c
new file mode 100644
index 0000000..7b0c5cf
--- /dev/null
+++ b/test cases/common/210 link custom_i multiple from multiple/prog.c
@@ -0,0 +1,8 @@
+void flob_1(void);
+void flob_2(void);
+
+int main(void) {
+ flob_1();
+ flob_2();
+ return 0;
+}
diff --git a/test cases/common/211 dependency get_variable method/meson.build b/test cases/common/211 dependency get_variable method/meson.build
new file mode 100644
index 0000000..b7e7035
--- /dev/null
+++ b/test cases/common/211 dependency get_variable method/meson.build
@@ -0,0 +1,67 @@
+project(
+ 'dependency get_variable',
+ ['c', 'cpp'],
+)
+
+# Just some string that nothing should return
+default = 'asufoiqwjtl;adjfbpiuqwoehtl;ajdfl;ghal;sdjg'
+
+dep = dependency('zlib', method: 'pkg-config', required : false)
+if not dep.found()
+ warning('Skipping pkg-config tests as zlib is not available or is not pkg-config')
+else
+ # Test for regular pkg-config
+ # We don't know what the value will be, but we know it should be the same
+ dep = dependency('zlib', method : 'pkg-config')
+ assert(dep.get_pkgconfig_variable('prefix') == dep.get_variable(pkgconfig : 'prefix'),
+ 'Got different values from get_pkgconfig_variable and get_variable(pkgconfig: )')
+ assert(dep.get_variable(pkgconfig : default, default_value : default) == default,
+ 'pkg-config didn\'t get default when we should have.')
+ assert(dep.get_variable(pkgconfig : 'prefix', default_value : default) != default,
+ 'pkg-config got default when we shouldn\'t have.')
+ assert(dep.get_variable(pkgconfig : 'pkgvarnotfound', default_value : '') == '')
+endif
+
+dep_ct = dependency('llvm', method : 'config-tool', required : false)
+if not dep_ct.found()
+ warning('Skipping config-tool tests as llvm is not available or llvm-config was not found.')
+else
+ assert(dep_ct.get_configtool_variable('has-rtti') == dep_ct.get_variable(configtool : 'has-rtti'),
+ 'Got different values from get_configtool_variable and get_variable(configtool: )')
+ assert(dep_ct.get_variable(configtool : default, default_value : default) == default,
+ 'config-tool didn\'t get default when we should have.')
+ assert(dep_ct.get_variable(configtool : 'has-rtti', default_value : default) != default,
+ 'config-tool got default when we shouldn\'t have.')
+endif
+
+dep_cm = dependency('llvm', method : 'cmake', required : false)
+if not dep_cm.found()
+ warning('Skipping cmake tests as llvm is not available via the cmake finder.')
+else
+ if dep_ct.found()
+ assert((dep_cm.get_variable(cmake : 'LLVM_ENABLE_RTTI') == 'ON') == (dep_ct.get_variable(configtool : 'has-rtti') == 'YES'),
+ 'RTTI information for cmake and config tools disagree')
+ endif
+ assert(dep_cm.get_variable(cmake : default, default_value : default) == default,
+ 'cmake didn\'t get default when we should have.')
+ assert(dep_cm.get_variable(cmake : 'LLVM_ENABLE_RTTI', default_value : default) != default,
+ 'cmake config-tool got default when we shouldn\'t have.')
+endif
+
+idep = declare_dependency(variables : {'foo' : 'value'})
+assert(idep.get_variable(pkgconfig : 'foo', cmake : 'foo', configtool : 'foo',
+ internal : 'foo', default_value : default) == 'value',
+ 'internal got default when it shouldn\'t have.')
+assert(idep.get_variable(pkgconfig : 'foo', cmake : 'foo', configtool : 'foo',
+ internal : 'bar', default_value : default) == default,
+ 'internal didn\'t default when it should have.')
+
+idep = declare_dependency()
+assert(idep.get_variable(pkgconfig : 'foo', cmake : 'foo', configtool : 'foo',
+ default_value : default) == default,
+ 'something went wrong with an InternalDependency with no variables.')
+
+idep = declare_dependency(variables : ['foo=value'])
+assert(idep.get_variable(internal: 'foo') == 'value')
+assert(idep.get_variable('foo') == 'value')
+assert(idep.get_variable('invalid', internal: 'foo') == 'value')
diff --git a/test cases/common/211 dependency get_variable method/test.json b/test cases/common/211 dependency get_variable method/test.json
new file mode 100644
index 0000000..5281618
--- /dev/null
+++ b/test cases/common/211 dependency get_variable method/test.json
@@ -0,0 +1,9 @@
+{
+ "stdout": [
+ {
+ "line": ".*pkgvarnotfound.*",
+ "match": "re",
+ "count": 0
+ }
+ ]
+ }
diff --git a/test cases/common/212 source set configuration_data/a.c b/test cases/common/212 source set configuration_data/a.c
new file mode 100644
index 0000000..0570dff
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/a.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include "all.h"
+
+int main(void)
+{
+ if (p) abort();
+ f();
+}
diff --git a/test cases/common/212 source set configuration_data/all.h b/test cases/common/212 source set configuration_data/all.h
new file mode 100644
index 0000000..e3547df
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/all.h
@@ -0,0 +1,9 @@
+extern void f(void);
+extern void g(void);
+extern void h(void);
+extern void undefined(void);
+
+/* Defined in nope.c and f.c,
+ * value depends on the source set and configuration used.
+ */
+extern void (*p)(void);
diff --git a/test cases/common/212 source set configuration_data/f.c b/test cases/common/212 source set configuration_data/f.c
new file mode 100644
index 0000000..33d2f18
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/f.c
@@ -0,0 +1,7 @@
+#include "all.h"
+
+void (*p)(void) = (void *)0x12AB34CD;
+
+void f(void)
+{
+}
diff --git a/test cases/common/212 source set configuration_data/g.c b/test cases/common/212 source set configuration_data/g.c
new file mode 100644
index 0000000..4a6f253
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/g.c
@@ -0,0 +1,6 @@
+#include "all.h"
+
+void g(void)
+{
+ h();
+}
diff --git a/test cases/common/212 source set configuration_data/meson.build b/test cases/common/212 source set configuration_data/meson.build
new file mode 100644
index 0000000..9aacbc4
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/meson.build
@@ -0,0 +1,54 @@
+project('a', 'c')
+
+good = declare_dependency(link_with: static_library('good', 'g.c'))
+bad = declare_dependency(link_args: 'nonexistent.a')
+not_found = dependency('invalid', required: false)
+
+source_set = import('sourceset')
+
+sources = source_set.source_set()
+sources.add(when: 'YES', if_false: ['nope.c'])
+sources.add(when: 'YES1', if_true: [files('a.c'), not_found])
+subdir('subdir')
+sources.add(when: 'NO', if_true: 'nope.c', if_false: ['f.c'])
+sources.add(when: 'NO', if_true: bad, if_false: ['f.c'])
+
+sources.add(when: 'YES2', if_true: good)
+
+# dependencies as conditions
+sources.add(when: not_found, if_true: 'nope.c')
+
+# test add_all
+sources2 = source_set.source_set()
+sources2.add(when: 'YES1', if_true: 'nope.c')
+sources.add_all(when: 'NO', if_true: sources2)
+
+# test duplicate items
+sources.add(when: 'YES1', if_true: [files('a.c'), not_found])
+
+conf1 = configuration_data()
+conf1.set10('YES', true)
+conf1.set10('YES1', true)
+conf1.set10('YES2', false)
+conf1.set10('NO', false)
+result1 = sources.apply(conf1)
+
+conf2 = configuration_data()
+conf2.set10('YES', true)
+conf2.set10('YES1', false)
+conf2.set10('YES2', true)
+conf2.set10('NO', false)
+result2 = sources.apply(conf2)
+
+# Each target will recompile the objects
+executable('first', sources: result1.sources(), dependencies: result1.dependencies())
+executable('second', sources: result2.sources(), dependencies: result2.dependencies())
+
+# All target will use the same object files
+if meson.is_unity()
+ message('Skipping extraction test because this is a Unity build.')
+else
+ all_objs = static_library('all_objs', sources.all_sources())
+ executable('first_via_lib', objects: all_objs.extract_objects(result1.sources()), dependencies: result1.dependencies())
+ executable('second_via_lib', objects: all_objs.extract_objects(result2.sources()), dependencies: result2.dependencies())
+endif
diff --git a/test cases/common/212 source set configuration_data/nope.c b/test cases/common/212 source set configuration_data/nope.c
new file mode 100644
index 0000000..0ce1d3b
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/nope.c
@@ -0,0 +1,3 @@
+#include "all.h"
+
+void (*p)(void) = undefined;
diff --git a/test cases/common/212 source set configuration_data/subdir/b.c b/test cases/common/212 source set configuration_data/subdir/b.c
new file mode 100644
index 0000000..31c3789
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/subdir/b.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include "all.h"
+
+void h(void)
+{
+}
+
+int main(void)
+{
+ if (p) abort();
+ f();
+ g();
+}
diff --git a/test cases/common/212 source set configuration_data/subdir/meson.build b/test cases/common/212 source set configuration_data/subdir/meson.build
new file mode 100644
index 0000000..b497de5
--- /dev/null
+++ b/test cases/common/212 source set configuration_data/subdir/meson.build
@@ -0,0 +1 @@
+sources.add(when: ['YES2', good], if_true: [ files('b.c') ])
diff --git a/test cases/common/213 source set dictionary/a.c b/test cases/common/213 source set dictionary/a.c
new file mode 100644
index 0000000..0570dff
--- /dev/null
+++ b/test cases/common/213 source set dictionary/a.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include "all.h"
+
+int main(void)
+{
+ if (p) abort();
+ f();
+}
diff --git a/test cases/common/213 source set dictionary/all.h b/test cases/common/213 source set dictionary/all.h
new file mode 100644
index 0000000..e3547df
--- /dev/null
+++ b/test cases/common/213 source set dictionary/all.h
@@ -0,0 +1,9 @@
+extern void f(void);
+extern void g(void);
+extern void h(void);
+extern void undefined(void);
+
+/* Defined in nope.c and f.c,
+ * value depends on the source set and configuration used.
+ */
+extern void (*p)(void);
diff --git a/test cases/common/213 source set dictionary/f.c b/test cases/common/213 source set dictionary/f.c
new file mode 100644
index 0000000..9c5bb1c
--- /dev/null
+++ b/test cases/common/213 source set dictionary/f.c
@@ -0,0 +1,7 @@
+#include "all.h"
+
+void (*p)(void) = (void *)0x1234ABCD;
+
+void f(void)
+{
+}
diff --git a/test cases/common/213 source set dictionary/g.c b/test cases/common/213 source set dictionary/g.c
new file mode 100644
index 0000000..4a6f253
--- /dev/null
+++ b/test cases/common/213 source set dictionary/g.c
@@ -0,0 +1,6 @@
+#include "all.h"
+
+void g(void)
+{
+ h();
+}
diff --git a/test cases/common/213 source set dictionary/meson.build b/test cases/common/213 source set dictionary/meson.build
new file mode 100644
index 0000000..9a34507
--- /dev/null
+++ b/test cases/common/213 source set dictionary/meson.build
@@ -0,0 +1,56 @@
+project('a', 'c')
+
+good = declare_dependency(link_with: static_library('good', 'g.c'))
+bad = declare_dependency(link_args: 'nonexistent.a')
+not_found = dependency('invalid', required: false)
+
+source_set = import('sourceset')
+
+sources = source_set.source_set()
+sources.add(when: 'YES', if_false: ['nope.c'])
+sources.add(when: 'YES1', if_true: files('a.c'))
+subdir('subdir')
+sources.add(when: 'NO', if_true: 'nope.c', if_false: ['f.c'])
+sources.add(when: 'NO', if_true: bad, if_false: ['f.c'])
+
+sources.add(when: 'YES2', if_true: good)
+
+# dependencies as conditions
+sources.add(when: not_found, if_true: 'nope.c')
+
+# test add_all
+sources2 = source_set.source_set()
+sources2.add(when: 'YES1', if_true: 'nope.c')
+sources.add_all(when: 'NO', if_true: sources2)
+
+# test duplicate items
+sources.add(when: 'YES1', if_true: files('a.c'))
+
+conf1 = {
+ 'YES': true,
+ 'YES1': true,
+ 'YES2': false,
+ 'NO': false,
+}
+result1 = sources.apply(conf1)
+
+conf2 = {
+ 'YES': true,
+ 'YES1': false,
+ 'YES2': true,
+ 'NO': false,
+}
+result2 = sources.apply(conf2)
+
+# Each target will recompile the objects
+executable('first', sources: result1.sources(), dependencies: result1.dependencies())
+executable('second', sources: result2.sources(), dependencies: result2.dependencies())
+
+# All target will use the same object files
+if meson.is_unity()
+ message('Skipping extraction test because this is a Unity build.')
+else
+ all_objs = static_library('all_objs', sources.all_sources())
+ executable('first_via_lib', objects: all_objs.extract_objects(result1.sources()), dependencies: result1.dependencies())
+ executable('second_via_lib', objects: all_objs.extract_objects(result2.sources()), dependencies: result2.dependencies())
+endif
diff --git a/test cases/common/213 source set dictionary/nope.c b/test cases/common/213 source set dictionary/nope.c
new file mode 100644
index 0000000..0ce1d3b
--- /dev/null
+++ b/test cases/common/213 source set dictionary/nope.c
@@ -0,0 +1,3 @@
+#include "all.h"
+
+void (*p)(void) = undefined;
diff --git a/test cases/common/213 source set dictionary/subdir/b.c b/test cases/common/213 source set dictionary/subdir/b.c
new file mode 100644
index 0000000..31c3789
--- /dev/null
+++ b/test cases/common/213 source set dictionary/subdir/b.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include "all.h"
+
+void h(void)
+{
+}
+
+int main(void)
+{
+ if (p) abort();
+ f();
+ g();
+}
diff --git a/test cases/common/213 source set dictionary/subdir/meson.build b/test cases/common/213 source set dictionary/subdir/meson.build
new file mode 100644
index 0000000..b497de5
--- /dev/null
+++ b/test cases/common/213 source set dictionary/subdir/meson.build
@@ -0,0 +1 @@
+sources.add(when: ['YES2', good], if_true: [ files('b.c') ])
diff --git a/test cases/common/214 source set custom target/a.c b/test cases/common/214 source set custom target/a.c
new file mode 100644
index 0000000..39a3b6b
--- /dev/null
+++ b/test cases/common/214 source set custom target/a.c
@@ -0,0 +1,7 @@
+#include "all.h"
+
+int main(void)
+{
+ f();
+ g();
+}
diff --git a/test cases/common/214 source set custom target/all.h b/test cases/common/214 source set custom target/all.h
new file mode 100644
index 0000000..5885e32
--- /dev/null
+++ b/test cases/common/214 source set custom target/all.h
@@ -0,0 +1,2 @@
+extern void f(void);
+extern void g(void);
diff --git a/test cases/common/214 source set custom target/cp.py b/test cases/common/214 source set custom target/cp.py
new file mode 100644
index 0000000..cb09cf3
--- /dev/null
+++ b/test cases/common/214 source set custom target/cp.py
@@ -0,0 +1,5 @@
+#! /usr/bin/env python3
+
+import sys
+from shutil import copyfile
+copyfile(*sys.argv[1:])
diff --git a/test cases/common/214 source set custom target/f.c b/test cases/common/214 source set custom target/f.c
new file mode 100644
index 0000000..a50ecda
--- /dev/null
+++ b/test cases/common/214 source set custom target/f.c
@@ -0,0 +1,5 @@
+#include "all.h"
+
+void f(void)
+{
+}
diff --git a/test cases/common/214 source set custom target/g.c b/test cases/common/214 source set custom target/g.c
new file mode 100644
index 0000000..7098584
--- /dev/null
+++ b/test cases/common/214 source set custom target/g.c
@@ -0,0 +1,5 @@
+#include "all.h"
+
+void g(void)
+{
+}
diff --git a/test cases/common/214 source set custom target/meson.build b/test cases/common/214 source set custom target/meson.build
new file mode 100644
index 0000000..fe6e6e1
--- /dev/null
+++ b/test cases/common/214 source set custom target/meson.build
@@ -0,0 +1,28 @@
+# Try using sourceset with various kinds of generated sources
+
+project('a', 'c')
+
+cp = find_program('cp.py')
+
+source_set = import('sourceset')
+sources = source_set.source_set()
+
+a_c = custom_target('gen-custom-target',
+ input: 'a.c', output: 'out_a.c',
+ command: [cp, '@INPUT@', '@OUTPUT@'])
+sources.add(when: 'YES', if_true: a_c)
+sources.add(when: 'YES', if_true: a_c[0])
+
+f_c = configure_file(input: 'f.c', output: 'out_f.c', copy: true)
+sources.add(when: 'YES', if_true: f_c)
+sources.add(when: 'YES', if_true: f_c)
+
+gen = generator(cp, output: 'out_@PLAINNAME@', arguments: ['@INPUT@', '@OUTPUT@'])
+g_c = gen.process(files('g.c'))
+sources.add(when: 'YES', if_true: g_c)
+sources.add(when: 'YES', if_true: g_c)
+
+conf1 = { 'YES': true, }
+result1 = sources.apply(conf1)
+
+executable('first', sources: result1.sources(), dependencies: result1.dependencies())
diff --git a/test cases/common/215 source set realistic example/boards/arm/aarch64.cc b/test cases/common/215 source set realistic example/boards/arm/aarch64.cc
new file mode 100644
index 0000000..386c771
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/arm/aarch64.cc
@@ -0,0 +1,8 @@
+#include "common.h"
+#include <iostream>
+
+void initialize_target()
+{
+ std::cout << ANSI_START << "some " << THE_TARGET
+ << " initialization" << ANSI_END << std::endl;
+}
diff --git a/test cases/common/215 source set realistic example/boards/arm/arm.cc b/test cases/common/215 source set realistic example/boards/arm/arm.cc
new file mode 100644
index 0000000..b463ebe
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/arm/arm.cc
@@ -0,0 +1,10 @@
+#include "arm.h"
+
+const char *ARMBoard::target()
+{
+ return THE_TARGET;
+}
+
+void ARMBoard::some_arm_thing()
+{
+}
diff --git a/test cases/common/215 source set realistic example/boards/arm/arm.h b/test cases/common/215 source set realistic example/boards/arm/arm.h
new file mode 100644
index 0000000..4dd6b69
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/arm/arm.h
@@ -0,0 +1,12 @@
+#ifndef ARM_H
+#define ARM_H 1
+
+#include "common.h"
+
+struct ARMBoard: Board {
+ const char *target();
+ void some_arm_thing();
+};
+
+
+#endif
diff --git a/test cases/common/215 source set realistic example/boards/arm/arm32.cc b/test cases/common/215 source set realistic example/boards/arm/arm32.cc
new file mode 100644
index 0000000..72a2427
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/arm/arm32.cc
@@ -0,0 +1,8 @@
+#include "common.h"
+#include <iostream>
+
+void initialize_target()
+{
+ std::cout << ANSI_START << "a different " << THE_TARGET
+ << " initialization" << ANSI_END << std::endl;
+}
diff --git a/test cases/common/215 source set realistic example/boards/arm/versatilepb.cc b/test cases/common/215 source set realistic example/boards/arm/versatilepb.cc
new file mode 100644
index 0000000..3d1a9fe
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/arm/versatilepb.cc
@@ -0,0 +1,16 @@
+#include <iostream>
+#include "common.h"
+#include "arm.h"
+
+struct VersatilePBBoard: ARMBoard {
+ void say_hello();
+};
+
+void VersatilePBBoard::say_hello()
+{
+ some_arm_thing();
+ std::cout << ANSI_START << "I am the versatilepb board"
+ << ANSI_END << std::endl;
+}
+
+static VersatilePBBoard versatilepb;
diff --git a/test cases/common/215 source set realistic example/boards/arm/virt.cc b/test cases/common/215 source set realistic example/boards/arm/virt.cc
new file mode 100644
index 0000000..6f9a1ca
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/arm/virt.cc
@@ -0,0 +1,16 @@
+#include <iostream>
+#include "common.h"
+#include "arm.h"
+
+struct VirtBoard: ARMBoard {
+ void say_hello();
+};
+
+void VirtBoard::say_hello()
+{
+ some_arm_thing();
+ std::cout << ANSI_START << "I am the virt board"
+ << ANSI_END << std::endl;
+}
+
+static VirtBoard virt;
diff --git a/test cases/common/215 source set realistic example/boards/arm/xlnx_zcu102.cc b/test cases/common/215 source set realistic example/boards/arm/xlnx_zcu102.cc
new file mode 100644
index 0000000..8921e00
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/arm/xlnx_zcu102.cc
@@ -0,0 +1,16 @@
+#include <iostream>
+#include "common.h"
+#include "arm.h"
+
+struct XlnxZCU102Board: ARMBoard {
+ void say_hello();
+};
+
+void XlnxZCU102Board::say_hello()
+{
+ some_arm_thing();
+ std::cout << ANSI_START << "I am the xlnx_zcu102 board"
+ << ANSI_END << std::endl;
+}
+
+static XlnxZCU102Board xlnx_zcu102;
diff --git a/test cases/common/215 source set realistic example/boards/meson.build b/test cases/common/215 source set realistic example/boards/meson.build
new file mode 100644
index 0000000..41ead4c
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/meson.build
@@ -0,0 +1,7 @@
+specific.add(when: 'TARGET_ARM', if_true: files('arm/arm.cc', 'arm/arm32.cc'))
+specific.add(when: 'TARGET_AARCH64', if_true: files('arm/arm.cc', 'arm/aarch64.cc'))
+specific.add(when: 'CONFIG_VIRT', if_true: files('arm/virt.cc'))
+specific.add(when: 'CONFIG_XLNX_ZCU102', if_true: files('arm/xlnx_zcu102.cc'))
+specific.add(when: 'CONFIG_VERSATILEPB', if_true: files('arm/versatilepb.cc'))
+
+specific.add(when: 'TARGET_X86', if_true: files('x86/pc.cc'))
diff --git a/test cases/common/215 source set realistic example/boards/x86/pc.cc b/test cases/common/215 source set realistic example/boards/x86/pc.cc
new file mode 100644
index 0000000..04ec392
--- /dev/null
+++ b/test cases/common/215 source set realistic example/boards/x86/pc.cc
@@ -0,0 +1,26 @@
+#include <iostream>
+#include "common.h"
+
+struct X86Board: Board {
+ const char *target();
+ void say_hello();
+};
+
+const char *X86Board::target()
+{
+ return THE_TARGET;
+}
+
+void X86Board::say_hello()
+{
+ std::cout << ANSI_START << "I am a 1996 PC"
+ << ANSI_END << std::endl;
+}
+
+void initialize_target()
+{
+ std::cout << ANSI_START << "ready, set, go"
+ << ANSI_END << std::endl;
+}
+
+static X86Board pc;
diff --git a/test cases/common/215 source set realistic example/common.h b/test cases/common/215 source set realistic example/common.h
new file mode 100644
index 0000000..6e325c7
--- /dev/null
+++ b/test cases/common/215 source set realistic example/common.h
@@ -0,0 +1,41 @@
+#ifndef COMMON_H
+#define COMMON_H 1
+
+/*
+ * target-specific code will print in yellow, common code will print
+ * in grey.
+ */
+#ifdef THE_TARGET
+#define ANSI_START "\x1b[33;1m"
+#define ANSI_END "\x1b[0m"
+#else
+#define ANSI_START ""
+#define ANSI_END ""
+#endif
+
+void some_random_function();
+void initialize_target();
+
+struct Board {
+ Board *next;
+ Board();
+ virtual ~Board();
+ virtual void say_hello() = 0;
+ virtual const char *target() = 0;
+};
+
+struct Device {
+ Device *next;
+ Device();
+ virtual ~Device();
+ virtual void say_hello() = 0;
+};
+
+struct Dependency {
+ Dependency *next;
+ Dependency();
+ virtual ~Dependency();
+ virtual void initialize() = 0;
+};
+
+#endif
diff --git a/test cases/common/215 source set realistic example/config/aarch64 b/test cases/common/215 source set realistic example/config/aarch64
new file mode 100644
index 0000000..55b90eb
--- /dev/null
+++ b/test cases/common/215 source set realistic example/config/aarch64
@@ -0,0 +1,5 @@
+TARGET_AARCH64=y
+CONFIG_VIRT=y
+CONFIG_XLNX_ZCU102=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_MMIO=y
diff --git a/test cases/common/215 source set realistic example/config/arm b/test cases/common/215 source set realistic example/config/arm
new file mode 100644
index 0000000..d3f7ac7
--- /dev/null
+++ b/test cases/common/215 source set realistic example/config/arm
@@ -0,0 +1,3 @@
+TARGET_ARM=y
+CONFIG_VIRT=y
+CONFIG_VERSATILEPB=y
diff --git a/test cases/common/215 source set realistic example/config/x86 b/test cases/common/215 source set realistic example/config/x86
new file mode 100644
index 0000000..6caa3e2
--- /dev/null
+++ b/test cases/common/215 source set realistic example/config/x86
@@ -0,0 +1,4 @@
+TARGET_X86=y
+CONFIG_PC=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_PCI=y
diff --git a/test cases/common/215 source set realistic example/devices/meson.build b/test cases/common/215 source set realistic example/devices/meson.build
new file mode 100644
index 0000000..68ee68e
--- /dev/null
+++ b/test cases/common/215 source set realistic example/devices/meson.build
@@ -0,0 +1,3 @@
+specific.add(when: 'CONFIG_VIRTIO', if_true: files('virtio.cc'))
+common.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('virtio-pci.cc'))
+common.add(when: 'CONFIG_VIRTIO_MMIO', if_true: files('virtio-mmio.cc'))
diff --git a/test cases/common/215 source set realistic example/devices/virtio-mmio.cc b/test cases/common/215 source set realistic example/devices/virtio-mmio.cc
new file mode 100644
index 0000000..5dab97e
--- /dev/null
+++ b/test cases/common/215 source set realistic example/devices/virtio-mmio.cc
@@ -0,0 +1,16 @@
+#include <iostream>
+#include "common.h"
+#include "virtio.h"
+
+struct VirtioMMIODevice: VirtioDevice {
+ void say_hello();
+};
+
+void VirtioMMIODevice::say_hello()
+{
+ some_virtio_thing();
+ std::cout << ANSI_START << "virtio-mmio is available"
+ << ANSI_END << std::endl;
+}
+
+static VirtioMMIODevice virtio_mmio;
diff --git a/test cases/common/215 source set realistic example/devices/virtio-pci.cc b/test cases/common/215 source set realistic example/devices/virtio-pci.cc
new file mode 100644
index 0000000..7df7a82
--- /dev/null
+++ b/test cases/common/215 source set realistic example/devices/virtio-pci.cc
@@ -0,0 +1,16 @@
+#include <iostream>
+#include "common.h"
+#include "virtio.h"
+
+struct VirtioPCIDevice: VirtioDevice {
+ void say_hello();
+};
+
+void VirtioPCIDevice::say_hello()
+{
+ some_virtio_thing();
+ std::cout << ANSI_START << "virtio-pci is available"
+ << ANSI_END << std::endl;
+}
+
+static VirtioPCIDevice virtio_pci;
diff --git a/test cases/common/215 source set realistic example/devices/virtio.cc b/test cases/common/215 source set realistic example/devices/virtio.cc
new file mode 100644
index 0000000..fc51275
--- /dev/null
+++ b/test cases/common/215 source set realistic example/devices/virtio.cc
@@ -0,0 +1,6 @@
+#include <iostream>
+#include "common.h"
+#include "virtio.h"
+
+void VirtioDevice::some_virtio_thing() {
+}
diff --git a/test cases/common/215 source set realistic example/devices/virtio.h b/test cases/common/215 source set realistic example/devices/virtio.h
new file mode 100644
index 0000000..a157731
--- /dev/null
+++ b/test cases/common/215 source set realistic example/devices/virtio.h
@@ -0,0 +1,10 @@
+#ifndef VIRTIO_H
+#define VIRTIO_H 1
+
+#include "common.h"
+
+struct VirtioDevice: Device {
+ void some_virtio_thing();
+};
+
+#endif
diff --git a/test cases/common/215 source set realistic example/dummy.cpp b/test cases/common/215 source set realistic example/dummy.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/215 source set realistic example/dummy.cpp
diff --git a/test cases/common/215 source set realistic example/main.cc b/test cases/common/215 source set realistic example/main.cc
new file mode 100644
index 0000000..2b55217
--- /dev/null
+++ b/test cases/common/215 source set realistic example/main.cc
@@ -0,0 +1,32 @@
+#include <iostream>
+#include <vector>
+#include "common.h"
+
+Board* boards;
+Device* devices;
+Dependency* deps;
+
+Board::Board() { this->next = boards; boards = this; }
+Board::~Board() {}
+
+Device::Device() { this->next = devices; devices = this; }
+Device::~Device() {}
+
+Dependency::Dependency() { this->next = deps; deps = this; }
+Dependency::~Dependency() {}
+
+int main(void)
+{
+ some_random_function();
+ for (auto d = deps; d; d = d->next)
+ d->initialize();
+
+ initialize_target();
+ for (auto b = boards; b; b = b->next) {
+ std::cout << ANSI_START << b->target() << " - " << ANSI_END;
+ b->say_hello();
+ }
+
+ for (auto d = devices; d; d = d->next)
+ d->say_hello();
+}
diff --git a/test cases/common/215 source set realistic example/meson.build b/test cases/common/215 source set realistic example/meson.build
new file mode 100644
index 0000000..3ff8f12
--- /dev/null
+++ b/test cases/common/215 source set realistic example/meson.build
@@ -0,0 +1,53 @@
+# a sort-of realistic example that combines the sourceset and keyval
+# modules, inspired by QEMU's build system
+
+project('sourceset-example', 'cpp', default_options: ['cpp_std=c++11'])
+
+cppid = meson.get_compiler('cpp').get_id()
+if cppid == 'pgi'
+ error('MESON_SKIP_TEST: Even PGI 19.4 that claims C++17 full support, cannot handle auto x = y syntax used in this test.')
+endif
+
+ss = import('sourceset')
+keyval = import('keyval')
+
+zlib = declare_dependency(compile_args: '-DZLIB=1')
+another = declare_dependency(compile_args: '-DANOTHER=1')
+not_found = dependency('not-found', required: false, method : 'pkg-config')
+
+common = ss.source_set()
+specific = ss.source_set()
+
+common.add(files('main.cc'))
+common.add(when: [zlib, another], if_true: files('zlib.cc'))
+common.add(when: not_found,
+ if_true: files('was-found.cc'),
+ if_false: files('not-found.cc'))
+
+subdir('boards')
+subdir('devices')
+
+if meson.is_unity()
+ specific.add_all(common)
+ common = ss.source_set()
+ common.add(files('dummy.cpp'))
+endif
+
+common_lib = static_library('common', common.all_sources(),
+ dependencies: common.all_dependencies())
+
+targets = [ 'arm', 'aarch64', 'x86' ]
+target_dirs = { 'arm' : 'arm', 'aarch64' : 'arm', 'x86': 'x86' }
+
+foreach x : targets
+ config = keyval.load('config' / x)
+ target_specific = specific.apply(config, strict: false)
+ target_common = common.apply(config, strict: false)
+ target_deps = target_specific.dependencies() + target_common.dependencies()
+ executable(x,
+ objects: common_lib.extract_objects(target_common.sources()),
+ sources: target_specific.sources(),
+ dependencies: target_deps,
+ include_directories: 'boards' / target_dirs[x],
+ cpp_args: '-DTHE_TARGET="' + x + '"')
+endforeach
diff --git a/test cases/common/215 source set realistic example/not-found.cc b/test cases/common/215 source set realistic example/not-found.cc
new file mode 100644
index 0000000..955a7a2
--- /dev/null
+++ b/test cases/common/215 source set realistic example/not-found.cc
@@ -0,0 +1,8 @@
+#include <iostream>
+#include "common.h"
+
+void some_random_function()
+{
+ std::cout << ANSI_START << "everything's alright"
+ << ANSI_END << std::endl;
+}
diff --git a/test cases/common/215 source set realistic example/was-found.cc b/test cases/common/215 source set realistic example/was-found.cc
new file mode 100644
index 0000000..f1eaf1e
--- /dev/null
+++ b/test cases/common/215 source set realistic example/was-found.cc
@@ -0,0 +1,7 @@
+#include <iostream>
+
+void some_random_function()
+{
+ std::cout << ANSI_START << "huh?"
+ << ANSI_END << std::endl;
+}
diff --git a/test cases/common/215 source set realistic example/zlib.cc b/test cases/common/215 source set realistic example/zlib.cc
new file mode 100644
index 0000000..434e0b7
--- /dev/null
+++ b/test cases/common/215 source set realistic example/zlib.cc
@@ -0,0 +1,15 @@
+#include <iostream>
+#include "common.h"
+
+struct ZLibDependency : Dependency {
+ void initialize();
+};
+
+void ZLibDependency::initialize() {
+ if (ZLIB && ANOTHER) {
+ std::cout << ANSI_START << "hello from zlib"
+ << ANSI_END << std::endl;
+ }
+}
+
+ZLibDependency zlib;
diff --git a/test cases/common/216 custom target input extracted objects/check_object.py b/test cases/common/216 custom target input extracted objects/check_object.py
new file mode 100644
index 0000000..d521b43
--- /dev/null
+++ b/test cases/common/216 custom target input extracted objects/check_object.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+if __name__ == '__main__':
+ if len(sys.argv) < 4:
+ print(sys.argv[0], 'n output objects...')
+ sys.exit(1)
+ if len(sys.argv) != int(sys.argv[1]) + 3:
+ print(f'expected {sys.argv[1]} objects, got {len(sys.argv) - 3}')
+ sys.exit(1)
+ for i in sys.argv[3:]:
+ print('testing', i)
+ if not os.path.exists(i):
+ sys.exit(1)
+ with open(sys.argv[2], 'wb') as out:
+ pass
diff --git a/test cases/common/216 custom target input extracted objects/libdir/gen.py b/test cases/common/216 custom target input extracted objects/libdir/gen.py
new file mode 100644
index 0000000..095fffd
--- /dev/null
+++ b/test cases/common/216 custom target input extracted objects/libdir/gen.py
@@ -0,0 +1,6 @@
+#! /usr/bin/env python3
+import sys
+with open(sys.argv[1], 'r') as f:
+ for l in f:
+ l = l.rstrip()
+ print(l.replace(sys.argv[2], sys.argv[3]))
diff --git a/test cases/common/216 custom target input extracted objects/libdir/meson.build b/test cases/common/216 custom target input extracted objects/libdir/meson.build
new file mode 100644
index 0000000..93a7bcc
--- /dev/null
+++ b/test cases/common/216 custom target input extracted objects/libdir/meson.build
@@ -0,0 +1,21 @@
+gen_py = find_program('gen.py')
+ctsrc = custom_target('custom_target sources',
+ output: 'ct-source.c',
+ input: 'source.c',
+ command: [ gen_py, '@INPUT@', 'func1', 'func2' ], capture: true)
+
+gen = generator(gen_py, arguments: ['@INPUT@', 'func1', 'func3'],
+ output: 'gen-@PLAINNAME@',
+ capture: true)
+gensrc = gen.process('source.c')
+
+
+gen = generator(gen_py, arguments: ['@INPUT@', 'func1', 'func4'],
+ output: 'gen-@PLAINNAME@',
+ capture: true)
+sublibsrc = gen.process('source.c')
+subobjlib = static_library('subobject', sublibsrc)
+
+objlib = static_library('object', 'source.c', ctsrc, gensrc,
+ objects: subobjlib.extract_all_objects(recursive: false),
+ override_options : ['unity=off'])
diff --git a/test cases/common/216 custom target input extracted objects/libdir/source.c b/test cases/common/216 custom target input extracted objects/libdir/source.c
new file mode 100644
index 0000000..1dc08e1
--- /dev/null
+++ b/test cases/common/216 custom target input extracted objects/libdir/source.c
@@ -0,0 +1,3 @@
+int func1_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/216 custom target input extracted objects/meson.build b/test cases/common/216 custom target input extracted objects/meson.build
new file mode 100644
index 0000000..654b76d
--- /dev/null
+++ b/test cases/common/216 custom target input extracted objects/meson.build
@@ -0,0 +1,48 @@
+project('custom target input extracted objects', 'c')
+
+if meson.backend() == 'xcode'
+ error('MESON_SKIP_TEST: sometimes Xcode puts object files in weird paths and we can not extract them.')
+endif
+
+
+checker = find_program('check_object.py')
+
+cc = meson.get_compiler('c').cmd_array().get(-1)
+
+subdir('libdir')
+
+custom_target('check',
+ input: objlib.extract_objects('source.c'),
+ output: 'objcheck',
+ command: [checker, '1', '@OUTPUT@', '@INPUT@'],
+ build_by_default: true)
+
+custom_target('checkct',
+ input: objlib.extract_objects(ctsrc),
+ output: 'objcheck-ct',
+ command: [checker, '1', '@OUTPUT@', '@INPUT@'],
+ build_by_default: true)
+
+custom_target('checkcti',
+ input: objlib.extract_objects(ctsrc[0]),
+ output: 'objcheck-cti',
+ command: [checker, '1', '@OUTPUT@', '@INPUT@'],
+ build_by_default: true)
+
+custom_target('checkgen',
+ input: objlib.extract_objects(gensrc),
+ output: 'objcheck-gen',
+ command: [checker, '1', '@OUTPUT@', '@INPUT@'],
+ build_by_default: true)
+
+custom_target('checkall',
+ input: objlib.extract_all_objects(recursive: false),
+ output: 'objcheck-all',
+ command: [checker, '3', '@OUTPUT@', '@INPUT@'],
+ build_by_default: true)
+
+custom_target('checkall-recursive',
+ input: objlib.extract_all_objects(recursive: true),
+ output: 'objcheck-all-recursive',
+ command: [checker, '4', '@OUTPUT@', '@INPUT@'],
+ build_by_default: true)
diff --git a/test cases/common/217 test priorities/meson.build b/test cases/common/217 test priorities/meson.build
new file mode 100644
index 0000000..159d56f
--- /dev/null
+++ b/test cases/common/217 test priorities/meson.build
@@ -0,0 +1,22 @@
+project('test priorities')
+
+test_prog = find_program('testprog.py')
+
+test('priority 0', test_prog,
+ args : ['0'],
+)
+
+test('priority neg 10', test_prog,
+ args : ['-10'],
+ priority : -10
+)
+
+test('priority 1000', test_prog,
+ args : ['1000'],
+ priority : 1000
+)
+
+test('priority 50', test_prog,
+ args : ['50'],
+ priority : 50
+)
diff --git a/test cases/common/217 test priorities/testprog.py b/test cases/common/217 test priorities/testprog.py
new file mode 100644
index 0000000..470f28c
--- /dev/null
+++ b/test cases/common/217 test priorities/testprog.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+import sys
+
+print(sys.argv[1])
diff --git a/test cases/common/218 include_dir dot/meson.build b/test cases/common/218 include_dir dot/meson.build
new file mode 100644
index 0000000..71f7189
--- /dev/null
+++ b/test cases/common/218 include_dir dot/meson.build
@@ -0,0 +1,8 @@
+project('Include Here', 'c')
+
+# The layout with the .h file in . and the .c files in src/ is critical to
+# tickle the bug #5847
+
+inc = include_directories('.')
+
+subdir('src') \ No newline at end of file
diff --git a/test cases/common/218 include_dir dot/rone.h b/test cases/common/218 include_dir dot/rone.h
new file mode 100644
index 0000000..48d7a79
--- /dev/null
+++ b/test cases/common/218 include_dir dot/rone.h
@@ -0,0 +1 @@
+int rOne(void); \ No newline at end of file
diff --git a/test cases/common/218 include_dir dot/src/main.c b/test cases/common/218 include_dir dot/src/main.c
new file mode 100644
index 0000000..192b783
--- /dev/null
+++ b/test cases/common/218 include_dir dot/src/main.c
@@ -0,0 +1,5 @@
+#include "rone.h"
+
+int main(void) {
+ return rOne();
+}
diff --git a/test cases/common/218 include_dir dot/src/meson.build b/test cases/common/218 include_dir dot/src/meson.build
new file mode 100644
index 0000000..fcbefb0
--- /dev/null
+++ b/test cases/common/218 include_dir dot/src/meson.build
@@ -0,0 +1,6 @@
+t = executable(
+ 'main',
+ ['main.c', 'rone.c'],
+ include_directories : inc,
+ implicit_include_directories : false,
+) \ No newline at end of file
diff --git a/test cases/common/218 include_dir dot/src/rone.c b/test cases/common/218 include_dir dot/src/rone.c
new file mode 100644
index 0000000..63cb0d3
--- /dev/null
+++ b/test cases/common/218 include_dir dot/src/rone.c
@@ -0,0 +1,3 @@
+int rOne(void) {
+ return 1;
+} \ No newline at end of file
diff --git a/test cases/common/219 include_type dependency/main.cpp b/test cases/common/219 include_type dependency/main.cpp
new file mode 100644
index 0000000..bf8c4a4
--- /dev/null
+++ b/test cases/common/219 include_type dependency/main.cpp
@@ -0,0 +1,8 @@
+#include <iostream>
+#include <boost/graph/filtered_graph.hpp>
+
+using namespace std;
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/219 include_type dependency/meson.build b/test cases/common/219 include_type dependency/meson.build
new file mode 100644
index 0000000..678fb4e
--- /dev/null
+++ b/test cases/common/219 include_type dependency/meson.build
@@ -0,0 +1,44 @@
+project(
+ 'dependency include_type',
+ ['c', 'cpp'],
+)
+
+dep = dependency('zlib', method: 'pkg-config', required : false)
+boost_dep = dependency('boost', modules: ['graph'], include_type : 'system', required: false)
+
+if not dep.found()
+ error('MESON_SKIP_TEST zlib was not found')
+endif
+
+if not boost_dep.found()
+ error('MESON_SKIP_TEST boost was not found')
+endif
+
+assert(dep.include_type() == 'preserve', 'include_type must default to "preserve"')
+
+dep_sys = dep.as_system()
+assert(dep_sys.include_type() == 'system', 'as_system must return a system dep')
+
+dep2 = dependency('zlib', method: 'pkg-config', include_type : 'system')
+assert(dep2.include_type() == 'system', 'include_type must be true when set')
+
+dep2_sys = dep2.as_system('non-system')
+assert(dep2_sys.include_type() == 'non-system', 'as_system must set include_type correctly')
+
+sp = subproject('subDep')
+sp_dep = sp.get_variable('subDep_dep')
+assert(sp_dep.include_type() == 'preserve', 'default is preserve')
+
+sp_dep_sys = sp_dep.as_system('system')
+assert(sp_dep_sys.include_type() == 'system', 'changing include_type works')
+assert(sp_dep.include_type() == 'preserve', 'as_system must not mutate the original object')
+
+fallback = dependency('sdffgagf_does_not_exist', include_type: 'system', fallback: ['subDep', 'subDep_dep'])
+assert(fallback.include_type() == 'system', 'include_type works with dependency fallback')
+
+fallback_empty = dependency('', include_type: 'system', fallback: ['subDep', 'subDep_dep'])
+assert(fallback_empty.include_type() == 'system', 'include_type works with empty name dependency fallback')
+
+# Check that PCH works with `include_type : 'system'` See https://github.com/mesonbuild/meson/issues/7167
+main_exe = executable('main_exe', 'main.cpp', cpp_pch: 'pch/test.hpp', dependencies: boost_dep)
+test('main_test', main_exe)
diff --git a/test cases/common/219 include_type dependency/pch/test.hpp b/test cases/common/219 include_type dependency/pch/test.hpp
new file mode 100644
index 0000000..0d40fe1
--- /dev/null
+++ b/test cases/common/219 include_type dependency/pch/test.hpp
@@ -0,0 +1 @@
+#include <boost/graph/filtered_graph.hpp>
diff --git a/test cases/common/219 include_type dependency/subprojects/subDep/meson.build b/test cases/common/219 include_type dependency/subprojects/subDep/meson.build
new file mode 100644
index 0000000..c3e87c4
--- /dev/null
+++ b/test cases/common/219 include_type dependency/subprojects/subDep/meson.build
@@ -0,0 +1,3 @@
+project('subDep', ['cpp'])
+
+subDep_dep = declare_dependency(compile_args : [])
diff --git a/test cases/common/22 object extraction/check-obj.py b/test cases/common/22 object extraction/check-obj.py
new file mode 100644
index 0000000..d6afbcc
--- /dev/null
+++ b/test cases/common/22 object extraction/check-obj.py
@@ -0,0 +1,21 @@
+#! /usr/bin/env python3
+
+import json
+import sys
+import os
+
+cc = None
+output = None
+
+# Only the ninja backend produces compile_commands.json
+if sys.argv[1] == 'ninja':
+ with open('compile_commands.json') as f:
+ cc = json.load(f)
+ output = {x['output'] for x in cc}
+
+for obj in sys.argv[2:]:
+ if not os.path.exists(obj):
+ sys.exit(f'File {obj} not found.')
+ if sys.argv[1] == 'ninja' and obj not in output:
+ sys.exit(1)
+ print('Verified', obj)
diff --git a/test cases/common/22 object extraction/create-source.py b/test cases/common/22 object extraction/create-source.py
new file mode 100644
index 0000000..d2e8e8b
--- /dev/null
+++ b/test cases/common/22 object extraction/create-source.py
@@ -0,0 +1,3 @@
+#! /usr/bin/env python3
+import sys
+print(f'#include "{sys.argv[1]}"')
diff --git a/test cases/common/22 object extraction/header.h b/test cases/common/22 object extraction/header.h
new file mode 100644
index 0000000..50403ce
--- /dev/null
+++ b/test cases/common/22 object extraction/header.h
@@ -0,0 +1 @@
+/* Check that extract_all_objects works with headers. */
diff --git a/test cases/common/22 object extraction/lib.c b/test cases/common/22 object extraction/lib.c
new file mode 100644
index 0000000..8180551
--- /dev/null
+++ b/test cases/common/22 object extraction/lib.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 42;
+}
diff --git a/test cases/common/22 object extraction/lib2.c b/test cases/common/22 object extraction/lib2.c
new file mode 100644
index 0000000..5020593
--- /dev/null
+++ b/test cases/common/22 object extraction/lib2.c
@@ -0,0 +1,3 @@
+int retval(void) {
+ return 43;
+}
diff --git a/test cases/common/22 object extraction/main.c b/test cases/common/22 object extraction/main.c
new file mode 100644
index 0000000..27162c5
--- /dev/null
+++ b/test cases/common/22 object extraction/main.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func() == 42 ? 0 : 1;
+}
diff --git a/test cases/common/22 object extraction/meson.build b/test cases/common/22 object extraction/meson.build
new file mode 100644
index 0000000..37ac66d
--- /dev/null
+++ b/test cases/common/22 object extraction/meson.build
@@ -0,0 +1,50 @@
+project('object extraction', 'c')
+
+if meson.is_unity()
+ message('Skipping extraction test because this is a Unity build.')
+else
+ lib1 = library('somelib', 'src/lib.c')
+ lib2 = library('somelib2', 'lib.c', 'header.h', 'lib2.c')
+
+ obj1 = lib1.extract_objects('src/lib.c')
+ obj2 = lib2.extract_objects(['lib.c'])
+ obj3 = lib2.extract_objects(files('lib.c'))
+ obj4 = lib2.extract_objects(['lib.c', 'lib.c'])
+ obj5 = lib2.extract_objects(['lib.c', 'header.h'])
+ obj6 = lib2.extract_all_objects(recursive: true)
+
+ e1 = executable('main1', 'main.c', objects : obj1)
+ e2 = executable('main2', 'main.c', objects : obj2)
+ e3 = executable('main3', 'main.c', objects : obj3)
+ e4 = executable('main4', 'main.c', objects : obj4)
+ e5 = executable('main5', 'main.c', objects : obj5)
+ e6 = executable('main6', 'main.c', objects : obj6)
+
+ ct_src = custom_target('lib3.c', output: 'lib3.c', capture: true,
+ command: [find_program('create-source.py'), 'lib.c'])
+ lib3 = library('somelib3', ct_src)
+ e7 = executable('main7', 'main.c', objects: lib3.extract_objects(ct_src[0]))
+ e8 = executable('main8', 'main.c', objects: lib3.extract_objects(ct_src))
+
+ gen = generator(find_program('create-source.py'), arguments: ['@INPUT@'],
+ output: '@BASENAME@4.c', capture: true)
+ gen_src = gen.process('lib.c')
+ lib4 = library('somelib4', gen_src)
+ e9 = executable('main9', 'main.c', objects: lib4.extract_objects(gen_src))
+
+ custom_target('custom_target with object inputs', output: 'objs',
+ input: [obj1, obj2, obj3, obj5, obj6],
+ build_by_default: true,
+ command: [find_program('check-obj.py'), meson.backend(), '@INPUT@'],
+ capture: true)
+
+ test('extraction test 1', e1)
+ test('extraction test 2', e2)
+ test('extraction test 3', e3)
+ test('extraction test 4', e4)
+ test('extraction test 5', e5)
+ test('extraction test 6', e6)
+ test('extraction test 7', e7)
+ test('extraction test 8', e8)
+ test('extraction test 9', e9)
+endif
diff --git a/test cases/common/22 object extraction/src/lib.c b/test cases/common/22 object extraction/src/lib.c
new file mode 100644
index 0000000..8180551
--- /dev/null
+++ b/test cases/common/22 object extraction/src/lib.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 42;
+}
diff --git a/test cases/common/220 fs module/meson.build b/test cases/common/220 fs module/meson.build
new file mode 100644
index 0000000..d38c872
--- /dev/null
+++ b/test cases/common/220 fs module/meson.build
@@ -0,0 +1,144 @@
+project('fs module test')
+
+is_windows = build_machine.system() == 'windows'
+
+fs = import('fs')
+
+f = files('meson.build')
+
+assert(fs.exists('meson.build'), 'Existing file reported as missing.')
+assert(not fs.exists('nonexisting'), 'Nonexisting file was found.')
+
+if not is_windows and build_machine.system() != 'cygwin'
+ # Symlinks on Windows have specific requirements including:
+ # * Meson running under Python >= 3.8
+ # * Windows user permissions to create symlinks, and/or Windows in Developer mode
+ # so at this time the symlink test is skipped for Windows.
+ symlink = meson.current_build_dir() / 'a_symlink'
+ run_command('ln', '-s', '-f', meson.current_source_dir() / 'meson.build', symlink, check: true)
+ assert(fs.is_symlink(symlink), 'Symlink not detected.')
+ assert(not fs.is_symlink('meson.build'), 'Regular file detected as symlink.')
+ assert(not fs.is_symlink(f[0]), 'Regular file detected as symlink.')
+endif
+
+assert(fs.is_file('meson.build'), 'File not detected as a file.')
+assert(not fs.is_file('subprojects'), 'Directory detected as a file.')
+assert(not fs.is_file('nonexisting'), 'Bad path detected as a file.')
+
+assert(fs.is_dir('subprojects'), 'Dir not detected correctly.')
+assert(not fs.is_dir('meson.build'), 'File detected as a dir.')
+assert(not fs.is_dir('nonexisting'), 'Bad path detected as a dir.')
+
+assert(fs.is_dir('~'), 'home directory not detected')
+assert(not fs.is_file('~'), 'home directory detected as file')
+
+# -- expanduser
+assert(fs.expanduser('~') != '~','expanduser failed')
+assert(fs.expanduser('~/foo').endswith('foo'), 'expanduser with tail failed')
+
+# -- as_posix
+assert(fs.as_posix('/') == '/', 'as_posix idempotent')
+assert(fs.as_posix('\\') == '/', 'as_posix simple')
+assert(fs.as_posix('\\\\') == '/', 'as_posix simple')
+assert(fs.as_posix('foo\\bar/baz') == 'foo/bar/baz', 'as_posix mixed slash')
+
+# -- is_absolute
+winabs = 'q:/foo'
+unixabs = '/foo'
+if is_windows
+ assert(fs.is_absolute(winabs), 'is_absolute windows not detected')
+ assert(not fs.is_absolute(unixabs), 'is_absolute unix false positive')
+else
+ assert(fs.is_absolute(unixabs), 'is_absolute unix not detected')
+ assert(not fs.is_absolute(winabs), 'is_absolute windows false positive')
+endif
+
+# -- replace_suffix
+
+original = 'foo'
+assert(fs.replace_suffix(original, '') == original, 'replace_suffix idempotent')
+assert(fs.replace_suffix(f[0], '') == 'meson', 'replace_suffix trim')
+
+original = 'foo.txt'
+new = fs.replace_suffix(original, '.ini')
+assert(new == 'foo.ini', 'replace_suffix failed')
+
+new = fs.replace_suffix(f[0], '.ini')
+assert(new == 'meson.ini', 'replace_suffix failed')
+
+original = 'foo'
+new = fs.replace_suffix(original, '.ini')
+assert(new == 'foo.ini', 'replace_suffix did not add suffix to suffixless file')
+
+original = 'foo.dll.a'
+new = fs.replace_suffix(original, '.so')
+assert(new == 'foo.dll.so', 'replace_suffix did not only modify last suffix')
+
+original = 'foo.dll'
+new = fs.replace_suffix(original, '')
+assert(new == 'foo', 'replace_suffix did not only delete last suffix')
+
+# `/` on windows is interpreted like `.drive` which in general may not be `c:/`
+# the files need not exist for fs.replace_suffix()
+original = is_windows ? 'j:/foo/bar.txt' : '/foo/bar.txt'
+new_check = is_windows ? 'j:\\foo\\bar.ini' : '/foo/bar.ini'
+
+new = fs.replace_suffix(original, '.ini')
+assert(new == new_check, 'absolute path replace_suffix failed')
+
+# -- hash
+
+md5 = fs.hash('subdir/subdirfile.txt', 'md5')
+sha256 = fs.hash('subdir/subdirfile.txt', 'sha256')
+assert(md5 == 'd0795db41614d25affdd548314b30b3b', 'md5sum did not match')
+assert(sha256 == 'be2170b0dae535b73f6775694fffa3fd726a43b5fabea11b7342f0605917a42a', 'sha256sum did not match')
+
+f = files('subdir/subdirfile.txt')
+md5 = fs.hash(f[0], 'md5')
+assert(md5 == 'd0795db41614d25affdd548314b30b3b', 'md5sum did not match')
+sha256 = fs.hash(f[0], 'sha256')
+assert(sha256 == 'be2170b0dae535b73f6775694fffa3fd726a43b5fabea11b7342f0605917a42a', 'sha256sum did not match')
+
+# -- size
+
+size = fs.size('subdir/subdirfile.txt')
+assert(size == 19, 'file size not found correctly')
+
+size = fs.size(f[0])
+assert(size == 19, 'file size not found correctly')
+
+# -- are filenames referring to the same file?
+f1 = 'meson.build'
+f2 = 'subdir/../meson.build'
+assert(fs.is_samepath(f1, f2), 'is_samepath not detecting same files')
+assert(fs.is_samepath(meson.source_root(), 'subdir/..'), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.project_source_root(), 'subdir/..'), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.project_build_root(), meson.current_build_dir() / 'subdir/..'), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.global_source_root(), meson.current_source_dir()), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.global_build_root(), meson.current_build_dir()), 'is_samepath not detecting same directory')
+assert(not fs.is_samepath(f1, 'subdir/subdirfile.txt'), 'is_samepath known bad comparison')
+assert(not fs.is_samepath('not-a-path', f2), 'is_samepath should not error if path(s) do not exist')
+
+f = files('meson.build', 'subdir/../meson.build')
+assert(fs.is_samepath(f[0], f[1]), 'is_samepath not detercting same files')
+
+if not is_windows and build_machine.system() != 'cygwin'
+ assert(fs.is_samepath(symlink, 'meson.build'), 'symlink is_samepath fail')
+endif
+
+# parts of path
+assert(fs.parent('foo/bar') == 'foo', 'failed to get dirname')
+if not is_windows
+assert(fs.parent(f[1]) == 'subdir/..', 'failed to get dirname')
+else
+assert(fs.parent(f[1]) == 'subdir\..', 'failed to get dirname')
+endif
+assert(fs.name('foo/bar') == 'bar', 'failed to get basename')
+assert(fs.name(f[1]) == 'meson.build', 'failed to get basename')
+assert(fs.name('foo/bar/baz.dll.a') == 'baz.dll.a', 'failed to get basename with compound suffix')
+assert(fs.stem('foo/bar/baz.dll') == 'baz', 'failed to get stem with suffix')
+assert(fs.stem('foo/bar/baz.dll.a') == 'baz.dll', 'failed to get stem with compound suffix')
+
+subdir('subdir')
+
+subproject('subbie')
diff --git a/test cases/common/220 fs module/subdir/meson.build b/test cases/common/220 fs module/subdir/meson.build
new file mode 100644
index 0000000..0cd2475
--- /dev/null
+++ b/test cases/common/220 fs module/subdir/meson.build
@@ -0,0 +1,6 @@
+subdirfiles = files('subdirfile.txt')
+assert(fs.exists('subdirfile.txt'), 'Subdir file lookup is broken.')
+assert(fs.is_samepath(meson.project_source_root(), '..'), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.project_build_root(), meson.current_build_dir() / '..'), 'is_samepath not detecting same directory')
+
+assert(fs.is_samepath(subdirfiles[0], 'subdirfile.txt'), 'is_samepath not detecting same directory when using File and str')
diff --git a/test cases/common/220 fs module/subdir/subdirfile.txt b/test cases/common/220 fs module/subdir/subdirfile.txt
new file mode 100644
index 0000000..bcf7cc0
--- /dev/null
+++ b/test cases/common/220 fs module/subdir/subdirfile.txt
@@ -0,0 +1 @@
+I have no content.
diff --git a/test cases/common/220 fs module/subprojects/subbie/meson.build b/test cases/common/220 fs module/subprojects/subbie/meson.build
new file mode 100644
index 0000000..f1e21ea
--- /dev/null
+++ b/test cases/common/220 fs module/subprojects/subbie/meson.build
@@ -0,0 +1,11 @@
+project('subbie')
+
+fs = import('fs')
+
+assert(fs.exists('subprojectfile.txt'), 'Subproject root file not found.')
+assert(fs.is_samepath(meson.project_source_root(), meson.current_source_dir()), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.project_build_root(), meson.current_build_dir()), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.global_source_root(), meson.current_source_dir() / '../..'), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.global_build_root(), meson.current_build_dir() / '../..'), 'is_samepath not detecting same directory')
+
+subdir('subsub')
diff --git a/test cases/common/220 fs module/subprojects/subbie/subprojectfile.txt b/test cases/common/220 fs module/subprojects/subbie/subprojectfile.txt
new file mode 100644
index 0000000..bedb84c
--- /dev/null
+++ b/test cases/common/220 fs module/subprojects/subbie/subprojectfile.txt
@@ -0,0 +1 @@
+I'm not empty. So there's at least that.
diff --git a/test cases/common/220 fs module/subprojects/subbie/subsub/meson.build b/test cases/common/220 fs module/subprojects/subbie/subsub/meson.build
new file mode 100644
index 0000000..4ac68ae
--- /dev/null
+++ b/test cases/common/220 fs module/subprojects/subbie/subsub/meson.build
@@ -0,0 +1,3 @@
+assert(fs.exists('subsubfile.txt'), 'Subproject subdir lookup failed.')
+assert(fs.is_samepath(meson.project_source_root(), meson.current_source_dir() / '..'), 'is_samepath not detecting same directory')
+assert(fs.is_samepath(meson.project_build_root(), meson.current_build_dir() / '..'), 'is_samepath not detecting same directory')
diff --git a/test cases/common/220 fs module/subprojects/subbie/subsub/subsubfile.txt b/test cases/common/220 fs module/subprojects/subbie/subsub/subsubfile.txt
new file mode 100644
index 0000000..2d5120d
--- /dev/null
+++ b/test cases/common/220 fs module/subprojects/subbie/subsub/subsubfile.txt
@@ -0,0 +1 @@
+Thank you for looking inside me.
diff --git a/test cases/common/221 zlib/meson.build b/test cases/common/221 zlib/meson.build
new file mode 100644
index 0000000..b5b813c
--- /dev/null
+++ b/test cases/common/221 zlib/meson.build
@@ -0,0 +1,23 @@
+project('zlib system dependency', 'c')
+
+if not ['darwin', 'freebsd', 'dragonfly', 'windows', 'android'].contains(host_machine.system())
+ error('MESON_SKIP_TEST only applicable on macOS, FreeBSD, DragonflyBSD, Windows, and Android.')
+endif
+
+cc = meson.get_compiler('c')
+
+if host_machine.system() == 'darwin' and cc.get_id() != 'clang'
+ # this will only work on mac if using Apple's clang compiler, but there is no
+ # way in the meson source level to differentiate apple clang and llvm clang
+ # In the meson CI only apple clang is tested
+ error('MESON_SKIP_TEST on macOS only clang is supported.')
+endif
+
+if not (cc.find_library('z', required: false).found() or
+ cc.find_library('zlib', required : false).found() or
+ cc.find_library('zlib1', required : false).found())
+ error('MESON_SKIP_TEST Cannot seem to find zlib via find_library, this test will probably fail.')
+endif
+
+z = dependency('zlib', method : 'system')
+assert(z.version().version_compare('>= 1.2'), 'Version does not seem to have been detected correctly.')
diff --git a/test cases/common/222 native prop/crossfile.ini b/test cases/common/222 native prop/crossfile.ini
new file mode 100644
index 0000000..13deef3
--- /dev/null
+++ b/test cases/common/222 native prop/crossfile.ini
@@ -0,0 +1,4 @@
+[properties]
+astring = 'cross'
+anarray = ['one', 'two']
+red = true
diff --git a/test cases/common/222 native prop/meson.build b/test cases/common/222 native prop/meson.build
new file mode 100644
index 0000000..8752371
--- /dev/null
+++ b/test cases/common/222 native prop/meson.build
@@ -0,0 +1,49 @@
+project('get prop')
+
+x = meson.get_external_property('astring')
+ref = meson.is_cross_build() ? 'cross' : 'mystring'
+assert(x==ref, 'did not get native property string. did you use "meson setup --native-file native.txt"')
+
+x = meson.get_external_property('astring', native: true)
+assert(x=='mystring', 'did not get native property with native:true and non-cross build.')
+
+x = meson.get_external_property('astring', 'fallback', native: false)
+assert(x==ref, 'did not get get native property with native:false and non-cross build.')
+
+
+x = meson.get_external_property('notexist', 'fallback')
+assert(x=='fallback', 'fallback did not work')
+
+x = meson.get_external_property('notexist', 'fallback', native: true)
+assert(x=='fallback', 'fallback native:true did not work')
+
+x = meson.get_external_property('notexist', 'fallback', native: false)
+assert(x=='fallback', 'fallback native:false did not work')
+
+
+x = meson.get_external_property('anarray')
+assert(x==['one', 'two'], 'array did not work')
+
+assert(meson.has_external_property('anarray'), 'expected property "anarray" to exist')
+assert(meson.has_external_property('astring'), 'expected property "astring" to exist')
+assert(not meson.has_external_property('abool'), 'did not expect property "abool" to exist')
+
+# These exist in both
+assert(meson.has_external_property('anarray', native: false), 'FIXME')
+assert(meson.has_external_property('anarray', native: true), 'FIXME')
+assert(meson.has_external_property('astring', native: false), 'FIXME')
+assert(meson.has_external_property('astring', native: true), 'FIXME')
+
+if meson.is_cross_build()
+ # This property only exists in the cross file
+ assert(meson.has_external_property('red'), 'expected property "red" to exist in cross file')
+ assert(meson.has_external_property('red', native: false), 'expected property "red" to exist in cross file')
+ assert(not meson.has_external_property('red', native: true), 'did not expect property "red" to exist in native file')
+
+ assert(not meson.has_external_property('abool', native: false), 'FIXME')
+ assert(not meson.has_external_property('abool', native: false), 'FIXME')
+else
+ assert(not meson.has_external_property('red'), 'did not expect property "red" to exist in native file')
+ assert(not meson.has_external_property('red', native: false), 'did not expect property "red" to exist in cross file because we are not doing a cross build')
+ assert(not meson.has_external_property('red', native: true), 'did not expect property "red" to exist in native file')
+endif
diff --git a/test cases/common/222 native prop/nativefile.ini b/test cases/common/222 native prop/nativefile.ini
new file mode 100644
index 0000000..03c1e03
--- /dev/null
+++ b/test cases/common/222 native prop/nativefile.ini
@@ -0,0 +1,3 @@
+[properties]
+astring = 'mystring'
+anarray = ['one', 'two'] \ No newline at end of file
diff --git a/test cases/common/223 persubproject options/foo.c b/test cases/common/223 persubproject options/foo.c
new file mode 100644
index 0000000..63e4de6
--- /dev/null
+++ b/test cases/common/223 persubproject options/foo.c
@@ -0,0 +1,5 @@
+int foo(void);
+
+int foo(void) {
+ return 0;
+}
diff --git a/test cases/common/223 persubproject options/main.cpp b/test cases/common/223 persubproject options/main.cpp
new file mode 100644
index 0000000..214f02b
--- /dev/null
+++ b/test cases/common/223 persubproject options/main.cpp
@@ -0,0 +1,3 @@
+int foo();
+
+int main(void) { return foo(); }
diff --git a/test cases/common/223 persubproject options/meson.build b/test cases/common/223 persubproject options/meson.build
new file mode 100644
index 0000000..25a0100
--- /dev/null
+++ b/test cases/common/223 persubproject options/meson.build
@@ -0,0 +1,20 @@
+project('persubproject options', 'c', 'cpp',
+ default_options : ['werror=true',
+ 'warning_level=3',
+ 'cpp_std=c++11'])
+
+assert(get_option('default_library') == 'both', 'Parent default_library should be "both"')
+assert(get_option('werror'))
+assert(get_option('warning_level') == '3')
+assert(get_option('cpp_std') == 'c++11')
+
+
+# Check it build both by calling a method only both_libraries target implement
+lib = library('lib1', 'foo.c')
+lib.get_static_lib()
+
+subproject('sub1')
+
+libcpp14_dep = dependency('libcpp14', fallback: 'sub2', default_options : ['default_library=static'])
+exe = executable('test1', 'main.cpp', dependencies : libcpp14_dep)
+test('mixing-cpp-version', exe)
diff --git a/test cases/common/223 persubproject options/subprojects/sub1/foo.c b/test cases/common/223 persubproject options/subprojects/sub1/foo.c
new file mode 100644
index 0000000..82ad2c2
--- /dev/null
+++ b/test cases/common/223 persubproject options/subprojects/sub1/foo.c
@@ -0,0 +1,8 @@
+int foo(void);
+
+int foo(void) {
+ /* This is built with -Werror, it would error if warning_level=3 was inherited
+ * from main project and not overridden by this subproject's default_options. */
+ int x;
+ return 0;
+}
diff --git a/test cases/common/223 persubproject options/subprojects/sub1/meson.build b/test cases/common/223 persubproject options/subprojects/sub1/meson.build
new file mode 100644
index 0000000..fb72837
--- /dev/null
+++ b/test cases/common/223 persubproject options/subprojects/sub1/meson.build
@@ -0,0 +1,10 @@
+project('sub1', 'c', 'cpp',
+ default_options : ['warning_level=0'])
+
+assert(get_option('default_library') == 'both', 'Should inherit parent project default_library')
+assert(get_option('warning_level') == '0')
+assert(get_option('cpp_std') == 'c++11')
+
+# Check it build both by calling a method only both_libraries target implement
+lib = library('lib1', 'foo.c')
+lib.get_static_lib()
diff --git a/test cases/common/223 persubproject options/subprojects/sub2/foo.c b/test cases/common/223 persubproject options/subprojects/sub2/foo.c
new file mode 100644
index 0000000..cf7201b
--- /dev/null
+++ b/test cases/common/223 persubproject options/subprojects/sub2/foo.c
@@ -0,0 +1,9 @@
+int foo(void);
+
+#ifdef __GNUC__
+#warning This should not produce error
+#endif
+
+int foo(void) {
+ return 0;
+}
diff --git a/test cases/common/223 persubproject options/subprojects/sub2/foo.cpp b/test cases/common/223 persubproject options/subprojects/sub2/foo.cpp
new file mode 100644
index 0000000..27d1720
--- /dev/null
+++ b/test cases/common/223 persubproject options/subprojects/sub2/foo.cpp
@@ -0,0 +1,10 @@
+#include <memory>
+
+class Dummy {
+ int x;
+};
+
+int foo() {
+ auto obj = std::make_unique<Dummy>();
+ return 0;
+}
diff --git a/test cases/common/223 persubproject options/subprojects/sub2/meson.build b/test cases/common/223 persubproject options/subprojects/sub2/meson.build
new file mode 100644
index 0000000..cf1435a
--- /dev/null
+++ b/test cases/common/223 persubproject options/subprojects/sub2/meson.build
@@ -0,0 +1,16 @@
+project('sub2', 'c', 'cpp',
+ default_options : ['default_library=shared',
+ 'werror=false',
+ 'cpp_std=c++14'])
+
+assert(get_option('default_library') == 'static', 'Parent should override default_library')
+assert(not get_option('werror'))
+assert(get_option('cpp_std') == 'c++14')
+
+# If it doesn't build only a static library, it would make target name clash.
+library('lib1', 'foo.c')
+shared_library('lib1', 'foo.c')
+
+# Parent project is c++11 but this one uses c++14 to build.
+libcpp14 = library('lib2', 'foo.cpp')
+meson.override_dependency('libcpp14', declare_dependency(link_with: libcpp14))
diff --git a/test cases/common/223 persubproject options/test.json b/test cases/common/223 persubproject options/test.json
new file mode 100644
index 0000000..ccfa9ff
--- /dev/null
+++ b/test cases/common/223 persubproject options/test.json
@@ -0,0 +1,7 @@
+{
+ "matrix": {
+ "options": {
+ "default_library": [ { "val": "both" } ]
+ }
+ }
+}
diff --git a/test cases/common/224 arithmetic operators/meson.build b/test cases/common/224 arithmetic operators/meson.build
new file mode 100644
index 0000000..a904bd0
--- /dev/null
+++ b/test cases/common/224 arithmetic operators/meson.build
@@ -0,0 +1,8 @@
+project('arithmetic operators')
+assert(5 - 3 - 1 == 1)
+assert(5 - (3 - 1) == 3)
+assert(5 - 1 * 3 - 3 == -1)
+assert(420 - 300 - 51 == 69)
+assert(1000 / 2 / 2 / 2 == 125)
+assert(4 * 9 / 3 % 8 - 3 - 10 / 2 == -4)
+assert(94 - 30 + (2 - (40 - 6 + 7) - 9) - 10 == 6)
diff --git a/test cases/common/225 link language/c_linkage.cpp b/test cases/common/225 link language/c_linkage.cpp
new file mode 100644
index 0000000..dc006b9
--- /dev/null
+++ b/test cases/common/225 link language/c_linkage.cpp
@@ -0,0 +1,5 @@
+extern "C" {
+ int makeInt(void) {
+ return 0;
+ }
+}
diff --git a/test cases/common/225 link language/c_linkage.h b/test cases/common/225 link language/c_linkage.h
new file mode 100644
index 0000000..1609f47
--- /dev/null
+++ b/test cases/common/225 link language/c_linkage.h
@@ -0,0 +1,10 @@
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int makeInt(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test cases/common/225 link language/lib.cpp b/test cases/common/225 link language/lib.cpp
new file mode 100644
index 0000000..ab43828
--- /dev/null
+++ b/test cases/common/225 link language/lib.cpp
@@ -0,0 +1,5 @@
+extern "C" {
+ int makeInt(void) {
+ return 1;
+ }
+}
diff --git a/test cases/common/225 link language/main.c b/test cases/common/225 link language/main.c
new file mode 100644
index 0000000..5a167e7
--- /dev/null
+++ b/test cases/common/225 link language/main.c
@@ -0,0 +1,5 @@
+#include "c_linkage.h"
+
+int main(void) {
+ return makeInt();
+}
diff --git a/test cases/common/225 link language/meson.build b/test cases/common/225 link language/meson.build
new file mode 100644
index 0000000..f9af6cd
--- /dev/null
+++ b/test cases/common/225 link language/meson.build
@@ -0,0 +1,18 @@
+project(
+ 'link_language',
+ ['c', 'cpp'],
+)
+
+exe = executable(
+ 'main',
+ ['main.c', 'c_linkage.cpp'],
+ link_language : 'c',
+)
+
+lib = library(
+ 'mylib',
+ ['lib.cpp'],
+ link_language : 'c',
+)
+
+test('main', exe)
diff --git a/test cases/common/226 link depends indexed custom target/check_arch.py b/test cases/common/226 link depends indexed custom target/check_arch.py
new file mode 100644
index 0000000..927bf87
--- /dev/null
+++ b/test cases/common/226 link depends indexed custom target/check_arch.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+
+import re
+import sys
+import shutil
+import subprocess
+
+exepath = sys.argv[1]
+want_arch = sys.argv[2]
+dummy_output = sys.argv[3]
+
+with open(dummy_output, 'w') as f:
+ f.write('')
+
+if not shutil.which('dumpbin'):
+ print('dumpbin not found, skipping')
+ sys.exit(0)
+
+out = subprocess.check_output(['dumpbin', '/HEADERS', exepath],
+ universal_newlines=True)
+for line in out.split('\n'):
+ m = re.match(r'.* machine \(([A-Za-z0-9]+)\)$', line)
+ if m:
+ arch = m.groups()[0].lower()
+
+if arch == 'arm64':
+ arch = 'aarch64'
+elif arch == 'x64':
+ arch = 'x86_64'
+
+if arch != want_arch:
+ raise RuntimeError(f'Wanted arch {want_arch} but exe uses {arch}')
diff --git a/test cases/common/226 link depends indexed custom target/foo.c b/test cases/common/226 link depends indexed custom target/foo.c
new file mode 100644
index 0000000..58c86a6
--- /dev/null
+++ b/test cases/common/226 link depends indexed custom target/foo.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main(void) {
+ const char *fn = DEPFILE;
+ FILE *f = fopen(fn, "r");
+ if (!f) {
+ printf("could not open %s", fn);
+ return 1;
+ }
+ else {
+ printf("successfully opened %s", fn);
+ }
+
+ return 0;
+}
diff --git a/test cases/common/226 link depends indexed custom target/make_file.py b/test cases/common/226 link depends indexed custom target/make_file.py
new file mode 100644
index 0000000..6a43b7d
--- /dev/null
+++ b/test cases/common/226 link depends indexed custom target/make_file.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ print('# this file does nothing', file=f)
+
+with open(sys.argv[2], 'w') as f:
+ print('# this file does nothing', file=f)
diff --git a/test cases/common/226 link depends indexed custom target/meson.build b/test cases/common/226 link depends indexed custom target/meson.build
new file mode 100644
index 0000000..27f3a3f
--- /dev/null
+++ b/test cases/common/226 link depends indexed custom target/meson.build
@@ -0,0 +1,20 @@
+project('link_depends_indexed_custom_target', 'c')
+
+cmd = find_program('make_file.py')
+
+dep_files = custom_target('gen_dep',
+ command: [cmd, '@OUTPUT@'],
+ output: ['dep_file1', 'dep_file2'])
+
+exe = executable('foo', 'foo.c',
+ link_depends: dep_files[1],
+ c_args: ['-DDEPFILE="' + dep_files[0].full_path()+ '"'])
+
+check_arch = find_program('check_arch.py')
+custom_target('check-arch',
+ command: [check_arch, exe, host_machine.cpu_family(), '@OUTPUT@'],
+ build_by_default: true,
+ output: 'dummy.txt')
+
+# check that dep_file1 exists, which means that link_depends target ran
+test('runtest', exe)
diff --git a/test cases/common/227 very long commmand line/codegen.py b/test cases/common/227 very long commmand line/codegen.py
new file mode 100755
index 0000000..b1de607
--- /dev/null
+++ b/test cases/common/227 very long commmand line/codegen.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys
+from pathlib import Path
+
+Path(sys.argv[2]).write_text(
+ 'int func{n}(void) {{ return {n}; }}'.format(n=sys.argv[1]))
diff --git a/test cases/common/227 very long commmand line/main.c b/test cases/common/227 very long commmand line/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/227 very long commmand line/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/227 very long commmand line/meson.build b/test cases/common/227 very long commmand line/meson.build
new file mode 100644
index 0000000..f8df311
--- /dev/null
+++ b/test cases/common/227 very long commmand line/meson.build
@@ -0,0 +1,49 @@
+project('very long command lines', 'c')
+
+# Get the current system's commandline length limit.
+if build_machine.system() == 'windows'
+ # Various limits on windows:
+ # cmd.exe: 8kb
+ # CreateProcess: 32kb
+ limit = 32767
+ # NOTE: filename limit is 260 characters unless
+ # 1. Python >= 3.6 is being used
+ # 2. Windows 10 registry has been edited to enable long pathnaems
+ # ninja backend uses absolute filenames, so we ensure they don't exceed 260.
+elif build_machine.system() == 'cygwin'
+ # cygwin-to-win32: see above
+ # cygwin-to-cygwin: no limit?
+ # Cygwin is slow, so only test it lightly here.
+ limit = 8192
+else
+ # ninja passes whole line as a single argument, for which
+ # the limit is 128k as of Linux 2.6.23. See MAX_ARG_STRLEN.
+ # BSD seems similar, see https://www.in-ulm.de/~mascheck/various/argmax
+ limit = 131072
+endif
+# Now exceed that limit, but not so far that the test takes too long.
+namelen = 260
+nfiles = 50 + limit / namelen
+message('Expected link commandline length is approximately ' + '@0@'.format((nfiles * (namelen+28))))
+
+seq = run_command('name_gen.py', nfiles.to_string(), meson.build_root(), check: true).stdout().strip().split('\n')
+
+sources = []
+codegen = find_program('codegen.py')
+
+i=0
+foreach name : seq
+ sources += custom_target('codegen' + i.to_string(),
+ command: [codegen, i.to_string(), '@OUTPUT@'],
+ output: name + '.c')
+ i+=1
+endforeach
+
+shared_library('sharedlib', sources)
+static_library('staticlib', sources)
+executable('app', 'main.c', sources)
+
+# Also test short commandlines to make sure that doesn't regress
+shared_library('sharedlib0', sources[0])
+static_library('staticlib0', sources[0])
+executable('app0', 'main.c', sources[0])
diff --git a/test cases/common/227 very long commmand line/name_gen.py b/test cases/common/227 very long commmand line/name_gen.py
new file mode 100755
index 0000000..8435298
--- /dev/null
+++ b/test cases/common/227 very long commmand line/name_gen.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+"""
+generate sequence of filename that does not exceed MAX_LEN=260
+for Python < 3.6 and Windows without modified registry
+"""
+
+import sys
+import string
+
+name_len = 260 - len(sys.argv[2]) - 4 - 39 - 4 - 2
+if name_len < 1:
+ raise ValueError('The meson build directory pathname is so long '
+ 'that we cannot generate filenames within 260 characters.')
+# leave room for suffix and file separators, and meson generated text
+# e.g. ".c.obj.d" and other decorators added by Meson at configuration
+# for intermediate files
+
+base = string.ascii_letters * 5 # 260 characters
+max_num_len = len(str(sys.argv[1]))
+base = base[: name_len - max_num_len]
+
+for i in range(int(sys.argv[1])):
+ print("{base}{i:0{max_num_len}d}".format(base=base, max_num_len=max_num_len, i=i))
diff --git a/test cases/common/228 custom_target source/a b/test cases/common/228 custom_target source/a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/228 custom_target source/a
diff --git a/test cases/common/228 custom_target source/meson.build b/test cases/common/228 custom_target source/meson.build
new file mode 100644
index 0000000..98b9d26
--- /dev/null
+++ b/test cases/common/228 custom_target source/meson.build
@@ -0,0 +1,5 @@
+project('a', ['c'])
+
+x = find_program('x.py')
+outs = custom_target('foo', output: ['x.c', 'y'], input: 'a', command: [x])
+executable('testprog', outs[0])
diff --git a/test cases/common/228 custom_target source/x.py b/test cases/common/228 custom_target source/x.py
new file mode 100644
index 0000000..12f40c8
--- /dev/null
+++ b/test cases/common/228 custom_target source/x.py
@@ -0,0 +1,5 @@
+#! /usr/bin/env python3
+with open('x.c', 'w') as f:
+ print('int main(void) { return 0; }', file=f)
+with open('y', 'w'):
+ pass
diff --git a/test cases/common/229 disabler array addition/meson.build b/test cases/common/229 disabler array addition/meson.build
new file mode 100644
index 0000000..231f76a
--- /dev/null
+++ b/test cases/common/229 disabler array addition/meson.build
@@ -0,0 +1,9 @@
+project('disabler_inside_array', 'c')
+
+exes = []
+
+exes += library('a', 'test.c')
+
+exes += library('b', 'test.c', dependencies : disabler())
+
+exes += library('c', 'test.c')
diff --git a/test cases/common/229 disabler array addition/test.c b/test cases/common/229 disabler array addition/test.c
new file mode 100644
index 0000000..e9a7aac
--- /dev/null
+++ b/test cases/common/229 disabler array addition/test.c
@@ -0,0 +1 @@
+int stub(void) { return 0; }
diff --git a/test cases/common/23 endian/meson.build b/test cases/common/23 endian/meson.build
new file mode 100644
index 0000000..80186fe
--- /dev/null
+++ b/test cases/common/23 endian/meson.build
@@ -0,0 +1,7 @@
+project('endian check', 'c')
+
+if host_machine.endian() == 'big'
+ add_global_arguments('-DIS_BE', language : 'c')
+endif
+
+test('endiantest', executable('prog', 'prog.c'))
diff --git a/test cases/common/23 endian/prog.c b/test cases/common/23 endian/prog.c
new file mode 100644
index 0000000..90bd958
--- /dev/null
+++ b/test cases/common/23 endian/prog.c
@@ -0,0 +1,24 @@
+#include<stdint.h>
+
+int is_big_endian(void) {
+ uint32_t one = 1;
+ if(*((uint8_t*) &one) == 1)
+ return 0;
+ return 1;
+}
+
+
+int main(void) {
+ int is_be_check = is_big_endian();
+ int is_be;
+#ifdef IS_BE
+ is_be = 1;
+#else
+ is_be = 0;
+#endif
+ if(is_be_check && is_be)
+ return 0;
+ if(!is_be_check && !is_be)
+ return 0;
+ return 1;
+}
diff --git a/test cases/common/230 external project/app.c b/test cases/common/230 external project/app.c
new file mode 100644
index 0000000..a8266e7
--- /dev/null
+++ b/test cases/common/230 external project/app.c
@@ -0,0 +1,6 @@
+#include <libfoo.h>
+
+int main(void)
+{
+ return call_foo() == 42 ? 0 : 1;
+}
diff --git a/test cases/common/230 external project/func.c b/test cases/common/230 external project/func.c
new file mode 100644
index 0000000..31393fd
--- /dev/null
+++ b/test cases/common/230 external project/func.c
@@ -0,0 +1,6 @@
+#include "func.h"
+
+int func(void)
+{
+ return 1;
+}
diff --git a/test cases/common/230 external project/func.h b/test cases/common/230 external project/func.h
new file mode 100644
index 0000000..340b82a
--- /dev/null
+++ b/test cases/common/230 external project/func.h
@@ -0,0 +1 @@
+int func(void);
diff --git a/test cases/common/230 external project/libfoo/configure b/test cases/common/230 external project/libfoo/configure
new file mode 100755
index 0000000..0e4aa72
--- /dev/null
+++ b/test cases/common/230 external project/libfoo/configure
@@ -0,0 +1,44 @@
+#! /bin/sh
+
+srcdir=$(dirname "$0")
+
+for i in "$@"
+do
+case $i in
+ --prefix=*)
+ PREFIX="${i#*=}"
+ shift
+ ;;
+ --libdir=*)
+ LIBDIR="${i#*=}"
+ shift
+ ;;
+ --includedir=*)
+ INCDIR="${i#*=}"
+ shift
+ ;;
+ --libext=*)
+ LIBEXT="${i#*=}"
+ shift
+ ;;
+ *)
+ shift
+ ;;
+esac
+done
+
+DEP_ARGS=$(pkg-config --cflags --libs somelib)
+
+cat > Makefile << EOL
+all: libfoo.$LIBEXT
+
+libfoo.$LIBEXT:
+ $CC "$srcdir/libfoo.c" -shared -fPIC $DEP_ARGS -o \$@
+
+install: libfoo.$LIBEXT
+ mkdir -p "\$(DESTDIR)$LIBDIR";
+ mkdir -p "\$(DESTDIR)$LIBDIR/pkgconfig";
+ mkdir -p "\$(DESTDIR)$INCDIR";
+ cp \$< "\$(DESTDIR)$LIBDIR";
+ cp "$srcdir/libfoo.h" "\$(DESTDIR)$INCDIR";
+EOL
diff --git a/test cases/common/230 external project/libfoo/libfoo.c b/test cases/common/230 external project/libfoo/libfoo.c
new file mode 100644
index 0000000..3f62282
--- /dev/null
+++ b/test cases/common/230 external project/libfoo/libfoo.c
@@ -0,0 +1,8 @@
+#include "libfoo.h"
+
+int func(void);
+
+int call_foo()
+{
+ return func() == 1 ? 42 : 0;
+}
diff --git a/test cases/common/230 external project/libfoo/libfoo.h b/test cases/common/230 external project/libfoo/libfoo.h
new file mode 100644
index 0000000..8981f18
--- /dev/null
+++ b/test cases/common/230 external project/libfoo/libfoo.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int call_foo(void);
diff --git a/test cases/common/230 external project/libfoo/meson.build b/test cases/common/230 external project/libfoo/meson.build
new file mode 100644
index 0000000..a2512aa
--- /dev/null
+++ b/test cases/common/230 external project/libfoo/meson.build
@@ -0,0 +1,23 @@
+mod = import('unstable-external_project')
+
+target_system = target_machine.system()
+if target_system in ['windows', 'cygwin']
+ libext = 'dll'
+elif target_system == 'darwin'
+ libext = 'dylib'
+else
+ libext = 'so'
+endif
+
+p = mod.add_project('configure',
+ configure_options : [
+ '--prefix=@PREFIX@',
+ '--libdir=@PREFIX@/@LIBDIR@',
+ '--includedir=@PREFIX@/@INCLUDEDIR@',
+ '--libext=' + libext,
+ ],
+ depends: somelib,
+)
+
+libfoo_dep = declare_dependency(link_with : somelib,
+ dependencies : p.dependency('foo'))
diff --git a/test cases/common/230 external project/meson.build b/test cases/common/230 external project/meson.build
new file mode 100644
index 0000000..d1ed797
--- /dev/null
+++ b/test cases/common/230 external project/meson.build
@@ -0,0 +1,27 @@
+project('test external project', 'c')
+
+if not find_program('pkg-config', required: false).found()
+ error('MESON_SKIP_TEST: pkg-config not found')
+endif
+
+if not find_program('make', required : false).found()
+ error('MESON_SKIP_TEST: make not found')
+endif
+
+if host_machine.system() == 'windows'
+ error('MESON_SKIP_TEST: The fake configure script is too dumb to work on Windows')
+endif
+
+if meson.is_cross_build()
+ # CI uses PKG_CONFIG_SYSROOT_DIR which breaks -uninstalled.pc usage.
+ error('MESON_SKIP_TEST: Cross build support is too limited for this test')
+endif
+
+pkg = import('pkgconfig')
+
+somelib = library('somelib', 'func.c')
+pkg.generate(somelib)
+
+subdir('libfoo')
+
+executable('test-find-library', 'app.c', dependencies : libfoo_dep)
diff --git a/test cases/common/230 external project/test.json b/test cases/common/230 external project/test.json
new file mode 100644
index 0000000..4888e87
--- /dev/null
+++ b/test cases/common/230 external project/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ { "type": "shared_lib", "file": "usr/lib/foo" },
+ { "type": "file", "file": "usr/include/libfoo.h" },
+ { "type": "file", "file": "usr/lib/pkgconfig/somelib.pc" }
+ ]
+}
diff --git a/test cases/common/231 subdir files/meson.build b/test cases/common/231 subdir files/meson.build
new file mode 100644
index 0000000..eb472f3
--- /dev/null
+++ b/test cases/common/231 subdir files/meson.build
@@ -0,0 +1,3 @@
+project('subdir files test', 'c')
+subdir('subdir')
+executable('prog', sources: subdir_sources)
diff --git a/test cases/common/231 subdir files/subdir/meson.build b/test cases/common/231 subdir files/subdir/meson.build
new file mode 100644
index 0000000..70909c7
--- /dev/null
+++ b/test cases/common/231 subdir files/subdir/meson.build
@@ -0,0 +1 @@
+subdir_sources = files(['prog.c'])
diff --git a/test cases/common/231 subdir files/subdir/prog.c b/test cases/common/231 subdir files/subdir/prog.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/231 subdir files/subdir/prog.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/232 dependency allow_fallback/meson.build b/test cases/common/232 dependency allow_fallback/meson.build
new file mode 100644
index 0000000..32d225f
--- /dev/null
+++ b/test cases/common/232 dependency allow_fallback/meson.build
@@ -0,0 +1,12 @@
+project('subproject fallback')
+
+foob_dep = dependency('foob', allow_fallback: true, required: false)
+assert(foob_dep.found())
+
+# Careful! Once a submodule has been triggered and it has
+# overridden the dependency, it sticks.
+foob_dep = dependency('foob', allow_fallback: false, required: false)
+assert(foob_dep.found())
+
+foob3_dep = dependency('foob3', allow_fallback: false, required: false)
+assert(not foob3_dep.found())
diff --git a/test cases/common/232 dependency allow_fallback/subprojects/foob/meson.build b/test cases/common/232 dependency allow_fallback/subprojects/foob/meson.build
new file mode 100644
index 0000000..b2c4814
--- /dev/null
+++ b/test cases/common/232 dependency allow_fallback/subprojects/foob/meson.build
@@ -0,0 +1,2 @@
+project('foob', 'c')
+meson.override_dependency('foob', declare_dependency())
diff --git a/test cases/common/232 dependency allow_fallback/subprojects/foob3/meson.build b/test cases/common/232 dependency allow_fallback/subprojects/foob3/meson.build
new file mode 100644
index 0000000..9fdb188
--- /dev/null
+++ b/test cases/common/232 dependency allow_fallback/subprojects/foob3/meson.build
@@ -0,0 +1,2 @@
+project('foob3', 'c')
+# Note that there is no override_dependency here
diff --git a/test cases/common/233 wrap case/meson.build b/test cases/common/233 wrap case/meson.build
new file mode 100644
index 0000000..2b82bf3
--- /dev/null
+++ b/test cases/common/233 wrap case/meson.build
@@ -0,0 +1,6 @@
+project('CaSe DePenDenCy In Wrap', 'c')
+
+d = dependency('UP_down')
+
+e = executable('prog', 'prog.c', dependencies: d)
+test('prog', e)
diff --git a/test cases/common/233 wrap case/prog.c b/test cases/common/233 wrap case/prog.c
new file mode 100644
index 0000000..5183dea
--- /dev/null
+++ b/test cases/common/233 wrap case/prog.c
@@ -0,0 +1,13 @@
+#include<up_down.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ if(argc == 42) {
+ printf("Very sneaky, %s\n", argv[0]);
+ }
+#ifdef UP_IS_DOWN
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/test cases/common/233 wrap case/subprojects/up_down.wrap b/test cases/common/233 wrap case/subprojects/up_down.wrap
new file mode 100644
index 0000000..d66818f
--- /dev/null
+++ b/test cases/common/233 wrap case/subprojects/up_down.wrap
@@ -0,0 +1,5 @@
+[wrap-file]
+directory = up_down
+
+[provide]
+UP_down = up_down_dep
diff --git a/test cases/common/233 wrap case/subprojects/up_down/meson.build b/test cases/common/233 wrap case/subprojects/up_down/meson.build
new file mode 100644
index 0000000..5db89d1
--- /dev/null
+++ b/test cases/common/233 wrap case/subprojects/up_down/meson.build
@@ -0,0 +1,3 @@
+project('up down', 'c')
+
+up_down_dep = declare_dependency(include_directories: '.')
diff --git a/test cases/common/233 wrap case/subprojects/up_down/up_down.h b/test cases/common/233 wrap case/subprojects/up_down/up_down.h
new file mode 100644
index 0000000..8d968ce
--- /dev/null
+++ b/test cases/common/233 wrap case/subprojects/up_down/up_down.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define UP_IS_DOWN
diff --git a/test cases/common/234 get_file_contents/.gitattributes b/test cases/common/234 get_file_contents/.gitattributes
new file mode 100644
index 0000000..abec47d
--- /dev/null
+++ b/test cases/common/234 get_file_contents/.gitattributes
@@ -0,0 +1 @@
+utf-16-text binary
diff --git a/test cases/common/234 get_file_contents/VERSION b/test cases/common/234 get_file_contents/VERSION
new file mode 100644
index 0000000..26aaba0
--- /dev/null
+++ b/test cases/common/234 get_file_contents/VERSION
@@ -0,0 +1 @@
+1.2.0
diff --git a/test cases/common/234 get_file_contents/meson.build b/test cases/common/234 get_file_contents/meson.build
new file mode 100644
index 0000000..a8c68d6
--- /dev/null
+++ b/test cases/common/234 get_file_contents/meson.build
@@ -0,0 +1,21 @@
+project(
+ 'meson-fs-read-file',
+ [],
+ version: files('VERSION')
+)
+fs = import('fs')
+
+assert(fs.read('VERSION').strip() == meson.project_version(), 'file misread')
+
+expected = (
+ '∮ Eâ‹…da = Q, n → ∞, ∑ f(i) = ∠g(i), ∀x∈â„: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β)'
+)
+assert(
+ fs.read('utf-16-text', encoding: 'utf-16').strip() == expected,
+ 'file was not decoded correctly'
+)
+
+# Make sure we handle `files()` objects properly, too
+version_file = files('VERSION')
+
+subdir('other')
diff --git a/test cases/common/234 get_file_contents/other/meson.build b/test cases/common/234 get_file_contents/other/meson.build
new file mode 100644
index 0000000..9a7e4be
--- /dev/null
+++ b/test cases/common/234 get_file_contents/other/meson.build
@@ -0,0 +1,3 @@
+fs = import('fs')
+assert(fs.read(version_file).strip() == '1.2.0')
+assert(fs.read('../VERSION').strip() == '1.2.0')
diff --git a/test cases/common/234 get_file_contents/utf-16-text b/test cases/common/234 get_file_contents/utf-16-text
new file mode 100644
index 0000000..ed1fefe
--- /dev/null
+++ b/test cases/common/234 get_file_contents/utf-16-text
Binary files differ
diff --git a/test cases/common/235 invalid standard overriden to valid/main.c b/test cases/common/235 invalid standard overriden to valid/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/common/235 invalid standard overriden to valid/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/235 invalid standard overriden to valid/meson.build b/test cases/common/235 invalid standard overriden to valid/meson.build
new file mode 100644
index 0000000..6dc3201
--- /dev/null
+++ b/test cases/common/235 invalid standard overriden to valid/meson.build
@@ -0,0 +1,8 @@
+project(
+ 'invalid C standard overridden to valid one',
+ 'c',
+ default_options : ['c_std=invalid99'],
+)
+
+exe = executable('main', 'main.c')
+test('main', exe)
diff --git a/test cases/common/235 invalid standard overriden to valid/test.json b/test cases/common/235 invalid standard overriden to valid/test.json
new file mode 100644
index 0000000..c9b00ce
--- /dev/null
+++ b/test cases/common/235 invalid standard overriden to valid/test.json
@@ -0,0 +1,9 @@
+{
+ "matrix": {
+ "options": {
+ "c_std": [
+ { "val": "c89" }
+ ]
+ }
+ }
+}
diff --git a/test cases/common/236 proper args splitting/main.c b/test cases/common/236 proper args splitting/main.c
new file mode 100644
index 0000000..4b2038f
--- /dev/null
+++ b/test cases/common/236 proper args splitting/main.c
@@ -0,0 +1,11 @@
+#ifndef FOO
+# error "FOO is not defined"
+#endif
+
+#ifndef BAR
+# error "BAR is not defined"
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/236 proper args splitting/meson.build b/test cases/common/236 proper args splitting/meson.build
new file mode 100644
index 0000000..4a36f9c
--- /dev/null
+++ b/test cases/common/236 proper args splitting/meson.build
@@ -0,0 +1,9 @@
+project('proper args splitting', 'c')
+
+test(
+ 'main',
+ executable(
+ 'main',
+ 'main.c',
+ )
+)
diff --git a/test cases/common/236 proper args splitting/test.json b/test cases/common/236 proper args splitting/test.json
new file mode 100644
index 0000000..b1738aa
--- /dev/null
+++ b/test cases/common/236 proper args splitting/test.json
@@ -0,0 +1,9 @@
+{
+ "matrix": {
+ "options": {
+ "c_args": [
+ { "val": "-DFOO -DBAR" }
+ ]
+ }
+ }
+}
diff --git a/test cases/common/237 fstrings/meson.build b/test cases/common/237 fstrings/meson.build
new file mode 100644
index 0000000..d686f6b
--- /dev/null
+++ b/test cases/common/237 fstrings/meson.build
@@ -0,0 +1,7 @@
+project('meson-test')
+
+n = 10
+m = 'bar'
+s = f'test @n@ string (@@n@@): @m@'
+
+assert(s == 'test 10 string (@10@): bar', 'Incorrect string formatting')
diff --git a/test cases/common/238 dependency include_type inconsistency/bar/meson.build b/test cases/common/238 dependency include_type inconsistency/bar/meson.build
new file mode 100644
index 0000000..6e1218b
--- /dev/null
+++ b/test cases/common/238 dependency include_type inconsistency/bar/meson.build
@@ -0,0 +1,5 @@
+baz_dep = dependency('baz',
+ fallback: ['baz', 'baz_dep'],
+ include_type: 'system',
+ method: 'pkg-config', # if we comment this out or change to 'auto' the build is successful
+ required: false)
diff --git a/test cases/common/238 dependency include_type inconsistency/meson.build b/test cases/common/238 dependency include_type inconsistency/meson.build
new file mode 100644
index 0000000..69b5d19
--- /dev/null
+++ b/test cases/common/238 dependency include_type inconsistency/meson.build
@@ -0,0 +1,5 @@
+project('test')
+
+foo_dep = subproject('foo').get_variable('foo_dep')
+
+subdir('bar')
diff --git a/test cases/common/238 dependency include_type inconsistency/subprojects/baz.wrap b/test cases/common/238 dependency include_type inconsistency/subprojects/baz.wrap
new file mode 100644
index 0000000..c727794
--- /dev/null
+++ b/test cases/common/238 dependency include_type inconsistency/subprojects/baz.wrap
@@ -0,0 +1,3 @@
+[wrap-file]
+source_url = http://host.invalid/baz.tar.gz
+source_filename = baz.tar.gz
diff --git a/test cases/common/238 dependency include_type inconsistency/subprojects/baz/meson.build b/test cases/common/238 dependency include_type inconsistency/subprojects/baz/meson.build
new file mode 100644
index 0000000..4f454e6
--- /dev/null
+++ b/test cases/common/238 dependency include_type inconsistency/subprojects/baz/meson.build
@@ -0,0 +1,3 @@
+project('baz')
+
+baz_dep = declare_dependency()
diff --git a/test cases/common/238 dependency include_type inconsistency/subprojects/foo.wrap b/test cases/common/238 dependency include_type inconsistency/subprojects/foo.wrap
new file mode 100644
index 0000000..dcc434b
--- /dev/null
+++ b/test cases/common/238 dependency include_type inconsistency/subprojects/foo.wrap
@@ -0,0 +1,3 @@
+[wrap-file]
+source_url = http://host.invalid/foo.tar.gz
+source_filename = foo.tar.gz
diff --git a/test cases/common/238 dependency include_type inconsistency/subprojects/foo/meson.build b/test cases/common/238 dependency include_type inconsistency/subprojects/foo/meson.build
new file mode 100644
index 0000000..1ed7011
--- /dev/null
+++ b/test cases/common/238 dependency include_type inconsistency/subprojects/foo/meson.build
@@ -0,0 +1,9 @@
+project('foo')
+
+baz_dep = dependency('baz',
+ fallback: ['baz', 'baz_dep'],
+ include_type: 'system',
+ method: 'pkg-config',
+ required: false)
+
+foo_dep = declare_dependency(dependencies: baz_dep)
diff --git a/test cases/common/239 includedir violation/meson.build b/test cases/common/239 includedir violation/meson.build
new file mode 100644
index 0000000..b84fdf2
--- /dev/null
+++ b/test cases/common/239 includedir violation/meson.build
@@ -0,0 +1,11 @@
+project('foo')
+
+# It is fine to include the root source dir
+include_directories('.')
+subproject('sub')
+
+# This is here rather than in failing because this needs a
+# transition period to avoid breaking existing projects.
+# Once this becomes an error, move this under failing tests.
+
+inc = include_directories('subprojects/sub/include')
diff --git a/test cases/common/239 includedir violation/subprojects/sub/include/placeholder.h b/test cases/common/239 includedir violation/subprojects/sub/include/placeholder.h
new file mode 100644
index 0000000..196f917
--- /dev/null
+++ b/test cases/common/239 includedir violation/subprojects/sub/include/placeholder.h
@@ -0,0 +1,3 @@
+#pragma once
+
+// Git can not handle empty directories, so there must be something here.
diff --git a/test cases/common/239 includedir violation/subprojects/sub/meson.build b/test cases/common/239 includedir violation/subprojects/sub/meson.build
new file mode 100644
index 0000000..06f45d6
--- /dev/null
+++ b/test cases/common/239 includedir violation/subprojects/sub/meson.build
@@ -0,0 +1,3 @@
+project('subproj')
+
+include_directories('.')
diff --git a/test cases/common/239 includedir violation/test.json b/test cases/common/239 includedir violation/test.json
new file mode 100644
index 0000000..fea19a1
--- /dev/null
+++ b/test cases/common/239 includedir violation/test.json
@@ -0,0 +1,9 @@
+{
+ "stdout": [
+ {
+ "line": ".*WARNING: include_directories sandbox violation!",
+ "match": "re",
+ "count": 1
+ }
+ ]
+}
diff --git a/test cases/common/24 library versions/lib.c b/test cases/common/24 library versions/lib.c
new file mode 100644
index 0000000..e49cb2d
--- /dev/null
+++ b/test cases/common/24 library versions/lib.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC myFunc(void) {
+ return 55;
+}
diff --git a/test cases/common/24 library versions/meson.build b/test cases/common/24 library versions/meson.build
new file mode 100644
index 0000000..2e2bef7
--- /dev/null
+++ b/test cases/common/24 library versions/meson.build
@@ -0,0 +1,9 @@
+project('library versions', 'c')
+
+shared_library('somelib', 'lib.c',
+ name_prefix : 'prefix',
+ name_suffix : 'suffix',
+ install_dir : 'lib',
+ install : true)
+
+subdir('subdir')
diff --git a/test cases/common/24 library versions/subdir/meson.build b/test cases/common/24 library versions/subdir/meson.build
new file mode 100644
index 0000000..a83fdb5
--- /dev/null
+++ b/test cases/common/24 library versions/subdir/meson.build
@@ -0,0 +1,8 @@
+# Test that using files generated with configure_file as sources works.
+# We do this inside a subdir so that the path isn't accidentally correct
+# because there is no structure in the build dir.
+genlib = configure_file(input : '../lib.c',
+ output : 'genlib.c',
+ copy: true)
+shared_library('genlib', genlib,
+ install : false)
diff --git a/test cases/common/24 library versions/test.json b/test cases/common/24 library versions/test.json
new file mode 100644
index 0000000..64b7ab0
--- /dev/null
+++ b/test cases/common/24 library versions/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/prefixsomelib.suffix"},
+ {"type": "implib", "file": "usr/lib/prefixsomelib"},
+ {"type": "pdb", "file": "usr/lib/prefixsomelib"}
+ ]
+}
diff --git a/test cases/common/240 dependency native host == build/meson.build b/test cases/common/240 dependency native host == build/meson.build
new file mode 100644
index 0000000..347b1f6
--- /dev/null
+++ b/test cases/common/240 dependency native host == build/meson.build
@@ -0,0 +1,18 @@
+project('foo')
+
+if meson.is_cross_build()
+ error('MESON_SKIP_TEST Test does not make sense for cross builds')
+endif
+
+dep_zlib = dependency('zlib', required : false)
+if not dep_zlib.found()
+ error('MESON_SKIP_TEST Test requires zlib')
+endif
+dependency('zlib', native : true, required : false)
+dependency('zlib', native : false)
+
+# `native: true` should not make a difference when doing a native build.
+meson.override_dependency('expat', declare_dependency())
+dependency('expat')
+dependency('expat', native : true)
+dependency('expat', native : false)
diff --git a/test cases/common/240 dependency native host == build/test.json b/test cases/common/240 dependency native host == build/test.json
new file mode 100644
index 0000000..5e2a715
--- /dev/null
+++ b/test cases/common/240 dependency native host == build/test.json
@@ -0,0 +1,14 @@
+{
+ "stdout": [
+ {
+ "line": "Dependency zlib found: YES .* \\(cached\\)",
+ "match": "re",
+ "count": 2
+ },
+ {
+ "line": "Dependency expat found: YES .* \\(overridden\\)",
+ "match": "re",
+ "count": 3
+ }
+ ]
+}
diff --git a/test cases/common/241 set and get variable/meson.build b/test cases/common/241 set and get variable/meson.build
new file mode 100644
index 0000000..4ecdb35
--- /dev/null
+++ b/test cases/common/241 set and get variable/meson.build
@@ -0,0 +1,71 @@
+project('set and get')
+
+var1 = 'test1.txt'
+var2 = files('test1.txt')[0]
+
+# Use is_disabler for accessing variables
+assert(var1 == 'test1.txt')
+assert(not is_disabler(var2))
+
+# Ensure that set variables behave correctly
+set_variable('var3', 'test2.txt')
+set_variable('var4', files('test2.txt')[0])
+
+assert(var3 == 'test2.txt')
+assert(not is_disabler(var4))
+
+# Test Equality
+assert(var1 == get_variable('var1'))
+assert(var2 == get_variable('var2'))
+
+# Test get_variable directly
+assert(get_variable('var1') == 'test1.txt')
+assert(not is_disabler(get_variable('var2')))
+assert(get_variable('var3') == 'test2.txt')
+assert(not is_disabler(get_variable('var4')))
+
+# Test get_variable indirectly
+
+var5 = get_variable('var1')
+var6 = get_variable('var2')
+var7 = get_variable('var3')
+var8 = get_variable('var4')
+set_variable('var9', get_variable('var7'))
+set_variable('var0', get_variable('var8'))
+
+assert(var5 == 'test1.txt')
+assert(not is_disabler(var6))
+assert(var7 == 'test2.txt')
+assert(not is_disabler(var8))
+assert(get_variable('var9') == 'test2.txt')
+assert(not is_disabler(get_variable('var0')))
+assert(not is_disabler(get_variable('var0', var8)))
+assert(not is_disabler(get_variable('----', var8)))
+assert(not is_disabler(get_variable('----', [var8])))
+assert(not is_disabler(get_variable('----', {'asd': var8})))
+
+# test dict get
+dict = {'a': var2}
+
+dict_t1 = dict['a']
+dict_t2 = dict.get('a')
+dict_t3 = dict.get('a', var2)
+dict_t4 = dict.get('b', var2)
+
+assert(not is_disabler(dict_t1))
+assert(not is_disabler(dict_t2))
+assert(not is_disabler(dict_t3))
+assert(not is_disabler(dict_t4))
+
+# test lists
+list = [var2]
+
+list_t1 = list[0]
+list_t2 = list.get(0)
+list_t3 = list.get(0, var2)
+list_t4 = list.get(1, var2)
+
+assert(not is_disabler(list_t1))
+assert(not is_disabler(list_t2))
+assert(not is_disabler(list_t3))
+assert(not is_disabler(list_t4))
diff --git a/test cases/common/241 set and get variable/test1.txt b/test cases/common/241 set and get variable/test1.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/241 set and get variable/test1.txt
diff --git a/test cases/common/241 set and get variable/test2.txt b/test cases/common/241 set and get variable/test2.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/241 set and get variable/test2.txt
diff --git a/test cases/common/242 custom target feed/data_source.txt b/test cases/common/242 custom target feed/data_source.txt
new file mode 100644
index 0000000..0c23cc0
--- /dev/null
+++ b/test cases/common/242 custom target feed/data_source.txt
@@ -0,0 +1 @@
+This is a text only input file.
diff --git a/test cases/common/242 custom target feed/meson.build b/test cases/common/242 custom target feed/meson.build
new file mode 100644
index 0000000..73351ae
--- /dev/null
+++ b/test cases/common/242 custom target feed/meson.build
@@ -0,0 +1,24 @@
+project('custom target feed')
+
+python3 = import('python3').find_python()
+
+# Note that this will not add a dependency to the compiler executable.
+# Code will not be rebuilt if it changes.
+comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
+
+mytarget = custom_target('bindat',
+ output : 'data.dat',
+ input : 'data_source.txt',
+ feed : true,
+ command : [python3, comp, '@OUTPUT@'],
+ install : true,
+ install_dir : 'subdir'
+)
+
+ct_output_exists = '''import os, sys
+if not os.path.exists(sys.argv[1]):
+ print("could not find {!r} in {!r}".format(sys.argv[1], os.getcwd()))
+ sys.exit(1)
+'''
+
+test('capture-wrote', python3, args : ['-c', ct_output_exists, mytarget])
diff --git a/test cases/common/242 custom target feed/my_compiler.py b/test cases/common/242 custom target feed/my_compiler.py
new file mode 100755
index 0000000..97d4208
--- /dev/null
+++ b/test cases/common/242 custom target feed/my_compiler.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import sys
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print(sys.argv[0], 'output_file')
+ sys.exit(1)
+ ifile = sys.stdin.read()
+ if ifile != 'This is a text only input file.\n':
+ print('Malformed input')
+ sys.exit(1)
+ with open(sys.argv[1], 'w+') as f:
+ f.write('This is a binary output file.')
diff --git a/test cases/common/242 custom target feed/test.json b/test cases/common/242 custom target feed/test.json
new file mode 100644
index 0000000..ba66b02
--- /dev/null
+++ b/test cases/common/242 custom target feed/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/subdir/data.dat"}
+ ]
+}
diff --git a/test cases/common/243 escape++/meson.build b/test cases/common/243 escape++/meson.build
new file mode 100644
index 0000000..5fcc00f
--- /dev/null
+++ b/test cases/common/243 escape++/meson.build
@@ -0,0 +1,4 @@
+project('regex escape test', 'c')
+
+exe = executable('testprog', 'test.c')
+test('runtest', exe)
diff --git a/test cases/common/243 escape++/test.c b/test cases/common/243 escape++/test.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/common/243 escape++/test.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/244 variable scope/meson.build b/test cases/common/244 variable scope/meson.build
new file mode 100644
index 0000000..e5e7973
--- /dev/null
+++ b/test cases/common/244 variable scope/meson.build
@@ -0,0 +1,15 @@
+project('variable scope')
+
+x = 1
+
+assert(is_variable('x'))
+
+assert(get_variable('x') == 1)
+
+set_variable('x', 10)
+
+assert(get_variable('x') == 10)
+
+unset_variable('x')
+
+assert(not is_variable('x'))
diff --git a/test cases/common/245 custom target index source/code_source.c b/test cases/common/245 custom target index source/code_source.c
new file mode 100644
index 0000000..484955b
--- /dev/null
+++ b/test cases/common/245 custom target index source/code_source.c
@@ -0,0 +1,6 @@
+extern int genfunc(void);
+
+int genfunc(void)
+{
+ return 0;
+}
diff --git a/test cases/common/245 custom target index source/copyfile.py b/test cases/common/245 custom target index source/copyfile.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/common/245 custom target index source/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/245 custom target index source/copyfile2.py b/test cases/common/245 custom target index source/copyfile2.py
new file mode 100644
index 0000000..efbfc28
--- /dev/null
+++ b/test cases/common/245 custom target index source/copyfile2.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
+shutil.copyfile(sys.argv[3], sys.argv[4])
diff --git a/test cases/common/245 custom target index source/header_source.h b/test cases/common/245 custom target index source/header_source.h
new file mode 100644
index 0000000..e06c9de
--- /dev/null
+++ b/test cases/common/245 custom target index source/header_source.h
@@ -0,0 +1 @@
+extern int genfunc(void);
diff --git a/test cases/common/245 custom target index source/main.c b/test cases/common/245 custom target index source/main.c
new file mode 100644
index 0000000..48af141
--- /dev/null
+++ b/test cases/common/245 custom target index source/main.c
@@ -0,0 +1,8 @@
+#include <assert.h>
+#include "gen.h"
+
+int main(int argc)
+{
+ assert(argc == 3);
+ return genfunc();
+}
diff --git a/test cases/common/245 custom target index source/meson.build b/test cases/common/245 custom target index source/meson.build
new file mode 100644
index 0000000..c8087dd
--- /dev/null
+++ b/test cases/common/245 custom target index source/meson.build
@@ -0,0 +1,51 @@
+project('custom target index source', 'c')
+
+# Test that using a custom target index as a sourcefile works correctly
+
+copy1 = find_program('copyfile.py')
+copy2 = find_program('copyfile2.py')
+
+step_1 = custom_target('step_1',
+ input: ['code_source.c', files('header_source.h')],
+ output: ['step_1.c', 'step_1.h'],
+ command: [copy2, '@INPUT0@', '@OUTPUT0@', '@INPUT1@', '@OUTPUT1@'],
+ build_by_default: false)
+
+# test custom target with a single CustomTargetIndex input
+step_2_c = custom_target('step_2_c',
+ input: step_1[0],
+ output: 'step_2.c',
+ command: [copy1, '@INPUT0@', '@OUTPUT0@'],
+ build_by_default: false)
+
+step_2_h = custom_target('step_2_h',
+ input: step_1[1],
+ output: 'step_2.h',
+ command: [copy1, '@INPUT0@', '@OUTPUT0@'],
+ build_by_default: false,
+)
+
+# test custom target with multiple CustomTargetIndex inputs
+gen = custom_target('step_3',
+ input: [step_2_c, step_2_h],
+ output: ['gen.c', 'gen.h'],
+ command: [copy2, '@INPUT0@', '@OUTPUT0@', '@INPUT1@', '@OUTPUT1@'],
+ build_by_default: false)
+gen_c = gen[0]
+gen_h = gen[1]
+
+exe_separate = executable('exe_separate',
+ ['main.c', gen_c, gen_h],
+ build_by_default: false,
+ install: false,
+)
+
+exe_together = executable('exe_together',
+ ['main.c', gen],
+ build_by_default: false,
+ install: false,
+)
+
+# also cover passing custom target to tests as arguments
+test('exe_separate', exe_separate, args: [gen_c, gen_h])
+test('exe_together', exe_together, args: gen)
diff --git a/test cases/common/246 dependency fallbacks/meson.build b/test cases/common/246 dependency fallbacks/meson.build
new file mode 100644
index 0000000..b418088
--- /dev/null
+++ b/test cases/common/246 dependency fallbacks/meson.build
@@ -0,0 +1,10 @@
+project('dependency fallbacks')
+
+# pkg-config has 'libpng' but cmake has 'png' and we have a 'png' subproject
+# for platforms that have neither.
+d = dependency('libpng', 'png', 'foo')
+assert(d.found())
+
+# Check that dependency 'foo' has been implicitly overridden.
+d = dependency('foo')
+assert(d.found())
diff --git a/test cases/common/246 dependency fallbacks/subprojects/png/meson.build b/test cases/common/246 dependency fallbacks/subprojects/png/meson.build
new file mode 100644
index 0000000..5efc60a
--- /dev/null
+++ b/test cases/common/246 dependency fallbacks/subprojects/png/meson.build
@@ -0,0 +1,3 @@
+project('png')
+
+meson.override_dependency('libpng', declare_dependency())
diff --git a/test cases/common/247 deprecated option/meson.build b/test cases/common/247 deprecated option/meson.build
new file mode 100644
index 0000000..4c734ee
--- /dev/null
+++ b/test cases/common/247 deprecated option/meson.build
@@ -0,0 +1,20 @@
+project('deprecated options',
+ default_options: [
+ 'o1=false',
+ 'o2=a,b',
+ 'o3=a,b',
+ 'o4=true',
+ 'o5=auto',
+ 'o6=false',
+ 'o8=/foo',
+ ]
+)
+
+assert(get_option('o1') == false)
+assert(get_option('o2') == ['a', 'b'])
+assert(get_option('o3') == ['c', 'b'])
+assert(get_option('o4').enabled())
+assert(get_option('o5') == false)
+assert(get_option('o6') == false)
+assert(get_option('o7').disabled())
+assert(get_option('python.platlibdir') == '/foo')
diff --git a/test cases/common/247 deprecated option/meson_options.txt b/test cases/common/247 deprecated option/meson_options.txt
new file mode 100644
index 0000000..9665501
--- /dev/null
+++ b/test cases/common/247 deprecated option/meson_options.txt
@@ -0,0 +1,23 @@
+# Option fully deprecated, it warns when any value is set.
+option('o1', type: 'boolean', deprecated: true)
+
+# One of the choices is deprecated, it warns only when 'a' is in the list of values.
+option('o2', type: 'array', choices: ['a', 'b'], deprecated: ['a'])
+
+# One of the choices is deprecated, it warns only when 'a' is in the list of values
+# and replace it by 'c'.
+option('o3', type: 'array', choices: ['a', 'b', 'c'], deprecated: {'a': 'c'})
+
+# A boolean option has been replaced by a feature, old true/false values are remapped.
+option('o4', type: 'feature', deprecated: {'true': 'enabled', 'false': 'disabled'})
+
+# A feature option has been replaced by a boolean, enabled/disabled/auto values are remapped.
+option('o5', type: 'boolean', deprecated: {'enabled': 'true', 'disabled': 'false', 'auto': 'false'})
+
+# A boolean option has been replaced by a feature with another name, old true/false values
+# are accepted by the new option for backward compatibility.
+option('o6', type: 'boolean', value: 'true', deprecated: 'o7')
+option('o7', type: 'feature', value: 'enabled', deprecated: {'true': 'enabled', 'false': 'disabled'})
+
+# A project option is replaced by a module option
+option('o8', type: 'string', value: '', deprecated: 'python.platlibdir')
diff --git a/test cases/common/247 deprecated option/test.json b/test cases/common/247 deprecated option/test.json
new file mode 100644
index 0000000..c2f2ca3
--- /dev/null
+++ b/test cases/common/247 deprecated option/test.json
@@ -0,0 +1,29 @@
+{
+ "stdout": [
+ {
+ "line": ".*DEPRECATION: Option 'o1' is deprecated",
+ "match": "re",
+ "count": 1
+ },
+ {
+ "line": ".*DEPRECATION: Option 'o2' value 'a' is deprecated",
+ "match": "re",
+ "count": 1
+ },
+ {
+ "line": ".*DEPRECATION: Option 'o3' value 'a' is replaced by 'c'",
+ "match": "re",
+ "count": 1
+ },
+ {
+ "line": ".*DEPRECATION: Option 'o4' value 'true' is replaced by 'enabled'",
+ "match": "re",
+ "count": 1
+ },
+ {
+ "line": ".*DEPRECATION: Option 'o5' value 'auto' is replaced by 'false'",
+ "match": "re",
+ "count": 1
+ }
+ ]
+}
diff --git a/test cases/common/248 install_emptydir/meson.build b/test cases/common/248 install_emptydir/meson.build
new file mode 100644
index 0000000..a5eb046
--- /dev/null
+++ b/test cases/common/248 install_emptydir/meson.build
@@ -0,0 +1,4 @@
+project('install_emptydir')
+
+install_emptydir(get_option('datadir')/'new_directory', install_mode: 'rwx------')
+install_emptydir(get_option('datadir')/'new_directory/subdir', install_mode: 'rwxr-----')
diff --git a/test cases/common/248 install_emptydir/test.json b/test cases/common/248 install_emptydir/test.json
new file mode 100644
index 0000000..17abe74
--- /dev/null
+++ b/test cases/common/248 install_emptydir/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ { "type": "dir", "file": "usr/share/new_directory" },
+ { "type": "dir", "file": "usr/share/new_directory/subdir" }
+ ]
+}
+
diff --git a/test cases/common/249 install_symlink/datafile.dat b/test cases/common/249 install_symlink/datafile.dat
new file mode 100644
index 0000000..ff3104b
--- /dev/null
+++ b/test cases/common/249 install_symlink/datafile.dat
@@ -0,0 +1 @@
+this is a data file
diff --git a/test cases/common/249 install_symlink/meson.build b/test cases/common/249 install_symlink/meson.build
new file mode 100644
index 0000000..ae30382
--- /dev/null
+++ b/test cases/common/249 install_symlink/meson.build
@@ -0,0 +1,9 @@
+project('install_emptydir')
+
+if build_machine.system() == 'windows' and meson.backend() == 'ninja'
+ error('MESON_SKIP_TEST windows does not support symlinks unless root or in development mode')
+endif
+
+install_data('datafile.dat', install_dir: 'share/progname/C')
+install_symlink('datafile.dat', pointing_to: '../C/datafile.dat', install_dir: 'share/progname/es')
+install_symlink('rename_datafile.dat', pointing_to: '../C/datafile.dat', install_dir: 'share/progname/fr')
diff --git a/test cases/common/249 install_symlink/test.json b/test cases/common/249 install_symlink/test.json
new file mode 100644
index 0000000..33aa76e
--- /dev/null
+++ b/test cases/common/249 install_symlink/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/progname/C/datafile.dat"},
+ {"type": "file", "file": "usr/share/progname/es/datafile.dat"},
+ {"type": "file", "file": "usr/share/progname/fr/rename_datafile.dat"}
+ ]
+}
diff --git a/test cases/common/25 config subdir/include/config.h.in b/test cases/common/25 config subdir/include/config.h.in
new file mode 100644
index 0000000..4c3c62d
--- /dev/null
+++ b/test cases/common/25 config subdir/include/config.h.in
@@ -0,0 +1,6 @@
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+#define RETURN_VALUE @number@
+
+#endif
diff --git a/test cases/common/25 config subdir/include/meson.build b/test cases/common/25 config subdir/include/meson.build
new file mode 100644
index 0000000..f14111a
--- /dev/null
+++ b/test cases/common/25 config subdir/include/meson.build
@@ -0,0 +1,4 @@
+conf_data = configuration_data()
+conf_data.set('number', '0')
+
+configure_file(input:'config.h.in', output:'config.h', configuration:conf_data)
diff --git a/test cases/common/25 config subdir/meson.build b/test cases/common/25 config subdir/meson.build
new file mode 100644
index 0000000..25f53db
--- /dev/null
+++ b/test cases/common/25 config subdir/meson.build
@@ -0,0 +1,6 @@
+project('subdirconfig', 'c')
+
+inc = include_directories('include')
+
+subdir('include')
+subdir('src')
diff --git a/test cases/common/25 config subdir/src/meson.build b/test cases/common/25 config subdir/src/meson.build
new file mode 100644
index 0000000..97598a4
--- /dev/null
+++ b/test cases/common/25 config subdir/src/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.c', include_directories : inc)
+test('subdir config', exe)
diff --git a/test cases/common/25 config subdir/src/prog.c b/test cases/common/25 config subdir/src/prog.c
new file mode 100644
index 0000000..b9db890
--- /dev/null
+++ b/test cases/common/25 config subdir/src/prog.c
@@ -0,0 +1,5 @@
+#include "config.h"
+
+int main(void) {
+ return RETURN_VALUE;
+}
diff --git a/test cases/common/250 system include dir/lib/lib.hpp b/test cases/common/250 system include dir/lib/lib.hpp
new file mode 100644
index 0000000..a1fbf85
--- /dev/null
+++ b/test cases/common/250 system include dir/lib/lib.hpp
@@ -0,0 +1,4 @@
+#pragma once
+
+// This will trigger -Wsign-conversion
+inline unsigned convert_to_unsigned(int i) { return i; }
diff --git a/test cases/common/250 system include dir/main.cpp b/test cases/common/250 system include dir/main.cpp
new file mode 100644
index 0000000..9f83297
--- /dev/null
+++ b/test cases/common/250 system include dir/main.cpp
@@ -0,0 +1,3 @@
+#include <lib.hpp>
+
+int main() { return 0; }
diff --git a/test cases/common/250 system include dir/meson.build b/test cases/common/250 system include dir/meson.build
new file mode 100644
index 0000000..724a8e4
--- /dev/null
+++ b/test cases/common/250 system include dir/meson.build
@@ -0,0 +1,13 @@
+project('system_include_dir', 'cpp',
+ version : '0.1',
+ default_options : 'werror=true',
+)
+
+compiler_id = meson.get_compiler('cpp').get_id()
+if not ['gcc', 'clang', 'clang-cl'].contains(compiler_id)
+ error('MESON_SKIP_TEST: compiler @0@ either doesn\'t support is_system includes or needs to have support for this test added'.format(compiler_id))
+endif
+
+lib_include_directories = include_directories('lib', is_system: true)
+add_project_arguments('-Wsign-conversion', language: 'cpp')
+executable('system_include_dir_test', sources: 'main.cpp', include_directories: lib_include_directories)
diff --git a/test cases/common/251 add_project_dependencies/inc/lib.h b/test cases/common/251 add_project_dependencies/inc/lib.h
new file mode 100644
index 0000000..ceca99f
--- /dev/null
+++ b/test cases/common/251 add_project_dependencies/inc/lib.h
@@ -0,0 +1,2 @@
+#pragma once
+extern int ok(void);
diff --git a/test cases/common/251 add_project_dependencies/lib.c b/test cases/common/251 add_project_dependencies/lib.c
new file mode 100644
index 0000000..ac46bfc
--- /dev/null
+++ b/test cases/common/251 add_project_dependencies/lib.c
@@ -0,0 +1,14 @@
+#include <zlib.h>
+#include <math.h>
+
+#ifndef DEFINED
+#error expected compile_arg not found
+#endif
+
+double zero;
+int ok(void) {
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return (int)cos(zero);
+}
diff --git a/test cases/common/251 add_project_dependencies/main.c b/test cases/common/251 add_project_dependencies/main.c
new file mode 100644
index 0000000..93b7f72
--- /dev/null
+++ b/test cases/common/251 add_project_dependencies/main.c
@@ -0,0 +1,5 @@
+#include "lib.h"
+
+int main(void) {
+ return ok();
+}
diff --git a/test cases/common/251 add_project_dependencies/meson.build b/test cases/common/251 add_project_dependencies/meson.build
new file mode 100644
index 0000000..4047e6d
--- /dev/null
+++ b/test cases/common/251 add_project_dependencies/meson.build
@@ -0,0 +1,22 @@
+project('zlib system dependency', 'c')
+
+cc = meson.get_compiler('c')
+
+m = cc.find_library('m', required: false)
+add_project_dependencies(m, language: ['c'])
+
+z = dependency('zlib', method: 'system', required: false)
+if not z.found()
+ error('MESON_SKIP_TEST zlib not present')
+endif
+
+z_c_args = z.partial_dependency(compile_args: true, includes: true)
+add_project_dependencies(z_c_args, language: 'c', native: false)
+
+global_dep = declare_dependency(include_directories: include_directories('inc'),
+ compile_args: '-DDEFINED')
+add_project_dependencies(global_dep, language: 'c', native: false)
+
+lib = static_library('rary', 'lib.c')
+exe = executable('prog', 'main.c', link_with: lib, dependencies: z)
+test('test', exe)
diff --git a/test cases/common/252 install data structured/dir1/bad b/test cases/common/252 install data structured/dir1/bad
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/bad
diff --git a/test cases/common/252 install data structured/dir1/file1 b/test cases/common/252 install data structured/dir1/file1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/file1
diff --git a/test cases/common/252 install data structured/dir1/file2 b/test cases/common/252 install data structured/dir1/file2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/file2
diff --git a/test cases/common/252 install data structured/dir1/file3 b/test cases/common/252 install data structured/dir1/file3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir1/file3
diff --git a/test cases/common/252 install data structured/dir2/bad b/test cases/common/252 install data structured/dir2/bad
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/bad
diff --git a/test cases/common/252 install data structured/dir2/file1 b/test cases/common/252 install data structured/dir2/file1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/file1
diff --git a/test cases/common/252 install data structured/dir2/file2 b/test cases/common/252 install data structured/dir2/file2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/file2
diff --git a/test cases/common/252 install data structured/dir2/file3 b/test cases/common/252 install data structured/dir2/file3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir2/file3
diff --git a/test cases/common/252 install data structured/dir3/bad b/test cases/common/252 install data structured/dir3/bad
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/bad
diff --git a/test cases/common/252 install data structured/dir3/file1 b/test cases/common/252 install data structured/dir3/file1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/file1
diff --git a/test cases/common/252 install data structured/dir3/file2 b/test cases/common/252 install data structured/dir3/file2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/file2
diff --git a/test cases/common/252 install data structured/dir3/file3 b/test cases/common/252 install data structured/dir3/file3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/252 install data structured/dir3/file3
diff --git a/test cases/common/252 install data structured/meson.build b/test cases/common/252 install data structured/meson.build
new file mode 100644
index 0000000..9d29794
--- /dev/null
+++ b/test cases/common/252 install data structured/meson.build
@@ -0,0 +1,16 @@
+project('install structured data')
+
+install_data(
+ 'dir1/file1',
+ 'dir1/file2',
+ 'dir1/file3',
+ 'dir2/file1',
+ 'dir2/file2',
+ 'dir2/file3',
+ 'dir3/file1',
+ 'dir3/file2',
+ 'dir3/file3',
+ install_dir: get_option('datadir'),
+ preserve_path: true,
+)
+subdir('pysrc')
diff --git a/test cases/common/252 install data structured/pysrc/__init__.py b/test cases/common/252 install data structured/pysrc/__init__.py
new file mode 100644
index 0000000..cb831ca
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/__init__.py
@@ -0,0 +1 @@
+'''init for mod'''
diff --git a/test cases/common/252 install data structured/pysrc/bad.py b/test cases/common/252 install data structured/pysrc/bad.py
new file mode 100644
index 0000000..d2f862e
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/bad.py
@@ -0,0 +1 @@
+'''mod.bad should not be installed'''
diff --git a/test cases/common/252 install data structured/pysrc/bar.py b/test cases/common/252 install data structured/pysrc/bar.py
new file mode 100644
index 0000000..1ac5d08
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/bar.py
@@ -0,0 +1 @@
+'''mod.bar module'''
diff --git a/test cases/common/252 install data structured/pysrc/foo.py b/test cases/common/252 install data structured/pysrc/foo.py
new file mode 100644
index 0000000..eff906b
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/foo.py
@@ -0,0 +1 @@
+'''mod.foo module'''
diff --git a/test cases/common/252 install data structured/pysrc/meson.build b/test cases/common/252 install data structured/pysrc/meson.build
new file mode 100644
index 0000000..64c0f4d
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/meson.build
@@ -0,0 +1,11 @@
+py_inst = import('python').find_installation()
+
+py_inst.install_sources(
+ '__init__.py',
+ 'foo.py',
+ 'bar.py',
+ 'submod/__init__.py',
+ 'submod/baz.py',
+ subdir: 'mod',
+ preserve_path: true,
+)
diff --git a/test cases/common/252 install data structured/pysrc/submod/__init__.py b/test cases/common/252 install data structured/pysrc/submod/__init__.py
new file mode 100644
index 0000000..65a3500
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/submod/__init__.py
@@ -0,0 +1 @@
+'''init for submod'''
diff --git a/test cases/common/252 install data structured/pysrc/submod/bad.py b/test cases/common/252 install data structured/pysrc/submod/bad.py
new file mode 100644
index 0000000..6661a6d
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/submod/bad.py
@@ -0,0 +1 @@
+'''mod.submod.bad should not be installed'''
diff --git a/test cases/common/252 install data structured/pysrc/submod/baz.py b/test cases/common/252 install data structured/pysrc/submod/baz.py
new file mode 100644
index 0000000..d0b2904
--- /dev/null
+++ b/test cases/common/252 install data structured/pysrc/submod/baz.py
@@ -0,0 +1 @@
+'''mod.submod.baz module'''
diff --git a/test cases/common/252 install data structured/test.json b/test cases/common/252 install data structured/test.json
new file mode 100644
index 0000000..f4dc2df
--- /dev/null
+++ b/test cases/common/252 install data structured/test.json
@@ -0,0 +1,18 @@
+{
+ "installed": [
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/__init__.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/foo.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/bar.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/submod/__init__.py"},
+ {"type": "python_file", "file": "usr/@PYTHON_PURELIB@/mod/submod/baz.py"},
+ {"type": "file", "file": "usr/share/dir1/file1"},
+ {"type": "file", "file": "usr/share/dir1/file2"},
+ {"type": "file", "file": "usr/share/dir1/file3"},
+ {"type": "file", "file": "usr/share/dir2/file1"},
+ {"type": "file", "file": "usr/share/dir2/file2"},
+ {"type": "file", "file": "usr/share/dir2/file3"},
+ {"type": "file", "file": "usr/share/dir3/file1"},
+ {"type": "file", "file": "usr/share/dir3/file2"},
+ {"type": "file", "file": "usr/share/dir3/file3"}
+ ]
+}
diff --git a/test cases/common/253 subproject dependency variables/meson.build b/test cases/common/253 subproject dependency variables/meson.build
new file mode 100644
index 0000000..403b6f1
--- /dev/null
+++ b/test cases/common/253 subproject dependency variables/meson.build
@@ -0,0 +1,18 @@
+project('subproject dependency variables', 'c')
+
+subfiles_dep = subproject('subfiles').get_variable('files_dep')
+
+executable(
+ 'foo',
+ join_paths(subfiles_dep.get_variable('pkgdatadir'), 'foo.c')
+)
+
+executable(
+ 'foo2',
+ subfiles_dep.get_variable('pkgdatadir2') / 'foo.c'
+)
+
+executable(
+ 'foor32',
+ subfiles_dep.get_variable('pkgdatadir3') / 'foo.c'
+)
diff --git a/test cases/common/253 subproject dependency variables/subprojects/subfiles/foo.c b/test cases/common/253 subproject dependency variables/subprojects/subfiles/foo.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/253 subproject dependency variables/subprojects/subfiles/foo.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/253 subproject dependency variables/subprojects/subfiles/meson.build b/test cases/common/253 subproject dependency variables/subprojects/subfiles/meson.build
new file mode 100644
index 0000000..f5ad0f2
--- /dev/null
+++ b/test cases/common/253 subproject dependency variables/subprojects/subfiles/meson.build
@@ -0,0 +1,29 @@
+project('dependency variable resource')
+
+files_dep = declare_dependency(
+ variables: [
+ 'pkgdatadir=@0@/subdir'.format(meson.current_source_dir()),
+ 'pkgdatadir2=@0@/subdir2'.format(meson.current_source_dir()),
+ 'pkgdatadir3=@0@'.format(meson.current_source_dir()),
+ ]
+)
+
+install_data('subdir/foo.c', install_dir: get_option('datadir') / 'subdir')
+install_subdir('subdir2', install_dir: get_option('datadir'))
+install_data('foo.c', install_dir: get_option('datadir'))
+
+import('pkgconfig').generate(
+ name: 'depvar_resource',
+ description: 'Get a resource file from pkgconfig or a subproject',
+ version: '0.1',
+ variables: [
+ 'pkgdatadir=${datadir}/subdir',
+ 'pkgdatadir2=${datadir}/subdir2',
+ ],
+ uninstalled_variables: [
+ 'pkgdatadir=@0@/subdir'.format(meson.current_source_dir()),
+ 'pkgdatadir2=@0@/subdir2'.format(meson.current_source_dir()),
+ 'pkgdatadir3=@0@'.format(meson.current_source_dir()),
+ ],
+ dataonly: true,
+)
diff --git a/test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir/foo.c b/test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir/foo.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir/foo.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir2/foo.c b/test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir2/foo.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/common/253 subproject dependency variables/subprojects/subfiles/subdir2/foo.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/common/253 subproject dependency variables/test.json b/test cases/common/253 subproject dependency variables/test.json
new file mode 100644
index 0000000..c345bbe
--- /dev/null
+++ b/test cases/common/253 subproject dependency variables/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ { "type": "file", "file": "usr/share/pkgconfig/depvar_resource.pc" },
+ { "type": "file", "file": "usr/share/foo.c" },
+ { "type": "file", "file": "usr/share/subdir/foo.c" },
+ { "type": "file", "file": "usr/share/subdir2/foo.c" }
+ ]
+}
diff --git a/test cases/common/254 long output/dumper.c b/test cases/common/254 long output/dumper.c
new file mode 100644
index 0000000..d479e08
--- /dev/null
+++ b/test cases/common/254 long output/dumper.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main(void)
+{
+ for (int i = 0 ; i < 100000 ; i++)
+ fprintf(stderr, "# Iteration %d to stderr\n", i + 1);
+
+ printf("ok 1 - dumper to stderr\n");
+
+ for (int i = 0 ; i < 100000 ; i++)
+ fprintf(stdout, "# Iteration %d to stdout\n", i + 1);
+
+ printf("ok 2 - dumper to stdout\n1..2\n");
+
+ return 0;
+}
+
diff --git a/test cases/common/254 long output/meson.build b/test cases/common/254 long output/meson.build
new file mode 100644
index 0000000..6d8d62b
--- /dev/null
+++ b/test cases/common/254 long output/meson.build
@@ -0,0 +1,5 @@
+project('long-stderr', 'c')
+
+dumper = executable('dumper', 'dumper.c')
+test('dump-test', dumper)
+test('dump-test-TAP', dumper, protocol : 'tap')
diff --git a/test cases/common/255 module warnings/meson.build b/test cases/common/255 module warnings/meson.build
new file mode 100644
index 0000000..56e2055
--- /dev/null
+++ b/test cases/common/255 module warnings/meson.build
@@ -0,0 +1,9 @@
+project('module warnings', meson_version : '>= 0.56')
+
+import('python3') # deprecated module
+import('java') # new module
+import('unstable-keyval') # module that has been stabilized, import with unstable-
+import('unstable_simd') # A module with the deprecated `unstable_foo` instead of `unstable-foo`
+
+ice = import('icestorm', required : false)
+assert(not ice.found(), 'unstable-icestorm module should not be importable as `simd`')
diff --git a/test cases/common/255 module warnings/test.json b/test cases/common/255 module warnings/test.json
new file mode 100644
index 0000000..5556b90
--- /dev/null
+++ b/test cases/common/255 module warnings/test.json
@@ -0,0 +1,16 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/common/255 module warnings/meson.build:3: WARNING: Project targets '>= 0.56' but uses feature deprecated since '0.48.0': module python3."
+ },
+ {
+ "line": "test cases/common/255 module warnings/meson.build:4: WARNING: Project targets '>= 0.56' but uses feature introduced in '0.60.0': module java."
+ },
+ {
+ "line": "test cases/common/255 module warnings/meson.build:5: WARNING: Project targets '>= 0.56' but uses feature deprecated since '0.56.0': module keyval has been stabilized. drop \"unstable-\" prefix from the module name"
+ },
+ {
+ "line": "test cases/common/255 module warnings/meson.build:6: DEPRECATION: Importing unstable modules as \"unstable_simd\" instead of \"unstable-simd\""
+ }
+ ]
+}
diff --git a/test cases/common/256 subproject extracted objects/foo.c b/test cases/common/256 subproject extracted objects/foo.c
new file mode 100644
index 0000000..f6c7aeb
--- /dev/null
+++ b/test cases/common/256 subproject extracted objects/foo.c
@@ -0,0 +1,11 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_IMPORT __declspec(dllimport)
+#else
+ #define DLL_IMPORT
+#endif
+
+int DLL_IMPORT cppfunc(void);
+
+int otherfunc(void) {
+ return cppfunc() != 42;
+}
diff --git a/test cases/common/256 subproject extracted objects/meson.build b/test cases/common/256 subproject extracted objects/meson.build
new file mode 100644
index 0000000..bad450f
--- /dev/null
+++ b/test cases/common/256 subproject extracted objects/meson.build
@@ -0,0 +1,5 @@
+project('link to extracted objects', 'c')
+
+sublib = subproject('myobjects').get_variable('sublib')
+
+mainlib = static_library('foo', 'foo.c', install: true, link_with: sublib)
diff --git a/test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.cpp b/test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.cpp
new file mode 100644
index 0000000..12ef756
--- /dev/null
+++ b/test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.cpp
@@ -0,0 +1,6 @@
+#define BUILDING_DLL
+#include "cpplib.h"
+
+extern "C" int DLL_PUBLIC cppfunc(void) {
+ return 42;
+}
diff --git a/test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.h b/test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.h
new file mode 100644
index 0000000..a1c38b3
--- /dev/null
+++ b/test cases/common/256 subproject extracted objects/subprojects/myobjects/cpplib.h
@@ -0,0 +1,12 @@
+/* See http://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support */
+#if defined(_WIN32) || defined(__CYGWIN__)
+ #ifdef BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #define DLL_PUBLIC __attribute__ ((visibility ("default")))
+#endif
+
+extern "C" int DLL_PUBLIC cppfunc(void);
diff --git a/test cases/common/256 subproject extracted objects/subprojects/myobjects/meson.build b/test cases/common/256 subproject extracted objects/subprojects/myobjects/meson.build
new file mode 100644
index 0000000..1c2729b
--- /dev/null
+++ b/test cases/common/256 subproject extracted objects/subprojects/myobjects/meson.build
@@ -0,0 +1,3 @@
+project('myobjects', 'cpp')
+
+sublib = static_library('sublib', 'cpplib.cpp')
diff --git a/test cases/common/256 subproject extracted objects/test.json b/test cases/common/256 subproject extracted objects/test.json
new file mode 100644
index 0000000..baa5dfb
--- /dev/null
+++ b/test cases/common/256 subproject extracted objects/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ { "type": "file", "file": "usr/lib/libfoo.a" }
+ ]
+}
diff --git a/test cases/common/257 generated header dep/foo.c b/test cases/common/257 generated header dep/foo.c
new file mode 100644
index 0000000..f4de601
--- /dev/null
+++ b/test cases/common/257 generated header dep/foo.c
@@ -0,0 +1 @@
+#include "foo.h"
diff --git a/test cases/common/257 generated header dep/meson.build b/test cases/common/257 generated header dep/meson.build
new file mode 100644
index 0000000..195d082
--- /dev/null
+++ b/test cases/common/257 generated header dep/meson.build
@@ -0,0 +1,22 @@
+project('generated header dep', 'c')
+
+# Regression test case for a very specific case:
+# - Uses both_libraries(), or library() with default_library=both.
+# - A header file is generated by a custom_target() and passed as source.
+# - A C file that uses that header is passed as a declare_dependency() source.
+# Under those specific conditions, the static library used to miss an order
+# dependency on the header file. This happened in GLib:
+# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2917.
+
+python = import('python').find_installation()
+header = custom_target(
+ output: 'foo.h',
+ capture: true,
+ command: [python, '-c', 'print("#define FOO")'],
+)
+
+sources_dep = declare_dependency(sources: files('foo.c'))
+
+both_libraries('foo', header,
+ dependencies: sources_dep,
+)
diff --git a/test cases/common/258 subsubproject inplace/meson.build b/test cases/common/258 subsubproject inplace/meson.build
new file mode 100644
index 0000000..26a421b
--- /dev/null
+++ b/test cases/common/258 subsubproject inplace/meson.build
@@ -0,0 +1,3 @@
+project('main')
+
+subproject('sub')
diff --git a/test cases/common/258 subsubproject inplace/subprojects/sub/meson.build b/test cases/common/258 subsubproject inplace/subprojects/sub/meson.build
new file mode 100644
index 0000000..5e33d21
--- /dev/null
+++ b/test cases/common/258 subsubproject inplace/subprojects/sub/meson.build
@@ -0,0 +1,3 @@
+project('sub')
+
+subproject('subsub')
diff --git a/test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub-1.0/meson.build b/test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub-1.0/meson.build
new file mode 100644
index 0000000..7807a1b
--- /dev/null
+++ b/test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub-1.0/meson.build
@@ -0,0 +1 @@
+project('subsub')
diff --git a/test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub.wrap b/test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub.wrap
new file mode 100644
index 0000000..bf39852
--- /dev/null
+++ b/test cases/common/258 subsubproject inplace/subprojects/sub/subprojects/subsub.wrap
@@ -0,0 +1,2 @@
+[wrap-file]
+directory = subsub-1.0
diff --git a/test cases/common/258 subsubproject inplace/subprojects/subsub.wrap b/test cases/common/258 subsubproject inplace/subprojects/subsub.wrap
new file mode 100644
index 0000000..30faa64
--- /dev/null
+++ b/test cases/common/258 subsubproject inplace/subprojects/subsub.wrap
@@ -0,0 +1,2 @@
+[wrap-redirect]
+filename = sub/subprojects/subsub.wrap
diff --git a/test cases/common/259 preprocess/bar.c b/test cases/common/259 preprocess/bar.c
new file mode 100644
index 0000000..43737b9
--- /dev/null
+++ b/test cases/common/259 preprocess/bar.c
@@ -0,0 +1,3 @@
+int bar(void) {
+ return BAR;
+}
diff --git a/test cases/common/259 preprocess/foo.c b/test cases/common/259 preprocess/foo.c
new file mode 100644
index 0000000..c9d16c5
--- /dev/null
+++ b/test cases/common/259 preprocess/foo.c
@@ -0,0 +1 @@
+#include <foo.h>
diff --git a/test cases/common/259 preprocess/foo.h b/test cases/common/259 preprocess/foo.h
new file mode 100644
index 0000000..ba60bf3
--- /dev/null
+++ b/test cases/common/259 preprocess/foo.h
@@ -0,0 +1,2 @@
+int bar(void);
+int main(void) { return FOO + bar(); }
diff --git a/test cases/common/259 preprocess/meson.build b/test cases/common/259 preprocess/meson.build
new file mode 100644
index 0000000..4824598
--- /dev/null
+++ b/test cases/common/259 preprocess/meson.build
@@ -0,0 +1,15 @@
+project('preprocess', 'c')
+
+cc = meson.get_compiler('c')
+
+add_project_arguments(['-DFOO=0', '-DBAR=0'], language: 'c')
+
+pp_files = cc.preprocess('foo.c', 'bar.c', output: '@PLAINNAME@')
+
+foreach f : pp_files
+ message(f.full_path())
+endforeach
+
+subdir('src')
+
+test('test-foo', executable('app', pp_files, link_depends: file_map))
diff --git a/test cases/common/259 preprocess/src/file.map.in b/test cases/common/259 preprocess/src/file.map.in
new file mode 100644
index 0000000..152fb65
--- /dev/null
+++ b/test cases/common/259 preprocess/src/file.map.in
@@ -0,0 +1,3 @@
+#if 1
+Hello World
+#endif
diff --git a/test cases/common/259 preprocess/src/meson.build b/test cases/common/259 preprocess/src/meson.build
new file mode 100644
index 0000000..4cd9554
--- /dev/null
+++ b/test cases/common/259 preprocess/src/meson.build
@@ -0,0 +1,3 @@
+file_map = cc.preprocess('file.map.in',
+ output: '@BASENAME@',
+)
diff --git a/test cases/common/26 find program/meson.build b/test cases/common/26 find program/meson.build
new file mode 100644
index 0000000..5d38d0b
--- /dev/null
+++ b/test cases/common/26 find program/meson.build
@@ -0,0 +1,39 @@
+project('find program')
+
+if build_machine.system() == 'windows'
+ # Things Windows does not provide:
+ # - an executable to copy files without prompting
+ # - working command line quoting
+ # - anything that you might actually need
+ # Because of these reasons we only check that
+ # the program can be found.
+ cp = find_program('xcopy')
+else
+ cp = find_program('donotfindme', 'cp')
+ gen = generator(cp, \
+ output : '@BASENAME@.c', \
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+ generated = gen.process('source.in')
+ add_languages('c', required: true)
+ e = executable('prog', generated)
+ test('external exe', e)
+endif
+
+prog = find_program('print-version.py', version : '>=2.0', required : false)
+assert(not prog.found(), 'Version should be too old')
+
+prog = find_program('print-version.py', version : '>=1.0')
+assert(prog.found(), 'Program version should match')
+
+prog = find_program('print-version.py')
+assert(prog.version() == '1.0', 'Program version should be detectable')
+
+prog = find_program('print-version-with-prefix.py', version : '>=1.0')
+assert(prog.found(), 'Program version should match')
+
+prog = find_program('test_subdir.py', required : false)
+assert(not prog.found(), 'Program should not be found')
+
+prog = find_program('test_subdir.py', dirs : ['/donotexist', meson.current_source_dir() / 'scripts'])
+assert(prog.found(), 'Program should be found')
diff --git a/test cases/common/26 find program/print-version-with-prefix.py b/test cases/common/26 find program/print-version-with-prefix.py
new file mode 100644
index 0000000..520e0ba
--- /dev/null
+++ b/test cases/common/26 find program/print-version-with-prefix.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import sys
+
+if len(sys.argv) != 2 or sys.argv[1] != '--version':
+ exit(1)
+
+print('Version: 1.0')
diff --git a/test cases/common/26 find program/print-version.py b/test cases/common/26 find program/print-version.py
new file mode 100644
index 0000000..4a78e5b
--- /dev/null
+++ b/test cases/common/26 find program/print-version.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import sys
+
+if len(sys.argv) != 2 or sys.argv[1] != '--version':
+ exit(1)
+
+print('1.0')
diff --git a/test cases/common/26 find program/scripts/test_subdir.py b/test cases/common/26 find program/scripts/test_subdir.py
new file mode 100644
index 0000000..947ffe4
--- /dev/null
+++ b/test cases/common/26 find program/scripts/test_subdir.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+exit(0)
diff --git a/test cases/common/26 find program/source.in b/test cases/common/26 find program/source.in
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/test cases/common/26 find program/source.in
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/27 multiline string/meson.build b/test cases/common/27 multiline string/meson.build
new file mode 100644
index 0000000..a87d29a
--- /dev/null
+++ b/test cases/common/27 multiline string/meson.build
@@ -0,0 +1,37 @@
+project('multiline string', 'c')
+
+x = '''hello again'''
+y = '''hello
+again'''
+
+if x == y
+ error('Things are wrong.')
+endif
+
+multieol = '''
+'''
+singleeol = '\n'
+
+if multieol != singleeol
+ error('Newline quoting is broken.')
+endif
+
+# And one more for good measure.
+quote1 = ''' ' '''.strip()
+quote2 = '\''
+
+if quote1 != quote2
+ error('Single quote quoting is broken.')
+endif
+
+cc = meson.get_compiler('c')
+prog = '''
+#include <stdio.h>
+
+int main(void) {
+ int num = 1;
+ printf("%d\n", num);
+ return 0;
+}'''
+
+assert(cc.compiles(prog), 'multline test compile failed')
diff --git a/test cases/common/28 try compile/invalid.c b/test cases/common/28 try compile/invalid.c
new file mode 100644
index 0000000..6c9cfb8
--- /dev/null
+++ b/test cases/common/28 try compile/invalid.c
@@ -0,0 +1,2 @@
+#include<nonexisting.h>
+void func(void) { printf("This won't work.\n"); }
diff --git a/test cases/common/28 try compile/meson.build b/test cases/common/28 try compile/meson.build
new file mode 100644
index 0000000..cb41e1d
--- /dev/null
+++ b/test cases/common/28 try compile/meson.build
@@ -0,0 +1,27 @@
+project('try compile', 'c', 'cpp')
+
+code = '''#include<stdio.h>
+void func(void) { printf("Something.\n"); }
+'''
+
+breakcode = '''#include<nonexisting.h>
+void func(void) { printf("This won't work.\n"); }
+'''
+
+foreach compiler : [meson.get_compiler('c'), meson.get_compiler('cpp')]
+ if compiler.compiles(code, name : 'should succeed') == false
+ error('Compiler ' + compiler.get_id() + ' is fail.')
+ endif
+
+ if compiler.compiles(files('valid.c'), name : 'should succeed') == false
+ error('Compiler ' + compiler.get_id() + ' is fail.')
+ endif
+
+ if compiler.compiles(breakcode, name : 'should fail')
+ error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
+ endif
+
+ if compiler.compiles(files('invalid.c'), name : 'should fail')
+ error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
+ endif
+endforeach
diff --git a/test cases/common/28 try compile/valid.c b/test cases/common/28 try compile/valid.c
new file mode 100644
index 0000000..f8e76f4
--- /dev/null
+++ b/test cases/common/28 try compile/valid.c
@@ -0,0 +1,2 @@
+#include<stdio.h>
+void func(void) { printf("Something.\n"); }
diff --git a/test cases/common/29 compiler id/meson.build b/test cases/common/29 compiler id/meson.build
new file mode 100644
index 0000000..280d4f7
--- /dev/null
+++ b/test cases/common/29 compiler id/meson.build
@@ -0,0 +1,15 @@
+project('compiler_id')
+
+foreach lang : ['c', 'cpp', 'fortran', 'objc', 'objcpp']
+
+ if not add_languages(lang, required: false)
+ continue
+ endif
+
+ comp = meson.get_compiler(lang)
+
+ message(lang + ' compiler name is: ' + comp.get_id())
+
+ message(lang + ' linker name is: ' + comp.get_linker_id())
+
+endforeach \ No newline at end of file
diff --git a/test cases/common/3 static/libfile.c b/test cases/common/3 static/libfile.c
new file mode 100644
index 0000000..846485e
--- /dev/null
+++ b/test cases/common/3 static/libfile.c
@@ -0,0 +1,3 @@
+int libfunc(void) {
+ return 3;
+}
diff --git a/test cases/common/3 static/libfile2.c b/test cases/common/3 static/libfile2.c
new file mode 100644
index 0000000..4df60c5
--- /dev/null
+++ b/test cases/common/3 static/libfile2.c
@@ -0,0 +1,3 @@
+int libfunc2(void) {
+ return 4;
+}
diff --git a/test cases/common/3 static/meson.build b/test cases/common/3 static/meson.build
new file mode 100644
index 0000000..04ff2f6
--- /dev/null
+++ b/test cases/common/3 static/meson.build
@@ -0,0 +1,14 @@
+project('static library test', 'c')
+
+lib = static_library('mylib', get_option('source'),
+ link_args : '-THISMUSTNOBEUSED') # Static linker needs to ignore all link args.
+assert(lib.name() == 'mylib')
+has_not_changed = false
+if is_disabler(lib)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'Static library has changed.')
+
+assert(not is_disabler(lib), 'Static library is a disabler.')
diff --git a/test cases/common/3 static/meson_options.txt b/test cases/common/3 static/meson_options.txt
new file mode 100644
index 0000000..7261a19
--- /dev/null
+++ b/test cases/common/3 static/meson_options.txt
@@ -0,0 +1 @@
+option('source', type : 'combo', choices : ['libfile.c', 'libfile2.c'], value : 'libfile.c')
diff --git a/test cases/common/30 sizeof/config.h.in b/test cases/common/30 sizeof/config.h.in
new file mode 100644
index 0000000..a442e8a
--- /dev/null
+++ b/test cases/common/30 sizeof/config.h.in
@@ -0,0 +1,2 @@
+#define INTSIZE @INTSIZE@
+#define WCHARSIZE @WCHARSIZE@
diff --git a/test cases/common/30 sizeof/meson.build b/test cases/common/30 sizeof/meson.build
new file mode 100644
index 0000000..9de5b78
--- /dev/null
+++ b/test cases/common/30 sizeof/meson.build
@@ -0,0 +1,33 @@
+project('sizeof', 'c', 'cpp')
+
+# Test with C
+cc = meson.get_compiler('c')
+
+intsize = cc.sizeof('int')
+wcharsize = cc.sizeof('wchar_t', prefix : '#include<wchar.h>')
+
+cd = configuration_data()
+cd.set('INTSIZE', intsize)
+cd.set('WCHARSIZE', wcharsize)
+cd.set('CONFIG', 'config.h')
+configure_file(input : 'config.h.in', output : 'config.h', configuration : cd)
+s = configure_file(input : 'prog.c.in', output : 'prog.c', configuration : cd)
+
+e = executable('prog', s)
+test('sizeof test', e)
+
+# Test with C++
+cpp = meson.get_compiler('cpp')
+
+intsize = cpp.sizeof('int')
+wcharsize = cpp.sizeof('wchar_t', prefix : '#include<wchar.h>')
+
+cdpp = configuration_data()
+cdpp.set('INTSIZE', intsize)
+cdpp.set('WCHARSIZE', wcharsize)
+cdpp.set('CONFIG', 'config.hpp')
+configure_file(input : 'config.h.in', output : 'config.hpp', configuration : cdpp)
+spp = configure_file(input : 'prog.c.in', output : 'prog.cc', configuration : cdpp)
+
+epp = executable('progpp', spp)
+test('sizeof test c++', epp)
diff --git a/test cases/common/30 sizeof/prog.c.in b/test cases/common/30 sizeof/prog.c.in
new file mode 100644
index 0000000..44918ec
--- /dev/null
+++ b/test cases/common/30 sizeof/prog.c.in
@@ -0,0 +1,15 @@
+#include "@CONFIG@"
+#include <stdio.h>
+#include <wchar.h>
+
+int main(void) {
+ if(INTSIZE != sizeof(int)) {
+ fprintf(stderr, "Mismatch: detected int size %d, actual size %d.\n", INTSIZE, (int)sizeof(int));
+ return 1;
+ }
+ if(WCHARSIZE != sizeof(wchar_t)) {
+ fprintf(stderr, "Mismatch: detected wchar size %d, actual size %d.\n", WCHARSIZE, (int)sizeof(wchar_t));
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/31 define10/config.h.in b/test cases/common/31 define10/config.h.in
new file mode 100644
index 0000000..dc77346
--- /dev/null
+++ b/test cases/common/31 define10/config.h.in
@@ -0,0 +1,2 @@
+#mesondefine ONE
+#mesondefine ZERO
diff --git a/test cases/common/31 define10/meson.build b/test cases/common/31 define10/meson.build
new file mode 100644
index 0000000..a28e7e4
--- /dev/null
+++ b/test cases/common/31 define10/meson.build
@@ -0,0 +1,12 @@
+project('set10test', 'c')
+
+conf = configuration_data()
+conf.set10('ONE', true)
+conf.set10('ZERO', false)
+
+configure_file(input : 'config.h.in',
+ output : 'config.h',
+ configuration : conf)
+
+exe = executable('prog', 'prog.c')
+test('10test', exe)
diff --git a/test cases/common/31 define10/prog.c b/test cases/common/31 define10/prog.c
new file mode 100644
index 0000000..519b40d
--- /dev/null
+++ b/test cases/common/31 define10/prog.c
@@ -0,0 +1,13 @@
+#include<stdio.h>
+#include"config.h"
+
+int main(void) {
+ if(ONE != 1) {
+ fprintf(stderr, "ONE is not 1.\n");
+ return 1;
+ }
+ if(ZERO != 0) {
+ fprintf(stderr, "ZERO is not 0.\n");
+ }
+ return 0;
+}
diff --git a/test cases/common/32 has header/meson.build b/test cases/common/32 has header/meson.build
new file mode 100644
index 0000000..8096763
--- /dev/null
+++ b/test cases/common/32 has header/meson.build
@@ -0,0 +1,54 @@
+project('has header', 'c', 'cpp')
+
+host_system = host_machine.system()
+
+non_existent_header = 'ouagadougou.h'
+
+# Copy it into the builddir to ensure that it isn't found even if it's there
+configure_file(input : non_existent_header,
+ output : non_existent_header,
+ configuration : configuration_data())
+
+# Test that the fallback to __has_include also works on all compilers
+if host_system != 'darwin'
+ fallbacks = ['', '\n#undef __has_include']
+else
+ # On Darwin's clang you can't redefine builtin macros so the above doesn't work
+ fallbacks = ['']
+endif
+
+foreach fallback : fallbacks
+ foreach comp : [meson.get_compiler('c'), meson.get_compiler('cpp')]
+ assert(comp.has_header('stdio.h', prefix : fallback), 'Stdio missing.')
+
+ # stdio.h doesn't actually need stdlib.h, but just test that setting the
+ # prefix does not result in an error.
+ assert(comp.has_header('stdio.h', prefix : '#include <stdlib.h>' + fallback),
+ 'Stdio missing.')
+
+ # XInput.h should not require type definitions from windows.h, but it does
+ # require macro definitions. Specifically, it requires an arch setting for
+ # VS2015 at least.
+ # We only do this check on MSVC because MinGW often defines its own wrappers
+ # that pre-include windows.h
+ if comp.get_id() == 'msvc'
+ assert(comp.has_header('XInput.h', prefix : '#include <windows.h>' + fallback),
+ 'XInput.h should not be missing on Windows')
+ assert(comp.has_header('XInput.h', prefix : '#define _X86_' + fallback),
+ 'XInput.h should not need windows.h')
+ endif
+
+ # Test that the following GCC bug doesn't happen:
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80005
+ # https://github.com/mesonbuild/meson/issues/1458
+ if host_system == 'linux'
+ assert(comp.has_header('linux/if.h', prefix : fallback),
+ 'Could not find <linux/if.h>')
+ endif
+
+ # This header exists in the source and the builddir, but we still must not
+ # find it since we are looking in the system directories.
+ assert(not comp.has_header(non_existent_header, prefix : fallback),
+ 'Found non-existent header.')
+ endforeach
+endforeach
diff --git a/test cases/common/32 has header/ouagadougou.h b/test cases/common/32 has header/ouagadougou.h
new file mode 100644
index 0000000..2f76c49
--- /dev/null
+++ b/test cases/common/32 has header/ouagadougou.h
@@ -0,0 +1 @@
+#define OMG_THIS_SHOULDNT_BE_FOUND
diff --git a/test cases/common/33 run program/check-env.py b/test cases/common/33 run program/check-env.py
new file mode 100644
index 0000000..ef04433
--- /dev/null
+++ b/test cases/common/33 run program/check-env.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+import os
+
+assert os.environ['MY_PATH'] == os.pathsep.join(['0', '1', '2'])
diff --git a/test cases/common/33 run program/get-version.py b/test cases/common/33 run program/get-version.py
new file mode 100644
index 0000000..a22d559
--- /dev/null
+++ b/test cases/common/33 run program/get-version.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('1.2')
diff --git a/test cases/common/33 run program/meson.build b/test cases/common/33 run program/meson.build
new file mode 100644
index 0000000..aa0a1d6
--- /dev/null
+++ b/test cases/common/33 run program/meson.build
@@ -0,0 +1,85 @@
+project('run command', version : run_command('get-version.py', check : true).stdout().strip())
+
+if build_machine.system() == 'windows'
+ c = run_command('cmd', '/c', 'echo', 'hello', check: false)
+else
+ c = run_command('echo', 'hello', check: false)
+endif
+
+correct = 'hello'
+
+if c.returncode() != 0
+ error('Executing echo failed.')
+endif
+
+result = c.stdout().strip()
+
+if result != correct
+ error('Getting stdout failed.')
+endif
+
+if c.stderr() != ''
+ error('Extra text in stderr.')
+endif
+
+# Now the same with a script.
+
+if build_machine.system() == 'windows'
+ cs = run_command('scripts/hello.bat', check: false)
+else
+ cs = run_command('scripts/hello.sh', check: false)
+endif
+
+if cs.returncode() != 0
+ error('Executing script failed.')
+endif
+
+if cs.stdout().strip() != correct
+ error('Getting stdout failed (script).')
+endif
+
+if cs.stderr() != ''
+ error('Extra text in stderr (script).')
+endif
+
+# We should be able to have files() in argument
+f = files('meson.build')
+
+if build_machine.system() == 'windows'
+ c = run_command('cmd', '/c', 'echo', f, check: false)
+else
+ c = run_command('echo', f, check: false)
+endif
+
+if c.returncode() != 0
+ error('Using files() in argument failed.')
+endif
+
+py3 = import('python3').find_python()
+
+ret = run_command(py3, '-c', 'print("some output")', check: false)
+assert(ret.returncode() == 0, 'failed to run python3: ' + ret.stderr())
+assert(ret.stdout() == 'some output\n', 'failed to run python3')
+
+ret = run_command(py3, '-c', 'print("some output")', check: false, capture: false)
+assert(ret.returncode() == 0, 'failed to run python3: ' + ret.stderr())
+assert(ret.stdout() == '', 'stdout is "@0@" instead of empty'.format(ret.stdout()))
+
+c_env = environment()
+c_env.append('CUSTOM_ENV_VAR', 'FOOBAR')
+ret = run_command(py3, '-c', 'import os; print(os.environ.get("CUSTOM_ENV_VAR"))', env: c_env, check: false)
+assert(ret.returncode() == 0, 'failed to run python3: ' + ret.stderr())
+assert(ret.stdout() == 'FOOBAR\n', 'stdout is "@0@" instead of FOOBAR'.format(ret.stdout()))
+
+dd = find_program('dd', required : false)
+if dd.found()
+ ret = run_command(dd, 'if=/dev/urandom', 'bs=10', 'count=1', check: false, capture: false)
+ assert(ret.returncode() == 0, 'failed to run dd: ' + ret.stderr())
+ assert(ret.stdout() == '', 'stdout is "@0@" instead of empty'.format(ret.stdout()))
+endif
+
+env = environment()
+env.append('MY_PATH', '1')
+env.append('MY_PATH', '2')
+env.prepend('MY_PATH', '0')
+run_command('check-env.py', env: env, check: true)
diff --git a/test cases/common/33 run program/scripts/hello.bat b/test cases/common/33 run program/scripts/hello.bat
new file mode 100644
index 0000000..cbc346b
--- /dev/null
+++ b/test cases/common/33 run program/scripts/hello.bat
@@ -0,0 +1,2 @@
+@ECHO OFF
+ECHO hello
diff --git a/test cases/common/33 run program/scripts/hello.sh b/test cases/common/33 run program/scripts/hello.sh
new file mode 100755
index 0000000..2a22daa
--- /dev/null
+++ b/test cases/common/33 run program/scripts/hello.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo hello
diff --git a/test cases/common/34 logic ops/meson.build b/test cases/common/34 logic ops/meson.build
new file mode 100644
index 0000000..656fd18
--- /dev/null
+++ b/test cases/common/34 logic ops/meson.build
@@ -0,0 +1,95 @@
+project('logicopts')
+
+t = true
+f = false
+
+if (true)
+ message('Ok.')
+else
+ error('Not ok.')
+endif
+
+if (false)
+ error('Not ok.')
+else
+ message('Ok.')
+endif
+
+if (f)
+ error('Not ok.')
+else
+ message('Ok.')
+endif
+
+if (t)
+ message('Ok.')
+else
+ error('Not ok.')
+endif
+
+if true and t
+ message('Ok.')
+else
+ error('Not ok.')
+endif
+
+if t and false
+ error('Not ok.')
+else
+ message('Ok.')
+endif
+
+if f and t
+ error('Not ok.')
+else
+ message('Ok.')
+endif
+
+if f or false
+ error('Not ok.')
+else
+ message('Ok.')
+endif
+
+if true or f
+ message('Ok.')
+else
+ error('Not ok.')
+endif
+
+if t or true
+ message('Ok.')
+else
+ error('Not ok.')
+endif
+
+if not true
+ error('Negation failed.')
+else
+ message('Ok.')
+endif
+
+if not f
+ message('Ok.')
+else
+ error('Negation failed.')
+endif
+
+
+if f or f or f or f or f or f or f or f or t
+ message('Ok.')
+else
+ error('Chain of ors failed.')
+endif
+
+if t and t and t and t and t and t and t and t and f
+ error('Chain of ands failed.')
+else
+ message('Ok.')
+endif
+
+if t and t or t
+ message('Ok.')
+else
+ error('Combination of and-or failed.')
+endif
diff --git a/test cases/common/35 string operations/meson.build b/test cases/common/35 string operations/meson.build
new file mode 100644
index 0000000..116fe0b
--- /dev/null
+++ b/test cases/common/35 string operations/meson.build
@@ -0,0 +1,127 @@
+project('string formatting')
+
+templ = '@0@bar@1@'
+
+assert(templ.format('foo', 'baz') == 'foobarbaz', 'Basic string formatting is broken.')
+
+assert('@0@'.format(1) == '1', 'String number formatting is broken.')
+
+assert('@0@'.format(true) == 'true', 'String boolean formatting is broken.')
+
+templ2 = '@0@'
+subs2 = '42'
+
+assert(templ2.format(subs2) == '42', 'String formatting with variables is broken.')
+
+assert('@@0@@ @@1@@'.format(1, 2) == '@1@ @2@', 'String format is recursive.')
+
+long = 'abcde'
+prefix = 'abc'
+suffix = 'cde'
+
+assert(long[0] == 'a')
+assert(long[2] == 'c')
+
+assert(long.replace('b', 'd') == 'adcde')
+assert(long.replace('z', 'x') == long)
+assert(long.replace(prefix, suffix) == 'cdede')
+
+assert(long.startswith(prefix), 'Prefix.')
+
+assert(not long.startswith(suffix), 'Not prefix.')
+
+assert(long.endswith(suffix), 'Suffix.')
+
+assert(not long.endswith(prefix), 'Not suffix.')
+
+assert(long.contains(prefix), 'Does not contain prefix')
+
+assert(long.contains(suffix), 'Does not contain suffix')
+
+assert(long.contains('bcd'), 'Does not contain middle part')
+
+assert(not long.contains('dc'), 'Broken contains')
+
+assert(long.to_upper() == 'ABCDE', 'Broken to_upper')
+
+assert(long.to_upper().to_lower() == long, 'Broken to_lower')
+
+assert('struct stat.st_foo'.underscorify() == 'struct_stat_st_foo', 'Broken underscorify')
+
+assert('#include <foo/bar.h>'.underscorify() == '_include__foo_bar_h_', 'Broken underscorify')
+
+# case should not change, space should be replaced, numbers are ok too
+assert('Do SomeThing 09'.underscorify() == 'Do_SomeThing_09', 'Broken underscorify')
+
+assert('3'.to_int() == 3, 'String int conversion does not work.')
+
+assert(true.to_string() == 'true', 'bool string conversion failed')
+assert(false.to_string() == 'false', 'bool string conversion failed')
+assert(true.to_string('yes', 'no') == 'yes', 'bool string conversion with args failed')
+assert(false.to_string('yes', 'no') == 'no', 'bool string conversion with args failed')
+assert('@0@'.format(true) == 'true', 'bool string formatting failed')
+assert('@0@'.format(['one', 'two']) == '[\'one\', \'two\']', 'list string formatting failed')
+
+assert(' '.join(['a', 'b', 'c']) == 'a b c', 'join() array broken')
+assert(''.join(['a', 'b', 'c']) == 'abc', 'empty join() broken')
+assert(' '.join(['a']) == 'a', 'single join broken')
+assert(' '.join(['a'], ['b', ['c']], 'd') == 'a b c d', 'varargs join broken')
+
+version_number = '1.2.8'
+
+assert(version_number.version_compare('>=1.2.8'), 'Version_compare gt broken')
+assert(not version_number.version_compare('>1.2.8'), 'Version_compare greater broken')
+assert(not version_number.version_compare('<1.2.8'), 'Version_compare less broken')
+assert(version_number.version_compare('<=1.2.8'), 'Version_compare le broken')
+assert(version_number.version_compare('==1.2.8'), 'Version_compare eq broken')
+assert(not version_number.version_compare('!=1.2.8'), 'Version_compare neq broken')
+
+assert(version_number.version_compare('<2.0'), 'Version_compare major less broken')
+assert(version_number.version_compare('>0.9'), 'Version_compare major greater broken')
+
+assert(' spaces tabs '.strip() == 'spaces tabs', 'Spaces and tabs badly stripped')
+assert('''
+multiline string '''.strip() == '''multiline string''', 'Newlines badly stripped')
+assert('"1.1.20"'.strip('"') == '1.1.20', '" badly stripped')
+assert('"1.1.20"'.strip('".') == '1.1.20', '". badly stripped')
+assert('"1.1.20" '.strip('" ') == '1.1.20', '". badly stripped')
+
+bs_c = '''\c'''
+bs_bs_c = '''\\c'''
+nl = '''
+'''
+bs_n = '''\n'''
+bs_nl = '''\
+'''
+bs_bs_n = '''\\n'''
+bs_bs_nl = '''\\
+'''
+bs_bs = '''\\'''
+bs = '''\'''
+
+assert('\c' == bs_c, 'Single backslash broken')
+assert('\\c' == bs_c, 'Double backslash broken')
+assert('\\\c' == bs_bs_c, 'Three backslash broken')
+assert('\\\\c' == bs_bs_c, 'Four backslash broken')
+assert('\n' == nl, 'Newline escape broken')
+assert('\\n' == bs_n, 'Double backslash broken before n')
+assert('\\\n' == bs_nl, 'Three backslash broken before n')
+assert('\\\\n' == bs_bs_n, 'Four backslash broken before n')
+assert('\\\\\n' == bs_bs_nl, 'Five backslash broken before n')
+assert('\\\\' == bs_bs, 'Double-backslash broken')
+assert('\\' == bs, 'Backslash broken')
+
+mysubstring='foobarbaz'
+assert(mysubstring.substring() == 'foobarbaz', 'substring is broken')
+assert(mysubstring.substring(0) == 'foobarbaz', 'substring is broken')
+assert(mysubstring.substring(1) == 'oobarbaz', 'substring is broken')
+assert(mysubstring.substring(-5) == 'arbaz', 'substring is broken')
+assert(mysubstring.substring(1, 4) == 'oob', 'substring is broken')
+assert(mysubstring.substring(1,-5) == 'oob', 'substring is broken')
+assert(mysubstring.substring(1, 0) == '', 'substring is broken')
+assert(mysubstring.substring(0, 100) == 'foobarbaz', 'substring is broken')
+assert(mysubstring.substring(-1, -5) == '', 'substring is broken')
+assert(mysubstring.substring(10, -25) == '', 'substring is broken')
+assert(mysubstring.substring(-4, 2) == '', 'substring is broken')
+assert(mysubstring.substring(10, 9) == '', 'substring is broken')
+assert(mysubstring.substring(8, 10) == 'z', 'substring is broken')
diff --git a/test cases/common/36 has function/meson.build b/test cases/common/36 has function/meson.build
new file mode 100644
index 0000000..a3f0a3c
--- /dev/null
+++ b/test cases/common/36 has function/meson.build
@@ -0,0 +1,116 @@
+project('has function', 'c', 'cpp')
+
+host_system = host_machine.system()
+
+# This is used in the `test_compiler_check_flags_order` unit test
+unit_test_args = '-I/tmp'
+defines_has_builtin = '''#ifndef __has_builtin
+#error "no __has_builtin"
+#endif
+'''
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
+
+foreach cc : compilers
+ if not cc.has_function('printf', prefix : '#include<stdio.h>',
+ args : unit_test_args)
+ error('"printf" function not found (should always exist).')
+ endif
+
+ # Should also be able to detect it without specifying the header
+ # We check for a different function here to make sure the result is
+ # not taken from a cache (ie. the check above)
+ # On MSVC fprintf is defined as an inline function in the header, so it cannot
+ # be found without the include.
+ if not ['msvc', 'intel-cl'].contains(cc.get_id())
+ assert(cc.has_function('fprintf', args : unit_test_args),
+ '"fprintf" function not found without include (on !msvc).')
+ else
+ assert(cc.has_function('fprintf', prefix : '#include <stdio.h>',
+ args : unit_test_args),
+ '"fprintf" function not found with include (on msvc).')
+ # Compiler intrinsics
+ assert(cc.has_function('strcmp'),
+ 'strcmp intrinsic should have been found on MSVC')
+ assert(cc.has_function('strcmp', prefix : '#include <string.h>'),
+ 'strcmp intrinsic should have been found with #include on MSVC')
+ endif
+
+ if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>',
+ args : unit_test_args)
+ error('Found non-existent function "hfkerhisadf".')
+ endif
+
+ if cc.has_function('hfkerhisadf', args : unit_test_args)
+ error('Found non-existent function "hfkerhisadf".')
+ endif
+
+ # With glibc (before 2.32, see below) on Linux, lchmod is a stub that will
+ # always return an error, we want to detect that and declare that the
+ # function is not available.
+ # We can't check for the C library used here of course, but the main
+ # alternative Linux C library (musl) doesn't use glibc's stub mechanism;
+ # also, it has implemented lchmod since 2013, so it should be safe to check
+ # that lchmod is available on Linux when not using glibc.
+ if host_system == 'linux' or host_system == 'darwin'
+ assert (cc.has_function('poll', prefix : '#include <poll.h>',
+ args : unit_test_args),
+ 'couldn\'t detect "poll" when defined by a header')
+ lchmod_prefix = '#include <sys/stat.h>\n#include <unistd.h>'
+ has_lchmod = cc.has_function('lchmod', prefix : lchmod_prefix, args : unit_test_args)
+
+ if host_system == 'linux'
+ # __GLIBC__ macro can be retrieved by including almost any C library header
+ glibc_major = cc.get_define('__GLIBC__', prefix: '#include <unistd.h>', args: unit_test_args)
+ # __GLIBC__ will only be set for glibc
+ if glibc_major != ''
+ glibc_minor = cc.get_define('__GLIBC_MINOR__', prefix: '#include <unistd.h>', args: unit_test_args)
+ glibc_vers = '@0@.@1@'.format(glibc_major, glibc_minor)
+ message('GLIBC version:', glibc_vers)
+
+ # lchmod was implemented in glibc 2.32 (https://sourceware.org/pipermail/libc-announce/2020/000029.html)
+ if glibc_vers.version_compare('<2.32')
+ assert (not has_lchmod, '"lchmod" check should have failed')
+ else
+ assert (has_lchmod, '"lchmod" check should have succeeded')
+ endif
+ else
+ # Other C libraries for Linux should have lchmod
+ assert (has_lchmod, '"lchmod" check should have succeeded')
+ endif
+ else
+ # macOS and *BSD have lchmod
+ assert (has_lchmod, '"lchmod" check should have succeeded')
+ endif
+ # Check that built-ins are found properly both with and without headers
+ assert(cc.has_function('alloca', args : unit_test_args),
+ 'built-in alloca must be found on ' + host_system)
+ assert(cc.has_function('alloca', prefix : '#include <alloca.h>',
+ args : unit_test_args),
+ 'built-in alloca must be found with #include')
+ if not cc.compiles(defines_has_builtin, args : unit_test_args)
+ assert(not cc.has_function('alloca',
+ prefix : '#include <alloca.h>\n#undef alloca',
+ args : unit_test_args),
+ 'built-in alloca must not be found with #include and #undef')
+ endif
+ endif
+
+ # For some functions one needs to define _GNU_SOURCE before including the
+ # right headers to get them picked up. Make sure we can detect these functions
+ # as well without any prefix
+ if cc.has_header_symbol('sys/socket.h', 'recvmmsg',
+ prefix : '#define _GNU_SOURCE',
+ args : unit_test_args)
+ # We assume that if recvmmsg exists sendmmsg does too
+ assert (cc.has_function('sendmmsg', args : unit_test_args),
+ 'Failed to detect function "sendmmsg" (should always exist).')
+ endif
+
+ # We should be able to find GCC and Clang __builtin functions
+ if ['gcc', 'clang'].contains(cc.get_id())
+ # __builtin_constant_p is documented to exist at least as far back as
+ # GCC 2.95.3
+ assert(cc.has_function('__builtin_constant_p', args : unit_test_args),
+ '__builtin_constant_p must be found under gcc and clang')
+ endif
+endforeach
diff --git a/test cases/common/37 has member/meson.build b/test cases/common/37 has member/meson.build
new file mode 100644
index 0000000..4e61956
--- /dev/null
+++ b/test cases/common/37 has member/meson.build
@@ -0,0 +1,21 @@
+project('has member', 'c', 'cpp')
+
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
+
+foreach cc : compilers
+ if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>')
+ error('Did not detect member of "struct tm" that exists: "tm_sec"')
+ endif
+
+ if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>')
+ error('Not existing member "tm_nonexistent" found.')
+ endif
+
+ if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>')
+ error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"')
+ endif
+
+ if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>')
+ error('Not existing member "tm_nonexistent2" found.')
+ endif
+endforeach
diff --git a/test cases/common/38 alignment/meson.build b/test cases/common/38 alignment/meson.build
new file mode 100644
index 0000000..a9bd65b
--- /dev/null
+++ b/test cases/common/38 alignment/meson.build
@@ -0,0 +1,31 @@
+project('alignment', 'c', 'cpp')
+
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
+
+foreach cc : compilers
+ # These tests should return the same value on all
+ # platforms. If (and when) they don't, fix 'em up.
+ if cc.alignment('char') != 1
+ error('Alignment of char misdetected.')
+ endif
+
+ ptr_size = cc.sizeof('void*')
+ dbl_alignment = cc.alignment('double')
+
+ # These tests are not thorough. Doing this properly
+ # would take a lot of work because it is strongly
+ # platform and compiler dependent. So just check
+ # that they produce something fairly sane.
+
+ if ptr_size == 8 or ptr_size == 4
+ message('Size of ptr ok.')
+ else
+ error('Size of ptr misdetected.')
+ endif
+
+ if dbl_alignment == 8 or dbl_alignment == 4
+ message('Alignment of double ok.')
+ else
+ error('Alignment of double misdetected.')
+ endif
+endforeach
diff --git a/test cases/common/39 library chain/main.c b/test cases/common/39 library chain/main.c
new file mode 100644
index 0000000..9c88e73
--- /dev/null
+++ b/test cases/common/39 library chain/main.c
@@ -0,0 +1,5 @@
+int libfun(void);
+
+int main(void) {
+ return libfun();
+}
diff --git a/test cases/common/39 library chain/meson.build b/test cases/common/39 library chain/meson.build
new file mode 100644
index 0000000..77528d7
--- /dev/null
+++ b/test cases/common/39 library chain/meson.build
@@ -0,0 +1,5 @@
+project('libchain', 'c')
+
+subdir('subdir')
+e = executable('prog', 'main.c', link_with : lib1, install : true)
+test('tst', e)
diff --git a/test cases/common/39 library chain/subdir/lib1.c b/test cases/common/39 library chain/subdir/lib1.c
new file mode 100644
index 0000000..88436b2
--- /dev/null
+++ b/test cases/common/39 library chain/subdir/lib1.c
@@ -0,0 +1,17 @@
+int lib2fun(void);
+int lib3fun(void);
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC libfun(void) {
+ return lib2fun() + lib3fun();
+}
diff --git a/test cases/common/39 library chain/subdir/meson.build b/test cases/common/39 library chain/subdir/meson.build
new file mode 100644
index 0000000..ab71bda
--- /dev/null
+++ b/test cases/common/39 library chain/subdir/meson.build
@@ -0,0 +1,4 @@
+subdir('subdir2')
+subdir('subdir3')
+
+lib1 = shared_library('lib1', 'lib1.c', install : false, link_with : [lib2, lib3])
diff --git a/test cases/common/39 library chain/subdir/subdir2/lib2.c b/test cases/common/39 library chain/subdir/subdir2/lib2.c
new file mode 100644
index 0000000..e788f07
--- /dev/null
+++ b/test cases/common/39 library chain/subdir/subdir2/lib2.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC lib2fun(void) {
+ return 0;
+}
diff --git a/test cases/common/39 library chain/subdir/subdir2/meson.build b/test cases/common/39 library chain/subdir/subdir2/meson.build
new file mode 100644
index 0000000..befd94d
--- /dev/null
+++ b/test cases/common/39 library chain/subdir/subdir2/meson.build
@@ -0,0 +1 @@
+lib2 = shared_library('lib2', 'lib2.c', install : false)
diff --git a/test cases/common/39 library chain/subdir/subdir3/lib3.c b/test cases/common/39 library chain/subdir/subdir3/lib3.c
new file mode 100644
index 0000000..a99c64e
--- /dev/null
+++ b/test cases/common/39 library chain/subdir/subdir3/lib3.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC lib3fun(void) {
+ return 0;
+}
diff --git a/test cases/common/39 library chain/subdir/subdir3/meson.build b/test cases/common/39 library chain/subdir/subdir3/meson.build
new file mode 100644
index 0000000..7bd249a
--- /dev/null
+++ b/test cases/common/39 library chain/subdir/subdir3/meson.build
@@ -0,0 +1 @@
+lib3 = shared_library('lib3', 'lib3.c', install : false)
diff --git a/test cases/common/39 library chain/test.json b/test cases/common/39 library chain/test.json
new file mode 100644
index 0000000..135300d
--- /dev/null
+++ b/test cases/common/39 library chain/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/common/4 shared/libfile.c b/test cases/common/4 shared/libfile.c
new file mode 100644
index 0000000..0797eec
--- /dev/null
+++ b/test cases/common/4 shared/libfile.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC libfunc(void) {
+ return 3;
+}
diff --git a/test cases/common/4 shared/meson.build b/test cases/common/4 shared/meson.build
new file mode 100644
index 0000000..1c88bc5
--- /dev/null
+++ b/test cases/common/4 shared/meson.build
@@ -0,0 +1,13 @@
+project('shared library test', 'c')
+lib = shared_library('mylib', 'libfile.c')
+build_target('mylib2', 'libfile.c', target_type: 'shared_library')
+
+has_not_changed = false
+if is_disabler(lib)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'Shared library has changed.')
+
+assert(not is_disabler(lib), 'Shared library is a disabler.')
diff --git a/test cases/common/40 options/meson.build b/test cases/common/40 options/meson.build
new file mode 100644
index 0000000..2eccef7
--- /dev/null
+++ b/test cases/common/40 options/meson.build
@@ -0,0 +1,45 @@
+project('options', 'c')
+
+if get_option('testoption') != 'optval'
+ error('Incorrect value to test option')
+endif
+
+if get_option('other_one') != false
+ error('Incorrect value to boolean option.')
+endif
+
+if get_option('combo_opt') != 'combo'
+ error('Incorrect value to combo option.')
+endif
+
+if get_option('array_opt') != ['one', 'two']
+ message(get_option('array_opt'))
+ error('Incorrect value for array option')
+endif
+
+# If the default changes, update test cases/unit/13 reconfigure
+if get_option('b_lto') != false
+ error('Incorrect value in base option.')
+endif
+
+if get_option('includedir') != 'include'
+ error('Incorrect value in builtin option.')
+endif
+
+if get_option('integer_opt') != 3
+ error('Incorrect value in integer option.')
+endif
+
+if get_option('neg_int_opt') != -3
+ error('Incorrect value in negative integer option.')
+endif
+
+if get_option('CaseSenSiTivE') != 'Some CAPS'
+ error('Incorrect value in mixed caps option.')
+endif
+
+if get_option('CASESENSITIVE') != 'ALL CAPS'
+ error('Incorrect value in all caps option.')
+endif
+
+assert(get_option('wrap_mode') == 'default', 'Wrap mode option is broken.')
diff --git a/test cases/common/40 options/meson_options.txt b/test cases/common/40 options/meson_options.txt
new file mode 100644
index 0000000..8067eae
--- /dev/null
+++ b/test cases/common/40 options/meson_options.txt
@@ -0,0 +1,9 @@
+option('testoption', type : 'string', value : 'optval', description : 'An option ' + 'to do something')
+option('other_one', type : 'boolean', value : not (not (not (not false))))
+option('combo_opt', type : 'co' + 'mbo', choices : ['one', 'two', 'combo'], value : 'combo')
+option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one', 'two'])
+option('free_array_opt', type : 'array')
+option('integer_opt', type : 'integer', min : 0, max : -(-5), value : 3)
+option('neg' + '_' + 'int' + '_' + 'opt', type : 'integer', min : -5, max : 5, value : -3)
+option('CaseSenSiTivE', type : 'string', value: 'Some CAPS', description : 'An option with mixed capitaliziation')
+option('CASESENSITIVE', type : 'string', value: 'ALL CAPS', description : 'An option with all caps')
diff --git a/test cases/common/41 test args/cmd_args.c b/test cases/common/41 test args/cmd_args.c
new file mode 100644
index 0000000..545b795
--- /dev/null
+++ b/test cases/common/41 test args/cmd_args.c
@@ -0,0 +1,18 @@
+#include<stdio.h>
+#include<string.h>
+
+int main(int argc, char **argv) {
+ if(argc != 3) {
+ fprintf(stderr, "Incorrect number of arguments.\n");
+ return 1;
+ }
+ if(strcmp(argv[1], "first") != 0) {
+ fprintf(stderr, "First argument is wrong.\n");
+ return 1;
+ }
+ if(strcmp(argv[2], "second") != 0) {
+ fprintf(stderr, "Second argument is wrong.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/41 test args/copyfile.py b/test cases/common/41 test args/copyfile.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/common/41 test args/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/41 test args/env2vars.c b/test cases/common/41 test args/env2vars.c
new file mode 100644
index 0000000..e940c9a
--- /dev/null
+++ b/test cases/common/41 test args/env2vars.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<string.h>
+#include<stdlib.h>
+
+int main(void) {
+ if(strcmp(getenv("first"), "something-else") != 0) {
+ fprintf(stderr, "First envvar is wrong. %s\n", getenv("first"));
+ return 1;
+ }
+ if(strcmp(getenv("second"), "val2") != 0) {
+ fprintf(stderr, "Second envvar is wrong.\n");
+ return 1;
+ }
+ if(strcmp(getenv("third"), "val3:and_more") != 0) {
+ fprintf(stderr, "Third envvar is wrong.\n");
+ return 1;
+ }
+ if(strstr(getenv("PATH"), "fakepath:") != NULL) {
+ fprintf(stderr, "Third envvar is wrong.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/41 test args/envvars.c b/test cases/common/41 test args/envvars.c
new file mode 100644
index 0000000..086b0be
--- /dev/null
+++ b/test cases/common/41 test args/envvars.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<string.h>
+#include<stdlib.h>
+
+int main(void) {
+ if(strcmp(getenv("first"), "val1") != 0) {
+ fprintf(stderr, "First envvar is wrong. %s\n", getenv("first"));
+ return 1;
+ }
+ if(strcmp(getenv("second"), "val2") != 0) {
+ fprintf(stderr, "Second envvar is wrong.\n");
+ return 1;
+ }
+ if(strcmp(getenv("third"), "val3:and_more") != 0) {
+ fprintf(stderr, "Third envvar is wrong.\n");
+ return 1;
+ }
+ if(strstr(getenv("PATH"), "fakepath:") != NULL) {
+ fprintf(stderr, "Third envvar is wrong.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/41 test args/meson.build b/test cases/common/41 test args/meson.build
new file mode 100644
index 0000000..b21f1ad
--- /dev/null
+++ b/test cases/common/41 test args/meson.build
@@ -0,0 +1,35 @@
+project('test features', 'c')
+
+e1 = executable('cmd_args', 'cmd_args.c')
+e2 = executable('envvars', 'envvars.c')
+e3 = executable('env2vars', 'env2vars.c')
+
+env = environment()
+env.set('first', 'val1')
+env.set('second', 'val2')
+env.set('third', 'val3', 'and_more', separator: ':')
+env.append('PATH', 'fakepath', separator: ':')
+
+# Make sure environment objects are copied on assignment and we can
+# change the copy without affecting the original environment object.
+env2 = env
+env2.set('first', 'something-else')
+
+test('command line arguments', e1, args : ['first', 'second'])
+test('environment variables', e2, env : env)
+test('environment variables 2', e3, env : env2)
+
+# https://github.com/mesonbuild/meson/issues/2211#issuecomment-327741571
+env_array = ['MESONTESTING=picklerror']
+testfile = files('testfile.txt')
+testerpy = find_program('tester.py')
+test('file arg', testerpy, args : testfile, env : [env_array, 'TEST_LIST_FLATTENING=1'])
+
+copy = find_program('copyfile.py')
+tester = executable('tester', 'tester.c')
+testfilect = custom_target('testfile',
+ input : testfile,
+ output : 'outfile.txt',
+ build_by_default : true,
+ command : [copy, '@INPUT@', '@OUTPUT@'])
+test('custom target arg', tester, args : testfilect, env : env_array)
diff --git a/test cases/common/41 test args/tester.c b/test cases/common/41 test args/tester.c
new file mode 100644
index 0000000..419277e
--- /dev/null
+++ b/test cases/common/41 test args/tester.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+
+int main(int argc, char **argv) {
+ char data[10];
+ int fd, size;
+
+ if (argc != 2) {
+ fprintf(stderr, "Incorrect number of arguments, got %i\n", argc);
+ return 1;
+ }
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "First argument is wrong.\n");
+ return 1;
+ }
+
+ size = read(fd, data, 8);
+ if (size < 0) {
+ fprintf(stderr, "Failed to read: %s\n", strerror(errno));
+ return 1;
+ }
+ if (strncmp(data, "contents", 8) != 0) {
+ fprintf(stderr, "Contents don't match, got %s\n", data);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/41 test args/tester.py b/test cases/common/41 test args/tester.py
new file mode 100755
index 0000000..b5884cc
--- /dev/null
+++ b/test cases/common/41 test args/tester.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+
+import sys
+import os
+
+assert os.environ['MESONTESTING'] == 'picklerror'
+assert os.environ['TEST_LIST_FLATTENING'] == '1'
+
+with open(sys.argv[1]) as f:
+ if f.read() != 'contents\n':
+ sys.exit(1)
diff --git a/test cases/common/41 test args/testfile.txt b/test cases/common/41 test args/testfile.txt
new file mode 100644
index 0000000..12f00e9
--- /dev/null
+++ b/test cases/common/41 test args/testfile.txt
@@ -0,0 +1 @@
+contents
diff --git a/test cases/common/42 subproject/meson.build b/test cases/common/42 subproject/meson.build
new file mode 100644
index 0000000..7f322bc
--- /dev/null
+++ b/test cases/common/42 subproject/meson.build
@@ -0,0 +1,28 @@
+project('subproj user', 'c',
+ version : '2.3.4',
+ license : 'mylicense')
+
+assert(meson.project_name() == 'subproj user', 'Incorrect project name')
+
+sub = subproject('sublib', version : '1.0.0')
+
+if meson.project_version() != '2.3.4'
+ error('Incorrect master project version string:' + meson.project_version())
+endif
+
+if meson.is_subproject()
+ error('Claimed to be a subproject even though we are the master project.')
+endif
+
+inc = sub.get_variable('i')
+lib = sub.get_variable('l')
+
+e = executable('user', 'user.c', include_directories : inc, link_with : lib, install : true)
+test('subdirtest', e)
+
+meson.install_dependency_manifest('share/sublib/sublib.depmf')
+
+unknown_var = sub.get_variable('does-not-exist', [])
+if unknown_var != []
+ error ('unexpetced fallback value for subproject.get_variable()')
+endif
diff --git a/test cases/common/42 subproject/subprojects/sublib/include/subdefs.h b/test cases/common/42 subproject/subprojects/sublib/include/subdefs.h
new file mode 100644
index 0000000..6ae8462
--- /dev/null
+++ b/test cases/common/42 subproject/subprojects/sublib/include/subdefs.h
@@ -0,0 +1,21 @@
+#ifndef SUBDEFS_H_
+#define SUBDEFS_H_
+
+#if defined _WIN32 || defined __CYGWIN__
+#if defined BUILDING_SUB
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #define DLL_PUBLIC __declspec(dllimport)
+#endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC subfunc(void);
+
+#endif
diff --git a/test cases/common/42 subproject/subprojects/sublib/meson.build b/test cases/common/42 subproject/subprojects/sublib/meson.build
new file mode 100644
index 0000000..3a620fe
--- /dev/null
+++ b/test cases/common/42 subproject/subprojects/sublib/meson.build
@@ -0,0 +1,19 @@
+project('subproject', 'c',
+ version : '1.0.0',
+ license : ['sublicense1', 'sublicense2'])
+
+if not meson.is_subproject()
+ error('Claimed to be master project even though we are a subproject.')
+endif
+
+assert(meson.project_name() == 'subproject', 'Incorrect subproject name')
+
+if meson.project_version() != '1.0.0'
+ error('Incorrect version string in subproject.')
+endif
+
+i = include_directories('include')
+l = shared_library('sublib', 'sublib.c', include_directories : i, install : false,
+ c_args : '-DBUILDING_SUB=2')
+t = executable('simpletest', 'simpletest.c', include_directories : i, link_with : l)
+test('plain', t)
diff --git a/test cases/common/42 subproject/subprojects/sublib/simpletest.c b/test cases/common/42 subproject/subprojects/sublib/simpletest.c
new file mode 100644
index 0000000..2184bc6
--- /dev/null
+++ b/test cases/common/42 subproject/subprojects/sublib/simpletest.c
@@ -0,0 +1,5 @@
+#include<subdefs.h>
+
+int main(void) {
+ return subfunc() == 42 ? 0 : 1;
+}
diff --git a/test cases/common/42 subproject/subprojects/sublib/sublib.c b/test cases/common/42 subproject/subprojects/sublib/sublib.c
new file mode 100644
index 0000000..f71564f
--- /dev/null
+++ b/test cases/common/42 subproject/subprojects/sublib/sublib.c
@@ -0,0 +1,5 @@
+#include<subdefs.h>
+
+int DLL_PUBLIC subfunc(void) {
+ return 42;
+}
diff --git a/test cases/common/42 subproject/test.json b/test cases/common/42 subproject/test.json
new file mode 100644
index 0000000..a56106f
--- /dev/null
+++ b/test cases/common/42 subproject/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/user"},
+ {"type": "pdb", "file": "usr/bin/user"},
+ {"type": "file", "file": "usr/share/sublib/sublib.depmf"}
+ ]
+}
diff --git a/test cases/common/42 subproject/user.c b/test cases/common/42 subproject/user.c
new file mode 100644
index 0000000..9181622
--- /dev/null
+++ b/test cases/common/42 subproject/user.c
@@ -0,0 +1,16 @@
+#include<subdefs.h>
+#include<stdio.h>
+
+
+int main(void) {
+ int res;
+ printf("Calling into sublib now.\n");
+ res = subfunc();
+ if(res == 42) {
+ printf("Everything is fine.\n");
+ return 0;
+ } else {
+ printf("Something went wrong.\n");
+ return 1;
+ }
+}
diff --git a/test cases/common/43 subproject options/meson.build b/test cases/common/43 subproject options/meson.build
new file mode 100644
index 0000000..a905272
--- /dev/null
+++ b/test cases/common/43 subproject options/meson.build
@@ -0,0 +1,7 @@
+project('suboptions')
+
+subproject('subproject')
+
+if not get_option('opt')
+ error('option unset when it should be set')
+endif
diff --git a/test cases/common/43 subproject options/meson_options.txt b/test cases/common/43 subproject options/meson_options.txt
new file mode 100644
index 0000000..c295ddd
--- /dev/null
+++ b/test cases/common/43 subproject options/meson_options.txt
@@ -0,0 +1 @@
+option('opt', type : 'boolean', value : true, description : 'main project option')
diff --git a/test cases/common/43 subproject options/subprojects/subproject/meson.build b/test cases/common/43 subproject options/subprojects/subproject/meson.build
new file mode 100644
index 0000000..d00a024
--- /dev/null
+++ b/test cases/common/43 subproject options/subprojects/subproject/meson.build
@@ -0,0 +1,5 @@
+project('subproject')
+
+if get_option('opt')
+ error('option set when it should be unset.')
+endif
diff --git a/test cases/common/43 subproject options/subprojects/subproject/meson_options.txt b/test cases/common/43 subproject options/subprojects/subproject/meson_options.txt
new file mode 100644
index 0000000..ac78533
--- /dev/null
+++ b/test cases/common/43 subproject options/subprojects/subproject/meson_options.txt
@@ -0,0 +1 @@
+option('opt', type : 'boolean', value : false, description : 'subproject option')
diff --git a/test cases/common/44 pkgconfig-gen/answer.c b/test cases/common/44 pkgconfig-gen/answer.c
new file mode 100644
index 0000000..df5f54f
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/answer.c
@@ -0,0 +1,3 @@
+int answer_to_life_the_universe_and_everything(void) {
+ return 42;
+}
diff --git a/test cases/common/44 pkgconfig-gen/dependencies/custom.c b/test cases/common/44 pkgconfig-gen/dependencies/custom.c
new file mode 100644
index 0000000..1d3deca
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/dependencies/custom.c
@@ -0,0 +1,3 @@
+int custom_function(void) {
+ return 42;
+}
diff --git a/test cases/common/44 pkgconfig-gen/dependencies/dummy.c b/test cases/common/44 pkgconfig-gen/dependencies/dummy.c
new file mode 100644
index 0000000..ef7be51
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/dependencies/dummy.c
@@ -0,0 +1,3 @@
+int dummy(void) {
+ return 0;
+}
diff --git a/test cases/common/44 pkgconfig-gen/dependencies/exposed.c b/test cases/common/44 pkgconfig-gen/dependencies/exposed.c
new file mode 100644
index 0000000..caa4591
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/dependencies/exposed.c
@@ -0,0 +1,3 @@
+int exposed_function(void) {
+ return 42;
+}
diff --git a/test cases/common/44 pkgconfig-gen/dependencies/internal.c b/test cases/common/44 pkgconfig-gen/dependencies/internal.c
new file mode 100644
index 0000000..23b07ec
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/dependencies/internal.c
@@ -0,0 +1,3 @@
+int internal_function(void) {
+ return 42;
+}
diff --git a/test cases/common/44 pkgconfig-gen/dependencies/main.c b/test cases/common/44 pkgconfig-gen/dependencies/main.c
new file mode 100644
index 0000000..397d40c
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/dependencies/main.c
@@ -0,0 +1,10 @@
+#include <simple.h>
+
+#ifndef LIBFOO
+#error LIBFOO should be defined in pkgconfig cflags
+#endif
+
+int main(int argc, char *argv[])
+{
+ return simple_function() == 42 ? 0 : 1;
+}
diff --git a/test cases/common/44 pkgconfig-gen/dependencies/meson.build b/test cases/common/44 pkgconfig-gen/dependencies/meson.build
new file mode 100644
index 0000000..6e27ae8
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/dependencies/meson.build
@@ -0,0 +1,62 @@
+project('pkgconfig-gen-dependencies', 'c', version: '1.0')
+
+pkgg = import('pkgconfig')
+
+# libmain internally use libinternal and expose libexpose in its API
+exposed_lib = shared_library('libexposed', 'exposed.c')
+internal_lib = shared_library('libinternal', 'internal.c')
+main_lib = both_libraries('libmain', 'dummy.c', link_with : [exposed_lib, internal_lib])
+custom_lib = shared_library('custom', 'custom.c')
+
+pkgg.generate(exposed_lib)
+
+# Declare a few different Dependency objects
+pc_dep = dependency('libfoo', version : '>=1.0')
+pc_dep_dup = dependency('libfoo', version : '>= 1.0')
+notfound_dep = dependency('notfound', required : false)
+threads_dep = dependency('threads')
+custom_dep = declare_dependency(link_with : custom_lib, compile_args : ['-DCUSTOM'])
+custom2_dep = declare_dependency(link_args : ['-lcustom2'], compile_args : ['-DCUSTOM2'])
+
+exe = executable('test1', 'main.c', dependencies : [pc_dep])
+test('Test1', exe)
+
+# Generate a PC file:
+# - Having libmain in libraries should pull implicitly libexposed and libinternal in Libs.private
+# - Having libexposed in libraries should remove it from Libs.private
+# - We generated a pc file for libexposed so it should be in Requires instead of Libs
+# - Having threads_dep in libraries should add '-pthread' in both Libs and Cflags
+# - Having custom_dep in libraries and libraries_private should only add it in Libs
+# - Having custom2_dep in libraries_private should not add its Cflags
+# - Having pc_dep in libraries_private should add it in Requires.private
+# - pc_dep_dup is the same library and same version, should be ignored
+# - notfound_dep is not required so it shouldn't appear in the pc file.
+pkgg.generate(libraries : [main_lib, exposed_lib, threads_dep, threads_dep, custom_dep, custom_dep, '-pthread'],
+ libraries_private : [custom_dep, custom2_dep, custom2_dep, pc_dep, pc_dep_dup, notfound_dep],
+ version : '1.0',
+ name : 'dependency-test',
+ filebase : 'dependency-test',
+ description : 'A dependency test.'
+)
+
+pkgg.generate(
+ name : 'requires-test',
+ version : '1.0',
+ description : 'Dependency Requires field test.',
+ requires : [exposed_lib, pc_dep, 'libhello'],
+)
+
+pkgg.generate(
+ name : 'requires-private-test',
+ version : '1.0',
+ description : 'Dependency Requires.private field test.',
+ requires_private : [exposed_lib, pc_dep, 'libhello', notfound_dep],
+)
+
+# Verify that if we promote internal_lib as public dependency, it comes after
+# the main library.
+main_lib2 = both_libraries('libmain2', 'dummy.c', link_with : internal_lib)
+pkgg.generate(main_lib2,
+ libraries : internal_lib,
+ filebase : 'pub-lib-order',
+)
diff --git a/test cases/common/44 pkgconfig-gen/foo.c b/test cases/common/44 pkgconfig-gen/foo.c
new file mode 100644
index 0000000..83bb06a
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/foo.c
@@ -0,0 +1,7 @@
+#include"simple.h"
+
+int answer_to_life_the_universe_and_everything (void);
+
+int simple_function(void) {
+ return answer_to_life_the_universe_and_everything();
+}
diff --git a/test cases/common/44 pkgconfig-gen/meson.build b/test cases/common/44 pkgconfig-gen/meson.build
new file mode 100644
index 0000000..12a110e
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/meson.build
@@ -0,0 +1,178 @@
+project('pkgconfig-gen', 'c', meson_version: '>=0.60.0')
+
+# Some CI runners does not have zlib, just skip them as we need some common
+# external dependency.
+cc = meson.get_compiler('c')
+if not cc.find_library('z', required: false).found()
+ error('MESON_SKIP_TEST: zlib missing')
+endif
+
+# First check we have pkg-config >= 0.29
+pkgconfig = find_program('pkg-config', required: false)
+if not pkgconfig.found()
+ error('MESON_SKIP_TEST: pkg-config not found')
+endif
+
+v = run_command(pkgconfig, '--version', check: true).stdout().strip()
+if v.version_compare('<0.29')
+ error('MESON_SKIP_TEST: pkg-config version \'' + v + '\' too old')
+endif
+
+python = import('python').find_installation()
+fs = import('fs')
+pkgg = import('pkgconfig')
+
+lib = shared_library('simple', 'simple.c')
+libver = '1.0'
+h = install_headers('simple.h')
+
+pkgg.generate(
+ libraries : [lib, '-lz'],
+ subdirs : '.',
+ version : libver,
+ name : 'libsimple',
+ filebase : 'simple',
+ description : 'A simple demo library.',
+ requires : 'glib-2.0', # Not really, but only here to test that this works.
+ requires_private : ['gio-2.0', 'gobject-2.0'],
+ libraries_private : [lib, '-lz'],
+)
+
+env = environment()
+env.prepend('PKG_CONFIG_PATH', meson.current_build_dir() / 'meson-private')
+
+test(
+ 'pkgconfig-validation',
+ pkgconfig,
+ args: ['--validate', 'simple'],
+ env : env,
+)
+
+answerlib = shared_library('answer', 'answer.c')
+
+pkgg.generate(answerlib,
+ name : 'libanswer',
+ description : 'An answer library.',
+ extra_cflags : ['-DLIBFOO'],
+)
+
+# Test that name_prefix='' and name='libfoo' results in '-lfoo'
+lib2 = shared_library('libfoo', 'foo.c',
+ link_with: answerlib,
+ name_prefix : '',
+ version : libver)
+
+pkgg.generate(lib2,
+ libraries : [lib2, answerlib],
+ name : 'libfoo',
+ version : libver,
+ description : 'A foo library.',
+ variables : ['foo=bar', 'datadir=${prefix}/data'],
+ extra_cflags : ['-DLIBFOO'],
+)
+
+pkgg.generate(
+ name : 'libhello',
+ description : 'A minimalistic pkgconfig file.',
+ version : libver,
+)
+
+pkgg.generate(
+ name : 'libhello_nolib',
+ description : 'A minimalistic pkgconfig file.',
+ version : libver,
+ dataonly: true,
+ variables : {
+ 'foo': 'bar',
+ # prefix is not set by default for dataonly pc files, but it is allowed to
+ # define it manually.
+ 'prefix': get_option('prefix'),
+ 'escaped_var': 'hello world',
+ },
+ unescaped_variables: {
+ 'unescaped_var': 'hello world',
+ }
+)
+
+# Regression test for 2 cases:
+# - link_whole from InternalDependency used to be ignored, but we should still
+# recurse to add libraries they link to. In this case it must add `-lsimple1`
+# in generated pc file.
+# - dependencies from InternalDependency used to be ignored. In this it must add
+# `-lz` in generated pc file.
+simple1 = shared_library('simple1', 'simple.c')
+stat1 = static_library('stat1', 'simple.c', link_with: simple1)
+dep = declare_dependency(link_whole: stat1, dependencies: cc.find_library('z'))
+simple2 = library('simple2', 'simple.c')
+pkgg.generate(simple2, libraries: dep)
+
+# Regression test: as_system() does a deepcopy() of the InternalDependency object
+# which caused `-lsimple3` to be duplicated because generator used to compare
+# Target instances instead of their id.
+simple3 = shared_library('simple3', 'simple.c')
+dep1 = declare_dependency(link_with: simple3)
+dep2 = dep1.as_system()
+pkgg.generate(libraries: [dep1, dep2],
+ name: 'simple3',
+ description: 'desc')
+
+# Regression test: stat2 is both link_with and link_whole, it should not appear
+# in generated pc file.
+stat2 = static_library('stat2', 'simple.c', install: true)
+simple4 = library('simple4', 'simple.c', link_with: stat2)
+simple5 = library('simple5', 'simple5.c', link_with: simple4, link_whole: stat2)
+pkgg.generate(simple5)
+
+# Test passing a linkable CustomTarget and CustomTargetIndex to generator.
+# Do this only with gcc/clang to not have to deal with other compiler command
+# line specificities.
+if cc.get_id() in ['gcc', 'clang']
+ ct = custom_target('ct',
+ input: 'simple.c',
+ output: 'libct.so',
+ command: [cc.cmd_array(), '@INPUT@', '-shared', '-o', '@OUTPUT@'],
+ )
+ pkgg.generate(libraries: ct,
+ name: 'ct',
+ description: 'custom target'
+ )
+ pkgg.generate(libraries: ct[0],
+ name: 'ct0',
+ description: 'custom target index'
+ )
+endif
+
+# Regression test: A library linking to an uninstalled custom_target static
+# library used to crash when generating its pkgconfig file.
+# Copy libstat2.a to libstat3.a to have a static library as custom target.
+infile = stat2.full_path()
+outfile = meson.current_build_dir() / 'libstat3.a'
+script = 'import shutil ; shutil.copyfile("@0@", "@1@")'.format(infile, outfile)
+ct = custom_target('stat3',
+ input: stat2,
+ output: fs.name(outfile),
+ command: [python, '-c', script],
+)
+simple6 = library('simple6', 'dependencies/dummy.c', link_with: ct)
+pkgg.generate(simple6)
+
+# implicit variables
+pkgg.generate(
+ name : 'libvartest',
+ description : 'Check that implicit vars are created',
+ version : libver,
+ variables: ['datadir=${prefix}/data', 'foo=${datadir}/foo', 'bar=${bindir}/bar']
+)
+pkgg.generate(
+ name : 'libvartest2',
+ description : 'Check that libdir is not an implicit var',
+ version : libver,
+ variables: ['bar=${libdir}/bar']
+)
+
+# Regression test: variables kwarg should listify single string value
+pkgg.generate(
+ name : 'libvartest3',
+ description : 'Check that variables can be single string',
+ variables: 'foo=bar',
+)
diff --git a/test cases/common/44 pkgconfig-gen/simple.c b/test cases/common/44 pkgconfig-gen/simple.c
new file mode 100644
index 0000000..ff86f31
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/simple.c
@@ -0,0 +1,5 @@
+#include"simple.h"
+
+int simple_function(void) {
+ return 42;
+}
diff --git a/test cases/common/44 pkgconfig-gen/simple.h b/test cases/common/44 pkgconfig-gen/simple.h
new file mode 100644
index 0000000..6896bfd
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/simple.h
@@ -0,0 +1,6 @@
+#ifndef SIMPLE_H_
+#define SIMPLE_H_
+
+int simple_function(void);
+
+#endif
diff --git a/test cases/common/44 pkgconfig-gen/simple5.c b/test cases/common/44 pkgconfig-gen/simple5.c
new file mode 100644
index 0000000..9f924bd
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/simple5.c
@@ -0,0 +1,6 @@
+int simple5(void);
+
+int simple5(void)
+{
+ return 0;
+}
diff --git a/test cases/common/44 pkgconfig-gen/test.json b/test cases/common/44 pkgconfig-gen/test.json
new file mode 100644
index 0000000..4d9f4c8
--- /dev/null
+++ b/test cases/common/44 pkgconfig-gen/test.json
@@ -0,0 +1,33 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/simple.h"},
+ {"type": "file", "file": "usr/lib/libstat2.a"},
+ {"type": "file", "file": "usr/lib/pkgconfig/simple.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libanswer.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libfoo.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libhello.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libvartest.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libvartest2.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libvartest3.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/simple2.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/simple3.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/simple5.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/simple6.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/ct.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/ct0.pc"},
+ {"type": "file", "file": "usr/share/pkgconfig/libhello_nolib.pc"}
+ ],
+ "stdout": [
+ {
+ "line": "test cases/common/44 pkgconfig-gen/meson.build:164: WARNING: Project targets '>=0.60.0' but uses feature introduced in '0.62.0': pkgconfig.generate implicit variable for builtin directories."
+ },
+ {
+ "line": "test cases/common/44 pkgconfig-gen/meson.build:170: WARNING: Project targets '>=0.60.0' but uses feature introduced in '0.62.0': pkgconfig.generate implicit variable for builtin directories.",
+ "count": 0
+ },
+ {
+ "comment": "This will either match in the future-deprecated notice summary, or match the warning summary",
+ "line": " * 0.62.0: {'pkgconfig.generate variable for builtin directories'}"
+ }
+ ]
+}
diff --git a/test cases/common/45 custom install dirs/datafile.cat b/test cases/common/45 custom install dirs/datafile.cat
new file mode 100644
index 0000000..53d81fc
--- /dev/null
+++ b/test cases/common/45 custom install dirs/datafile.cat
@@ -0,0 +1 @@
+Installed cat is installed.
diff --git a/test cases/common/45 custom install dirs/meson.build b/test cases/common/45 custom install dirs/meson.build
new file mode 100644
index 0000000..494ff0e
--- /dev/null
+++ b/test cases/common/45 custom install dirs/meson.build
@@ -0,0 +1,11 @@
+project('custom install dirs', 'c')
+executable('prog', 'prog.c', install : true, install_dir : 'dib/dab/dub')
+executable('prog2', 'prog.c', install : true, install_dir : get_option('prefix') + '/dib/dab/dub2')
+install_headers('sample.h', install_dir : 'some/dir')
+install_headers('sample.h', install_dir : get_option('prefix') + '/some/dir2')
+install_man('prog.1', install_dir : 'woman')
+install_man('prog.1', install_dir : get_option('prefix') + '/woman2')
+install_data('datafile.cat', install_dir : 'meow')
+install_data('datafile.cat', install_dir : get_option('prefix') + '/meow2')
+install_subdir('subdir', install_dir : 'woof')
+install_subdir('subdir', install_dir : get_option('prefix') + '/woof2')
diff --git a/test cases/common/45 custom install dirs/prog.1 b/test cases/common/45 custom install dirs/prog.1
new file mode 100644
index 0000000..08ef7da
--- /dev/null
+++ b/test cases/common/45 custom install dirs/prog.1
@@ -0,0 +1 @@
+Man up, you.
diff --git a/test cases/common/45 custom install dirs/prog.c b/test cases/common/45 custom install dirs/prog.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/common/45 custom install dirs/prog.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/45 custom install dirs/sample.h b/test cases/common/45 custom install dirs/sample.h
new file mode 100644
index 0000000..dc030da
--- /dev/null
+++ b/test cases/common/45 custom install dirs/sample.h
@@ -0,0 +1,6 @@
+#ifndef SAMPLE_H
+#define SAMPLE_H
+
+int wackiness();
+
+#endif
diff --git a/test cases/common/45 custom install dirs/subdir/datafile.dog b/test cases/common/45 custom install dirs/subdir/datafile.dog
new file mode 100644
index 0000000..7a5bcb7
--- /dev/null
+++ b/test cases/common/45 custom install dirs/subdir/datafile.dog
@@ -0,0 +1 @@
+Installed dog is installed.
diff --git a/test cases/common/45 custom install dirs/test.json b/test cases/common/45 custom install dirs/test.json
new file mode 100644
index 0000000..ac82fdb
--- /dev/null
+++ b/test cases/common/45 custom install dirs/test.json
@@ -0,0 +1,16 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/dib/dab/dub/prog"},
+ {"type": "pdb", "file": "usr/dib/dab/dub/prog"},
+ {"type": "exe", "file": "usr/dib/dab/dub2/prog2"},
+ {"type": "pdb", "file": "usr/dib/dab/dub2/prog2"},
+ {"type": "file", "file": "usr/some/dir/sample.h"},
+ {"type": "file", "file": "usr/some/dir2/sample.h"},
+ {"type": "file", "file": "usr/woman/prog.1"},
+ {"type": "file", "file": "usr/woman2/prog.1"},
+ {"type": "file", "file": "usr/meow/datafile.cat"},
+ {"type": "file", "file": "usr/meow2/datafile.cat"},
+ {"type": "file", "file": "usr/woof/subdir/datafile.dog"},
+ {"type": "file", "file": "usr/woof2/subdir/datafile.dog"}
+ ]
+}
diff --git a/test cases/common/46 subproject subproject/meson.build b/test cases/common/46 subproject subproject/meson.build
new file mode 100644
index 0000000..d8735a1
--- /dev/null
+++ b/test cases/common/46 subproject subproject/meson.build
@@ -0,0 +1,11 @@
+project('sub sub', 'c')
+
+a = subproject('a')
+lib = a.get_variable('l')
+
+dependency('not-found-dep', required : false,
+ version : '>=1',
+ fallback : ['c', 'notfound_dep'])
+
+exe = executable('prog', 'prog.c', link_with : lib)
+test('basic', exe)
diff --git a/test cases/common/46 subproject subproject/prog.c b/test cases/common/46 subproject subproject/prog.c
new file mode 100644
index 0000000..27162c5
--- /dev/null
+++ b/test cases/common/46 subproject subproject/prog.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func() == 42 ? 0 : 1;
+}
diff --git a/test cases/common/46 subproject subproject/subprojects/a/a.c b/test cases/common/46 subproject subproject/subprojects/a/a.c
new file mode 100644
index 0000000..102041e
--- /dev/null
+++ b/test cases/common/46 subproject subproject/subprojects/a/a.c
@@ -0,0 +1,14 @@
+int func2(void);
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func(void) { return func2(); }
diff --git a/test cases/common/46 subproject subproject/subprojects/a/meson.build b/test cases/common/46 subproject subproject/subprojects/a/meson.build
new file mode 100644
index 0000000..f0dfc44
--- /dev/null
+++ b/test cases/common/46 subproject subproject/subprojects/a/meson.build
@@ -0,0 +1,4 @@
+project('a', 'c')
+
+b = subproject('b')
+l = shared_library('a', 'a.c', link_with : b.get_variable('lb'))
diff --git a/test cases/common/46 subproject subproject/subprojects/b/b.c b/test cases/common/46 subproject subproject/subprojects/b/b.c
new file mode 100644
index 0000000..8c07177
--- /dev/null
+++ b/test cases/common/46 subproject subproject/subprojects/b/b.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func2(void) {
+ return 42;
+}
diff --git a/test cases/common/46 subproject subproject/subprojects/b/meson.build b/test cases/common/46 subproject subproject/subprojects/b/meson.build
new file mode 100644
index 0000000..e7af606
--- /dev/null
+++ b/test cases/common/46 subproject subproject/subprojects/b/meson.build
@@ -0,0 +1,3 @@
+project('b', 'c')
+
+lb = shared_library('b', 'b.c')
diff --git a/test cases/common/46 subproject subproject/subprojects/c/meson.build b/test cases/common/46 subproject subproject/subprojects/c/meson.build
new file mode 100644
index 0000000..97a5be1
--- /dev/null
+++ b/test cases/common/46 subproject subproject/subprojects/c/meson.build
@@ -0,0 +1,3 @@
+project('not-found-dep-subproj', 'c', version : '1.0')
+
+notfound_dep = dependency('', required : false)
diff --git a/test cases/common/47 same file name/d1/file.c b/test cases/common/47 same file name/d1/file.c
new file mode 100644
index 0000000..46e5172
--- /dev/null
+++ b/test cases/common/47 same file name/d1/file.c
@@ -0,0 +1 @@
+int func1(void) { return 42; }
diff --git a/test cases/common/47 same file name/d2/file.c b/test cases/common/47 same file name/d2/file.c
new file mode 100644
index 0000000..3d367f1
--- /dev/null
+++ b/test cases/common/47 same file name/d2/file.c
@@ -0,0 +1 @@
+int func2(void) { return 42; }
diff --git a/test cases/common/47 same file name/meson.build b/test cases/common/47 same file name/meson.build
new file mode 100644
index 0000000..3f351af
--- /dev/null
+++ b/test cases/common/47 same file name/meson.build
@@ -0,0 +1,3 @@
+project('samefile', 'c')
+
+test('basic', executable('prog', 'prog.c', 'd1/file.c', 'd2/file.c'))
diff --git a/test cases/common/47 same file name/prog.c b/test cases/common/47 same file name/prog.c
new file mode 100644
index 0000000..1eee6c2
--- /dev/null
+++ b/test cases/common/47 same file name/prog.c
@@ -0,0 +1,6 @@
+int func1(void);
+int func2(void);
+
+int main(void) {
+ return func1() - func2();
+}
diff --git a/test cases/common/48 file grabber/a.c b/test cases/common/48 file grabber/a.c
new file mode 100644
index 0000000..8f63c2d
--- /dev/null
+++ b/test cases/common/48 file grabber/a.c
@@ -0,0 +1 @@
+int funca(void) { return 0; }
diff --git a/test cases/common/48 file grabber/b.c b/test cases/common/48 file grabber/b.c
new file mode 100644
index 0000000..f38baca
--- /dev/null
+++ b/test cases/common/48 file grabber/b.c
@@ -0,0 +1 @@
+int funcb(void) { return 0; }
diff --git a/test cases/common/48 file grabber/c.c b/test cases/common/48 file grabber/c.c
new file mode 100644
index 0000000..2e8abbf
--- /dev/null
+++ b/test cases/common/48 file grabber/c.c
@@ -0,0 +1 @@
+int funcc(void) { return 0; }
diff --git a/test cases/common/48 file grabber/grabber.bat b/test cases/common/48 file grabber/grabber.bat
new file mode 100644
index 0000000..8660314
--- /dev/null
+++ b/test cases/common/48 file grabber/grabber.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+echo a.c
+echo b.c
+echo c.c
+echo prog.c
diff --git a/test cases/common/48 file grabber/grabber.sh b/test cases/common/48 file grabber/grabber.sh
new file mode 100755
index 0000000..5e8f4b9
--- /dev/null
+++ b/test cases/common/48 file grabber/grabber.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+for i in *.c; do
+ echo $i
+done
diff --git a/test cases/common/48 file grabber/grabber2.bat b/test cases/common/48 file grabber/grabber2.bat
new file mode 100644
index 0000000..d1a3f98
--- /dev/null
+++ b/test cases/common/48 file grabber/grabber2.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+echo suba.c
+echo subb.c
+echo subc.c
+echo subprog.c
diff --git a/test cases/common/48 file grabber/meson.build b/test cases/common/48 file grabber/meson.build
new file mode 100644
index 0000000..a042b23
--- /dev/null
+++ b/test cases/common/48 file grabber/meson.build
@@ -0,0 +1,35 @@
+project('grabber', 'c')
+
+# What this script does is NOT reliable. Simply adding a file in this directory
+# will NOT make it automatically appear in the build. You have to manually
+# re-invoke Meson (not just Ninja) for that to happen. The simplest way
+# is to touch meson-private/coredata.dat.
+
+# This is not the recommended way to do things, but if the tradeoffs are
+# acceptable to you, then we're certainly not going to stop you. Just don't
+# file bugs when it fails. :)
+
+if build_machine.system() == 'windows'
+ c = run_command('grabber.bat', check: false)
+ grabber = find_program('grabber2.bat')
+else
+ c = run_command('grabber.sh', check: false)
+ grabber = find_program('grabber.sh')
+endif
+
+
+# First test running command explicitly.
+if c.returncode() != 0
+ error('Executing script failed.')
+endif
+
+newline = '''
+'''
+
+sources = c.stdout().strip().split(newline)
+
+e = executable('prog', sources)
+test('grabtest', e)
+
+# Then test using program with find_program
+subdir('subdir')
diff --git a/test cases/common/48 file grabber/prog.c b/test cases/common/48 file grabber/prog.c
new file mode 100644
index 0000000..ff55723
--- /dev/null
+++ b/test cases/common/48 file grabber/prog.c
@@ -0,0 +1,7 @@
+int funca(void);
+int funcb(void);
+int funcc(void);
+
+int main(void) {
+ return funca() + funcb() + funcc();
+}
diff --git a/test cases/common/48 file grabber/subdir/meson.build b/test cases/common/48 file grabber/subdir/meson.build
new file mode 100644
index 0000000..9990e30
--- /dev/null
+++ b/test cases/common/48 file grabber/subdir/meson.build
@@ -0,0 +1,5 @@
+sc = run_command(grabber, check: true)
+subsources = sc.stdout().strip().split(newline)
+
+se = executable('subprog', subsources)
+test('subgrabtest', se)
diff --git a/test cases/common/48 file grabber/subdir/suba.c b/test cases/common/48 file grabber/subdir/suba.c
new file mode 100644
index 0000000..8f63c2d
--- /dev/null
+++ b/test cases/common/48 file grabber/subdir/suba.c
@@ -0,0 +1 @@
+int funca(void) { return 0; }
diff --git a/test cases/common/48 file grabber/subdir/subb.c b/test cases/common/48 file grabber/subdir/subb.c
new file mode 100644
index 0000000..f38baca
--- /dev/null
+++ b/test cases/common/48 file grabber/subdir/subb.c
@@ -0,0 +1 @@
+int funcb(void) { return 0; }
diff --git a/test cases/common/48 file grabber/subdir/subc.c b/test cases/common/48 file grabber/subdir/subc.c
new file mode 100644
index 0000000..2e8abbf
--- /dev/null
+++ b/test cases/common/48 file grabber/subdir/subc.c
@@ -0,0 +1 @@
+int funcc(void) { return 0; }
diff --git a/test cases/common/48 file grabber/subdir/subprog.c b/test cases/common/48 file grabber/subdir/subprog.c
new file mode 100644
index 0000000..ff55723
--- /dev/null
+++ b/test cases/common/48 file grabber/subdir/subprog.c
@@ -0,0 +1,7 @@
+int funca(void);
+int funcb(void);
+int funcc(void);
+
+int main(void) {
+ return funca() + funcb() + funcc();
+}
diff --git a/test cases/common/49 custom target/data_source.txt b/test cases/common/49 custom target/data_source.txt
new file mode 100644
index 0000000..0c23cc0
--- /dev/null
+++ b/test cases/common/49 custom target/data_source.txt
@@ -0,0 +1 @@
+This is a text only input file.
diff --git a/test cases/common/49 custom target/depfile/dep.py b/test cases/common/49 custom target/depfile/dep.py
new file mode 100755
index 0000000..c9e8f94
--- /dev/null
+++ b/test cases/common/49 custom target/depfile/dep.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import sys, os
+from glob import glob
+
+_, srcdir, depfile, output = sys.argv
+
+depfiles = glob(os.path.join(srcdir, '*'))
+
+quoted_depfiles = [x.replace(' ', r'\ ') for x in depfiles]
+
+with open(output, 'w') as f:
+ f.write('I am the result of globbing.')
+with open(depfile, 'w') as f:
+ f.write('{}: {}\n'.format(output, ' '.join(quoted_depfiles)))
diff --git a/test cases/common/49 custom target/depfile/meson.build b/test cases/common/49 custom target/depfile/meson.build
new file mode 100644
index 0000000..46bca74
--- /dev/null
+++ b/test cases/common/49 custom target/depfile/meson.build
@@ -0,0 +1,7 @@
+
+
+mytarget = custom_target('depfile',
+ output : 'dep.dat',
+ depfile : 'dep.dat.d',
+ command : [find_program('dep.py'), meson.current_source_dir(), '@DEPFILE@', '@OUTPUT@'],
+)
diff --git a/test cases/common/49 custom target/meson.build b/test cases/common/49 custom target/meson.build
new file mode 100644
index 0000000..a51e526
--- /dev/null
+++ b/test cases/common/49 custom target/meson.build
@@ -0,0 +1,73 @@
+project('custom target')
+
+python = find_program('python3', required : false)
+if not python.found()
+ python = find_program('python')
+endif
+
+# Note that this will not add a dependency to the compiler executable.
+# Code will not be rebuilt if it changes.
+comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
+# Test that files() in command: works. The compiler just discards it.
+useless = files('test.json')
+
+mytarget = custom_target('bindat',
+output : 'data.dat',
+input : 'data_source.txt',
+command : [python, comp, '--input=@INPUT@', '--output=@OUTPUT@', useless],
+env: {'MY_COMPILER_ENV': 'value'},
+install : true,
+install_dir : 'subdir'
+)
+
+has_not_changed = false
+if is_disabler(mytarget)
+ has_not_changed = true
+else
+ has_not_changed = true
+endif
+assert(has_not_changed, 'Custom target has changed.')
+
+assert(not is_disabler(mytarget), 'Custom target is a disabler.')
+
+mytarget_disabler = custom_target('bindat',
+output : 'data.dat',
+input : 'data_source.txt',
+command : [disabler(), comp, '--input=@INPUT@', '--output=@OUTPUT@', useless],
+install : true,
+install_dir : 'subdir'
+)
+
+if mytarget_disabler.found()
+ mytarget_disabled = false
+else
+ mytarget_disabled = true
+endif
+
+assert(mytarget_disabled, 'Disabled custom target should not be found.')
+
+mytarget_ci = custom_target('bindat_ci',
+output : 'data_ci.dat',
+input : 'data_source.txt',
+command : [python, comp, '--input=@INPUT@', '--output=@OUTPUT@', mytarget.to_list()],
+)
+
+mytarget_disabler = custom_target('bindat',
+output : 'data.dat',
+input : disabler(),
+command : [python, comp, '--input=@INPUT@', '--output=@OUTPUT@', useless],
+install : true,
+install_dir : 'subdir'
+)
+
+assert(is_disabler(mytarget_disabler), 'Disabled custom target is not a disabler.')
+
+if mytarget_disabler.found()
+ mytarget_disabled = false
+else
+ mytarget_disabled = true
+endif
+
+assert(mytarget_disabled, 'Disabled custom target should not be found.')
+
+subdir('depfile')
diff --git a/test cases/common/49 custom target/my_compiler.py b/test cases/common/49 custom target/my_compiler.py
new file mode 100755
index 0000000..a32cbdb
--- /dev/null
+++ b/test cases/common/49 custom target/my_compiler.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+assert os.path.exists(sys.argv[3])
+
+args = sys.argv[:-1]
+
+if __name__ == '__main__':
+ assert os.environ['MY_COMPILER_ENV'] == 'value'
+ if len(args) != 3 or not args[1].startswith('--input') or \
+ not args[2].startswith('--output'):
+ print(args[0], '--input=input_file --output=output_file')
+ sys.exit(1)
+ with open(args[1].split('=')[1]) as f:
+ ifile = f.read()
+ if ifile != 'This is a text only input file.\n':
+ print('Malformed input')
+ sys.exit(1)
+ with open(args[2].split('=')[1], 'w') as ofile:
+ ofile.write('This is a binary output file.\n')
diff --git a/test cases/common/49 custom target/test.json b/test cases/common/49 custom target/test.json
new file mode 100644
index 0000000..ba66b02
--- /dev/null
+++ b/test cases/common/49 custom target/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/subdir/data.dat"}
+ ]
+}
diff --git a/test cases/common/5 linkstatic/libfile.c b/test cases/common/5 linkstatic/libfile.c
new file mode 100644
index 0000000..9180030
--- /dev/null
+++ b/test cases/common/5 linkstatic/libfile.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 0;
+}
diff --git a/test cases/common/5 linkstatic/libfile2.c b/test cases/common/5 linkstatic/libfile2.c
new file mode 100644
index 0000000..5badf23
--- /dev/null
+++ b/test cases/common/5 linkstatic/libfile2.c
@@ -0,0 +1,3 @@
+int func2(void) {
+ return 2;
+}
diff --git a/test cases/common/5 linkstatic/libfile3.c b/test cases/common/5 linkstatic/libfile3.c
new file mode 100644
index 0000000..4bfe52a
--- /dev/null
+++ b/test cases/common/5 linkstatic/libfile3.c
@@ -0,0 +1,3 @@
+int func3(void) {
+ return 3;
+}
diff --git a/test cases/common/5 linkstatic/libfile4.c b/test cases/common/5 linkstatic/libfile4.c
new file mode 100644
index 0000000..ce1fe68
--- /dev/null
+++ b/test cases/common/5 linkstatic/libfile4.c
@@ -0,0 +1,3 @@
+int func4(void) {
+ return 4;
+}
diff --git a/test cases/common/5 linkstatic/main.c b/test cases/common/5 linkstatic/main.c
new file mode 100644
index 0000000..128f2bb
--- /dev/null
+++ b/test cases/common/5 linkstatic/main.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/5 linkstatic/meson.build b/test cases/common/5 linkstatic/meson.build
new file mode 100644
index 0000000..1f02a5c
--- /dev/null
+++ b/test cases/common/5 linkstatic/meson.build
@@ -0,0 +1,6 @@
+project('static library linking test', 'c')
+
+lib = build_target('mylib', 'libfile.c', 'libfile2.c', 'libfile3.c', 'libfile4.c', target_type : 'static_library')
+exe = executable('prog', 'main.c', link_with : lib)
+
+test('runtest', exe)
diff --git a/test cases/common/50 custom target chain/data_source.txt b/test cases/common/50 custom target chain/data_source.txt
new file mode 100644
index 0000000..0c23cc0
--- /dev/null
+++ b/test cases/common/50 custom target chain/data_source.txt
@@ -0,0 +1 @@
+This is a text only input file.
diff --git a/test cases/common/50 custom target chain/meson.build b/test cases/common/50 custom target chain/meson.build
new file mode 100644
index 0000000..138f795
--- /dev/null
+++ b/test cases/common/50 custom target chain/meson.build
@@ -0,0 +1,34 @@
+project('custom target', 'c')
+
+python = find_program('python3', required : false)
+if not python.found()
+ python = find_program('python')
+endif
+
+# files() is the correct way to do this, but some people
+# do this so test that it works.
+comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
+comp2 = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler2.py')
+infile = files('data_source.txt')[0]
+
+mytarget = custom_target('bindat',
+ output : 'data.dat',
+ command : [python, comp, infile, '@OUTPUT@'],
+)
+
+mytarget2 = custom_target('bindat2',
+ output : 'data2.dat',
+ command : [python, comp2, mytarget, '@OUTPUT@'],
+ install : true,
+ install_dir : 'subdir'
+)
+
+mytarget3 = custom_target('bindat3',
+ output : 'data3.dat',
+ input : [mytarget],
+ command : [python, comp2, '@INPUT@', '@OUTPUT@'],
+ install : true,
+ install_dir : 'subdir'
+)
+
+subdir('usetarget')
diff --git a/test cases/common/50 custom target chain/my_compiler.py b/test cases/common/50 custom target chain/my_compiler.py
new file mode 100755
index 0000000..d99029b
--- /dev/null
+++ b/test cases/common/50 custom target chain/my_compiler.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import sys
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print(sys.argv[0], 'input_file output_file')
+ sys.exit(1)
+ with open(sys.argv[1]) as f:
+ ifile = f.read()
+ if ifile != 'This is a text only input file.\n':
+ print('Malformed input')
+ sys.exit(1)
+ with open(sys.argv[2], 'w') as ofile:
+ ofile.write('This is a binary output file.\n')
diff --git a/test cases/common/50 custom target chain/my_compiler2.py b/test cases/common/50 custom target chain/my_compiler2.py
new file mode 100755
index 0000000..22ec789
--- /dev/null
+++ b/test cases/common/50 custom target chain/my_compiler2.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import sys
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print(sys.argv[0], 'input_file output_file')
+ sys.exit(1)
+ with open(sys.argv[1]) as f:
+ ifile = f.read()
+ if ifile != 'This is a binary output file.\n':
+ print('Malformed input')
+ sys.exit(1)
+ with open(sys.argv[2], 'w') as ofile:
+ ofile.write('This is a different binary output file.\n')
diff --git a/test cases/common/50 custom target chain/test.json b/test cases/common/50 custom target chain/test.json
new file mode 100644
index 0000000..d6b0fa9
--- /dev/null
+++ b/test cases/common/50 custom target chain/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/subdir/data2.dat"},
+ {"type": "file", "file": "usr/subdir/data3.dat"}
+ ]
+}
diff --git a/test cases/common/50 custom target chain/usetarget/meson.build b/test cases/common/50 custom target chain/usetarget/meson.build
new file mode 100644
index 0000000..9aece8c
--- /dev/null
+++ b/test cases/common/50 custom target chain/usetarget/meson.build
@@ -0,0 +1,8 @@
+e = executable('myexe', 'myexe.c')
+subexe = find_program('subcomp.py')
+
+custom_target('use_exe',
+ input : e,
+ output : 'subout.res',
+ command : [subexe, '@INPUT@', '@OUTPUT@'],
+)
diff --git a/test cases/common/50 custom target chain/usetarget/myexe.c b/test cases/common/50 custom target chain/usetarget/myexe.c
new file mode 100644
index 0000000..3331133
--- /dev/null
+++ b/test cases/common/50 custom target chain/usetarget/myexe.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I am myexe.\n");
+ return 0;
+}
diff --git a/test cases/common/50 custom target chain/usetarget/subcomp.py b/test cases/common/50 custom target chain/usetarget/subcomp.py
new file mode 100755
index 0000000..52dc0bb
--- /dev/null
+++ b/test cases/common/50 custom target chain/usetarget/subcomp.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys
+
+with open(sys.argv[1], 'rb') as ifile:
+ with open(sys.argv[2], 'w') as ofile:
+ ofile.write('Everything ok.\n')
diff --git a/test cases/common/51 run target/.clang-format b/test cases/common/51 run target/.clang-format
new file mode 100644
index 0000000..9b3aa8b
--- /dev/null
+++ b/test cases/common/51 run target/.clang-format
@@ -0,0 +1 @@
+BasedOnStyle: LLVM
diff --git a/test cases/common/51 run target/.clang-tidy b/test cases/common/51 run target/.clang-tidy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/51 run target/.clang-tidy
diff --git a/test cases/common/51 run target/check-env.py b/test cases/common/51 run target/check-env.py
new file mode 100644
index 0000000..1c66ffa
--- /dev/null
+++ b/test cases/common/51 run target/check-env.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+
+import os, sys
+from pathlib import Path
+
+assert 'MESON_SOURCE_ROOT' in os.environ
+assert 'MESON_BUILD_ROOT' in os.environ
+assert 'MESON_SUBDIR' in os.environ
+assert 'MESONINTROSPECT' in os.environ
+assert 'MY_ENV' in os.environ
+
+# Environment has absolute paths and argv has relative paths when using ninja
+# backend and absolute paths when using vs backend. What matters is once
+# resolved they point to same location.
+env_source_root = Path(os.environ['MESON_SOURCE_ROOT']).resolve()
+env_build_root = Path(os.environ['MESON_BUILD_ROOT']).resolve()
+env_current_source_dir = Path(env_source_root, os.environ['MESON_SUBDIR']).resolve()
+
+print(sys.argv)
+argv_paths = [Path(i).resolve() for i in sys.argv[1:]]
+source_root, build_root, current_source_dir = argv_paths
+
+print(f'{source_root} == {env_source_root}')
+assert source_root == env_source_root
+print(f'{build_root} == {env_build_root}')
+assert build_root == env_build_root
+print(f'{current_source_dir} == {env_current_source_dir}')
+assert current_source_dir == env_current_source_dir
diff --git a/test cases/common/51 run target/check_exists.py b/test cases/common/51 run target/check_exists.py
new file mode 100755
index 0000000..b6fc967
--- /dev/null
+++ b/test cases/common/51 run target/check_exists.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+if not os.path.isfile(sys.argv[1]):
+ raise Exception("Couldn't find {!r}".format(sys.argv[1]))
diff --git a/test cases/common/51 run target/configure.in b/test cases/common/51 run target/configure.in
new file mode 100755
index 0000000..0d42d04
--- /dev/null
+++ b/test cases/common/51 run target/configure.in
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('Success') \ No newline at end of file
diff --git a/test cases/common/51 run target/converter.py b/test cases/common/51 run target/converter.py
new file mode 100644
index 0000000..8dd31fe
--- /dev/null
+++ b/test cases/common/51 run target/converter.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+
+with open(sys.argv[1], 'rb') as ifile, open(sys.argv[2], 'wb') as ofile:
+ ofile.write(ifile.read())
diff --git a/test cases/common/51 run target/fakeburner.py b/test cases/common/51 run target/fakeburner.py
new file mode 100755
index 0000000..8b1f353
--- /dev/null
+++ b/test cases/common/51 run target/fakeburner.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+
+import sys
+
+plain_arg = sys.argv[1]
+_, filename, _ = plain_arg.split(':')
+try:
+ with open(filename, 'rb') as f:
+ content = f.read()
+except FileNotFoundError:
+ print('Could not open file. Missing dependency?')
+ sys.exit(1)
+print('File opened, pretending to send it somewhere.')
+print(len(content), 'bytes uploaded')
diff --git a/test cases/common/51 run target/helloprinter.c b/test cases/common/51 run target/helloprinter.c
new file mode 100644
index 0000000..4a6e0ac
--- /dev/null
+++ b/test cases/common/51 run target/helloprinter.c
@@ -0,0 +1,11 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ if(argc != 2) {
+ printf("I can not haz argument.\n");
+ return 1;
+ } else {
+ printf("I can haz argument: %s\n", argv[1]);
+ }
+ return 0;
+}
diff --git a/test cases/common/51 run target/meson.build b/test cases/common/51 run target/meson.build
new file mode 100644
index 0000000..dbb6732
--- /dev/null
+++ b/test cases/common/51 run target/meson.build
@@ -0,0 +1,112 @@
+project('run target', 'c')
+
+# Make it possible to run built programs.
+# In cross builds exe_wrapper should be added if it exists.
+
+exe = executable('helloprinter', 'helloprinter.c')
+
+if not meson.is_cross_build() or meson.can_run_host_binaries()
+ run_target('runhello',
+ command : [exe, 'argument'])
+endif
+
+converter = find_program('converter.py')
+
+hex = custom_target('exe.hex',
+ input : exe,
+ output : 'exe.hex',
+ command : [converter, '@INPUT@', '@OUTPUT@',
+ ],
+)
+
+fakeburner = find_program('fakeburner.py')
+
+# These emulates the Arduino flasher application. It sandwiches the filename inside
+# a packed argument. Thus we need to declare it manually.
+run_target('upload',
+ command : [fakeburner, 'x:@0@:y'.format(exe.full_path())],
+ depends : exe,
+)
+
+run_target('upload2',
+ command : [fakeburner, 'x:@0@:y'.format(hex.full_path())],
+ depends : hex,
+)
+
+python3 = find_program('python3', required : false)
+if not python3.found()
+ python3 = find_program('python')
+endif
+
+run_target('py3hi',
+ command : [python3, '-c', 'print("I am Python3.")'])
+
+run_target('check_exists',
+ command : [find_program('check_exists.py'), files('helloprinter.c')])
+
+run_target('check_exists',
+ command : [find_program('check_exists.py'), files('helloprinter.c')],
+ depends : disabler(),
+)
+
+run_target('check_exists',
+ command : [disabler(), files('helloprinter.c')])
+
+# What if the output of a custom_target is the command to
+# execute. Obviously this will not work as hex is not an
+# executable but test that the output is generated correctly.
+run_target('donotrunme',
+ command : hex)
+
+# Ensure configure files can be passed
+conf = configure_file(
+ input: 'configure.in',
+ output: 'configure',
+ configuration: configuration_data()
+)
+
+run_target('configure_script',
+ command : conf
+)
+
+custom_target('configure_script_ct',
+ command: conf,
+ output: 'dummy.txt',
+ capture: true)
+
+# Target names that clash with potential builtin functionality.
+run_target('ctags',
+ command : converter)
+
+clangf = run_target('clang-format',
+ command : [converter, files('.clang-format'), meson.current_build_dir() / 'clang-format'])
+custom_target('clang-tidy',
+ input: '.clang-tidy',
+ output: 'clang-tidy',
+ command : [converter, '@INPUT@', '@OUTPUT@'])
+alias_target('clang-format-check', clangf)
+
+# Check we can pass env to the program. Also check some string substitutions
+# that were added in 0.57.0 but not documented. This is documented behaviour
+# since 0.57.1.
+run_target('check-env',
+ command: [find_program('check-env.py'), '@SOURCE_ROOT@', '@BUILD_ROOT@',
+ '@CURRENT_SOURCE_DIR@'],
+ env: {'MY_ENV': '1'},
+)
+
+# Check some string substitutions that has always been done but never documented.
+# Some projects have been relying on this implementation detail. This is
+# documented behaviour since 0.57.1.
+custom_target('check-env-ct',
+ command: [find_program('check-env.py'), '@SOURCE_ROOT@', '@BUILD_ROOT@',
+ '@CURRENT_SOURCE_DIR@'],
+ env: {'MESON_SOURCE_ROOT': meson.source_root(),
+ 'MESON_BUILD_ROOT': meson.build_root(),
+ 'MESON_SUBDIR': meson.current_source_dir(),
+ 'MESONINTROSPECT': 'fake value',
+ 'MY_ENV': '1'},
+ output: 'check-env-ct',
+)
+
+run_target('textprinter', command: ['subdir/textprinter.py'])
diff --git a/test cases/common/51 run target/subdir/textprinter.py b/test cases/common/51 run target/subdir/textprinter.py
new file mode 100644
index 0000000..3159c08
--- /dev/null
+++ b/test cases/common/51 run target/subdir/textprinter.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('I am a script. Being run.')
diff --git a/test cases/common/52 object generator/meson.build b/test cases/common/52 object generator/meson.build
new file mode 100644
index 0000000..e20da6f
--- /dev/null
+++ b/test cases/common/52 object generator/meson.build
@@ -0,0 +1,34 @@
+project('object generator', 'c')
+
+python = find_program('python3', required : false)
+if not python.found()
+ python = find_program('python')
+endif
+
+# Note that this will not add a dependency to the compiler executable.
+# Code will not be rebuilt if it changes.
+comp = '@0@/@1@'.format(meson.current_source_dir(), 'obj_generator.py')
+
+if host_machine.system() == 'windows'
+ outputname = '@BASENAME@.obj'
+else
+ outputname = '@BASENAME@.o'
+endif
+
+cc = meson.get_compiler('c').cmd_array().get(-1)
+# Generate an object file manually.
+gen = generator(python,
+ output : outputname,
+ arguments : [comp, cc, '@INPUT@', '@OUTPUT@'])
+
+generated = gen.process(['source.c', 'source2.c'])
+
+# Generate an object file with indexed OUTPUT replacement.
+gen2 = generator(python,
+ output : outputname,
+ arguments : [comp, cc, '@INPUT@', '@OUTPUT0@'])
+generated2 = gen2.process(['source3.c'])
+
+e = executable('prog', 'prog.c', generated, generated2)
+
+test('objgen', e) \ No newline at end of file
diff --git a/test cases/common/52 object generator/obj_generator.py b/test cases/common/52 object generator/obj_generator.py
new file mode 100755
index 0000000..a33872a
--- /dev/null
+++ b/test cases/common/52 object generator/obj_generator.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+# Mimic a binary that generates an object file (e.g. windres).
+
+import sys, subprocess
+
+if __name__ == '__main__':
+ if len(sys.argv) != 4:
+ print(sys.argv[0], 'compiler input_file output_file')
+ sys.exit(1)
+ compiler = sys.argv[1]
+ ifile = sys.argv[2]
+ ofile = sys.argv[3]
+ if compiler.endswith('cl'):
+ cmd = [compiler, '/nologo', '/MDd', '/Fo' + ofile, '/c', ifile]
+ else:
+ cmd = [compiler, '-c', ifile, '-o', ofile]
+ sys.exit(subprocess.call(cmd))
diff --git a/test cases/common/52 object generator/prog.c b/test cases/common/52 object generator/prog.c
new file mode 100644
index 0000000..9841180
--- /dev/null
+++ b/test cases/common/52 object generator/prog.c
@@ -0,0 +1,7 @@
+int func1_in_obj(void);
+int func2_in_obj(void);
+int func3_in_obj(void);
+
+int main(void) {
+ return func1_in_obj() + func2_in_obj() + func3_in_obj();
+}
diff --git a/test cases/common/52 object generator/source.c b/test cases/common/52 object generator/source.c
new file mode 100644
index 0000000..1dc08e1
--- /dev/null
+++ b/test cases/common/52 object generator/source.c
@@ -0,0 +1,3 @@
+int func1_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/52 object generator/source2.c b/test cases/common/52 object generator/source2.c
new file mode 100644
index 0000000..8024b97
--- /dev/null
+++ b/test cases/common/52 object generator/source2.c
@@ -0,0 +1,3 @@
+int func2_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/52 object generator/source3.c b/test cases/common/52 object generator/source3.c
new file mode 100644
index 0000000..c4362c4
--- /dev/null
+++ b/test cases/common/52 object generator/source3.c
@@ -0,0 +1,3 @@
+int func3_in_obj(void) {
+ return 0;
+}
diff --git a/test cases/common/53 install script/customtarget.py b/test cases/common/53 install script/customtarget.py
new file mode 100755
index 0000000..e28373a
--- /dev/null
+++ b/test cases/common/53 install script/customtarget.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('dirname')
+ args = parser.parse_args()
+
+ with open(os.path.join(args.dirname, '1.txt'), 'w') as f:
+ f.write('')
+ with open(os.path.join(args.dirname, '2.txt'), 'w') as f:
+ f.write('')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/common/53 install script/meson.build b/test cases/common/53 install script/meson.build
new file mode 100644
index 0000000..24d5dc8
--- /dev/null
+++ b/test cases/common/53 install script/meson.build
@@ -0,0 +1,45 @@
+project('custom install script', 'c')
+
+meson.add_install_script('myinstall.py', 'diiba/daaba', 'file.dat')
+meson.add_install_script('myinstall.py', 'this/should', 'also-work.dat')
+
+subdir('src')
+
+meson.add_install_script('myinstall.py', 'dir', afile, '--mode=copy')
+
+data = configuration_data()
+data.set10('foo', true)
+conf = configure_file(
+ configuration : data,
+ output : 'conf.txt'
+)
+
+meson.add_install_script('myinstall.py', 'dir', conf, '--mode=copy')
+
+t = custom_target(
+ 'ct',
+ command : [find_program('customtarget.py'), '@OUTDIR@'],
+ output : ['1.txt', '2.txt'],
+)
+
+meson.add_install_script('myinstall.py', 'customtarget', t, '--mode=copy')
+meson.add_install_script('myinstall.py', 'customtargetindex', t[0], '--mode=copy')
+
+installer = configure_file(
+ input : 'myinstall.py',
+ output : 'myinstall_copy.py',
+ copy : true,
+)
+
+meson.add_install_script(installer, 'otherdir', afile, '--mode=copy')
+
+# This executable links on a library built in src/ directory. On Windows this
+# means meson must add src/ into $PATH to find the DLL when running it as
+# install script.
+myexe = executable('prog', 'prog.c',
+ link_with: mylib,
+ install : true,
+)
+if meson.can_run_host_binaries()
+ meson.add_install_script(myexe)
+endif
diff --git a/test cases/common/53 install script/myinstall.py b/test cases/common/53 install script/myinstall.py
new file mode 100755
index 0000000..a573342
--- /dev/null
+++ b/test cases/common/53 install script/myinstall.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import shutil
+
+prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX']
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('dirname')
+ parser.add_argument('files', nargs='+')
+ parser.add_argument('--mode', action='store', default='create', choices=['create', 'copy'])
+ args = parser.parse_args()
+
+ dirname = os.path.join(prefix, args.dirname)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
+ if args.mode == 'create':
+ for name in args.files:
+ with open(os.path.join(dirname, name), 'w') as f:
+ f.write('')
+ else:
+ for name in args.files:
+ shutil.copy(name, dirname)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/common/53 install script/prog.c b/test cases/common/53 install script/prog.c
new file mode 100644
index 0000000..85f8df9
--- /dev/null
+++ b/test cases/common/53 install script/prog.c
@@ -0,0 +1,14 @@
+#include<stdio.h>
+
+#ifdef _WIN32
+ #define DO_IMPORT __declspec(dllimport)
+#else
+ #define DO_IMPORT
+#endif
+
+DO_IMPORT int foo(void);
+
+int main(void) {
+ printf("This is text.\n");
+ return foo();
+}
diff --git a/test cases/common/53 install script/src/a file.txt b/test cases/common/53 install script/src/a file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/53 install script/src/a file.txt
diff --git a/test cases/common/53 install script/src/foo.c b/test cases/common/53 install script/src/foo.c
new file mode 100644
index 0000000..46cb845
--- /dev/null
+++ b/test cases/common/53 install script/src/foo.c
@@ -0,0 +1,10 @@
+#ifdef _WIN32
+ #define DO_EXPORT __declspec(dllexport)
+#else
+ #define DO_EXPORT
+#endif
+
+DO_EXPORT int foo(void)
+{
+ return 0;
+}
diff --git a/test cases/common/53 install script/src/meson.build b/test cases/common/53 install script/src/meson.build
new file mode 100644
index 0000000..72de346
--- /dev/null
+++ b/test cases/common/53 install script/src/meson.build
@@ -0,0 +1,5 @@
+meson.add_install_script('myinstall.py', 'this/does', 'something-different.dat')
+
+afile = files('a file.txt')
+
+mylib = shared_library('mylib', 'foo.c')
diff --git a/test cases/common/53 install script/src/myinstall.py b/test cases/common/53 install script/src/myinstall.py
new file mode 100644
index 0000000..3a9d89b
--- /dev/null
+++ b/test cases/common/53 install script/src/myinstall.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX']
+
+dirname = os.path.join(prefix, sys.argv[1])
+
+if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
+with open(os.path.join(dirname, sys.argv[2] + '.in'), 'w') as f:
+ f.write('')
diff --git a/test cases/common/53 install script/test.json b/test cases/common/53 install script/test.json
new file mode 100644
index 0000000..7ac2607
--- /dev/null
+++ b/test cases/common/53 install script/test.json
@@ -0,0 +1,15 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/diiba/daaba/file.dat"},
+ {"type": "file", "file": "usr/this/should/also-work.dat"},
+ {"type": "file", "file": "usr/this/does/something-different.dat.in"},
+ {"type": "file", "file": "usr/dir/a file.txt"},
+ {"type": "file", "file": "usr/dir/conf.txt"},
+ {"type": "file", "file": "usr/otherdir/a file.txt"},
+ {"type": "file", "file": "usr/customtarget/1.txt"},
+ {"type": "file", "file": "usr/customtarget/2.txt"},
+ {"type": "file", "file": "usr/customtargetindex/1.txt"}
+ ]
+}
diff --git a/test cases/common/54 custom target source output/generator.py b/test cases/common/54 custom target source output/generator.py
new file mode 100755
index 0000000..1bec8e8
--- /dev/null
+++ b/test cases/common/54 custom target source output/generator.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+if len(sys.argv) != 2:
+ print(sys.argv[0], '<output dir>')
+
+odir = sys.argv[1]
+
+with open(os.path.join(odir, 'mylib.h'), 'w') as f:
+ f.write('int func(void);\n')
+with open(os.path.join(odir, 'mylib.c'), 'w') as f:
+ f.write('''int func(void) {
+ return 0;
+}
+''')
diff --git a/test cases/common/54 custom target source output/main.c b/test cases/common/54 custom target source output/main.c
new file mode 100644
index 0000000..bca1387
--- /dev/null
+++ b/test cases/common/54 custom target source output/main.c
@@ -0,0 +1,5 @@
+#include"mylib.h"
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/54 custom target source output/meson.build b/test cases/common/54 custom target source output/meson.build
new file mode 100644
index 0000000..f9d039d
--- /dev/null
+++ b/test cases/common/54 custom target source output/meson.build
@@ -0,0 +1,9 @@
+project('source generation', 'c')
+
+ct = custom_target('gen',
+output : ['mylib.h', 'mylib.c'],
+command : [find_program('generator.py'), '@OUTDIR@'],
+)
+
+e = executable('prog', 'main.c', ct)
+test('gentest', e)
diff --git a/test cases/common/55 exe static shared/meson.build b/test cases/common/55 exe static shared/meson.build
new file mode 100644
index 0000000..69ede5e
--- /dev/null
+++ b/test cases/common/55 exe static shared/meson.build
@@ -0,0 +1,15 @@
+project('statchain', 'c')
+
+subdir('subdir')
+# Test that -fPIC in c_args is also accepted (on platforms where it's permitted)
+picflag = []
+if not ['darwin', 'windows'].contains(host_machine.system())
+ picflag = ['-fPIC']
+endif
+statlib2 = static_library('stat2', 'stat2.c', c_args : picflag, pic : false)
+# Test that pic is needed for both direct and indirect static library
+# dependencies of shared libraries (on Linux and BSD)
+statlib = static_library('stat', 'stat.c', link_with : [shlib, statlib2], pic : true)
+shlib2 = shared_library('shr2', 'shlib2.c', link_with : statlib)
+exe = executable('prog', 'prog.c', link_with : shlib2)
+test('runtest', exe)
diff --git a/test cases/common/55 exe static shared/prog.c b/test cases/common/55 exe static shared/prog.c
new file mode 100644
index 0000000..6dba60d
--- /dev/null
+++ b/test cases/common/55 exe static shared/prog.c
@@ -0,0 +1,10 @@
+int shlibfunc2(void);
+int statlibfunc(void);
+
+int main(void) {
+ if (statlibfunc() != 42)
+ return 1;
+ if (shlibfunc2() != 24)
+ return 1;
+ return 0;
+}
diff --git a/test cases/common/55 exe static shared/shlib2.c b/test cases/common/55 exe static shared/shlib2.c
new file mode 100644
index 0000000..12bc913
--- /dev/null
+++ b/test cases/common/55 exe static shared/shlib2.c
@@ -0,0 +1,8 @@
+#include "subdir/exports.h"
+
+int statlibfunc(void);
+int statlibfunc2(void);
+
+int DLL_PUBLIC shlibfunc2(void) {
+ return statlibfunc() - statlibfunc2();
+}
diff --git a/test cases/common/55 exe static shared/stat.c b/test cases/common/55 exe static shared/stat.c
new file mode 100644
index 0000000..eddc4d8
--- /dev/null
+++ b/test cases/common/55 exe static shared/stat.c
@@ -0,0 +1,7 @@
+#include "subdir/exports.h"
+
+int shlibfunc(void);
+
+int DLL_PUBLIC statlibfunc(void) {
+ return shlibfunc();
+}
diff --git a/test cases/common/55 exe static shared/stat2.c b/test cases/common/55 exe static shared/stat2.c
new file mode 100644
index 0000000..4abb49f
--- /dev/null
+++ b/test cases/common/55 exe static shared/stat2.c
@@ -0,0 +1,3 @@
+int statlibfunc2(void) {
+ return 18;
+}
diff --git a/test cases/common/55 exe static shared/subdir/exports.h b/test cases/common/55 exe static shared/subdir/exports.h
new file mode 100644
index 0000000..c89ccb2
--- /dev/null
+++ b/test cases/common/55 exe static shared/subdir/exports.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
diff --git a/test cases/common/55 exe static shared/subdir/meson.build b/test cases/common/55 exe static shared/subdir/meson.build
new file mode 100644
index 0000000..2b7393b
--- /dev/null
+++ b/test cases/common/55 exe static shared/subdir/meson.build
@@ -0,0 +1 @@
+shlib = shared_library('shar', 'shlib.c')
diff --git a/test cases/common/55 exe static shared/subdir/shlib.c b/test cases/common/55 exe static shared/subdir/shlib.c
new file mode 100644
index 0000000..dd9c6b2
--- /dev/null
+++ b/test cases/common/55 exe static shared/subdir/shlib.c
@@ -0,0 +1,5 @@
+#include "exports.h"
+
+int DLL_PUBLIC shlibfunc(void) {
+ return 42;
+}
diff --git a/test cases/common/56 array methods/a.txt b/test cases/common/56 array methods/a.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/56 array methods/a.txt
diff --git a/test cases/common/56 array methods/b.txt b/test cases/common/56 array methods/b.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/56 array methods/b.txt
diff --git a/test cases/common/56 array methods/c.txt b/test cases/common/56 array methods/c.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/56 array methods/c.txt
diff --git a/test cases/common/56 array methods/meson.build b/test cases/common/56 array methods/meson.build
new file mode 100644
index 0000000..d323db8
--- /dev/null
+++ b/test cases/common/56 array methods/meson.build
@@ -0,0 +1,70 @@
+project('array methods')
+
+empty = []
+one = ['abc']
+two = ['def', 'ghi']
+combined = [empty, one, two]
+
+file_list = files('a.txt', 'b.txt')
+file_a = files('a.txt')
+file_c = files('c.txt')
+
+if file_a[0] != file_list[0]
+ error('Files are not equal')
+endif
+
+if not file_list.contains(file_a[0])
+ error('Contains with ObjectHolder lists does not work')
+endif
+
+if file_list.contains(file_c[0])
+ error('Contains with ObjectHolder lists found non existent object')
+endif
+
+if empty.contains('abc')
+ error('Empty is not empty.')
+endif
+
+if one.contains('a')
+ error('One claims to contain a')
+endif
+
+if not one.contains('abc')
+ error('One claims to not contain abc.')
+endif
+
+if one.contains('abcd')
+ error('One claims to contain abcd.')
+endif
+
+if two.contains('abc')
+ error('Two claims to contain abc.')
+endif
+
+if not two.contains('def')
+ error('Two claims not to contain def.')
+endif
+
+if not two.contains('ghi')
+ error('Two claims not to contain ghi.')
+endif
+
+if two.contains('defg')
+ error('Two claims to contain defg.')
+endif
+
+if not combined.contains('abc')
+ error('Combined claims not to contain abc.')
+endif
+
+if not combined.contains(one)
+ error('Combined claims not to contain [abc].')
+endif
+
+if not combined.contains(two)
+ error('Combined claims not to contain [def, ghi].')
+endif
+
+if not combined.contains('ghi')
+ error('Combined claims not to contain ghi.')
+endif
diff --git a/test cases/common/57 custom header generator/input.def b/test cases/common/57 custom header generator/input.def
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test cases/common/57 custom header generator/input.def
@@ -0,0 +1 @@
+0
diff --git a/test cases/common/57 custom header generator/makeheader.py b/test cases/common/57 custom header generator/makeheader.py
new file mode 100644
index 0000000..f156834
--- /dev/null
+++ b/test cases/common/57 custom header generator/makeheader.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+# NOTE: this file does not have the executable bit set. This tests that
+# Meson can automatically parse shebang lines.
+
+import sys
+
+template = '#define RET_VAL %s\n'
+with open(sys.argv[1]) as f:
+ output = template % (f.readline().strip(), )
+with open(sys.argv[2], 'w') as f:
+ f.write(output)
diff --git a/test cases/common/57 custom header generator/meson.build b/test cases/common/57 custom header generator/meson.build
new file mode 100644
index 0000000..d43915a
--- /dev/null
+++ b/test cases/common/57 custom header generator/meson.build
@@ -0,0 +1,21 @@
+project('custom header generator', 'c')
+
+cc_id = meson.get_compiler('c').get_id()
+cc_ver = meson.get_compiler('c').version()
+
+if cc_id == 'intel' or (cc_id == 'lcc' and cc_ver.version_compare('<=1.23.08'))
+ # ICC and LCC <= 1.23.08 do not escape spaces in paths in the dependency file, so Ninja
+ # (correctly) thinks that the rule has multiple outputs and errors out:
+ # 'depfile has multiple output paths'
+ error('MESON_SKIP_TEST: Skipping test because your compiler is known to generate broken dependency files')
+endif
+
+gen = find_program('makeheader.py')
+
+generated_h = custom_target('makeheader.py',
+ output : 'myheader.lh', # Suffix not .h to ensure this works with custom suffixes, too.
+ input : 'input.def',
+ command : [gen, '@INPUT0@', '@OUTPUT0@', files('somefile.txt')])
+
+prog = executable('prog', 'prog.c', generated_h)
+test('gentest', prog)
diff --git a/test cases/common/57 custom header generator/prog.c b/test cases/common/57 custom header generator/prog.c
new file mode 100644
index 0000000..acd0ff7
--- /dev/null
+++ b/test cases/common/57 custom header generator/prog.c
@@ -0,0 +1,5 @@
+#include"myheader.lh"
+
+int main(void) {
+ return RET_VAL;
+}
diff --git a/test cases/common/57 custom header generator/somefile.txt b/test cases/common/57 custom header generator/somefile.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/57 custom header generator/somefile.txt
diff --git a/test cases/common/58 multiple generators/data2.dat b/test cases/common/58 multiple generators/data2.dat
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/test cases/common/58 multiple generators/data2.dat
@@ -0,0 +1 @@
+2
diff --git a/test cases/common/58 multiple generators/main.cpp b/test cases/common/58 multiple generators/main.cpp
new file mode 100644
index 0000000..f1a01bd
--- /dev/null
+++ b/test cases/common/58 multiple generators/main.cpp
@@ -0,0 +1,6 @@
+#include"source1.h"
+#include"source2.h"
+
+int main(void) {
+ return func1() + func2();
+}
diff --git a/test cases/common/58 multiple generators/meson.build b/test cases/common/58 multiple generators/meson.build
new file mode 100644
index 0000000..66f7fa9
--- /dev/null
+++ b/test cases/common/58 multiple generators/meson.build
@@ -0,0 +1,13 @@
+project('trickier generator', 'cpp')
+
+comp = find_program('mygen.py')
+subdir('subdir')
+
+generated2 = custom_target('generated2',
+ output : ['source2.h', 'source2.cpp'],
+ input : 'data2.dat',
+ command : [comp, '@INPUT0@', '@OUTDIR@'])
+
+exe = executable('prog', 'main.cpp', generated, generated2,
+ include_directories : include_directories('subdir'))
+ test('generated test', exe)
diff --git a/test cases/common/58 multiple generators/mygen.py b/test cases/common/58 multiple generators/mygen.py
new file mode 100755
index 0000000..99dc331
--- /dev/null
+++ b/test cases/common/58 multiple generators/mygen.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+if len(sys.argv) != 3:
+ print("You is fail.")
+ sys.exit(1)
+
+with open(sys.argv[1]) as f:
+ val = f.read().strip()
+outdir = sys.argv[2]
+
+outhdr = os.path.join(outdir, 'source%s.h' % val)
+outsrc = os.path.join(outdir, 'source%s.cpp' % val)
+
+with open(outhdr, 'w') as f:
+ f.write('int func%s();\n' % val)
+with open(outsrc, 'w') as f:
+ f.write('''int func%s() {
+ return 0;
+}
+''' % val)
diff --git a/test cases/common/58 multiple generators/subdir/data.dat b/test cases/common/58 multiple generators/subdir/data.dat
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/test cases/common/58 multiple generators/subdir/data.dat
@@ -0,0 +1 @@
+1
diff --git a/test cases/common/58 multiple generators/subdir/meson.build b/test cases/common/58 multiple generators/subdir/meson.build
new file mode 100644
index 0000000..2456ecb
--- /dev/null
+++ b/test cases/common/58 multiple generators/subdir/meson.build
@@ -0,0 +1,4 @@
+generated = custom_target('generated',
+output : ['source1.h', 'source1.cpp'],
+input : 'data.dat',
+command : [comp, '@INPUT0@', '@OUTDIR@'])
diff --git a/test cases/common/59 install subdir/meson.build b/test cases/common/59 install subdir/meson.build
new file mode 100644
index 0000000..13d41be
--- /dev/null
+++ b/test cases/common/59 install subdir/meson.build
@@ -0,0 +1,21 @@
+project('install a whole subdir',
+ default_options : ['install_umask=preserve'])
+
+# A subdir with an exclusion:
+install_subdir('sub2',
+ exclude_files : ['excluded-three.dat'],
+ exclude_directories : ['excluded'],
+ install_dir : 'share')
+
+subdir('subdir')
+# A subdir with write perms only for the owner
+# and read-list perms for owner and group
+install_subdir('sub1', install_dir : 'share', install_mode : ['rwxr-x--t', 'root'])
+install_subdir('sub/sub1', install_dir : 'share')
+
+# strip_directory
+install_subdir('sub_elided', install_dir : 'share', strip_directory : true)
+install_subdir('nested_elided/sub', install_dir : 'share', strip_directory : true)
+
+# Create new empty directory that doesn't exist in the source tree
+install_subdir('new_directory', install_dir : 'share')
diff --git a/test cases/common/59 install subdir/nested_elided/sub/dircheck/ninth.dat b/test cases/common/59 install subdir/nested_elided/sub/dircheck/ninth.dat
new file mode 100644
index 0000000..c4eaca7
--- /dev/null
+++ b/test cases/common/59 install subdir/nested_elided/sub/dircheck/ninth.dat
@@ -0,0 +1 @@
+Nested file under nested elided directory.
diff --git a/test cases/common/59 install subdir/nested_elided/sub/eighth.dat b/test cases/common/59 install subdir/nested_elided/sub/eighth.dat
new file mode 100644
index 0000000..fa9b7b7
--- /dev/null
+++ b/test cases/common/59 install subdir/nested_elided/sub/eighth.dat
@@ -0,0 +1 @@
+File in nested elided directory.
diff --git a/test cases/common/59 install subdir/sub/sub1/third.dat b/test cases/common/59 install subdir/sub/sub1/third.dat
new file mode 100644
index 0000000..5ccbc43
--- /dev/null
+++ b/test cases/common/59 install subdir/sub/sub1/third.dat
@@ -0,0 +1 @@
+This is a third data file for sub1 dir.
diff --git a/test cases/common/59 install subdir/sub1/second.dat b/test cases/common/59 install subdir/sub1/second.dat
new file mode 100644
index 0000000..48857a8
--- /dev/null
+++ b/test cases/common/59 install subdir/sub1/second.dat
@@ -0,0 +1 @@
+Test that multiple install_subdirs meld their results. \ No newline at end of file
diff --git a/test cases/common/59 install subdir/sub2/dircheck/excluded-three.dat b/test cases/common/59 install subdir/sub2/dircheck/excluded-three.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/59 install subdir/sub2/dircheck/excluded-three.dat
diff --git a/test cases/common/59 install subdir/sub2/excluded-three.dat b/test cases/common/59 install subdir/sub2/excluded-three.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/59 install subdir/sub2/excluded-three.dat
diff --git a/test cases/common/59 install subdir/sub2/excluded/two.dat b/test cases/common/59 install subdir/sub2/excluded/two.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/59 install subdir/sub2/excluded/two.dat
diff --git a/test cases/common/59 install subdir/sub2/one.dat b/test cases/common/59 install subdir/sub2/one.dat
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/59 install subdir/sub2/one.dat
diff --git a/test cases/common/59 install subdir/sub_elided/dircheck/fifth.dat b/test cases/common/59 install subdir/sub_elided/dircheck/fifth.dat
new file mode 100644
index 0000000..b6ca009
--- /dev/null
+++ b/test cases/common/59 install subdir/sub_elided/dircheck/fifth.dat
@@ -0,0 +1 @@
+Data file in a subdir of elided directory.
diff --git a/test cases/common/59 install subdir/sub_elided/fourth.dat b/test cases/common/59 install subdir/sub_elided/fourth.dat
new file mode 100644
index 0000000..ca5f26a
--- /dev/null
+++ b/test cases/common/59 install subdir/sub_elided/fourth.dat
@@ -0,0 +1 @@
+Test that this file is installed directly into install_dir.
diff --git a/test cases/common/59 install subdir/subdir/meson.build b/test cases/common/59 install subdir/subdir/meson.build
new file mode 100644
index 0000000..0f81cdb
--- /dev/null
+++ b/test cases/common/59 install subdir/subdir/meson.build
@@ -0,0 +1,5 @@
+install_subdir('sub1', install_dir : 'share',
+ # This mode will be overridden by the mode set in the outer install_subdir
+ install_mode : 'rwxr-x---')
+
+install_subdir('sub_elided', install_dir : 'share', strip_directory : true)
diff --git a/test cases/common/59 install subdir/subdir/sub1/data1.dat b/test cases/common/59 install subdir/subdir/sub1/data1.dat
new file mode 100644
index 0000000..d83c370
--- /dev/null
+++ b/test cases/common/59 install subdir/subdir/sub1/data1.dat
@@ -0,0 +1 @@
+This is a data file in a subdir.
diff --git a/test cases/common/59 install subdir/subdir/sub1/sub2/data2.dat b/test cases/common/59 install subdir/subdir/sub1/sub2/data2.dat
new file mode 100644
index 0000000..8ce1392
--- /dev/null
+++ b/test cases/common/59 install subdir/subdir/sub1/sub2/data2.dat
@@ -0,0 +1 @@
+This is a data file in a deeper subdir.
diff --git a/test cases/common/59 install subdir/subdir/sub_elided/dircheck/seventh.dat b/test cases/common/59 install subdir/subdir/sub_elided/dircheck/seventh.dat
new file mode 100644
index 0000000..ea0b8dc
--- /dev/null
+++ b/test cases/common/59 install subdir/subdir/sub_elided/dircheck/seventh.dat
@@ -0,0 +1 @@
+Nested file in a subdir.
diff --git a/test cases/common/59 install subdir/subdir/sub_elided/sixth.dat b/test cases/common/59 install subdir/subdir/sub_elided/sixth.dat
new file mode 100644
index 0000000..140f075
--- /dev/null
+++ b/test cases/common/59 install subdir/subdir/sub_elided/sixth.dat
@@ -0,0 +1 @@
+Elide test file in a subdir.
diff --git a/test cases/common/59 install subdir/test.json b/test cases/common/59 install subdir/test.json
new file mode 100644
index 0000000..0dd885c
--- /dev/null
+++ b/test cases/common/59 install subdir/test.json
@@ -0,0 +1,17 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/dircheck/fifth.dat"},
+ {"type": "file", "file": "usr/share/dircheck/seventh.dat"},
+ {"type": "file", "file": "usr/share/dircheck/ninth.dat"},
+ {"type": "file", "file": "usr/share/eighth.dat"},
+ {"type": "file", "file": "usr/share/fourth.dat"},
+ {"type": "file", "file": "usr/share/sixth.dat"},
+ {"type": "file", "file": "usr/share/sub1/data1.dat"},
+ {"type": "file", "file": "usr/share/sub1/second.dat"},
+ {"type": "file", "file": "usr/share/sub1/third.dat"},
+ {"type": "file", "file": "usr/share/sub1/sub2/data2.dat"},
+ {"type": "file", "file": "usr/share/sub2/one.dat"},
+ {"type": "file", "file": "usr/share/sub2/dircheck/excluded-three.dat"},
+ {"type": "dir", "file": "usr/share/new_directory"}
+ ]
+}
diff --git a/test cases/common/6 linkshared/cpplib.cpp b/test cases/common/6 linkshared/cpplib.cpp
new file mode 100644
index 0000000..247f820
--- /dev/null
+++ b/test cases/common/6 linkshared/cpplib.cpp
@@ -0,0 +1,6 @@
+#define BUILDING_DLL
+#include "cpplib.h"
+
+int DLL_PUBLIC cppfunc(void) {
+ return 42;
+}
diff --git a/test cases/common/6 linkshared/cpplib.h b/test cases/common/6 linkshared/cpplib.h
new file mode 100644
index 0000000..e2b0206
--- /dev/null
+++ b/test cases/common/6 linkshared/cpplib.h
@@ -0,0 +1,12 @@
+/* See http://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support */
+#if defined(_WIN32) || defined(__CYGWIN__)
+ #ifdef BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #define DLL_PUBLIC __attribute__ ((visibility ("default")))
+#endif
+
+int DLL_PUBLIC cppfunc(void);
diff --git a/test cases/common/6 linkshared/cppmain.cpp b/test cases/common/6 linkshared/cppmain.cpp
new file mode 100644
index 0000000..29e9a44
--- /dev/null
+++ b/test cases/common/6 linkshared/cppmain.cpp
@@ -0,0 +1,5 @@
+#include "cpplib.h"
+
+int main(void) {
+ return cppfunc() != 42;
+}
diff --git a/test cases/common/6 linkshared/libfile.c b/test cases/common/6 linkshared/libfile.c
new file mode 100644
index 0000000..91489b2
--- /dev/null
+++ b/test cases/common/6 linkshared/libfile.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func(void) {
+ return 0;
+}
diff --git a/test cases/common/6 linkshared/main.c b/test cases/common/6 linkshared/main.c
new file mode 100644
index 0000000..7777327
--- /dev/null
+++ b/test cases/common/6 linkshared/main.c
@@ -0,0 +1,11 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_IMPORT __declspec(dllimport)
+#else
+ #define DLL_IMPORT
+#endif
+
+int DLL_IMPORT func(void);
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/6 linkshared/meson.build b/test cases/common/6 linkshared/meson.build
new file mode 100644
index 0000000..846b4a0
--- /dev/null
+++ b/test cases/common/6 linkshared/meson.build
@@ -0,0 +1,12 @@
+project('shared library linking test', 'c', 'cpp')
+
+lib = shared_library('mylib',
+ 'libfile.c' # Split to different lines before and after the comma to test parser.
+ , install : false) # Don't install libraries in common tests; the path is platform-specific
+exe = executable('prog', 'main.c', link_with : lib, install : true)
+
+test('runtest', exe)
+
+cpplib = shared_library('mycpplib', 'cpplib.cpp')
+cppexe = executable('cppprog', 'cppmain.cpp', link_with : cpplib)
+test('cpptest', cppexe)
diff --git a/test cases/common/6 linkshared/test.json b/test cases/common/6 linkshared/test.json
new file mode 100644
index 0000000..067bca7
--- /dev/null
+++ b/test cases/common/6 linkshared/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ { "type": "exe", "file": "usr/bin/prog" },
+ { "type": "pdb", "file": "usr/bin/prog" }
+ ]
+}
diff --git a/test cases/common/60 foreach/meson.build b/test cases/common/60 foreach/meson.build
new file mode 100644
index 0000000..af60e0f
--- /dev/null
+++ b/test cases/common/60 foreach/meson.build
@@ -0,0 +1,53 @@
+project('foreach', 'c')
+
+tests = [['test1', 'prog1', 'prog1.c'],
+ ['test2', 'prog2', 'prog2.c', 'fallback'],
+ ['test3', 'prog3', 'prog3.c', 'urgh']]
+
+assert(tests[0].get(3, 'fallbck') == 'fallbck', 'array #1 fallback did not match')
+assert(tests[1].get(3, 'failbk') == 'fallback', 'array #2 value did not match')
+assert(tests[2].get(3, 'urgh') == 'urgh', 'array #3 value did not match')
+
+foreach i : tests
+ test(i.get(0), executable(i.get(1), i.get(2), install : true))
+
+ # Ensure that changing the tests variable does not
+ # affect ongoing iteration in the foreach loop.
+ #
+ # Being able to do that would make Meson Turing complete and
+ # we definitely don't want that.
+ tests = ['test4', 'prog4', 'prog4.c']
+endforeach
+
+items = ['a', 'continue', 'b', 'break', 'c']
+result = []
+foreach i : items
+ if i == 'continue'
+ continue
+ elif i == 'break'
+ break
+ endif
+ result += i
+endforeach
+
+assert(result == ['a', 'b'], 'Continue or break in foreach failed')
+
+items = []
+iter = range(2)
+foreach i : iter
+ items += i
+endforeach
+assert(items == [0, 1])
+assert(iter[1] == 1)
+
+items = []
+foreach i : range(1, 2)
+ items += i
+endforeach
+assert(items == [1])
+
+items = []
+foreach i : range(1, 10, 2)
+ items += i
+endforeach
+assert(items == [1, 3, 5, 7, 9])
diff --git a/test cases/common/60 foreach/prog1.c b/test cases/common/60 foreach/prog1.c
new file mode 100644
index 0000000..339dc49
--- /dev/null
+++ b/test cases/common/60 foreach/prog1.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("This is test #1.\n");
+ return 0;
+}
diff --git a/test cases/common/60 foreach/prog2.c b/test cases/common/60 foreach/prog2.c
new file mode 100644
index 0000000..c213288
--- /dev/null
+++ b/test cases/common/60 foreach/prog2.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("This is test #2.\n");
+ return 0;
+}
diff --git a/test cases/common/60 foreach/prog3.c b/test cases/common/60 foreach/prog3.c
new file mode 100644
index 0000000..905a530
--- /dev/null
+++ b/test cases/common/60 foreach/prog3.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("This is test #3.\n");
+ return 0;
+}
diff --git a/test cases/common/60 foreach/test.json b/test cases/common/60 foreach/test.json
new file mode 100644
index 0000000..2fc952d
--- /dev/null
+++ b/test cases/common/60 foreach/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog1"},
+ {"type": "pdb", "file": "usr/bin/prog1"},
+ {"type": "exe", "file": "usr/bin/prog2"},
+ {"type": "pdb", "file": "usr/bin/prog2"},
+ {"type": "exe", "file": "usr/bin/prog3"},
+ {"type": "pdb", "file": "usr/bin/prog3"}
+ ]
+}
diff --git a/test cases/common/61 number arithmetic/meson.build b/test cases/common/61 number arithmetic/meson.build
new file mode 100644
index 0000000..f8ab81b
--- /dev/null
+++ b/test cases/common/61 number arithmetic/meson.build
@@ -0,0 +1,76 @@
+project('number arithmetic')
+
+if 6 + 4 != 10
+ error('Number addition is broken')
+endif
+if 6 - 4 != 2
+ error('Number subtraction is broken')
+endif
+
+if 6 * 4 != 24
+ error('Number multiplication is broken')
+endif
+if 16 / 4 != 4
+ error('Number division is broken')
+endif
+
+#if (1 / 3) * 3 != 1
+# error('Float interconversion broken')
+#endif
+if (5 / 3) * 3 != 3
+ error('Integer division is broken')
+endif
+
+assert((5 % 2) == 1, 'Integer modulo (odd) is broken')
+assert((4 % 2) == 0, 'Integer modulo (even) is broken')
+
+if 2 * 1 % 2 != 0
+ error('Modulo precedence with multiplication is broken')
+endif
+if 2 + 1 % 2 != 3
+ error('Modulo precedence with addition is broken')
+endif
+if 9 / 9 % 2 != 1
+ error('Modulo precedence with division is broken')
+endif
+if 9 - 9 % 2 != 8
+ error('Modulo precedence with subtraction is broken')
+endif
+
+assert(2.is_even(), 'int is_even() broken for even value')
+assert(not(2.is_odd()), 'int is_odd() broken for even value')
+assert(not(3.is_even()), 'int is_even() broken for odd value')
+assert(3.is_odd(), 'int is_odd() broken for odd value')
+
+assert(3 < 4, 'Lt broken')
+assert(not(4 < 3), 'Lt broken')
+assert(3 <= 4, 'Lte broken')
+assert(not(4 <= 3), 'Lte broken')
+assert(3 <= 3, 'Lte broken')
+
+assert(4 > 3, 'Gt broken')
+assert(not(3 > 4), 'Gt broken')
+assert(4 >= 3, 'Gte broken')
+assert(not(3 >= 4), 'Gte broken')
+assert(3 >= 3, 'Gte broken')
+
+assert(true.to_int() == 1,'bool to_int() broken')
+assert(false.to_int() == 0,'bool to_int() broken')
+
+hex_255 = 0xff
+hex2_255 = 0XFF
+
+assert(hex_255 == 255, 'Hex parsing is broken.')
+assert(hex2_255 == 255, 'Uppercase hex parsing is broken.')
+
+bin_123 = 0b1111011
+bin2_123 = 0B1111011
+
+assert(bin_123 == 123, 'Bin number parsing is broken.')
+assert(bin2_123 == 123, 'Uppercase bin number parsing is broken.')
+
+oct_493 = 0o755
+oct2_493 = 0O755
+
+assert(oct_493 == 493, 'Oct number parsing is broken.')
+assert(oct2_493 == 493, 'Uppercase oct number parsing is broken.')
diff --git a/test cases/common/62 string arithmetic/meson.build b/test cases/common/62 string arithmetic/meson.build
new file mode 100644
index 0000000..acfac0b
--- /dev/null
+++ b/test cases/common/62 string arithmetic/meson.build
@@ -0,0 +1,49 @@
+project('string arithmetic', meson_version: '>=0.62.0')
+
+assert('foo' + 'bar' == 'foobar')
+assert('foo' + 'bar' + 'baz' == 'foobarbaz')
+
+a = 'a'
+b = 'b'
+assert(a + b + 'c' == 'abc')
+
+# ------------------------------------------------------------------------------
+# format strings:
+# ------------------------------------------------------------------------------
+sub1 = 'the'
+sub2 = ' quick\n'
+sub3 = ' brown'
+sub4 = '\nfox'
+x = f'@sub1@@sub2@@sub3@@sub4@'
+
+assert(x == sub1 + sub2 + sub3 + sub4)
+assert(x == 'the quick\n brown\nfox')
+
+# ------------------------------------------------------------------------------
+# multi-line format strings
+# ------------------------------------------------------------------------------
+y_actual = f'''This is a multi-line comment with string substitution:
+ "@sub1@@sub2@@sub3@@sub4@"
+
+And I can even substitute the entry multiple times!
+
+@sub1@
+@sub2@
+@sub3@
+'''
+
+y_expect = '''This is a multi-line comment with string substitution:
+ "the quick
+ brown
+fox"
+
+And I can even substitute the entry multiple times!
+
+the
+ quick
+
+ brown
+'''
+message('actual=' + y_actual)
+message('expect=' + y_expect)
+assert(y_actual == y_expect)
diff --git a/test cases/common/62 string arithmetic/test.json b/test cases/common/62 string arithmetic/test.json
new file mode 100644
index 0000000..5a11650
--- /dev/null
+++ b/test cases/common/62 string arithmetic/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/common/62 string arithmetic/meson.build:25: WARNING: Project targets '>=0.62.0' but uses feature introduced in '0.63.0': multiline format strings."
+ }
+ ]
+}
diff --git a/test cases/common/63 array arithmetic/meson.build b/test cases/common/63 array arithmetic/meson.build
new file mode 100644
index 0000000..7d5f54f
--- /dev/null
+++ b/test cases/common/63 array arithmetic/meson.build
@@ -0,0 +1,15 @@
+project('array arithmetic')
+
+array1 = ['foo', 'bar']
+array2 = ['qux', 'baz']
+
+if array1 + array2 != ['foo', 'bar', 'qux', 'baz']
+ error('Array concatenation is broken')
+endif
+if array2 + array1 != ['qux', 'baz', 'foo', 'bar']
+ error('Array concatenation is broken')
+endif
+
+if array1 + array1 + array1 != ['foo', 'bar', 'foo', 'bar', 'foo', 'bar']
+ error('Many-array concatenation is broken')
+endif
diff --git a/test cases/common/64 arithmetic bidmas/meson.build b/test cases/common/64 arithmetic bidmas/meson.build
new file mode 100644
index 0000000..548294b
--- /dev/null
+++ b/test cases/common/64 arithmetic bidmas/meson.build
@@ -0,0 +1,15 @@
+project('arithmetic bidmas')
+
+if 5 * 3 - 6 / 2 + 1 != 13
+ error('Arithmetic bidmas broken')
+endif
+if 5 * (3 - 6 / 2) + 1 != 1
+ error('Arithmetic bidmas with brackets broken')
+endif
+
+if 5 * 12 / 2 * 3 != 90
+ error('Sequential multiplication and division broken')
+endif
+if 5 * (12 / (2 * 3)) != 10
+ error('Sequential multiplication and division with brackets broken')
+endif
diff --git a/test cases/common/65 build always/main.c b/test cases/common/65 build always/main.c
new file mode 100644
index 0000000..a9ee55e
--- /dev/null
+++ b/test cases/common/65 build always/main.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+#include"version.h"
+
+int main(void) {
+ printf("Version is %s.\n", version_string);
+ return 0;
+}
diff --git a/test cases/common/65 build always/meson.build b/test cases/common/65 build always/meson.build
new file mode 100644
index 0000000..f720c89
--- /dev/null
+++ b/test cases/common/65 build always/meson.build
@@ -0,0 +1,14 @@
+project('run always', 'c')
+
+version = '1.0.0'
+
+vgen = find_program('version_gen.py')
+
+version_src = custom_target('Version string',
+input : 'version.c.in',
+output : 'version.c',
+command : [vgen, '@INPUT@', '@OUTPUT@', version],
+build_always : true,
+)
+
+executable('versionprinter', 'main.c', version_src)
diff --git a/test cases/common/65 build always/version.c.in b/test cases/common/65 build always/version.c.in
new file mode 100644
index 0000000..619e517
--- /dev/null
+++ b/test cases/common/65 build always/version.c.in
@@ -0,0 +1,3 @@
+#include"version.h"
+
+const char *version_string = "@VERSION@";
diff --git a/test cases/common/65 build always/version.h b/test cases/common/65 build always/version.h
new file mode 100644
index 0000000..7d433f0
--- /dev/null
+++ b/test cases/common/65 build always/version.h
@@ -0,0 +1,3 @@
+#pragma once
+
+extern const char *version_string;
diff --git a/test cases/common/65 build always/version_gen.py b/test cases/common/65 build always/version_gen.py
new file mode 100755
index 0000000..fbe2df9
--- /dev/null
+++ b/test cases/common/65 build always/version_gen.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+
+import sys, os, subprocess
+
+def generate(infile, outfile, fallback):
+ workdir = os.path.split(infile)[0]
+ if workdir == '':
+ workdir = '.'
+ try:
+ version = subprocess.check_output(['git', 'describe'], cwd=workdir).decode().strip()
+ except (subprocess.CalledProcessError, OSError, UnicodeDecodeError):
+ version = fallback
+ with open(infile) as f:
+ newdata = f.read().replace('@VERSION@', version)
+ try:
+ with open(outfile) as f:
+ olddata = f.read()
+ if olddata == newdata:
+ return
+ except OSError:
+ pass
+ with open(outfile, 'w') as f:
+ f.write(newdata)
+
+if __name__ == '__main__':
+ infile = sys.argv[1]
+ outfile = sys.argv[2]
+ fallback = sys.argv[3]
+ generate(infile, outfile, fallback)
diff --git a/test cases/common/66 vcstag/meson.build b/test cases/common/66 vcstag/meson.build
new file mode 100644
index 0000000..38fa590
--- /dev/null
+++ b/test cases/common/66 vcstag/meson.build
@@ -0,0 +1,42 @@
+project('vcstag', 'c')
+
+version_src = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag.c',
+fallback : '1.0.0')
+
+version_src_custom = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag-custom.c',
+command : ['git', 'show-ref', '-s', 'refs/heads/master'],
+fallback : '1.0.0')
+
+version_src_notfound_fallback = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag-notfound-fallback.c',
+command : ['git-but-not-found-sorry', 'show-ref', '-s', 'refs/heads/master'],
+fallback : '1.0.0')
+
+version_src_fallback = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag-fallback.c')
+
+git = find_program('git')
+
+version_src_git_program = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag-git-program.c',
+command : [git, 'rev-parse', 'HEAD'],
+fallback : '1.0.0')
+
+version_src_file = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag-file.c',
+command : files('version.py'))
+
+tagprog = executable('tagprog', 'tagprog.c', version_src)
+
+version_src_executable = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag-executable.c',
+command : [tagprog])
+
+executable('tagprog-custom', 'tagprog.c', version_src_custom)
+executable('tagprog-fallback', 'tagprog.c', version_src_fallback)
+executable('tagprog-notfound-fallback', 'tagprog.c', version_src_notfound_fallback)
+executable('tagprog-git-program', 'tagprog.c', version_src_git_program)
+executable('tagprog-executable', 'tagprog.c', version_src_executable)
+executable('tagprog-file', 'tagprog.c', version_src_file)
diff --git a/test cases/common/66 vcstag/tagprog.c b/test cases/common/66 vcstag/tagprog.c
new file mode 100644
index 0000000..5546802
--- /dev/null
+++ b/test cases/common/66 vcstag/tagprog.c
@@ -0,0 +1,8 @@
+#include<stdio.h>
+
+extern const char *vcstag;
+
+int main(void) {
+ printf("Version is %s\n", vcstag);
+ return 0;
+}
diff --git a/test cases/common/66 vcstag/vcstag.c.in b/test cases/common/66 vcstag/vcstag.c.in
new file mode 100644
index 0000000..6e6f7c5
--- /dev/null
+++ b/test cases/common/66 vcstag/vcstag.c.in
@@ -0,0 +1 @@
+const char *vcstag = "@VCS_TAG@";
diff --git a/test cases/common/66 vcstag/version.py b/test cases/common/66 vcstag/version.py
new file mode 100755
index 0000000..0e0185e
--- /dev/null
+++ b/test cases/common/66 vcstag/version.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('3.14')
diff --git a/test cases/common/67 modules/meson.build b/test cases/common/67 modules/meson.build
new file mode 100644
index 0000000..1cb42c4
--- /dev/null
+++ b/test cases/common/67 modules/meson.build
@@ -0,0 +1,14 @@
+project('module test')
+
+modtest = import('modtest')
+modtest.print_hello()
+assert(modtest.found())
+
+modtest = import('modtest', required : get_option('disabled'))
+assert(not modtest.found())
+
+notfound = import('not-found', required : false)
+assert(not notfound.found())
+
+disabled = import('not-found', required : false, disabler : true)
+assert(is_disabler(disabled))
diff --git a/test cases/common/67 modules/meson_options.txt b/test cases/common/67 modules/meson_options.txt
new file mode 100644
index 0000000..0671144
--- /dev/null
+++ b/test cases/common/67 modules/meson_options.txt
@@ -0,0 +1,6 @@
+option(
+ 'disabled',
+ type : 'feature',
+ value : 'disabled',
+ description : 'test disabled'
+)
diff --git a/test cases/common/68 should fail/failing.c b/test cases/common/68 should fail/failing.c
new file mode 100644
index 0000000..3e70e50
--- /dev/null
+++ b/test cases/common/68 should fail/failing.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 1;
+}
diff --git a/test cases/common/68 should fail/meson.build b/test cases/common/68 should fail/meson.build
new file mode 100644
index 0000000..dffbbb3
--- /dev/null
+++ b/test cases/common/68 should fail/meson.build
@@ -0,0 +1,4 @@
+project('should fail', 'c')
+
+exe = executable('prog', 'failing.c')
+test('failing', exe, should_fail : true)
diff --git a/test cases/common/69 configure file in custom target/inc/confdata.in b/test cases/common/69 configure file in custom target/inc/confdata.in
new file mode 100644
index 0000000..e44cdea
--- /dev/null
+++ b/test cases/common/69 configure file in custom target/inc/confdata.in
@@ -0,0 +1 @@
+@VALUE@
diff --git a/test cases/common/69 configure file in custom target/inc/meson.build b/test cases/common/69 configure file in custom target/inc/meson.build
new file mode 100644
index 0000000..05d2dcb
--- /dev/null
+++ b/test cases/common/69 configure file in custom target/inc/meson.build
@@ -0,0 +1,6 @@
+cdata = configuration_data()
+cdata.set('VALUE', '42')
+
+cfile = configure_file(input : 'confdata.in',
+output : 'confdata',
+configuration : cdata)
diff --git a/test cases/common/69 configure file in custom target/meson.build b/test cases/common/69 configure file in custom target/meson.build
new file mode 100644
index 0000000..562013d
--- /dev/null
+++ b/test cases/common/69 configure file in custom target/meson.build
@@ -0,0 +1,4 @@
+project('conf file in custom target')
+
+subdir('inc')
+subdir('src')
diff --git a/test cases/common/69 configure file in custom target/src/meson.build b/test cases/common/69 configure file in custom target/src/meson.build
new file mode 100644
index 0000000..e0ab9eb
--- /dev/null
+++ b/test cases/common/69 configure file in custom target/src/meson.build
@@ -0,0 +1,20 @@
+custom_target('thing',
+output : 'final.dat',
+input : cfile,
+command : [find_program('mycompiler.py'), '@INPUT@', '@OUTPUT@'])
+
+# Test usage of a `configure_file` as part of the command list
+py3 = find_program('python3', required : false)
+if not py3.found()
+ # Maybe 'python' is Python 3
+ py3 = find_program('python')
+endif
+
+compiler = configure_file(input : 'mycompiler.py',
+ output : 'mycompiler2.py',
+ copy: true)
+
+custom_target('thing2',
+output : 'final2.dat',
+input : cfile,
+command : [py3, compiler, '@INPUT@', '@OUTPUT@'])
diff --git a/test cases/common/69 configure file in custom target/src/mycompiler.py b/test cases/common/69 configure file in custom target/src/mycompiler.py
new file mode 100644
index 0000000..b00c862
--- /dev/null
+++ b/test cases/common/69 configure file in custom target/src/mycompiler.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import sys
+
+with open(sys.argv[1]) as ifile:
+ if ifile.readline().strip() != '42':
+ print('Incorrect input')
+with open(sys.argv[2], 'w') as ofile:
+ ofile.write('Success\n')
diff --git a/test cases/common/7 mixed/func.c b/test cases/common/7 mixed/func.c
new file mode 100644
index 0000000..c76c23d
--- /dev/null
+++ b/test cases/common/7 mixed/func.c
@@ -0,0 +1,4 @@
+int func(void) {
+ int class = 0;
+ return class;
+}
diff --git a/test cases/common/7 mixed/main.cc b/test cases/common/7 mixed/main.cc
new file mode 100644
index 0000000..9a7a7a6
--- /dev/null
+++ b/test cases/common/7 mixed/main.cc
@@ -0,0 +1,7 @@
+extern "C" int func();
+
+class BreakPlainCCompiler;
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/7 mixed/meson.build b/test cases/common/7 mixed/meson.build
new file mode 100644
index 0000000..af88a1e
--- /dev/null
+++ b/test cases/common/7 mixed/meson.build
@@ -0,0 +1,3 @@
+project('mixed C and C++', 'c', 'cpp')
+exe = executable('prog', 'main.cc', 'func.c')
+test('mixtest', exe)
diff --git a/test cases/common/70 external test program/meson.build b/test cases/common/70 external test program/meson.build
new file mode 100644
index 0000000..811f497
--- /dev/null
+++ b/test cases/common/70 external test program/meson.build
@@ -0,0 +1,3 @@
+project('test is external')
+
+test('external', find_program('mytest.py'), args : ['correct'])
diff --git a/test cases/common/70 external test program/mytest.py b/test cases/common/70 external test program/mytest.py
new file mode 100755
index 0000000..fee94e0
--- /dev/null
+++ b/test cases/common/70 external test program/mytest.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+
+
+import sys
+
+if sys.argv[1] == 'correct':
+ print('Argument is correct.')
+ sys.exit(0)
+print('Argument is incorrect:', sys.argv[1])
+sys.exit(1)
diff --git a/test cases/common/71 ctarget dependency/gen1.py b/test cases/common/71 ctarget dependency/gen1.py
new file mode 100755
index 0000000..dbadb6d
--- /dev/null
+++ b/test cases/common/71 ctarget dependency/gen1.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import time, sys
+
+# Make sure other script runs first if dependency
+# is missing.
+time.sleep(0.5)
+
+with open(sys.argv[1]) as f:
+ contents = f.read()
+with open(sys.argv[2], 'w') as f:
+ f.write(contents)
diff --git a/test cases/common/71 ctarget dependency/gen2.py b/test cases/common/71 ctarget dependency/gen2.py
new file mode 100755
index 0000000..6fde556
--- /dev/null
+++ b/test cases/common/71 ctarget dependency/gen2.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+
+import sys, os
+from glob import glob
+
+files = glob(os.path.join(sys.argv[1], '*.tmp'))
+assert len(files) == 1
+
+with open(files[0]) as ifile, open(sys.argv[2], 'w') as ofile:
+ ofile.write(ifile.read())
diff --git a/test cases/common/71 ctarget dependency/input.dat b/test cases/common/71 ctarget dependency/input.dat
new file mode 100644
index 0000000..7af91e2
--- /dev/null
+++ b/test cases/common/71 ctarget dependency/input.dat
@@ -0,0 +1 @@
+This is a piece of text.
diff --git a/test cases/common/71 ctarget dependency/meson.build b/test cases/common/71 ctarget dependency/meson.build
new file mode 100644
index 0000000..40f7398
--- /dev/null
+++ b/test cases/common/71 ctarget dependency/meson.build
@@ -0,0 +1,20 @@
+project('custom target dependency')
+
+# Sometimes custom targets do not take input files
+# but instead do globbing or some similar wackiness.
+# In this case we need to be able to specify a
+# manual dependency between two custom targets,
+# if one needs to be run before the other.
+
+g1 = find_program('gen1.py')
+g2 = find_program('gen2.py')
+
+c1 = custom_target('medput',
+input : 'input.dat',
+output : 'medput.tmp',
+command : [g1, '@INPUT@', '@OUTPUT@'])
+
+custom_target('output',
+output : 'output.dat',
+command : [g2, '@OUTDIR@', '@OUTPUT@'],
+depends : c1)
diff --git a/test cases/common/72 shared subproject/a.c b/test cases/common/72 shared subproject/a.c
new file mode 100644
index 0000000..7510a1b
--- /dev/null
+++ b/test cases/common/72 shared subproject/a.c
@@ -0,0 +1,13 @@
+#include<assert.h>
+char func_b(void);
+char func_c(void);
+
+int main(void) {
+ if(func_b() != 'b') {
+ return 1;
+ }
+ if(func_c() != 'c') {
+ return 2;
+ }
+ return 0;
+}
diff --git a/test cases/common/72 shared subproject/meson.build b/test cases/common/72 shared subproject/meson.build
new file mode 100644
index 0000000..6803d51
--- /dev/null
+++ b/test cases/common/72 shared subproject/meson.build
@@ -0,0 +1,10 @@
+project('A', 'c')
+
+B = subproject('B')
+b = B.get_variable('b')
+
+C = subproject('C')
+c = C.get_variable('c')
+
+a = executable('a', 'a.c', link_with : [b, c])
+test('a test', a)
diff --git a/test cases/common/72 shared subproject/subprojects/B/b.c b/test cases/common/72 shared subproject/subprojects/B/b.c
new file mode 100644
index 0000000..b8c7d83
--- /dev/null
+++ b/test cases/common/72 shared subproject/subprojects/B/b.c
@@ -0,0 +1,21 @@
+#include<stdlib.h>
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+
+char func_c(void);
+
+char DLL_PUBLIC func_b(void) {
+ if(func_c() != 'c') {
+ exit(3);
+ }
+ return 'b';
+}
diff --git a/test cases/common/72 shared subproject/subprojects/B/meson.build b/test cases/common/72 shared subproject/subprojects/B/meson.build
new file mode 100644
index 0000000..8f4cb02
--- /dev/null
+++ b/test cases/common/72 shared subproject/subprojects/B/meson.build
@@ -0,0 +1,4 @@
+project('B', 'c')
+C = subproject('C')
+c = C.get_variable('c')
+b = library('b', 'b.c', link_with : c)
diff --git a/test cases/common/72 shared subproject/subprojects/C/c.c b/test cases/common/72 shared subproject/subprojects/C/c.c
new file mode 100644
index 0000000..facd199
--- /dev/null
+++ b/test cases/common/72 shared subproject/subprojects/C/c.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_c(void) {
+ return 'c';
+}
diff --git a/test cases/common/72 shared subproject/subprojects/C/meson.build b/test cases/common/72 shared subproject/subprojects/C/meson.build
new file mode 100644
index 0000000..1f05f9e
--- /dev/null
+++ b/test cases/common/72 shared subproject/subprojects/C/meson.build
@@ -0,0 +1,3 @@
+project('C', 'c')
+# libc.so cannot be used, it already exists as a reserved name
+c = library('cee', 'c.c')
diff --git a/test cases/common/73 shared subproject 2/a.c b/test cases/common/73 shared subproject 2/a.c
new file mode 100644
index 0000000..7510a1b
--- /dev/null
+++ b/test cases/common/73 shared subproject 2/a.c
@@ -0,0 +1,13 @@
+#include<assert.h>
+char func_b(void);
+char func_c(void);
+
+int main(void) {
+ if(func_b() != 'b') {
+ return 1;
+ }
+ if(func_c() != 'c') {
+ return 2;
+ }
+ return 0;
+}
diff --git a/test cases/common/73 shared subproject 2/meson.build b/test cases/common/73 shared subproject 2/meson.build
new file mode 100644
index 0000000..0647325
--- /dev/null
+++ b/test cases/common/73 shared subproject 2/meson.build
@@ -0,0 +1,13 @@
+project('A', 'c')
+
+# Same as the previous test but use C and B in
+# the opposite order.
+
+C = subproject('C')
+c = C.get_variable('c')
+
+B = subproject('B')
+b = B.get_variable('b')
+
+a = executable('a', 'a.c', link_with : [b, c])
+test('a test', a)
diff --git a/test cases/common/73 shared subproject 2/subprojects/B/b.c b/test cases/common/73 shared subproject 2/subprojects/B/b.c
new file mode 100644
index 0000000..4d71c0f
--- /dev/null
+++ b/test cases/common/73 shared subproject 2/subprojects/B/b.c
@@ -0,0 +1,20 @@
+#include<stdlib.h>
+char func_c(void);
+
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_b(void) {
+ if(func_c() != 'c') {
+ exit(3);
+ }
+ return 'b';
+}
diff --git a/test cases/common/73 shared subproject 2/subprojects/B/meson.build b/test cases/common/73 shared subproject 2/subprojects/B/meson.build
new file mode 100644
index 0000000..8f4cb02
--- /dev/null
+++ b/test cases/common/73 shared subproject 2/subprojects/B/meson.build
@@ -0,0 +1,4 @@
+project('B', 'c')
+C = subproject('C')
+c = C.get_variable('c')
+b = library('b', 'b.c', link_with : c)
diff --git a/test cases/common/73 shared subproject 2/subprojects/C/c.c b/test cases/common/73 shared subproject 2/subprojects/C/c.c
new file mode 100644
index 0000000..facd199
--- /dev/null
+++ b/test cases/common/73 shared subproject 2/subprojects/C/c.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_c(void) {
+ return 'c';
+}
diff --git a/test cases/common/73 shared subproject 2/subprojects/C/meson.build b/test cases/common/73 shared subproject 2/subprojects/C/meson.build
new file mode 100644
index 0000000..1f05f9e
--- /dev/null
+++ b/test cases/common/73 shared subproject 2/subprojects/C/meson.build
@@ -0,0 +1,3 @@
+project('C', 'c')
+# libc.so cannot be used, it already exists as a reserved name
+c = library('cee', 'c.c')
diff --git a/test cases/common/74 file object/lib.c b/test cases/common/74 file object/lib.c
new file mode 100644
index 0000000..9180030
--- /dev/null
+++ b/test cases/common/74 file object/lib.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 0;
+}
diff --git a/test cases/common/74 file object/meson.build b/test cases/common/74 file object/meson.build
new file mode 100644
index 0000000..fc01bfe
--- /dev/null
+++ b/test cases/common/74 file object/meson.build
@@ -0,0 +1,8 @@
+project('file object', 'c')
+
+prog0 = files('prog.c')
+lib0 = files('lib.c')
+test('fobj', executable('fobj', prog0, lib0))
+
+subdir('subdir1')
+subdir('subdir2')
diff --git a/test cases/common/74 file object/prog.c b/test cases/common/74 file object/prog.c
new file mode 100644
index 0000000..78c6acc
--- /dev/null
+++ b/test cases/common/74 file object/prog.c
@@ -0,0 +1,13 @@
+#include<stdio.h>
+
+int func(void); /* Files in different subdirs return different values. */
+
+int main(void) {
+ if(func() == 0) {
+ printf("Iz success.\n");
+ } else {
+ printf("Iz fail.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/74 file object/subdir1/lib.c b/test cases/common/74 file object/subdir1/lib.c
new file mode 100644
index 0000000..8c13c21
--- /dev/null
+++ b/test cases/common/74 file object/subdir1/lib.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 1;
+}
diff --git a/test cases/common/74 file object/subdir1/meson.build b/test cases/common/74 file object/subdir1/meson.build
new file mode 100644
index 0000000..f5066f0
--- /dev/null
+++ b/test cases/common/74 file object/subdir1/meson.build
@@ -0,0 +1,7 @@
+prog1 = files('prog.c')
+lib1 = files('lib.c')
+
+test('subdir0', executable('subdir0', prog0, lib1), should_fail : true)
+test('subdir1', executable('subdir1', prog1, lib0), should_fail : true)
+
+test('subdir2', executable('subdir2', prog1, lib1)) \ No newline at end of file
diff --git a/test cases/common/74 file object/subdir1/prog.c b/test cases/common/74 file object/subdir1/prog.c
new file mode 100644
index 0000000..38d13d2
--- /dev/null
+++ b/test cases/common/74 file object/subdir1/prog.c
@@ -0,0 +1,13 @@
+#include<stdio.h>
+
+int func(void);
+
+int main(void) {
+ if(func() == 1) {
+ printf("Iz success.\n");
+ } else {
+ printf("Iz fail.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/74 file object/subdir2/lib.c b/test cases/common/74 file object/subdir2/lib.c
new file mode 100644
index 0000000..8e2b4eb
--- /dev/null
+++ b/test cases/common/74 file object/subdir2/lib.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 2;
+}
diff --git a/test cases/common/74 file object/subdir2/meson.build b/test cases/common/74 file object/subdir2/meson.build
new file mode 100644
index 0000000..5886510
--- /dev/null
+++ b/test cases/common/74 file object/subdir2/meson.build
@@ -0,0 +1,7 @@
+prog2 = files('prog.c')
+lib2 = files('lib.c')
+
+test('subdir3', executable('subdir3', prog1, lib2), should_fail : true)
+test('subdir4', executable('subdir4', prog2, lib1), should_fail : true)
+
+test('subdir4', executable('subdir5', prog2, lib2)) \ No newline at end of file
diff --git a/test cases/common/74 file object/subdir2/prog.c b/test cases/common/74 file object/subdir2/prog.c
new file mode 100644
index 0000000..8a8f0d0
--- /dev/null
+++ b/test cases/common/74 file object/subdir2/prog.c
@@ -0,0 +1,13 @@
+#include<stdio.h>
+
+int func(void);
+
+int main(void) {
+ if(func() == 2) {
+ printf("Iz success.\n");
+ } else {
+ printf("Iz fail.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/75 custom subproject dir/a.c b/test cases/common/75 custom subproject dir/a.c
new file mode 100644
index 0000000..7510a1b
--- /dev/null
+++ b/test cases/common/75 custom subproject dir/a.c
@@ -0,0 +1,13 @@
+#include<assert.h>
+char func_b(void);
+char func_c(void);
+
+int main(void) {
+ if(func_b() != 'b') {
+ return 1;
+ }
+ if(func_c() != 'c') {
+ return 2;
+ }
+ return 0;
+}
diff --git a/test cases/common/75 custom subproject dir/custom_subproject_dir/B/b.c b/test cases/common/75 custom subproject dir/custom_subproject_dir/B/b.c
new file mode 100644
index 0000000..4d71c0f
--- /dev/null
+++ b/test cases/common/75 custom subproject dir/custom_subproject_dir/B/b.c
@@ -0,0 +1,20 @@
+#include<stdlib.h>
+char func_c(void);
+
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_b(void) {
+ if(func_c() != 'c') {
+ exit(3);
+ }
+ return 'b';
+}
diff --git a/test cases/common/75 custom subproject dir/custom_subproject_dir/B/meson.build b/test cases/common/75 custom subproject dir/custom_subproject_dir/B/meson.build
new file mode 100644
index 0000000..280c60c
--- /dev/null
+++ b/test cases/common/75 custom subproject dir/custom_subproject_dir/B/meson.build
@@ -0,0 +1,4 @@
+project('B', 'c')
+C = subproject('C')
+c = C.get_variable('c')
+b = shared_library('b', 'b.c', link_with : c)
diff --git a/test cases/common/75 custom subproject dir/custom_subproject_dir/C/c.c b/test cases/common/75 custom subproject dir/custom_subproject_dir/C/c.c
new file mode 100644
index 0000000..facd199
--- /dev/null
+++ b/test cases/common/75 custom subproject dir/custom_subproject_dir/C/c.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+char DLL_PUBLIC func_c(void) {
+ return 'c';
+}
diff --git a/test cases/common/75 custom subproject dir/custom_subproject_dir/C/meson.build b/test cases/common/75 custom subproject dir/custom_subproject_dir/C/meson.build
new file mode 100644
index 0000000..3ac6217
--- /dev/null
+++ b/test cases/common/75 custom subproject dir/custom_subproject_dir/C/meson.build
@@ -0,0 +1,3 @@
+project('C', 'c')
+# libc.so cannot be used, it already exists as a reserved name
+c = shared_library('cee', 'c.c')
diff --git a/test cases/common/75 custom subproject dir/meson.build b/test cases/common/75 custom subproject dir/meson.build
new file mode 100644
index 0000000..d9ba649
--- /dev/null
+++ b/test cases/common/75 custom subproject dir/meson.build
@@ -0,0 +1,10 @@
+project('A', 'c', subproject_dir:'custom_subproject_dir')
+
+B = subproject('B')
+b = B.get_variable('b')
+
+C = subproject('C')
+c = C.get_variable('c')
+
+a = executable('a', 'a.c', link_with : [b, c])
+test('a test', a)
diff --git a/test cases/common/76 has type/meson.build b/test cases/common/76 has type/meson.build
new file mode 100644
index 0000000..de8dbc8
--- /dev/null
+++ b/test cases/common/76 has type/meson.build
@@ -0,0 +1,13 @@
+project('has type', 'c', 'cpp')
+
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
+
+foreach cc : compilers
+ if not cc.has_type('time_t', prefix : '#include<time.h>')
+ error('Did not detect type that exists.')
+ endif
+
+ if cc.has_type('no_time_t', prefix : '#include<time.h>')
+ error('Not existing type found.')
+ endif
+endforeach
diff --git a/test cases/common/77 extract from nested subdir/meson.build b/test cases/common/77 extract from nested subdir/meson.build
new file mode 100644
index 0000000..000e1aa
--- /dev/null
+++ b/test cases/common/77 extract from nested subdir/meson.build
@@ -0,0 +1,8 @@
+project('Extract objects from subdirs', 'c')
+
+if meson.is_unity()
+ message('Unity build: skipping incompatible test')
+else
+ subdir('src')
+ subdir('tst')
+endif
diff --git a/test cases/common/77 extract from nested subdir/src/first/lib_first.c b/test cases/common/77 extract from nested subdir/src/first/lib_first.c
new file mode 100644
index 0000000..5fc3267
--- /dev/null
+++ b/test cases/common/77 extract from nested subdir/src/first/lib_first.c
@@ -0,0 +1,3 @@
+int first(void) {
+ return 1001;
+}
diff --git a/test cases/common/77 extract from nested subdir/src/first/meson.build b/test cases/common/77 extract from nested subdir/src/first/meson.build
new file mode 100644
index 0000000..b97aef4
--- /dev/null
+++ b/test cases/common/77 extract from nested subdir/src/first/meson.build
@@ -0,0 +1 @@
+first_lib = shared_library('first_lib', 'lib_first.c')
diff --git a/test cases/common/77 extract from nested subdir/src/meson.build b/test cases/common/77 extract from nested subdir/src/meson.build
new file mode 100644
index 0000000..3f5ec32
--- /dev/null
+++ b/test cases/common/77 extract from nested subdir/src/meson.build
@@ -0,0 +1 @@
+subdir('first')
diff --git a/test cases/common/77 extract from nested subdir/tst/first/exe_first.c b/test cases/common/77 extract from nested subdir/tst/first/exe_first.c
new file mode 100644
index 0000000..e8188cd
--- /dev/null
+++ b/test cases/common/77 extract from nested subdir/tst/first/exe_first.c
@@ -0,0 +1,5 @@
+int first(void);
+
+int main(void) {
+ return first() - 1001;
+}
diff --git a/test cases/common/77 extract from nested subdir/tst/first/meson.build b/test cases/common/77 extract from nested subdir/tst/first/meson.build
new file mode 100644
index 0000000..a6fa7da
--- /dev/null
+++ b/test cases/common/77 extract from nested subdir/tst/first/meson.build
@@ -0,0 +1,4 @@
+first_exe = executable('first_exe', 'exe_first.c',
+ objects : first_lib.extract_objects('lib_first.c'))
+
+test('first_test', first_exe)
diff --git a/test cases/common/77 extract from nested subdir/tst/meson.build b/test cases/common/77 extract from nested subdir/tst/meson.build
new file mode 100644
index 0000000..3f5ec32
--- /dev/null
+++ b/test cases/common/77 extract from nested subdir/tst/meson.build
@@ -0,0 +1 @@
+subdir('first')
diff --git a/test cases/common/78 internal dependency/meson.build b/test cases/common/78 internal dependency/meson.build
new file mode 100644
index 0000000..6faedb0
--- /dev/null
+++ b/test cases/common/78 internal dependency/meson.build
@@ -0,0 +1,4 @@
+project('internal dependency', 'c')
+
+subdir('proj1')
+subdir('src')
diff --git a/test cases/common/78 internal dependency/proj1/include/proj1.h b/test cases/common/78 internal dependency/proj1/include/proj1.h
new file mode 100644
index 0000000..ecb1e4b
--- /dev/null
+++ b/test cases/common/78 internal dependency/proj1/include/proj1.h
@@ -0,0 +1,5 @@
+#pragma once
+
+void proj1_func1(void);
+void proj1_func2(void);
+void proj1_func3(void);
diff --git a/test cases/common/78 internal dependency/proj1/meson.build b/test cases/common/78 internal dependency/proj1/meson.build
new file mode 100644
index 0000000..422021e
--- /dev/null
+++ b/test cases/common/78 internal dependency/proj1/meson.build
@@ -0,0 +1,11 @@
+incdirs = include_directories('include')
+
+p1lib = static_library('proj1', 'proj1f1.c',
+ include_directories : incdirs
+)
+
+indirect_source = files('proj1f2.c')
+
+proj1_dep = declare_dependency(include_directories : incdirs,
+ link_with : p1lib,
+ sources : ['proj1f3.c', indirect_source])
diff --git a/test cases/common/78 internal dependency/proj1/proj1f1.c b/test cases/common/78 internal dependency/proj1/proj1f1.c
new file mode 100644
index 0000000..69fa823
--- /dev/null
+++ b/test cases/common/78 internal dependency/proj1/proj1f1.c
@@ -0,0 +1,6 @@
+#include<proj1.h>
+#include<stdio.h>
+
+void proj1_func1(void) {
+ printf("In proj1_func1.\n");
+}
diff --git a/test cases/common/78 internal dependency/proj1/proj1f2.c b/test cases/common/78 internal dependency/proj1/proj1f2.c
new file mode 100644
index 0000000..7dd621c
--- /dev/null
+++ b/test cases/common/78 internal dependency/proj1/proj1f2.c
@@ -0,0 +1,6 @@
+#include<proj1.h>
+#include<stdio.h>
+
+void proj1_func2(void) {
+ printf("In proj1_func2.\n");
+}
diff --git a/test cases/common/78 internal dependency/proj1/proj1f3.c b/test cases/common/78 internal dependency/proj1/proj1f3.c
new file mode 100644
index 0000000..2861ddc
--- /dev/null
+++ b/test cases/common/78 internal dependency/proj1/proj1f3.c
@@ -0,0 +1,6 @@
+#include<proj1.h>
+#include<stdio.h>
+
+void proj1_func3(void) {
+ printf("In proj1_func3.\n");
+}
diff --git a/test cases/common/78 internal dependency/src/main.c b/test cases/common/78 internal dependency/src/main.c
new file mode 100644
index 0000000..dbb7c4a
--- /dev/null
+++ b/test cases/common/78 internal dependency/src/main.c
@@ -0,0 +1,10 @@
+#include<stdio.h>
+#include<proj1.h>
+
+int main(void) {
+ printf("Now calling into library.\n");
+ proj1_func1();
+ proj1_func2();
+ proj1_func3();
+ return 0;
+}
diff --git a/test cases/common/78 internal dependency/src/meson.build b/test cases/common/78 internal dependency/src/meson.build
new file mode 100644
index 0000000..89f99ab
--- /dev/null
+++ b/test cases/common/78 internal dependency/src/meson.build
@@ -0,0 +1,2 @@
+exe = executable('projtest', 'main.c', dependencies : proj1_dep)
+test('projtest', exe)
diff --git a/test cases/common/79 same basename/exe1.c b/test cases/common/79 same basename/exe1.c
new file mode 100644
index 0000000..128f2bb
--- /dev/null
+++ b/test cases/common/79 same basename/exe1.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/common/79 same basename/exe2.c b/test cases/common/79 same basename/exe2.c
new file mode 100644
index 0000000..d2d8995
--- /dev/null
+++ b/test cases/common/79 same basename/exe2.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func() == 1 ? 0 : 1;
+}
diff --git a/test cases/common/79 same basename/lib.c b/test cases/common/79 same basename/lib.c
new file mode 100644
index 0000000..5b9122b
--- /dev/null
+++ b/test cases/common/79 same basename/lib.c
@@ -0,0 +1,22 @@
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+#if defined SHAR
+int DLL_PUBLIC func(void) {
+ return 1;
+}
+#elif defined STAT
+int func(void) {
+ return 0;
+}
+#else
+#error "Missing type definition."
+#endif
diff --git a/test cases/common/79 same basename/meson.build b/test cases/common/79 same basename/meson.build
new file mode 100644
index 0000000..856c536
--- /dev/null
+++ b/test cases/common/79 same basename/meson.build
@@ -0,0 +1,14 @@
+project('same basename', 'c')
+
+subdir('sharedsub')
+subdir('staticsub')
+
+# Use the same source file to check that each top level target
+# has its own unique working directory. If they don't
+# then the .o files will clobber each other.
+
+exe1 = executable('name', 'exe1.c', link_with : stlib)
+exe2 = executable('name2', 'exe2.c', link_with : shlib)
+
+test('static', exe1)
+test('shared', exe2)
diff --git a/test cases/common/79 same basename/sharedsub/meson.build b/test cases/common/79 same basename/sharedsub/meson.build
new file mode 100644
index 0000000..29654a9
--- /dev/null
+++ b/test cases/common/79 same basename/sharedsub/meson.build
@@ -0,0 +1 @@
+shlib = shared_library('name', '../lib.c', c_args : '-DSHAR')
diff --git a/test cases/common/79 same basename/staticsub/meson.build b/test cases/common/79 same basename/staticsub/meson.build
new file mode 100644
index 0000000..5e5242e
--- /dev/null
+++ b/test cases/common/79 same basename/staticsub/meson.build
@@ -0,0 +1,3 @@
+# On Windows a static lib is now libfoo.a, so it does not conflict with foo.lib
+# from the shared library above
+stlib = static_library('name', '../lib.c', c_args : '-DSTAT')
diff --git a/test cases/common/8 install/gendir.py b/test cases/common/8 install/gendir.py
new file mode 100755
index 0000000..b42327d
--- /dev/null
+++ b/test cases/common/8 install/gendir.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+dirname = sys.argv[1]
+fname = os.path.join(dirname, 'file.txt')
+os.makedirs(dirname, exist_ok=True)
+open(fname, 'w').close()
diff --git a/test cases/common/8 install/meson.build b/test cases/common/8 install/meson.build
new file mode 100644
index 0000000..6eb5ba5
--- /dev/null
+++ b/test cases/common/8 install/meson.build
@@ -0,0 +1,10 @@
+project('install test', 'c', default_options : ['libdir=libtest'])
+
+stlib = static_library('stat', 'stat.c', install : true)
+exe = executable('prog', 'prog.c', install : true)
+
+dirtarget = custom_target('dirtarget',
+ output: ['dir'],
+ install: true,
+ command: [find_program('gendir.py'), '@OUTPUT@'],
+ install_dir: get_option('datadir'))
diff --git a/test cases/common/8 install/prog.c b/test cases/common/8 install/prog.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/common/8 install/prog.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/common/8 install/stat.c b/test cases/common/8 install/stat.c
new file mode 100644
index 0000000..4825cef
--- /dev/null
+++ b/test cases/common/8 install/stat.c
@@ -0,0 +1 @@
+int func(void) { return 933; }
diff --git a/test cases/common/8 install/test.json b/test cases/common/8 install/test.json
new file mode 100644
index 0000000..b31f287
--- /dev/null
+++ b/test cases/common/8 install/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ { "type": "exe", "file": "usr/bin/prog" },
+ { "type": "pdb", "file": "usr/bin/prog" },
+ { "type": "file", "file": "usr/share/dir/file.txt" },
+ { "type": "file", "file": "usr/libtest/libstat.a" }
+ ],
+ "do_not_set_opts": ["libdir"]
+}
diff --git a/test cases/common/80 declare dep/entity/entity.h b/test cases/common/80 declare dep/entity/entity.h
new file mode 100644
index 0000000..959a8c3
--- /dev/null
+++ b/test cases/common/80 declare dep/entity/entity.h
@@ -0,0 +1,4 @@
+#pragma once
+
+int entity_func1(void);
+int entity_func2(void);
diff --git a/test cases/common/80 declare dep/entity/entity1.c b/test cases/common/80 declare dep/entity/entity1.c
new file mode 100644
index 0000000..d124e24
--- /dev/null
+++ b/test cases/common/80 declare dep/entity/entity1.c
@@ -0,0 +1,9 @@
+#include"entity.h"
+
+#ifdef USING_ENT
+#error "Entity use flag leaked into entity compilation."
+#endif
+
+int entity_func1(void) {
+ return 5;
+}
diff --git a/test cases/common/80 declare dep/entity/entity2.c b/test cases/common/80 declare dep/entity/entity2.c
new file mode 100644
index 0000000..4e8bb07
--- /dev/null
+++ b/test cases/common/80 declare dep/entity/entity2.c
@@ -0,0 +1,5 @@
+#include<entity.h>
+
+int entity_func2(void) {
+ return 9;
+}
diff --git a/test cases/common/80 declare dep/entity/meson.build b/test cases/common/80 declare dep/entity/meson.build
new file mode 100644
index 0000000..469ecd3
--- /dev/null
+++ b/test cases/common/80 declare dep/entity/meson.build
@@ -0,0 +1,10 @@
+entity_lib = static_library('entity', 'entity1.c')
+
+entity_dep = declare_dependency(link_with : [[entity_lib]],
+ include_directories : [['.']],
+ sources : 'entity2.c',
+ compile_args : ['-DUSING_ENT=1'],
+ version : '1.2.3',
+ link_args : []) # No simple way of testing linker flags :(.
+
+assert(entity_dep.version().version_compare('==1.2.3'), 'Declare_dep has incorrect version string.')
diff --git a/test cases/common/80 declare dep/main.c b/test cases/common/80 declare dep/main.c
new file mode 100644
index 0000000..62200c9
--- /dev/null
+++ b/test cases/common/80 declare dep/main.c
@@ -0,0 +1,18 @@
+#include<entity.h>
+#include<stdio.h>
+
+#ifndef USING_ENT
+#error "Entity use flag not used for compilation."
+#endif
+
+int main(void) {
+ if(entity_func1() != 5) {
+ printf("Error in func1.\n");
+ return 1;
+ }
+ if(entity_func2() != 9) {
+ printf("Error in func2.\n");
+ return 2;
+ }
+ return 0;
+}
diff --git a/test cases/common/80 declare dep/meson.build b/test cases/common/80 declare dep/meson.build
new file mode 100644
index 0000000..e427def
--- /dev/null
+++ b/test cases/common/80 declare dep/meson.build
@@ -0,0 +1,24 @@
+project('declare dependency', 'c')
+
+subdir('entity')
+
+exe = executable('dep_user', 'main.c',
+ dependencies : entity_dep)
+test('dep', exe)
+
+# just to make sure [] works as a no-op dep here
+executable('dummy', 'main.c',
+ dependencies : [entity_dep, []])
+
+# simple case
+declare_dependency(dependencies : entity_dep)
+
+# nested deps should be flattened
+declare_dependency(dependencies : [entity_dep])
+declare_dependency(dependencies : [[entity_dep]])
+
+# check that [] properly works as a no-op dep in declare_dependency() too
+declare_dependency(dependencies : [])
+declare_dependency(dependencies : [[]])
+declare_dependency(dependencies : [entity_dep, []])
+declare_dependency(dependencies : [[], entity_dep])
diff --git a/test cases/common/81 extract all/extractor.h b/test cases/common/81 extract all/extractor.h
new file mode 100644
index 0000000..cfb7ff6
--- /dev/null
+++ b/test cases/common/81 extract all/extractor.h
@@ -0,0 +1,6 @@
+#pragma once
+
+int func1(void);
+int func2(void);
+int func3(void);
+int func4(void);
diff --git a/test cases/common/81 extract all/four.c b/test cases/common/81 extract all/four.c
new file mode 100644
index 0000000..f67a85e
--- /dev/null
+++ b/test cases/common/81 extract all/four.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func4(void) {
+ return 4;
+}
diff --git a/test cases/common/81 extract all/meson.build b/test cases/common/81 extract all/meson.build
new file mode 100644
index 0000000..4f08a4f
--- /dev/null
+++ b/test cases/common/81 extract all/meson.build
@@ -0,0 +1,13 @@
+project('extract all', 'c')
+
+a = static_library('a', 'one.c', 'two.c')
+b = static_library('b', 'three.c', 'four.c')
+c = static_library('c', objects : [a.extract_all_objects(), b.extract_all_objects()])
+d = static_library('d', objects : [a.extract_all_objects(), b.extract_all_objects(), c.extract_all_objects()])
+d_recursive = static_library('d_recursive', objects : [c.extract_all_objects(recursive : true)])
+
+e = executable('proggie', 'prog.c', link_with : d)
+test('extall', e)
+
+e = executable('proggie_recursive', 'prog.c', link_with : d_recursive)
+test('extall_recursive', e)
diff --git a/test cases/common/81 extract all/one.c b/test cases/common/81 extract all/one.c
new file mode 100644
index 0000000..152a145
--- /dev/null
+++ b/test cases/common/81 extract all/one.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func1(void) {
+ return 1;
+}
diff --git a/test cases/common/81 extract all/prog.c b/test cases/common/81 extract all/prog.c
new file mode 100644
index 0000000..de0cc7f
--- /dev/null
+++ b/test cases/common/81 extract all/prog.c
@@ -0,0 +1,10 @@
+#include"extractor.h"
+#include<stdio.h>
+
+int main(void) {
+ if((1+2+3+4) != (func1() + func2() + func3() + func4())) {
+ printf("Arithmetic is fail.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/81 extract all/three.c b/test cases/common/81 extract all/three.c
new file mode 100644
index 0000000..24604ed
--- /dev/null
+++ b/test cases/common/81 extract all/three.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func3(void) {
+ return 3;
+}
diff --git a/test cases/common/81 extract all/two.c b/test cases/common/81 extract all/two.c
new file mode 100644
index 0000000..800cd2d
--- /dev/null
+++ b/test cases/common/81 extract all/two.c
@@ -0,0 +1,5 @@
+#include"extractor.h"
+
+int func2(void) {
+ return 2;
+}
diff --git a/test cases/common/82 add language/meson.build b/test cases/common/82 add language/meson.build
new file mode 100644
index 0000000..e99f33a
--- /dev/null
+++ b/test cases/common/82 add language/meson.build
@@ -0,0 +1,10 @@
+project('add language', 'c')
+
+test('C', executable('cprog', 'prog.c'))
+
+assert(add_languages('cpp', native: false), 'Add_languages returned false on success')
+assert(not add_languages('klingon', required : false), 'Add_languages returned true on failure.')
+
+test('C++', executable('cppprog', 'prog.cc'))
+
+add_languages('c', native: false)
diff --git a/test cases/common/82 add language/prog.c b/test cases/common/82 add language/prog.c
new file mode 100644
index 0000000..9d747f0
--- /dev/null
+++ b/test cases/common/82 add language/prog.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I am plain C.\n");
+ return 0;
+}
diff --git a/test cases/common/82 add language/prog.cc b/test cases/common/82 add language/prog.cc
new file mode 100644
index 0000000..03647dd
--- /dev/null
+++ b/test cases/common/82 add language/prog.cc
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int, char**) {
+ std::cout << "I am C++.\n";
+ return 0;
+}
diff --git a/test cases/common/83 identical target name in subproject/bar.c b/test cases/common/83 identical target name in subproject/bar.c
new file mode 100644
index 0000000..f1bd822
--- /dev/null
+++ b/test cases/common/83 identical target name in subproject/bar.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I'm a main project bar.\n");
+ return 0;
+}
diff --git a/test cases/common/83 identical target name in subproject/meson.build b/test cases/common/83 identical target name in subproject/meson.build
new file mode 100644
index 0000000..64b4363
--- /dev/null
+++ b/test cases/common/83 identical target name in subproject/meson.build
@@ -0,0 +1,9 @@
+project('toplevel bar', 'c')
+
+subproject('foo')
+
+true_cmd = find_program('true.py')
+
+executable('bar', 'bar.c')
+run_target('nop', command : [true_cmd])
+custom_target('cus', output: ['cus.c'], command : [true_cmd])
diff --git a/test cases/common/83 identical target name in subproject/subprojects/foo/bar.c b/test cases/common/83 identical target name in subproject/subprojects/foo/bar.c
new file mode 100644
index 0000000..5e7006b
--- /dev/null
+++ b/test cases/common/83 identical target name in subproject/subprojects/foo/bar.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I'm a subproject bar.\n");
+ return 0;
+}
diff --git a/test cases/common/83 identical target name in subproject/subprojects/foo/meson.build b/test cases/common/83 identical target name in subproject/subprojects/foo/meson.build
new file mode 100644
index 0000000..94b235c
--- /dev/null
+++ b/test cases/common/83 identical target name in subproject/subprojects/foo/meson.build
@@ -0,0 +1,7 @@
+project('subfoo', 'c')
+
+true_cmd = find_program('true.py')
+
+executable('bar', 'bar.c')
+run_target('nop', command : [true_cmd])
+custom_target('cus', output: ['cus.c'], command : [true_cmd])
diff --git a/test cases/common/83 identical target name in subproject/subprojects/foo/true.py b/test cases/common/83 identical target name in subproject/subprojects/foo/true.py
new file mode 100644
index 0000000..ddcac9e
--- /dev/null
+++ b/test cases/common/83 identical target name in subproject/subprojects/foo/true.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+if __name__ == '__main__':
+ pass
diff --git a/test cases/common/83 identical target name in subproject/true.py b/test cases/common/83 identical target name in subproject/true.py
new file mode 100644
index 0000000..ddcac9e
--- /dev/null
+++ b/test cases/common/83 identical target name in subproject/true.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+if __name__ == '__main__':
+ pass
diff --git a/test cases/common/84 plusassign/meson.build b/test cases/common/84 plusassign/meson.build
new file mode 100644
index 0000000..b419c6d
--- /dev/null
+++ b/test cases/common/84 plusassign/meson.build
@@ -0,0 +1,70 @@
+project('plusassign')
+
+x = []
+
+x += 'a'
+
+if x.length() != 1
+ error('Incorrect append')
+endif
+
+if x[0] != 'a'
+ error('Incorrect append 2.')
+endif
+
+y = x
+
+x += 'b'
+
+if y.length() != 1
+ error('Immutability broken.')
+endif
+
+if y[0] != 'a'
+ error('Immutability broken 2.')
+endif
+
+if x.length() != 2
+ error('Incorrect append 3')
+endif
+
+if x[0] != 'a'
+ error('Incorrect append 4.')
+endif
+
+if x[1] != 'b'
+ error('Incorrect append 5.')
+endif
+
+# Now with evil added: append yourself.
+
+x += x
+
+if x.length() != 4
+ error('Incorrect selfappend.')
+endif
+
+# += on strings
+
+bra = 'bra'
+foo = 'A'
+foo += bra
+foo += 'cada'
+foo += bra
+assert (foo == 'Abracadabra', 'string += failure [@0@]'.format(foo))
+assert (bra == 'bra', 'string += modified right argument!')
+foo += ' ' + foo
+assert (foo == 'Abracadabra Abracadabra', 'string += failure [@0@]'.format(foo))
+
+# += on ints
+
+foo = 5
+foo += 6
+assert (foo == 11, 'int += failure [@0@]'.format(foo))
+bar = 99
+foo += bar
+assert (foo == 110, 'int += failure [@0@]'.format(foo))
+assert (bar == 99, 'int += modified right argument"')
+bar += foo + 1
+assert (bar == 210, 'int += failure [@0@]'.format(bar))
+assert (foo == 110, 'int += modified right argument"')
diff --git a/test cases/common/85 skip subdir/meson.build b/test cases/common/85 skip subdir/meson.build
new file mode 100644
index 0000000..e503038
--- /dev/null
+++ b/test cases/common/85 skip subdir/meson.build
@@ -0,0 +1,3 @@
+project('foo')
+
+subdir('subdir1/subdir2')
diff --git a/test cases/common/85 skip subdir/subdir1/meson.build b/test cases/common/85 skip subdir/subdir1/meson.build
new file mode 100644
index 0000000..51cb003
--- /dev/null
+++ b/test cases/common/85 skip subdir/subdir1/meson.build
@@ -0,0 +1 @@
+error('This should not be called.')
diff --git a/test cases/common/85 skip subdir/subdir1/subdir2/meson.build b/test cases/common/85 skip subdir/subdir1/subdir2/meson.build
new file mode 100644
index 0000000..e37cad6
--- /dev/null
+++ b/test cases/common/85 skip subdir/subdir1/subdir2/meson.build
@@ -0,0 +1 @@
+message('I\'m in subdir subdir.')
diff --git a/test cases/common/86 private include/meson.build b/test cases/common/86 private include/meson.build
new file mode 100644
index 0000000..2485fbf
--- /dev/null
+++ b/test cases/common/86 private include/meson.build
@@ -0,0 +1,4 @@
+project('access private', 'c')
+
+subdir('stlib')
+subdir('user')
diff --git a/test cases/common/86 private include/stlib/compiler.py b/test cases/common/86 private include/stlib/compiler.py
new file mode 100755
index 0000000..7a2effa
--- /dev/null
+++ b/test cases/common/86 private include/stlib/compiler.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+assert len(sys.argv) == 3
+
+h_templ = '''#pragma once
+unsigned int %s(void);
+'''
+
+c_templ = '''#include"%s.h"
+
+unsigned int %s(void) {
+ return 0;
+}
+'''
+
+ifile = sys.argv[1]
+outdir = sys.argv[2]
+
+base = os.path.splitext(os.path.split(ifile)[-1])[0]
+
+cfile = os.path.join(outdir, base + '.c')
+hfile = os.path.join(outdir, base + '.h')
+
+c_code = c_templ % (base, base)
+h_code = h_templ % base
+
+with open(cfile, 'w') as f:
+ f.write(c_code)
+with open(hfile, 'w') as f:
+ f.write(h_code)
diff --git a/test cases/common/86 private include/stlib/foo1.def b/test cases/common/86 private include/stlib/foo1.def
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/86 private include/stlib/foo1.def
diff --git a/test cases/common/86 private include/stlib/foo2.def b/test cases/common/86 private include/stlib/foo2.def
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/86 private include/stlib/foo2.def
diff --git a/test cases/common/86 private include/stlib/meson.build b/test cases/common/86 private include/stlib/meson.build
new file mode 100644
index 0000000..8d70650
--- /dev/null
+++ b/test cases/common/86 private include/stlib/meson.build
@@ -0,0 +1,12 @@
+genbin = find_program('compiler.py')
+
+gen = generator(genbin,
+ output : ['@BASENAME@.h', '@BASENAME@.c'],
+ arguments : ['@INPUT@', '@BUILD_DIR@']
+ )
+
+defs = ['foo1.def', 'foo2.def']
+generated = gen.process(defs)
+
+stlib = static_library('st', generated)
+st_priv_inc = stlib.private_dir_include()
diff --git a/test cases/common/86 private include/user/libuser.c b/test cases/common/86 private include/user/libuser.c
new file mode 100644
index 0000000..c172486
--- /dev/null
+++ b/test cases/common/86 private include/user/libuser.c
@@ -0,0 +1,6 @@
+#include"foo1.h"
+#include"foo2.h"
+
+int main(void) {
+ return foo1() + foo2();
+}
diff --git a/test cases/common/86 private include/user/meson.build b/test cases/common/86 private include/user/meson.build
new file mode 100644
index 0000000..ab88b1d
--- /dev/null
+++ b/test cases/common/86 private include/user/meson.build
@@ -0,0 +1,5 @@
+exe = executable('libuser', 'libuser.c',
+ link_with : stlib,
+ include_directories : st_priv_inc)
+
+test('libuser', exe)
diff --git a/test cases/common/87 default options/meson.build b/test cases/common/87 default options/meson.build
new file mode 100644
index 0000000..51b5cda
--- /dev/null
+++ b/test cases/common/87 default options/meson.build
@@ -0,0 +1,33 @@
+project('default options', 'cpp', 'c', default_options : [
+ 'prefix=/absoluteprefix',
+ 'buildtype=debugoptimized',
+ 'cpp_std=c++11',
+ 'cpp_eh=none',
+ 'warning_level=3',
+ 'sub1:test_option=false',
+ ])
+
+assert(get_option('buildtype') == 'debugoptimized', 'Build type default value wrong.')
+
+cpp_eh = get_option('cpp_eh')
+assert(cpp_eh == 'none', 'EH value is "' + cpp_eh + '" instead of "none"')
+cpp_std = get_option('cpp_std')
+assert(cpp_std == 'c++11', 'C++ std value is "' + cpp_std + '" instead of c++11.')
+
+w_level = get_option('warning_level')
+assert(w_level == '3', 'warning level "' + w_level + '" instead of "3"')
+
+# FIXME. Since we no longer accept invalid options to c_std etc,
+# there is no simple way to test this. Gcc does not seem to expose
+# the C std used in a preprocessor token so we can't check for it.
+# Think of a way to fix this.
+#
+# # Verify that project args are not used when told not to.
+# # MSVC plain C does not have a simple arg to test so skip it.
+# if cpp.get_id() != 'msvc'
+# cc = meson.get_compiler('c')
+# assert(not cc.compiles('int foobar;'), 'Default arg not used in test.')
+# assert(cc.compiles('int foobar;', no_builtin_args : true), 'No_builtin did not disable builtins.')
+# endif
+
+subproject('sub1')
diff --git a/test cases/common/87 default options/subprojects/sub1/meson.build b/test cases/common/87 default options/subprojects/sub1/meson.build
new file mode 100644
index 0000000..de0dc21
--- /dev/null
+++ b/test cases/common/87 default options/subprojects/sub1/meson.build
@@ -0,0 +1,3 @@
+project('sub1')
+
+assert(get_option('test_option') == false)
diff --git a/test cases/common/87 default options/subprojects/sub1/meson_options.txt b/test cases/common/87 default options/subprojects/sub1/meson_options.txt
new file mode 100644
index 0000000..fc96f5e
--- /dev/null
+++ b/test cases/common/87 default options/subprojects/sub1/meson_options.txt
@@ -0,0 +1 @@
+option('test_option', type : 'boolean', value : true, description : 'Test option. Superproject overrides default to "false"')
diff --git a/test cases/common/88 dep fallback/gensrc.py b/test cases/common/88 dep fallback/gensrc.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/common/88 dep fallback/gensrc.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/common/88 dep fallback/meson.build b/test cases/common/88 dep fallback/meson.build
new file mode 100644
index 0000000..2e962f6
--- /dev/null
+++ b/test cases/common/88 dep fallback/meson.build
@@ -0,0 +1,38 @@
+project('dep fallback', 'c')
+
+bob = dependency('boblib', fallback : ['boblib', 'bob_dep'], required: false,
+ default_options : 'warning_level=1')
+if not bob.found()
+ error('Bob is actually needed')
+endif
+
+# boblib subproject exists, but bobinc is not a dependency variable
+sita = dependency('sitalib', fallback : ['boblib', 'bobinc'], required: false)
+assert(not sita.found())
+# boblib subproject exists, but sita_dep doesn't exist
+sita = dependency('sitalib', fallback : ['boblib', 'sita_dep'], required: false)
+assert(not sita.found())
+# boblib has been configured so zlib cannot be searched on the system
+zlib = dependency('zlib', fallback : ['boblib', 'notfound_dep'], required: false)
+assert(not zlib.found())
+# boblib has been configured so zlib cannot be searched on the system.
+# Not variable name provided and the subproject does not override zlib.
+zlib = dependency('zlib', fallback : 'boblib', required: false)
+assert(not zlib.found())
+
+# jimmylib subproject doesn't exist
+jimmy = dependency('jimmylib', fallback : ['jimmylib', 'jimmy_dep'], required: false)
+# dummylib subproject fails to configure
+dummy = dependency('dummylib', fallback : ['dummylib', 'dummy_dep'], required: false)
+
+gensrc_py = find_program('gensrc.py')
+gensrc = custom_target('gensrc.c',
+ input : 'tester.c',
+ output : 'gensrc.c',
+ command : [gensrc_py, '@INPUT@', '@OUTPUT@'])
+
+exe = executable('bobtester',
+ [gensrc],
+ dependencies : bob)
+
+test('bobtester', exe)
diff --git a/test cases/common/88 dep fallback/subprojects/boblib/bob.c b/test cases/common/88 dep fallback/subprojects/boblib/bob.c
new file mode 100644
index 0000000..52cf479
--- /dev/null
+++ b/test cases/common/88 dep fallback/subprojects/boblib/bob.c
@@ -0,0 +1,8 @@
+#include"bob.h"
+
+#ifdef _MSC_VER
+__declspec(dllexport)
+#endif
+const char* get_bob(void) {
+ return "bob";
+}
diff --git a/test cases/common/88 dep fallback/subprojects/boblib/bob.h b/test cases/common/88 dep fallback/subprojects/boblib/bob.h
new file mode 100644
index 0000000..8dd4b33
--- /dev/null
+++ b/test cases/common/88 dep fallback/subprojects/boblib/bob.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#ifdef _MSC_VER
+__declspec(dllimport)
+#endif
+const char* get_bob(void);
diff --git a/test cases/common/88 dep fallback/subprojects/boblib/genbob.py b/test cases/common/88 dep fallback/subprojects/boblib/genbob.py
new file mode 100644
index 0000000..34af779
--- /dev/null
+++ b/test cases/common/88 dep fallback/subprojects/boblib/genbob.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ f.write('')
diff --git a/test cases/common/88 dep fallback/subprojects/boblib/meson.build b/test cases/common/88 dep fallback/subprojects/boblib/meson.build
new file mode 100644
index 0000000..0a72a82
--- /dev/null
+++ b/test cases/common/88 dep fallback/subprojects/boblib/meson.build
@@ -0,0 +1,18 @@
+project('bob', 'c')
+
+gensrc_py = find_program('genbob.py')
+genbob_h = custom_target('genbob.h',
+ output : 'genbob.h',
+ command : [gensrc_py, '@OUTPUT@'])
+genbob_c = custom_target('genbob.c',
+ output : 'genbob.c',
+ command : [gensrc_py, '@OUTPUT@'])
+
+boblib = library('bob', ['bob.c', genbob_c])
+bobinc = include_directories('.')
+
+bob_dep = declare_dependency(link_with : boblib,
+ sources : [genbob_h],
+ include_directories : bobinc)
+
+notfound_dep = dependency('', required: false)
diff --git a/test cases/common/88 dep fallback/subprojects/dummylib/meson.build b/test cases/common/88 dep fallback/subprojects/dummylib/meson.build
new file mode 100644
index 0000000..3ad33e7
--- /dev/null
+++ b/test cases/common/88 dep fallback/subprojects/dummylib/meson.build
@@ -0,0 +1,4 @@
+project('dummylib', 'c')
+
+dummy_dep = declare_dependency()
+error('this subproject fails to configure')
diff --git a/test cases/common/88 dep fallback/tester.c b/test cases/common/88 dep fallback/tester.c
new file mode 100644
index 0000000..a46f3f6
--- /dev/null
+++ b/test cases/common/88 dep fallback/tester.c
@@ -0,0 +1,14 @@
+#include"bob.h"
+#include"genbob.h"
+#include<string.h>
+#include<stdio.h>
+
+int main(void) {
+ if(strcmp("bob", get_bob()) == 0) {
+ printf("Bob is indeed bob.\n");
+ } else {
+ printf("ERROR: bob is not bob.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/89 default library/ef.cpp b/test cases/common/89 default library/ef.cpp
new file mode 100644
index 0000000..34784f8
--- /dev/null
+++ b/test cases/common/89 default library/ef.cpp
@@ -0,0 +1,8 @@
+#include"ef.h"
+
+DLL_PUBLIC Ef::Ef() : x(99) {
+}
+
+int DLL_PUBLIC Ef::get_x() const {
+ return x;
+}
diff --git a/test cases/common/89 default library/ef.h b/test cases/common/89 default library/ef.h
new file mode 100644
index 0000000..21704b5
--- /dev/null
+++ b/test cases/common/89 default library/ef.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+class Ef {
+private:
+ int x;
+
+public:
+
+ DLL_PUBLIC Ef();
+ int DLL_PUBLIC get_x() const;
+};
diff --git a/test cases/common/89 default library/eftest.cpp b/test cases/common/89 default library/eftest.cpp
new file mode 100644
index 0000000..4d4412d
--- /dev/null
+++ b/test cases/common/89 default library/eftest.cpp
@@ -0,0 +1,14 @@
+#include"ef.h"
+
+#include<iostream>
+
+int main(int, char **) {
+ Ef var;
+ if(var.get_x() == 99) {
+ std::cout << "All is fine.\n";
+ return 0;
+ } else {
+ std::cout << "Something went wrong.\n";
+ return 1;
+ }
+}
diff --git a/test cases/common/89 default library/meson.build b/test cases/common/89 default library/meson.build
new file mode 100644
index 0000000..508f25f
--- /dev/null
+++ b/test cases/common/89 default library/meson.build
@@ -0,0 +1,10 @@
+project('default library', 'cpp')
+
+flib = library('ef', 'ef.cpp')
+exe = executable('eftest', 'eftest.cpp', link_with : flib)
+test('eftest', exe)
+
+# Same as above, but using build_target()
+flib2 = build_target('ef2', 'ef.cpp', target_type: 'library')
+exe2 = executable('eftest2', 'eftest.cpp', link_with : flib2)
+test('eftest2', exe2)
diff --git a/test cases/common/9 header install/child/childdir.h b/test cases/common/9 header install/child/childdir.h
new file mode 100644
index 0000000..5788511
--- /dev/null
+++ b/test cases/common/9 header install/child/childdir.h
@@ -0,0 +1,3 @@
+/* This file goes, depending on the state of `preserve_path` into subdirectory of include root or into the `child` dir of the subdirectory of include root. */
+
+int childdir_func();
diff --git a/test cases/common/9 header install/meson.build b/test cases/common/9 header install/meson.build
new file mode 100644
index 0000000..8c83be6
--- /dev/null
+++ b/test cases/common/9 header install/meson.build
@@ -0,0 +1,12 @@
+project('header install')
+
+as_array = ['subdir.h', 'child/childdir.h']
+
+subdir('vanishing_subdir')
+subdir('sub')
+
+h1 = install_headers('rootdir.h')
+h2 = install_headers(as_array, subdir : 'subdir')
+h3 = install_headers(as_array, subdir : 'subdir', preserve_path : true)
+h4 = install_headers(subheader)
+h5 = install_headers(disabler())
diff --git a/test cases/common/9 header install/rootdir.h b/test cases/common/9 header install/rootdir.h
new file mode 100644
index 0000000..72fb132
--- /dev/null
+++ b/test cases/common/9 header install/rootdir.h
@@ -0,0 +1,3 @@
+/* This header goes to include dir root. */
+
+int root_func();
diff --git a/test cases/common/9 header install/sub/fileheader.h b/test cases/common/9 header install/sub/fileheader.h
new file mode 100644
index 0000000..28e5c8d
--- /dev/null
+++ b/test cases/common/9 header install/sub/fileheader.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define LIFE "Is life! Na naa, naa-na na."
diff --git a/test cases/common/9 header install/sub/meson.build b/test cases/common/9 header install/sub/meson.build
new file mode 100644
index 0000000..1cff4b2
--- /dev/null
+++ b/test cases/common/9 header install/sub/meson.build
@@ -0,0 +1 @@
+subheader = files('fileheader.h')
diff --git a/test cases/common/9 header install/subdir.h b/test cases/common/9 header install/subdir.h
new file mode 100644
index 0000000..17f768e
--- /dev/null
+++ b/test cases/common/9 header install/subdir.h
@@ -0,0 +1,3 @@
+/* This file goes to subdirectory of include root. */
+
+int subdir_func();
diff --git a/test cases/common/9 header install/test.json b/test cases/common/9 header install/test.json
new file mode 100644
index 0000000..8514c90
--- /dev/null
+++ b/test cases/common/9 header install/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ { "type": "file", "file": "usr/include/rootdir.h" },
+ { "type": "file", "file": "usr/include/subdir/subdir.h" },
+ { "type": "file", "file": "usr/include/subdir/childdir.h" },
+ { "type": "file", "file": "usr/include/subdir/child/childdir.h" },
+ { "type": "file", "file": "usr/include/vanished.h" },
+ { "type": "file", "file": "usr/include/fileheader.h" }
+ ]
+}
diff --git a/test cases/common/9 header install/vanishing_subdir/meson.build b/test cases/common/9 header install/vanishing_subdir/meson.build
new file mode 100644
index 0000000..a81626c
--- /dev/null
+++ b/test cases/common/9 header install/vanishing_subdir/meson.build
@@ -0,0 +1 @@
+install_headers('vanished.h')
diff --git a/test cases/common/9 header install/vanishing_subdir/vanished.h b/test cases/common/9 header install/vanishing_subdir/vanished.h
new file mode 100644
index 0000000..ed7971b
--- /dev/null
+++ b/test cases/common/9 header install/vanishing_subdir/vanished.h
@@ -0,0 +1,5 @@
+#pragma once
+
+/* This is a header in a subdirectory. Make sure it installs into
+ * /prefix/include and not /prefix/include/vanishing_subdir.
+ */
diff --git a/test cases/common/90 gen extra/meson.build b/test cases/common/90 gen extra/meson.build
new file mode 100644
index 0000000..cbbdceb
--- /dev/null
+++ b/test cases/common/90 gen extra/meson.build
@@ -0,0 +1,40 @@
+project('extra args in gen', 'c')
+
+prog = find_program('srcgen.py')
+
+gen = generator(prog,
+ output : '@BASENAME@.c',
+ arguments : ['--input=@INPUT@', '--output=@OUTPUT@', '@EXTRA_ARGS@'])
+
+g1 = gen.process('name.dat')
+g2 = gen.process('name.dat', extra_args: '--upper')
+
+test('basic', executable('basic', 'plain.c', g1))
+test('upper', executable('upper', 'upper.c', g2))
+
+prog2 = find_program('srcgen2.py')
+basename_gen = generator(prog2,
+ output : ['@BASENAME@.tab.c', '@BASENAME@.tab.h'],
+ arguments : ['@BUILD_DIR@', '@BASENAME@', '@INPUT@'])
+
+basename_src = basename_gen.process('name.l')
+
+test('basename', executable('basename', basename_src))
+
+plainname_gen = generator(prog2,
+ output : ['@PLAINNAME@.tab.c', '@PLAINNAME@.tab.h'],
+ arguments : ['@BUILD_DIR@', '@PLAINNAME@', '@INPUT@'])
+
+plainname_src = plainname_gen.process('name.l')
+
+test('plainname', executable('plainname', plainname_src))
+
+prog3 = find_program('srcgen3.py')
+capture_gen = generator(prog3,
+ output : ['@BASENAME@.yy.c'],
+ arguments : ['@INPUT@'],
+ capture : true)
+
+capture_src = capture_gen.process('name.l')
+
+test('capture', executable('capture', capture_src))
diff --git a/test cases/common/90 gen extra/name.dat b/test cases/common/90 gen extra/name.dat
new file mode 100644
index 0000000..caf5b1c
--- /dev/null
+++ b/test cases/common/90 gen extra/name.dat
@@ -0,0 +1 @@
+bob_mcbob
diff --git a/test cases/common/90 gen extra/name.l b/test cases/common/90 gen extra/name.l
new file mode 100644
index 0000000..c4ba277
--- /dev/null
+++ b/test cases/common/90 gen extra/name.l
@@ -0,0 +1,3 @@
+int main(void) {
+return 0;
+}
diff --git a/test cases/common/90 gen extra/plain.c b/test cases/common/90 gen extra/plain.c
new file mode 100644
index 0000000..c068a02
--- /dev/null
+++ b/test cases/common/90 gen extra/plain.c
@@ -0,0 +1,5 @@
+int bob_mcbob(void);
+
+int main(void) {
+ return bob_mcbob();
+}
diff --git a/test cases/common/90 gen extra/srcgen.py b/test cases/common/90 gen extra/srcgen.py
new file mode 100755
index 0000000..c64f540
--- /dev/null
+++ b/test cases/common/90 gen extra/srcgen.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+
+import sys
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--input', dest='input',
+ help='the input file')
+parser.add_argument('--output', dest='output',
+ help='the output file')
+parser.add_argument('--upper', dest='upper', action='store_true', default=False,
+ help='Convert to upper case.')
+
+c_templ = '''int %s(void) {
+ return 0;
+}
+'''
+
+options = parser.parse_args(sys.argv[1:])
+
+with open(options.input) as f:
+ funcname = f.readline().strip()
+if options.upper:
+ funcname = funcname.upper()
+
+with open(options.output, 'w') as f:
+ f.write(c_templ % funcname)
diff --git a/test cases/common/90 gen extra/srcgen2.py b/test cases/common/90 gen extra/srcgen2.py
new file mode 100644
index 0000000..9cdf12d
--- /dev/null
+++ b/test cases/common/90 gen extra/srcgen2.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument('target_dir',
+ help='the target dir')
+parser.add_argument('stem',
+ help='the stem')
+parser.add_argument('input',
+ help='the input file')
+
+options = parser.parse_args(sys.argv[1:])
+
+with open(options.input) as f:
+ content = f.read()
+
+
+output_c = os.path.join(options.target_dir, options.stem + ".tab.c")
+with open(output_c, 'w') as f:
+ f.write(content)
+
+
+output_h = os.path.join(options.target_dir, options.stem + ".tab.h")
+h_content = '''#pragma once
+
+int myfun(void);
+'''
+with open(output_h, 'w') as f:
+ f.write(h_content)
diff --git a/test cases/common/90 gen extra/srcgen3.py b/test cases/common/90 gen extra/srcgen3.py
new file mode 100644
index 0000000..b737114
--- /dev/null
+++ b/test cases/common/90 gen extra/srcgen3.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import sys
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument('input',
+ help='the input file')
+
+options = parser.parse_args(sys.argv[1:])
+
+with open(options.input) as f:
+ content = f.read().strip()
+
+print(content)
diff --git a/test cases/common/90 gen extra/upper.c b/test cases/common/90 gen extra/upper.c
new file mode 100644
index 0000000..82c3252
--- /dev/null
+++ b/test cases/common/90 gen extra/upper.c
@@ -0,0 +1,5 @@
+int BOB_MCBOB(void);
+
+int main(void) {
+ return BOB_MCBOB();
+}
diff --git a/test cases/common/91 benchmark/delayer.c b/test cases/common/91 benchmark/delayer.c
new file mode 100644
index 0000000..b410c46
--- /dev/null
+++ b/test cases/common/91 benchmark/delayer.c
@@ -0,0 +1,20 @@
+/* Simple prog that sleeps for a random time. */
+
+#include<stdlib.h>
+#include<time.h>
+#if defined(_WIN32)
+#include<windows.h>
+#endif
+
+int main(void) {
+ srand(time(NULL));
+#if !defined(_WIN32)
+ struct timespec t;
+ t.tv_sec = 0;
+ t.tv_nsec = 199999999.0*rand()/RAND_MAX;
+ nanosleep(&t, NULL);
+#else
+ Sleep(50.0*rand()/RAND_MAX);
+#endif
+ return 0;
+}
diff --git a/test cases/common/91 benchmark/meson.build b/test cases/common/91 benchmark/meson.build
new file mode 100644
index 0000000..9d583d2
--- /dev/null
+++ b/test cases/common/91 benchmark/meson.build
@@ -0,0 +1,4 @@
+project('benchmark', 'c')
+
+delayer = executable('delayer', 'delayer.c', c_args : '-D_GNU_SOURCE')
+benchmark('delayer', delayer)
diff --git a/test cases/common/92 test workdir/meson.build b/test cases/common/92 test workdir/meson.build
new file mode 100644
index 0000000..a8290f7
--- /dev/null
+++ b/test cases/common/92 test workdir/meson.build
@@ -0,0 +1,8 @@
+project('test workdir', 'c')
+
+exe = executable('opener', 'opener.c')
+
+test('basic', exe, workdir : meson.source_root())
+test('shouldfail', exe, should_fail : true)
+
+subdir('subdir')
diff --git a/test cases/common/92 test workdir/opener.c b/test cases/common/92 test workdir/opener.c
new file mode 100644
index 0000000..c946e18
--- /dev/null
+++ b/test cases/common/92 test workdir/opener.c
@@ -0,0 +1,12 @@
+// This test only succeeds if run in the source root dir.
+
+#include<stdio.h>
+
+int main(void) {
+ FILE *f = fopen("opener.c", "r");
+ if(f) {
+ fclose(f);
+ return 0;
+ }
+ return 1;
+}
diff --git a/test cases/common/92 test workdir/subdir/checker.py b/test cases/common/92 test workdir/subdir/checker.py
new file mode 100755
index 0000000..66e287d
--- /dev/null
+++ b/test cases/common/92 test workdir/subdir/checker.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+import sys
+
+data = open(sys.argv[1], 'rb').read()
diff --git a/test cases/common/92 test workdir/subdir/meson.build b/test cases/common/92 test workdir/subdir/meson.build
new file mode 100644
index 0000000..687a1cf
--- /dev/null
+++ b/test cases/common/92 test workdir/subdir/meson.build
@@ -0,0 +1,4 @@
+exe2 = executable('dummy', '../opener.c')
+test('subdir', find_program('checker.py'),
+ workdir : meson.source_root(),
+ args: [exe2])
diff --git a/test cases/common/93 suites/exe1.c b/test cases/common/93 suites/exe1.c
new file mode 100644
index 0000000..6e32362
--- /dev/null
+++ b/test cases/common/93 suites/exe1.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I am test exe1.\n");
+ return 0;
+}
diff --git a/test cases/common/93 suites/exe2.c b/test cases/common/93 suites/exe2.c
new file mode 100644
index 0000000..21a9dd6
--- /dev/null
+++ b/test cases/common/93 suites/exe2.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I am test exe2.\n");
+ return 0;
+}
diff --git a/test cases/common/93 suites/meson.build b/test cases/common/93 suites/meson.build
new file mode 100644
index 0000000..2346b5b
--- /dev/null
+++ b/test cases/common/93 suites/meson.build
@@ -0,0 +1,9 @@
+project('multiple test suites', 'c')
+
+subproject('sub')
+
+exe1 = executable('exe1', 'exe1.c')
+exe2 = executable('exe2', 'exe2.c')
+
+test('exe1', exe1)
+test('exe2', exe2, suite : ['suite2', ['super-special']])
diff --git a/test cases/common/93 suites/subprojects/sub/meson.build b/test cases/common/93 suites/subprojects/sub/meson.build
new file mode 100644
index 0000000..697d95f
--- /dev/null
+++ b/test cases/common/93 suites/subprojects/sub/meson.build
@@ -0,0 +1,7 @@
+project('subproject test suites', 'c')
+
+sub1 = executable('sub1', 'sub1.c')
+sub2 = executable('sub2', 'sub2.c')
+
+test('sub1', sub1)
+test('sub2', sub2, suite : 'suite2')
diff --git a/test cases/common/93 suites/subprojects/sub/sub1.c b/test cases/common/93 suites/subprojects/sub/sub1.c
new file mode 100644
index 0000000..e067624
--- /dev/null
+++ b/test cases/common/93 suites/subprojects/sub/sub1.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I am test sub1.\n");
+ return 0;
+}
diff --git a/test cases/common/93 suites/subprojects/sub/sub2.c b/test cases/common/93 suites/subprojects/sub/sub2.c
new file mode 100644
index 0000000..0b457dc
--- /dev/null
+++ b/test cases/common/93 suites/subprojects/sub/sub2.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("I am test sub2.\n");
+ return 0;
+}
diff --git a/test cases/common/94 threads/meson.build b/test cases/common/94 threads/meson.build
new file mode 100644
index 0000000..6a939ff
--- /dev/null
+++ b/test cases/common/94 threads/meson.build
@@ -0,0 +1,21 @@
+project('threads', 'cpp', 'c',
+ default_options : ['cpp_std=c++11'])
+
+cc = meson.get_compiler('c')
+if cc.has_function_attribute('unused')
+ add_project_arguments('-DHAVE_UNUSED', language: 'c')
+endif
+
+threaddep = dependency('threads')
+
+test('cppthreadtest',
+ executable('cppthreadprog', 'threadprog.cpp',
+ dependencies : threaddep
+ )
+)
+
+test('cthreadtest',
+ executable('cthreadprog', 'threadprog.c',
+ dependencies : threaddep
+ )
+)
diff --git a/test cases/common/94 threads/threadprog.c b/test cases/common/94 threads/threadprog.c
new file mode 100644
index 0000000..19130d5
--- /dev/null
+++ b/test cases/common/94 threads/threadprog.c
@@ -0,0 +1,46 @@
+#if defined _WIN32
+
+#include<windows.h>
+#include<stdio.h>
+
+DWORD WINAPI thread_func(void) {
+ printf("Printing from a thread.\n");
+ return 0;
+}
+
+int main(void) {
+ DWORD id;
+ HANDLE th;
+ printf("Starting thread.\n");
+ th = CreateThread(NULL, 0, thread_func, NULL, 0, &id);
+ WaitForSingleObject(th, INFINITE);
+ printf("Stopped thread.\n");
+ return 0;
+}
+#else
+
+#include<pthread.h>
+#include<stdio.h>
+
+#ifdef HAVE_UNUSED
+ #define UNUSED_ATTR __attribute__((unused))
+#else
+ #define UNUSED_ATTR
+#endif
+
+void* main_func(void UNUSED_ATTR *arg) {
+ printf("Printing from a thread.\n");
+ return NULL;
+}
+
+int main(void) {
+ pthread_t thread;
+ int rc;
+ printf("Starting thread.\n");
+ rc = pthread_create(&thread, NULL, main_func, NULL);
+ rc = pthread_join(thread, NULL);
+ printf("Stopped thread.\n");
+ return rc;
+}
+
+#endif
diff --git a/test cases/common/94 threads/threadprog.cpp b/test cases/common/94 threads/threadprog.cpp
new file mode 100644
index 0000000..3c69dc3
--- /dev/null
+++ b/test cases/common/94 threads/threadprog.cpp
@@ -0,0 +1,43 @@
+/* On Windows not all versions of VS support C++11 and
+ * some (most?) versions of mingw don't support std::thread,
+ * even though they do support c++11. Since we only care about
+ * threads working, do the test with raw win threads.
+ */
+
+#if defined _WIN32
+
+#include<windows.h>
+#include<stdio.h>
+
+DWORD WINAPI thread_func(LPVOID) {
+ printf("Printing from a thread.\n");
+ return 0;
+}
+
+int main(void) {
+ printf("Starting thread.\n");
+ HANDLE th;
+ DWORD id;
+ th = CreateThread(NULL, 0, thread_func, NULL, 0, &id);
+ WaitForSingleObject(th, INFINITE);
+ printf("Stopped thread.\n");
+ return 0;
+}
+#else
+
+#include<thread>
+#include<cstdio>
+
+void main_func(void) {
+ printf("Printing from a thread.\n");
+}
+
+int main(void) {
+ printf("Starting thread.\n");
+ std::thread th(main_func);
+ th.join();
+ printf("Stopped thread.\n");
+ return 0;
+}
+
+#endif
diff --git a/test cases/common/95 manygen/depuser.c b/test cases/common/95 manygen/depuser.c
new file mode 100644
index 0000000..1ab2487
--- /dev/null
+++ b/test cases/common/95 manygen/depuser.c
@@ -0,0 +1,8 @@
+#include"gen_func.h"
+
+int main(void) {
+ unsigned int i = (unsigned int) gen_func_in_lib();
+ unsigned int j = (unsigned int) gen_func_in_obj();
+ unsigned int k = (unsigned int) gen_func_in_src();
+ return (int)(i + j + k);
+}
diff --git a/test cases/common/95 manygen/meson.build b/test cases/common/95 manygen/meson.build
new file mode 100644
index 0000000..e70a55a
--- /dev/null
+++ b/test cases/common/95 manygen/meson.build
@@ -0,0 +1,14 @@
+project('manygen', 'c')
+
+if meson.is_cross_build()
+ # FIXME error out with skip message once cross test runner
+ # recognizes it.
+ message('Not running this test during cross build.')
+else
+ subdir('subdir')
+
+ exe = executable('depuser', 'depuser.c',
+ generated)
+
+ test('depuser test', exe)
+endif
diff --git a/test cases/common/95 manygen/subdir/funcinfo.def b/test cases/common/95 manygen/subdir/funcinfo.def
new file mode 100644
index 0000000..b074186
--- /dev/null
+++ b/test cases/common/95 manygen/subdir/funcinfo.def
@@ -0,0 +1 @@
+gen_func
diff --git a/test cases/common/95 manygen/subdir/manygen.py b/test cases/common/95 manygen/subdir/manygen.py
new file mode 100755
index 0000000..931fb61
--- /dev/null
+++ b/test cases/common/95 manygen/subdir/manygen.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+
+
+# Generates a static library, object file, source
+# file and a header file.
+
+import sys, os
+import subprocess
+
+with open(sys.argv[1]) as f:
+ funcname = f.readline().strip()
+outdir = sys.argv[2]
+buildtype_args = sys.argv[3]
+compiler_type = sys.argv[4]
+compiler = sys.argv[5:]
+
+if not os.path.isdir(outdir):
+ print('Outdir does not exist.')
+ sys.exit(1)
+
+if compiler_type == 'msvc':
+ libsuffix = '.lib'
+ is_vs = True
+ if any(['clang-cl' in c for c in compiler]):
+ linker = 'llvm-lib'
+ else:
+ linker = 'lib'
+else:
+ libsuffix = '.a'
+ is_vs = False
+ linker = 'ar'
+
+objsuffix = '.o'
+
+outo = os.path.join(outdir, funcname + objsuffix)
+outa = os.path.join(outdir, funcname + libsuffix)
+outh = os.path.join(outdir, funcname + '.h')
+outc = os.path.join(outdir, funcname + '.c')
+
+tmpc = 'diibadaaba.c'
+tmpo = 'diibadaaba' + objsuffix
+
+with open(outc, 'w') as f:
+ f.write('''#include"{}.h"
+int {}_in_src(void) {{
+ return 0;
+}}
+'''.format(funcname, funcname))
+
+with open(outh, 'w') as f:
+ f.write('''#pragma once
+int {}_in_lib(void);
+int {}_in_obj(void);
+int {}_in_src(void);
+'''.format(funcname, funcname, funcname))
+
+with open(tmpc, 'w') as f:
+ f.write('''int %s_in_obj(void) {
+ return 0;
+}
+''' % funcname)
+
+if is_vs:
+ subprocess.check_call(compiler + ['/nologo', '/c', buildtype_args, '/Fo' + outo, tmpc])
+else:
+ subprocess.check_call(compiler + ['-c', '-o', outo, tmpc])
+
+with open(tmpc, 'w') as f:
+ f.write('''int %s_in_lib() {
+ return 0;
+}
+''' % funcname)
+
+if is_vs:
+ subprocess.check_call(compiler + ['/nologo', '/c', '/Fo' + tmpo, tmpc])
+ subprocess.check_call([linker, '/NOLOGO', '/OUT:' + outa, tmpo])
+else:
+ subprocess.check_call(compiler + ['-c', '-o', tmpo, tmpc])
+ subprocess.check_call([linker, 'csr', outa, tmpo])
+
+os.unlink(tmpo)
+os.unlink(tmpc)
diff --git a/test cases/common/95 manygen/subdir/meson.build b/test cases/common/95 manygen/subdir/meson.build
new file mode 100644
index 0000000..56f60e6
--- /dev/null
+++ b/test cases/common/95 manygen/subdir/meson.build
@@ -0,0 +1,26 @@
+gen = files('manygen.py')
+py3_bin = import('python3').find_python()
+
+buildtype = get_option('buildtype')
+buildtype_args = '-Dfooxxx' # a useless compiler argument
+cc = meson.get_compiler('c')
+if cc.get_argument_syntax() == 'msvc'
+ # We need our manually generated code to use the same CRT as the executable.
+ # Taken from compilers.py since build files do not have access to this.
+ if buildtype == 'debug'
+ buildtype_args = '/MDd'
+ elif buildtype == 'debugoptimized'
+ buildtype_args = '/MDd'
+ elif buildtype == 'release'
+ buildtype_args = '/MD'
+ endif
+ outfiles = ['gen_func.lib', 'gen_func.c', 'gen_func.h', 'gen_func.o']
+else
+ outfiles = ['gen_func.a', 'gen_func.c', 'gen_func.h', 'gen_func.o']
+endif
+
+generated = custom_target('manygen',
+ output : outfiles,
+ input : ['funcinfo.def'],
+ command : [py3_bin, gen[0], '@INPUT@', '@OUTDIR@', buildtype_args, cc.get_argument_syntax(), cc.cmd_array()],
+)
diff --git a/test cases/common/96 stringdef/meson.build b/test cases/common/96 stringdef/meson.build
new file mode 100644
index 0000000..3f9170e
--- /dev/null
+++ b/test cases/common/96 stringdef/meson.build
@@ -0,0 +1,3 @@
+project('stringdef', 'c')
+
+test('stringdef', executable('stringdef', 'stringdef.c', c_args : '-DFOO="bar"'))
diff --git a/test cases/common/96 stringdef/stringdef.c b/test cases/common/96 stringdef/stringdef.c
new file mode 100644
index 0000000..17e29fd
--- /dev/null
+++ b/test cases/common/96 stringdef/stringdef.c
@@ -0,0 +1,10 @@
+#include<stdio.h>
+#include<string.h>
+
+int main(void) {
+ if(strcmp(FOO, "bar")) {
+ printf("FOO is misquoted: %s\n", FOO);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/common/97 find program path/meson.build b/test cases/common/97 find program path/meson.build
new file mode 100644
index 0000000..23cf956
--- /dev/null
+++ b/test cases/common/97 find program path/meson.build
@@ -0,0 +1,22 @@
+project('find program')
+
+python = import('python3').find_python()
+
+# Source file via string
+prog = find_program('program.py')
+# Source file via files()
+progf = files('program.py')
+# Built file
+py = configure_file(input : 'program.py',
+ output : 'builtprogram.py',
+ configuration : configuration_data())
+
+foreach f : [prog, progf, py, find_program(py), find_program(progf)]
+ ret = run_command(python, f, check: false)
+ assert(ret.returncode() == 0, 'can\'t manually run @0@'.format(prog.path()))
+ assert(ret.stdout().strip() == 'Found', 'wrong output from manually-run @0@'.format(prog.path()))
+
+ ret = run_command(f, check: false)
+ assert(ret.returncode() == 0, 'can\'t run @0@'.format(prog.path()))
+ assert(ret.stdout().strip() == 'Found', 'wrong output from @0@'.format(prog.path()))
+endforeach
diff --git a/test cases/common/97 find program path/program.py b/test cases/common/97 find program path/program.py
new file mode 100755
index 0000000..2ebc564
--- /dev/null
+++ b/test cases/common/97 find program path/program.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print("Found")
diff --git a/test cases/common/98 subproject subdir/meson.build b/test cases/common/98 subproject subdir/meson.build
new file mode 100644
index 0000000..3053b3b
--- /dev/null
+++ b/test cases/common/98 subproject subdir/meson.build
@@ -0,0 +1,94 @@
+project('proj', 'c')
+subproject('sub')
+libSub = dependency('sub', fallback: ['sub', 'libSub'])
+
+exe = executable('prog', 'prog.c', dependencies: libSub)
+test('subproject subdir', exe)
+
+# Verify the subproject has placed dependency override.
+dependency('sub-1.0')
+
+# Verify we can now take 'sub' dependency without fallback, but only version 1.0.
+dependency('sub')
+d = dependency('sub', version : '>=2.0', required : false)
+assert(not d.found(), 'version should not match')
+
+# Verify that not-found does not get cached, we can still fallback afterward.
+dependency('sub2', required : false)
+d = dependency('sub2', fallback: ['sub', 'libSub'])
+assert(d.found(), 'Should fallback even if a previous call returned not-found')
+
+# Verify we can get a fallback dependency without specifying the variable name,
+# because the subproject overridden 'sub-novar'.
+dependency('sub-novar', fallback : 'sub_novar')
+
+# Verify a subproject can force a dependency to be not-found
+d = dependency('sub-notfound', fallback : 'sub_novar', required : false)
+assert(not d.found(), 'Dependency should be not-found')
+
+# Verify that implicit fallback works because subprojects/sub_implicit directory exists
+d = dependency('sub_implicit', default_options: 'opt=overriden')
+assert(d.found(), 'Should implicitly fallback')
+
+# Verify that implicit fallback works because sub_implicit.wrap has
+# `dependency_names=sub_implicit_provide1` and the subproject overrides sub_implicit_provide1.
+d = dependency('sub_implicit_provide1')
+assert(d.found(), 'Should implicitly fallback')
+
+# Verify that implicit fallback works because sub_implicit.wrap has
+# `sub_implicit_provide2=sub_implicit_provide2_dep` and does not override
+# sub_implicit_provide2.
+d = dependency('sub_implicit_provide2')
+assert(d.found(), 'Should implicitly fallback')
+
+# sub_implicit.wrap provides glib-2.0 and we already configured that subproject,
+# so we must not return the system dependency here. Using glib-2.0 here because
+# some CI runners have it installed.
+d = dependency('glib-2.0', required : false)
+assert(d.found())
+assert(d.type_name() == 'internal')
+
+# sub_implicit.wrap provides gobject-2.0 and we already configured that subproject,
+# so we must not return the system dependency here. But since the subproject did
+# not override that dependency and its not required, not-found should be returned.
+# Using gobject-2.0 here because some CI runners have it installed.
+d = dependency('gobject-2.0', required : false)
+assert(not d.found())
+
+# Verify that implicit fallback works because subprojects/sub_implicit/subprojects/subsub
+# directory exists.
+d = dependency('subsub')
+assert(d.found(), 'Should be able to fallback to sub-subproject')
+
+# Verify that implicit fallback works because
+# subprojects/sub_implicit/subprojects/subsub/subprojects/subsubsub.wrap
+# file exists.
+d = dependency('subsubsub')
+assert(d.found(), 'Should be able to fallback to sub-sub-subproject')
+
+# Verify that `static: true` implies 'default_library=static'.
+d = dependency('sub_static', static: true)
+assert(d.found())
+# Verify that when not specifying static kwarg we can still get fallback dep.
+d = dependency('sub_static')
+assert(d.found())
+# But when asking for shared library explicitly, it is not found.
+d = dependency('sub_static', static: false, required: false)
+assert(not d.found())
+# The subproject also overrides sub_static2 with `static: true`
+d = dependency('sub_static2')
+assert(d.found())
+d = dependency('sub_static2', static: true)
+assert(d.found())
+d = dependency('sub_static2', static: false, required: false)
+assert(not d.found())
+# sub_static3 is overridden twice with `static: true` and `static: false`
+d = dependency('sub_static3')
+assert(d.found())
+assert(d.get_variable('static') == 'true')
+d = dependency('sub_static3', static: true)
+assert(d.found())
+assert(d.get_variable('static') == 'true')
+d = dependency('sub_static3', static: false)
+assert(d.found())
+assert(d.get_variable('static') == 'false')
diff --git a/test cases/common/98 subproject subdir/prog.c b/test cases/common/98 subproject subdir/prog.c
new file mode 100644
index 0000000..9035ff1
--- /dev/null
+++ b/test cases/common/98 subproject subdir/prog.c
@@ -0,0 +1,5 @@
+#include <sub.h>
+
+int main(void) {
+ return sub();
+}
diff --git a/test cases/common/98 subproject subdir/subprojects/sub/lib/meson.build b/test cases/common/98 subproject subdir/subprojects/sub/lib/meson.build
new file mode 100644
index 0000000..53233ab
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub/lib/meson.build
@@ -0,0 +1,3 @@
+lib = static_library('sub', 'sub.c')
+libSub = declare_dependency(include_directories: include_directories('.'), link_with: lib)
+meson.override_dependency('sub-1.0', libSub)
diff --git a/test cases/common/98 subproject subdir/subprojects/sub/lib/sub.c b/test cases/common/98 subproject subdir/subprojects/sub/lib/sub.c
new file mode 100644
index 0000000..e748ac7
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub/lib/sub.c
@@ -0,0 +1,5 @@
+#include "sub.h"
+
+int sub(void) {
+ return 0;
+}
diff --git a/test cases/common/98 subproject subdir/subprojects/sub/lib/sub.h b/test cases/common/98 subproject subdir/subprojects/sub/lib/sub.h
new file mode 100644
index 0000000..2b59a3a
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub/lib/sub.h
@@ -0,0 +1,6 @@
+#ifndef SUB_H
+#define SUB_H
+
+int sub(void);
+
+#endif
diff --git a/test cases/common/98 subproject subdir/subprojects/sub/meson.build b/test cases/common/98 subproject subdir/subprojects/sub/meson.build
new file mode 100644
index 0000000..d8c4dce
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub/meson.build
@@ -0,0 +1,2 @@
+project('sub', 'c', version : '1.0')
+subdir('lib')
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_implicit.wrap b/test cases/common/98 subproject subdir/subprojects/sub_implicit.wrap
new file mode 100644
index 0000000..a809c43
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_implicit.wrap
@@ -0,0 +1,6 @@
+[wrap-file]
+
+[provide]
+glib-2.0 = glib_dep
+dependency_names = sub_implicit_provide1, gobject-2.0
+sub_implicit_provide2 = sub_implicit_provide2_dep
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_implicit/meson.build b/test cases/common/98 subproject subdir/subprojects/sub_implicit/meson.build
new file mode 100644
index 0000000..9f43604
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_implicit/meson.build
@@ -0,0 +1,13 @@
+project('sub_implicit', 'c', version : '1.0')
+
+dep = declare_dependency()
+meson.override_dependency('sub_implicit', dep)
+meson.override_dependency('sub_implicit_provide1', dep)
+
+# This one is not overridden but the wrap file tells the variable name to use.
+sub_implicit_provide2_dep = dep
+
+# This one is not overridden but the wrap file tells the variable name to use.
+glib_dep = dep
+
+assert(get_option('opt') == 'overriden') \ No newline at end of file
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_implicit/meson_options.txt b/test cases/common/98 subproject subdir/subprojects/sub_implicit/meson_options.txt
new file mode 100644
index 0000000..770178c
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_implicit/meson_options.txt
@@ -0,0 +1 @@
+option('opt', type: 'string', value: 'default') \ No newline at end of file
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/foo.h b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/foo.h
new file mode 100644
index 0000000..a8ad3da
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/foo.h
@@ -0,0 +1 @@
+#define DUMMY 42
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/meson.build b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/meson.build
new file mode 100644
index 0000000..fdbb03f
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/meson.build
@@ -0,0 +1,7 @@
+project('subsub')
+
+meson.override_dependency('subsub', declare_dependency())
+
+# Regression test: Installing a header from nested sub-subproject used to raise:
+# ERROR: Sandbox violation: Tried to grab file foo.h from a nested subproject.
+install_headers('foo.h')
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/packagefiles/subsubsub-1.0.zip b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/packagefiles/subsubsub-1.0.zip
new file mode 100644
index 0000000..dfb7576
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/packagefiles/subsubsub-1.0.zip
Binary files differ
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/subsubsub.wrap b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/subsubsub.wrap
new file mode 100644
index 0000000..6567ed0
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_implicit/subprojects/subsub/subprojects/subsubsub.wrap
@@ -0,0 +1,4 @@
+[wrap-file]
+directory = subsubsub-1.0
+source_filename = subsubsub-1.0.zip
+source_hash = c073a96b7251937e53216578f6f03d91b84816618a0f1ce3ecfb867beddf1498
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_novar/meson.build b/test cases/common/98 subproject subdir/subprojects/sub_novar/meson.build
new file mode 100644
index 0000000..6450a10
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_novar/meson.build
@@ -0,0 +1,4 @@
+project('sub-novar', 'c', version : '1.0')
+
+meson.override_dependency('sub-novar', declare_dependency())
+meson.override_dependency('sub-notfound', dependency('', required : false))
diff --git a/test cases/common/98 subproject subdir/subprojects/sub_static/meson.build b/test cases/common/98 subproject subdir/subprojects/sub_static/meson.build
new file mode 100644
index 0000000..6c00623
--- /dev/null
+++ b/test cases/common/98 subproject subdir/subprojects/sub_static/meson.build
@@ -0,0 +1,8 @@
+project('sub_static')
+
+assert(get_option('default_library') == 'static')
+meson.override_dependency('sub_static', declare_dependency())
+meson.override_dependency('sub_static2', declare_dependency(), static: true)
+meson.override_dependency('sub_static3', declare_dependency(variables: {'static': 'true'}), static: true)
+meson.override_dependency('sub_static3', declare_dependency(variables: {'static': 'false'}), static: false)
+
diff --git a/test cases/common/98 subproject subdir/test.json b/test cases/common/98 subproject subdir/test.json
new file mode 100644
index 0000000..1921fe5
--- /dev/null
+++ b/test cases/common/98 subproject subdir/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ { "type": "file", "file": "usr/include/foo.h" }
+ ]
+}
diff --git a/test cases/common/99 postconf/meson.build b/test cases/common/99 postconf/meson.build
new file mode 100644
index 0000000..12b3c5b
--- /dev/null
+++ b/test cases/common/99 postconf/meson.build
@@ -0,0 +1,5 @@
+project('postconf script', 'c')
+
+meson.add_postconf_script('postconf.py')
+
+test('post', executable('prog', 'prog.c'))
diff --git a/test cases/common/99 postconf/postconf.py b/test cases/common/99 postconf/postconf.py
new file mode 100644
index 0000000..950c706
--- /dev/null
+++ b/test cases/common/99 postconf/postconf.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import os
+
+template = '''#pragma once
+
+#define THE_NUMBER {}
+'''
+
+input_file = os.path.join(os.environ['MESON_SOURCE_ROOT'], 'raw.dat')
+output_file = os.path.join(os.environ['MESON_BUILD_ROOT'], 'generated.h')
+
+with open(input_file) as f:
+ data = f.readline().strip()
+with open(output_file, 'w') as f:
+ f.write(template.format(data))
diff --git a/test cases/common/99 postconf/prog.c b/test cases/common/99 postconf/prog.c
new file mode 100644
index 0000000..85a25a3
--- /dev/null
+++ b/test cases/common/99 postconf/prog.c
@@ -0,0 +1,5 @@
+#include"generated.h"
+
+int main(void) {
+ return THE_NUMBER != 9;
+}
diff --git a/test cases/common/99 postconf/raw.dat b/test cases/common/99 postconf/raw.dat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/test cases/common/99 postconf/raw.dat
@@ -0,0 +1 @@
+9
diff --git a/test cases/csharp/1 basic/meson.build b/test cases/csharp/1 basic/meson.build
new file mode 100644
index 0000000..09e46c2
--- /dev/null
+++ b/test cases/csharp/1 basic/meson.build
@@ -0,0 +1,4 @@
+project('simple c#', 'cs')
+
+e = executable('prog', 'prog.cs', 'text.cs', install : true)
+test('basic', e)
diff --git a/test cases/csharp/1 basic/prog.cs b/test cases/csharp/1 basic/prog.cs
new file mode 100644
index 0000000..6ee47b0
--- /dev/null
+++ b/test cases/csharp/1 basic/prog.cs
@@ -0,0 +1,8 @@
+using System;
+
+public class Prog {
+ static public void Main () {
+ TextGetter tg = new TextGetter();
+ Console.WriteLine(tg.getText());
+ }
+}
diff --git a/test cases/csharp/1 basic/test.json b/test cases/csharp/1 basic/test.json
new file mode 100644
index 0000000..650a6e2
--- /dev/null
+++ b/test cases/csharp/1 basic/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/csharp/1 basic/text.cs b/test cases/csharp/1 basic/text.cs
new file mode 100644
index 0000000..c83c424
--- /dev/null
+++ b/test cases/csharp/1 basic/text.cs
@@ -0,0 +1,7 @@
+using System;
+
+public class TextGetter {
+ public String getText() {
+ return "C# is working.";
+ }
+}
diff --git a/test cases/csharp/2 library/helper.cs b/test cases/csharp/2 library/helper.cs
new file mode 100644
index 0000000..266e379
--- /dev/null
+++ b/test cases/csharp/2 library/helper.cs
@@ -0,0 +1,7 @@
+using System;
+
+public class Helper {
+ public void print() {
+ Console.WriteLine("Library class called.");
+ }
+}
diff --git a/test cases/csharp/2 library/meson.build b/test cases/csharp/2 library/meson.build
new file mode 100644
index 0000000..6b246a4
--- /dev/null
+++ b/test cases/csharp/2 library/meson.build
@@ -0,0 +1,15 @@
+project('C# library', 'cs')
+
+python3 = import('python3').find_python()
+generated_sources = custom_target('gen_sources',
+ input: 'helper.cs',
+ output: 'helper.cs',
+ command: [python3, '-c',
+ 'import shutil, sys; shutil.copyfile(sys.argv[1], sys.argv[2])',
+ '@INPUT@', '@OUTPUT@']
+)
+
+l = shared_library('helper', generated_sources, install : true)
+
+e = executable('prog', 'prog.cs', link_with : l, install : true)
+test('libtest', e)
diff --git a/test cases/csharp/2 library/prog.cs b/test cases/csharp/2 library/prog.cs
new file mode 100644
index 0000000..8bf6a31
--- /dev/null
+++ b/test cases/csharp/2 library/prog.cs
@@ -0,0 +1,8 @@
+using System;
+
+public class Prog {
+ static public void Main () {
+ Helper h = new Helper();
+ h.print();
+ }
+}
diff --git a/test cases/csharp/2 library/test.json b/test cases/csharp/2 library/test.json
new file mode 100644
index 0000000..0523f45
--- /dev/null
+++ b/test cases/csharp/2 library/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/helper.dll"},
+ {"type": "pdb", "file": "usr/bin/helper"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/helper.dll"}
+ ]
+}
diff --git a/test cases/csharp/3 resource/TestRes.resx b/test cases/csharp/3 resource/TestRes.resx
new file mode 100644
index 0000000..c85f85c
--- /dev/null
+++ b/test cases/csharp/3 resource/TestRes.resx
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+<resheader name="resmimetype"><value>text/microsoft-resx</value></resheader><resheader name="version"><value>1.3</value></resheader><resheader name="reader"><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><resheader name="writer"><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><data name="message"><value>Hello from resources!</value></data>
+ </root> \ No newline at end of file
diff --git a/test cases/csharp/3 resource/meson.build b/test cases/csharp/3 resource/meson.build
new file mode 100644
index 0000000..25b273d
--- /dev/null
+++ b/test cases/csharp/3 resource/meson.build
@@ -0,0 +1,6 @@
+project('C# resource', 'cs')
+
+e = executable('resprog', 'resprog.cs',
+resources : 'TestRes.resx')
+
+test('restest', e)
diff --git a/test cases/csharp/3 resource/resprog.cs b/test cases/csharp/3 resource/resprog.cs
new file mode 100644
index 0000000..177201c
--- /dev/null
+++ b/test cases/csharp/3 resource/resprog.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Resources;
+
+public class Prog {
+
+ static public void Main () {
+ ResourceManager res = new ResourceManager(typeof(TestRes));
+ Console.WriteLine(res.GetString("message"));
+ }
+
+ internal class TestRes {
+ }
+}
diff --git a/test cases/csharp/4 external dep/hello.txt b/test cases/csharp/4 external dep/hello.txt
new file mode 100644
index 0000000..980a0d5
--- /dev/null
+++ b/test cases/csharp/4 external dep/hello.txt
@@ -0,0 +1 @@
+Hello World!
diff --git a/test cases/csharp/4 external dep/meson.build b/test cases/csharp/4 external dep/meson.build
new file mode 100644
index 0000000..019d618
--- /dev/null
+++ b/test cases/csharp/4 external dep/meson.build
@@ -0,0 +1,9 @@
+project('C# external library', 'cs')
+glib_sharp_2 = dependency('glib-sharp-2.0', required : false)
+
+if not glib_sharp_2.found()
+ error('MESON_SKIP_TEST glib# not found.')
+endif
+
+e = executable('prog', 'prog.cs', dependencies: glib_sharp_2, install : true)
+test('libtest', e, args: [join_paths(meson.current_source_dir(), 'hello.txt')])
diff --git a/test cases/csharp/4 external dep/prog.cs b/test cases/csharp/4 external dep/prog.cs
new file mode 100644
index 0000000..9393fef
--- /dev/null
+++ b/test cases/csharp/4 external dep/prog.cs
@@ -0,0 +1,8 @@
+using System;
+using GLib;
+
+public class Prog {
+ static public void Main (string[] args) {
+ Console.WriteLine(GLib.FileUtils.GetFileContents(args[0]));
+ }
+}
diff --git a/test cases/csharp/4 external dep/test.json b/test cases/csharp/4 external dep/test.json
new file mode 100644
index 0000000..a94303f
--- /dev/null
+++ b/test cases/csharp/4 external dep/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"}
+ ]
+}
diff --git a/test cases/cuda/1 simple/meson.build b/test cases/cuda/1 simple/meson.build
new file mode 100644
index 0000000..4f111d1
--- /dev/null
+++ b/test cases/cuda/1 simple/meson.build
@@ -0,0 +1,4 @@
+project('simple', 'cuda', version : '1.0.0')
+
+exe = executable('prog', 'prog.cu')
+test('cudatest', exe)
diff --git a/test cases/cuda/1 simple/prog.cu b/test cases/cuda/1 simple/prog.cu
new file mode 100644
index 0000000..06521b2
--- /dev/null
+++ b/test cases/cuda/1 simple/prog.cu
@@ -0,0 +1,29 @@
+#include <iostream>
+
+int main(void) {
+ int cuda_devices = 0;
+ std::cout << "CUDA version: " << CUDART_VERSION << "\n";
+ cudaGetDeviceCount(&cuda_devices);
+ if(cuda_devices == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+ std::cout << "This computer has " << cuda_devices << " Cuda device(s).\n";
+ cudaDeviceProp props;
+ cudaGetDeviceProperties(&props, 0);
+ std::cout << "Properties of device 0.\n\n";
+
+ std::cout << " Name: " << props.name << "\n";
+ std::cout << " Global memory: " << props.totalGlobalMem << "\n";
+ std::cout << " Shared memory: " << props.sharedMemPerBlock << "\n";
+ std::cout << " Constant memory: " << props.totalConstMem << "\n";
+ std::cout << " Block registers: " << props.regsPerBlock << "\n";
+
+ std::cout << " Warp size: " << props.warpSize << "\n";
+ std::cout << " Threads per block: " << props.maxThreadsPerBlock << "\n";
+ std::cout << " Max block dimensions: [ " << props.maxThreadsDim[0] << ", " << props.maxThreadsDim[1] << ", " << props.maxThreadsDim[2] << " ]" << "\n";
+ std::cout << " Max grid dimensions: [ " << props.maxGridSize[0] << ", " << props.maxGridSize[1] << ", " << props.maxGridSize[2] << " ]" << "\n";
+ std::cout << "\n";
+
+ return 0;
+}
diff --git a/test cases/cuda/10 cuda dependency/c/meson.build b/test cases/cuda/10 cuda dependency/c/meson.build
new file mode 100644
index 0000000..921bc43
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/c/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.c', dependencies: dependency('cuda'))
+test('cudatest', exe)
diff --git a/test cases/cuda/10 cuda dependency/c/prog.c b/test cases/cuda/10 cuda dependency/c/prog.c
new file mode 100644
index 0000000..ed9333e
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/c/prog.c
@@ -0,0 +1,19 @@
+#include <cuda_runtime.h>
+#include <stdio.h>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ printf("No CUDA hardware found. Exiting.\n");
+ return 0;
+ }
+
+ printf("Found %i CUDA devices.\n", n);
+ return 0;
+}
diff --git a/test cases/cuda/10 cuda dependency/cpp/meson.build b/test cases/cuda/10 cuda dependency/cpp/meson.build
new file mode 100644
index 0000000..a661b88
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/cpp/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.cc', dependencies: dependency('cuda'))
+test('cudatest', exe)
diff --git a/test cases/cuda/10 cuda dependency/cpp/prog.cc b/test cases/cuda/10 cuda dependency/cpp/prog.cc
new file mode 100644
index 0000000..4832afa
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/cpp/prog.cc
@@ -0,0 +1,19 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No CUDA hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << " CUDA devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/10 cuda dependency/meson.build b/test cases/cuda/10 cuda dependency/meson.build
new file mode 100644
index 0000000..3e602b6
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/meson.build
@@ -0,0 +1,6 @@
+project('cuda dependency', 'c', 'cpp')
+
+subdir('c')
+subdir('cpp')
+subdir('modules')
+subdir('version_reqs')
diff --git a/test cases/cuda/10 cuda dependency/modules/meson.build b/test cases/cuda/10 cuda dependency/modules/meson.build
new file mode 100644
index 0000000..0da43f2
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/modules/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.cc', dependencies: dependency('cuda', modules: ['cublas']))
+test('cudatest', exe)
diff --git a/test cases/cuda/10 cuda dependency/modules/prog.cc b/test cases/cuda/10 cuda dependency/modules/prog.cc
new file mode 100644
index 0000000..b4af4d4
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/modules/prog.cc
@@ -0,0 +1,33 @@
+#include <cuda_runtime.h>
+#include <cublas_v2.h>
+#include <iostream>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No CUDA hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << " CUDA devices.\n";
+
+ cublasHandle_t handle;
+ if (cublasCreate(&handle) != CUBLAS_STATUS_SUCCESS) {
+ std::cout << "cuBLAS initialization failed. Exiting.\n";
+ return -1;
+ }
+
+ std::cout << "Initialized cuBLAS\n";
+ if (cublasDestroy(handle) != CUBLAS_STATUS_SUCCESS) {
+ std::cout << "cuBLAS de-initialization failed. Exiting.\n";
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/test cases/cuda/10 cuda dependency/version_reqs/meson.build b/test cases/cuda/10 cuda dependency/version_reqs/meson.build
new file mode 100644
index 0000000..45b5daa
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/version_reqs/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.cc', dependencies: dependency('cuda', version: ['>=8.5', '<10'], required: false, disabler: true))
+test('cudatest', exe)
diff --git a/test cases/cuda/10 cuda dependency/version_reqs/prog.cc b/test cases/cuda/10 cuda dependency/version_reqs/prog.cc
new file mode 100644
index 0000000..5668830
--- /dev/null
+++ b/test cases/cuda/10 cuda dependency/version_reqs/prog.cc
@@ -0,0 +1,28 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int main(void) {
+ std::cout << "Compiled against CUDA version: " << CUDART_VERSION << "\n";
+ int runtime_version = 0;
+ cudaError_t r = cudaRuntimeGetVersion(&runtime_version);
+ if (r != cudaSuccess) {
+ std::cout << "Couldn't obtain CUDA runtime version (error " << r << "). Exiting.\n";
+ return -1;
+ }
+ std::cout << "CUDA runtime version: " << runtime_version << "\n";
+
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No CUDA hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << " CUDA devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/11 cuda dependency (nvcc)/meson.build b/test cases/cuda/11 cuda dependency (nvcc)/meson.build
new file mode 100644
index 0000000..67b6568
--- /dev/null
+++ b/test cases/cuda/11 cuda dependency (nvcc)/meson.build
@@ -0,0 +1,4 @@
+project('cuda dependency', 'cuda')
+
+subdir('modules')
+subdir('version_reqs')
diff --git a/test cases/cuda/11 cuda dependency (nvcc)/modules/meson.build b/test cases/cuda/11 cuda dependency (nvcc)/modules/meson.build
new file mode 100644
index 0000000..c0fed83
--- /dev/null
+++ b/test cases/cuda/11 cuda dependency (nvcc)/modules/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.cu', dependencies: dependency('cuda', modules: ['cublas']))
+test('cudatest', exe)
diff --git a/test cases/cuda/11 cuda dependency (nvcc)/modules/prog.cu b/test cases/cuda/11 cuda dependency (nvcc)/modules/prog.cu
new file mode 100644
index 0000000..b4af4d4
--- /dev/null
+++ b/test cases/cuda/11 cuda dependency (nvcc)/modules/prog.cu
@@ -0,0 +1,33 @@
+#include <cuda_runtime.h>
+#include <cublas_v2.h>
+#include <iostream>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No CUDA hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << " CUDA devices.\n";
+
+ cublasHandle_t handle;
+ if (cublasCreate(&handle) != CUBLAS_STATUS_SUCCESS) {
+ std::cout << "cuBLAS initialization failed. Exiting.\n";
+ return -1;
+ }
+
+ std::cout << "Initialized cuBLAS\n";
+ if (cublasDestroy(handle) != CUBLAS_STATUS_SUCCESS) {
+ std::cout << "cuBLAS de-initialization failed. Exiting.\n";
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/test cases/cuda/11 cuda dependency (nvcc)/version_reqs/meson.build b/test cases/cuda/11 cuda dependency (nvcc)/version_reqs/meson.build
new file mode 100644
index 0000000..6644c9e
--- /dev/null
+++ b/test cases/cuda/11 cuda dependency (nvcc)/version_reqs/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.cu', dependencies: dependency('cuda', version: ['>=10.1'], required: false, disabler: true))
+test('cudatest', exe)
diff --git a/test cases/cuda/11 cuda dependency (nvcc)/version_reqs/prog.cu b/test cases/cuda/11 cuda dependency (nvcc)/version_reqs/prog.cu
new file mode 100644
index 0000000..bc90081
--- /dev/null
+++ b/test cases/cuda/11 cuda dependency (nvcc)/version_reqs/prog.cu
@@ -0,0 +1,29 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int main(void) {
+ std::cout << "Compiled against CUDA version: " << CUDART_VERSION << "\n";
+
+ int runtime_version = 0;
+ switch (cudaError_t r = cudaRuntimeGetVersion(&runtime_version)) {
+ case cudaSuccess:
+ std::cout << "CUDA runtime version: " << runtime_version << "\n";
+ break;
+ case cudaErrorNoDevice:
+ std::cout << "No CUDA hardware found. Exiting.\n";
+ return 0;
+ default:
+ std::cout << "Couldn't obtain CUDA runtime version (error " << r << "). Exiting.\n";
+ return -1;
+ }
+
+ int n = cuda_devices();
+ std::cout << "Found " << n << " CUDA devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/12 cuda dependency (mixed)/kernel.cu b/test cases/cuda/12 cuda dependency (mixed)/kernel.cu
new file mode 100644
index 0000000..7daaa68
--- /dev/null
+++ b/test cases/cuda/12 cuda dependency (mixed)/kernel.cu
@@ -0,0 +1,8 @@
+#include <cuda_runtime.h>
+
+__global__ void kernel (void){
+}
+
+void do_cuda_stuff(void) {
+ kernel<<<1,1>>>();
+}
diff --git a/test cases/cuda/12 cuda dependency (mixed)/meson.build b/test cases/cuda/12 cuda dependency (mixed)/meson.build
new file mode 100644
index 0000000..5df4f84
--- /dev/null
+++ b/test cases/cuda/12 cuda dependency (mixed)/meson.build
@@ -0,0 +1,4 @@
+project('cuda dependency', 'cpp', 'cuda')
+
+exe = executable('prog', 'prog.cpp', 'kernel.cu', dependencies: dependency('cuda', modules: ['cublas']))
+test('cudatest', exe)
diff --git a/test cases/cuda/12 cuda dependency (mixed)/prog.cpp b/test cases/cuda/12 cuda dependency (mixed)/prog.cpp
new file mode 100644
index 0000000..50bb156
--- /dev/null
+++ b/test cases/cuda/12 cuda dependency (mixed)/prog.cpp
@@ -0,0 +1,37 @@
+#include <cuda_runtime.h>
+#include <cublas_v2.h>
+#include <iostream>
+
+void do_cuda_stuff(void);
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No CUDA hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << " CUDA devices.\n";
+
+ do_cuda_stuff();
+
+ cublasHandle_t handle;
+ if (cublasCreate(&handle) != CUBLAS_STATUS_SUCCESS) {
+ std::cout << "cuBLAS initialization failed. Exiting.\n";
+ return -1;
+ }
+
+ std::cout << "Initialized cuBLAS\n";
+ if (cublasDestroy(handle) != CUBLAS_STATUS_SUCCESS) {
+ std::cout << "cuBLAS de-initialization failed. Exiting.\n";
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/test cases/cuda/13 cuda compiler setting/meson.build b/test cases/cuda/13 cuda compiler setting/meson.build
new file mode 100644
index 0000000..4f111d1
--- /dev/null
+++ b/test cases/cuda/13 cuda compiler setting/meson.build
@@ -0,0 +1,4 @@
+project('simple', 'cuda', version : '1.0.0')
+
+exe = executable('prog', 'prog.cu')
+test('cudatest', exe)
diff --git a/test cases/cuda/13 cuda compiler setting/nativefile.ini b/test cases/cuda/13 cuda compiler setting/nativefile.ini
new file mode 100644
index 0000000..fb52e0d
--- /dev/null
+++ b/test cases/cuda/13 cuda compiler setting/nativefile.ini
@@ -0,0 +1,3 @@
+[binaries]
+
+cuda = 'nvcc'
diff --git a/test cases/cuda/13 cuda compiler setting/prog.cu b/test cases/cuda/13 cuda compiler setting/prog.cu
new file mode 100644
index 0000000..06521b2
--- /dev/null
+++ b/test cases/cuda/13 cuda compiler setting/prog.cu
@@ -0,0 +1,29 @@
+#include <iostream>
+
+int main(void) {
+ int cuda_devices = 0;
+ std::cout << "CUDA version: " << CUDART_VERSION << "\n";
+ cudaGetDeviceCount(&cuda_devices);
+ if(cuda_devices == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+ std::cout << "This computer has " << cuda_devices << " Cuda device(s).\n";
+ cudaDeviceProp props;
+ cudaGetDeviceProperties(&props, 0);
+ std::cout << "Properties of device 0.\n\n";
+
+ std::cout << " Name: " << props.name << "\n";
+ std::cout << " Global memory: " << props.totalGlobalMem << "\n";
+ std::cout << " Shared memory: " << props.sharedMemPerBlock << "\n";
+ std::cout << " Constant memory: " << props.totalConstMem << "\n";
+ std::cout << " Block registers: " << props.regsPerBlock << "\n";
+
+ std::cout << " Warp size: " << props.warpSize << "\n";
+ std::cout << " Threads per block: " << props.maxThreadsPerBlock << "\n";
+ std::cout << " Max block dimensions: [ " << props.maxThreadsDim[0] << ", " << props.maxThreadsDim[1] << ", " << props.maxThreadsDim[2] << " ]" << "\n";
+ std::cout << " Max grid dimensions: [ " << props.maxGridSize[0] << ", " << props.maxGridSize[1] << ", " << props.maxGridSize[2] << " ]" << "\n";
+ std::cout << "\n";
+
+ return 0;
+}
diff --git a/test cases/cuda/14 cuda has header symbol/meson.build b/test cases/cuda/14 cuda has header symbol/meson.build
new file mode 100644
index 0000000..a23892d
--- /dev/null
+++ b/test cases/cuda/14 cuda has header symbol/meson.build
@@ -0,0 +1,26 @@
+project('cuda has header symbol', 'cuda')
+
+cuda = meson.get_compiler('cuda')
+
+# C checks
+assert (cuda.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
+assert (cuda.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
+assert (cuda.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
+assert (cuda.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
+assert (not cuda.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
+assert (not cuda.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
+assert (not cuda.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
+assert (not cuda.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
+
+# C++ checks
+assert (cuda.has_header_symbol('iostream', 'std::iostream'), 'iostream not found in iostream.h')
+assert (cuda.has_header_symbol('vector', 'std::vector'), 'vector not found in vector.h')
+assert (not cuda.has_header_symbol('limits.h', 'std::iostream'), 'iostream should not be defined in limits.h')
+
+# CUDA checks
+assert (cuda.has_header_symbol('cuda.h', 'CUDA_VERSION'), 'CUDA_VERSION not found in cuda.h')
+assert (not cuda.has_header_symbol('cuda.h', 'cublasSaxpy'), 'cublasSaxpy is defined in cublas.h, not cuda.h')
+if cuda.version().version_compare('>=4.0')
+ assert (cuda.has_header_symbol('thrust/device_vector.h', 'thrust::device_vector'), 'thrust::device_vector not found')
+ assert (not cuda.has_header_symbol('thrust/fill.h', 'thrust::sort'), 'thrust::sort should not be defined in thrust/fill.h')
+endif
diff --git a/test cases/cuda/15 sanitizer/meson.build b/test cases/cuda/15 sanitizer/meson.build
new file mode 100644
index 0000000..367a4e2
--- /dev/null
+++ b/test cases/cuda/15 sanitizer/meson.build
@@ -0,0 +1,4 @@
+project('simple', 'cuda', version : '1.0.0',
+ default_options: ['b_sanitize=address,undefined'])
+
+libtests = shared_library('tests', 'prog.cu')
diff --git a/test cases/cuda/15 sanitizer/prog.cu b/test cases/cuda/15 sanitizer/prog.cu
new file mode 100644
index 0000000..5816809
--- /dev/null
+++ b/test cases/cuda/15 sanitizer/prog.cu
@@ -0,0 +1,29 @@
+#include <iostream>
+
+int run_tests(void) {
+ int cuda_devices = 0;
+ std::cout << "CUDA version: " << CUDART_VERSION << "\n";
+ cudaGetDeviceCount(&cuda_devices);
+ if(cuda_devices == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+ std::cout << "This computer has " << cuda_devices << " Cuda device(s).\n";
+ cudaDeviceProp props;
+ cudaGetDeviceProperties(&props, 0);
+ std::cout << "Properties of device 0.\n\n";
+
+ std::cout << " Name: " << props.name << "\n";
+ std::cout << " Global memory: " << props.totalGlobalMem << "\n";
+ std::cout << " Shared memory: " << props.sharedMemPerBlock << "\n";
+ std::cout << " Constant memory: " << props.totalConstMem << "\n";
+ std::cout << " Block registers: " << props.regsPerBlock << "\n";
+
+ std::cout << " Warp size: " << props.warpSize << "\n";
+ std::cout << " Threads per block: " << props.maxThreadsPerBlock << "\n";
+ std::cout << " Max block dimensions: [ " << props.maxThreadsDim[0] << ", " << props.maxThreadsDim[1] << ", " << props.maxThreadsDim[2] << " ]" << "\n";
+ std::cout << " Max grid dimensions: [ " << props.maxGridSize[0] << ", " << props.maxGridSize[1] << ", " << props.maxGridSize[2] << " ]" << "\n";
+ std::cout << "\n";
+
+ return 0;
+}
diff --git a/test cases/cuda/16 multistd/lib.cu b/test cases/cuda/16 multistd/lib.cu
new file mode 100644
index 0000000..8b5d5a7
--- /dev/null
+++ b/test cases/cuda/16 multistd/lib.cu
@@ -0,0 +1,3 @@
+int do_cuda_stuff() {
+ return 0;
+}
diff --git a/test cases/cuda/16 multistd/main.cu b/test cases/cuda/16 multistd/main.cu
new file mode 100644
index 0000000..7b06570
--- /dev/null
+++ b/test cases/cuda/16 multistd/main.cu
@@ -0,0 +1,21 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+auto cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+int do_cuda_stuff();
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << "Cuda devices.\n";
+ return do_cuda_stuff();
+}
diff --git a/test cases/cuda/16 multistd/meson.build b/test cases/cuda/16 multistd/meson.build
new file mode 100644
index 0000000..36709d8
--- /dev/null
+++ b/test cases/cuda/16 multistd/meson.build
@@ -0,0 +1,13 @@
+project('C++-CUDA multi-std', 'cpp', 'cuda',
+ version : '1.0.0',
+ default_options : ['cpp_std=c++17', 'cuda_std=c++14'])
+
+# Regression test: Passing override_options used to cause a crash.
+# See https://github.com/mesonbuild/meson/issues/9448.
+libcpp11 = static_library('testcpp11', 'lib.cu',
+ override_options: ['cpp_std=c++11']
+)
+
+exe = executable('prog', 'main.cu', link_with: libcpp11)
+# The runtimes leak memory, so ignore it.
+test('cudatest', exe, env: ['ASAN_OPTIONS=detect_leaks=0'])
diff --git a/test cases/cuda/2 split/lib.cu b/test cases/cuda/2 split/lib.cu
new file mode 100644
index 0000000..e891933
--- /dev/null
+++ b/test cases/cuda/2 split/lib.cu
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <iostream>
+
+__global__ void kernel (void){
+}
+
+int do_cuda_stuff(void) {
+ kernel<<<1,1>>>();
+
+ printf("Hello, World!\n");
+ return 0;
+}
diff --git a/test cases/cuda/2 split/main.cpp b/test cases/cuda/2 split/main.cpp
new file mode 100644
index 0000000..ce79003
--- /dev/null
+++ b/test cases/cuda/2 split/main.cpp
@@ -0,0 +1,7 @@
+#include<iostream>
+
+int do_cuda_stuff(void);
+
+int main(void) {
+ return do_cuda_stuff();
+}
diff --git a/test cases/cuda/2 split/meson.build b/test cases/cuda/2 split/meson.build
new file mode 100644
index 0000000..2e2bec1
--- /dev/null
+++ b/test cases/cuda/2 split/meson.build
@@ -0,0 +1,6 @@
+project('simple', 'cuda', 'cpp')
+
+exe = executable('prog', 'main.cpp', 'lib.cu')
+test('cudatest', exe)
+
+subdir('static')
diff --git a/test cases/cuda/2 split/static/lib.cu b/test cases/cuda/2 split/static/lib.cu
new file mode 100644
index 0000000..757c9b5
--- /dev/null
+++ b/test cases/cuda/2 split/static/lib.cu
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <iostream>
+
+__global__ void kernel (void){
+}
+
+int do_cuda_stuff() {
+ kernel<<<1,1>>>();
+
+ printf("Hello, World!\n");
+ return 0;
+}
diff --git a/test cases/cuda/2 split/static/libsta.cu b/test cases/cuda/2 split/static/libsta.cu
new file mode 100644
index 0000000..757c9b5
--- /dev/null
+++ b/test cases/cuda/2 split/static/libsta.cu
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <iostream>
+
+__global__ void kernel (void){
+}
+
+int do_cuda_stuff() {
+ kernel<<<1,1>>>();
+
+ printf("Hello, World!\n");
+ return 0;
+}
diff --git a/test cases/cuda/2 split/static/main_static.cpp b/test cases/cuda/2 split/static/main_static.cpp
new file mode 100644
index 0000000..ce79003
--- /dev/null
+++ b/test cases/cuda/2 split/static/main_static.cpp
@@ -0,0 +1,7 @@
+#include<iostream>
+
+int do_cuda_stuff(void);
+
+int main(void) {
+ return do_cuda_stuff();
+}
diff --git a/test cases/cuda/2 split/static/meson.build b/test cases/cuda/2 split/static/meson.build
new file mode 100644
index 0000000..9078198
--- /dev/null
+++ b/test cases/cuda/2 split/static/meson.build
@@ -0,0 +1,4 @@
+l = static_library('clib', 'lib.cu')
+exe = executable('staexe', 'main_static.cpp',
+ link_with : l)
+test('static Cuda test', exe)
diff --git a/test cases/cuda/3 cudamodule/meson.build b/test cases/cuda/3 cudamodule/meson.build
new file mode 100644
index 0000000..5c3ed60
--- /dev/null
+++ b/test cases/cuda/3 cudamodule/meson.build
@@ -0,0 +1,69 @@
+project('cudamodule', 'cuda', version : '1.0.0')
+
+nvcc = meson.get_compiler('cuda')
+cuda = import('unstable-cuda')
+
+arch_flags = cuda.nvcc_arch_flags(nvcc.version(), 'Auto', detected: ['6.0'])
+arch_readable = cuda.nvcc_arch_readable(nvcc.version(), 'Auto', detected: ['6.0'])
+driver_version = cuda.min_driver_version(nvcc.version())
+
+message('NVCC version: ' + nvcc.version())
+message('NVCC flags: ' + ' '.join(arch_flags))
+message('NVCC readable: ' + ' '.join(arch_readable))
+message('Driver version: >=' + driver_version)
+
+exe = executable('prog', 'prog.cu', cuda_args: arch_flags)
+test('cudatest', exe)
+
+
+#
+# Assert Series
+#
+
+# Sanity test.
+assert(' '.join(cuda.nvcc_arch_flags('11.1', '8.6')) ==
+ '-gencode arch=compute_86,code=sm_86')
+
+# CUDA Toolkit too old, flag filtered out.
+assert(' '.join(cuda.nvcc_arch_flags('11.0', '8.6')) ==
+ '')
+
+# Named architectures.
+assert(' '.join(cuda.nvcc_arch_flags('11.0', 'Ampere')) ==
+ '-gencode arch=compute_80,code=sm_80')
+
+# Splitting & deduplication.
+assert(' '.join(cuda.nvcc_arch_flags('11.0', 'Ampere;8.0,8.0')) ==
+ '-gencode arch=compute_80,code=sm_80')
+
+# Same, but list supplied as list.
+assert(' '.join(cuda.nvcc_arch_flags('11.0', ['Ampere', '8.0', '8.0'])) ==
+ '-gencode arch=compute_80,code=sm_80')
+
+# Same, but mode set to Auto with detected set to a string with a variety of separators.
+assert(' '.join(cuda.nvcc_arch_flags('11.0', 'Auto', detected: 'Ampere;8.0,8.0')) ==
+ '-gencode arch=compute_80,code=sm_80')
+
+# Same, but detected set to a list.
+assert(' '.join(cuda.nvcc_arch_flags('11.0', 'Auto', detected: ['Ampere', '8.0', '8.0'])) ==
+ '-gencode arch=compute_80,code=sm_80')
+
+# Ask for 8.6 binary with 8.0-level PTX.
+assert(' '.join(cuda.nvcc_arch_flags('11.1', '8.6(8.0)')) ==
+ '-gencode arch=compute_80,code=sm_86')
+
+# Same, but keep the 8.0 PTX.
+assert(' '.join(cuda.nvcc_arch_flags('11.1', '8.6(8.0)+PTX')) ==
+ '-gencode arch=compute_80,code=sm_86 -gencode arch=compute_80,code=compute_80')
+
+# Detected Ampere RTX 3090 on CUDA 10.2, saturate to 7.5+PTX
+assert(' '.join(cuda.nvcc_arch_flags('10.2', 'Auto', detected: ['8.0'])) ==
+ '-gencode arch=compute_75,code=sm_75 -gencode arch=compute_75,code=compute_75')
+
+# Failed to auto-detect with CUDA 10.2, default to common GPUs (3.0;3.5;5.0;5.2;6.0;6.1;7.0;7.5+PTX)
+assert(' '.join(cuda.nvcc_arch_flags('10.2', 'Auto', detected: [])) ==
+ '-gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 '+
+ '-gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52 '+
+ '-gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61 '+
+ '-gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=sm_75 '+
+ '-gencode arch=compute_75,code=compute_75')
diff --git a/test cases/cuda/3 cudamodule/prog.cu b/test cases/cuda/3 cudamodule/prog.cu
new file mode 100644
index 0000000..06521b2
--- /dev/null
+++ b/test cases/cuda/3 cudamodule/prog.cu
@@ -0,0 +1,29 @@
+#include <iostream>
+
+int main(void) {
+ int cuda_devices = 0;
+ std::cout << "CUDA version: " << CUDART_VERSION << "\n";
+ cudaGetDeviceCount(&cuda_devices);
+ if(cuda_devices == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+ std::cout << "This computer has " << cuda_devices << " Cuda device(s).\n";
+ cudaDeviceProp props;
+ cudaGetDeviceProperties(&props, 0);
+ std::cout << "Properties of device 0.\n\n";
+
+ std::cout << " Name: " << props.name << "\n";
+ std::cout << " Global memory: " << props.totalGlobalMem << "\n";
+ std::cout << " Shared memory: " << props.sharedMemPerBlock << "\n";
+ std::cout << " Constant memory: " << props.totalConstMem << "\n";
+ std::cout << " Block registers: " << props.regsPerBlock << "\n";
+
+ std::cout << " Warp size: " << props.warpSize << "\n";
+ std::cout << " Threads per block: " << props.maxThreadsPerBlock << "\n";
+ std::cout << " Max block dimensions: [ " << props.maxThreadsDim[0] << ", " << props.maxThreadsDim[1] << ", " << props.maxThreadsDim[2] << " ]" << "\n";
+ std::cout << " Max grid dimensions: [ " << props.maxGridSize[0] << ", " << props.maxGridSize[1] << ", " << props.maxGridSize[2] << " ]" << "\n";
+ std::cout << "\n";
+
+ return 0;
+}
diff --git a/test cases/cuda/4 shared/main.cu b/test cases/cuda/4 shared/main.cu
new file mode 100644
index 0000000..1235914
--- /dev/null
+++ b/test cases/cuda/4 shared/main.cu
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <cuda_runtime.h>
+#include "shared/kernels.h"
+
+
+int main(void) {
+ int cuda_devices = 0;
+ cudaGetDeviceCount(&cuda_devices);
+ if(cuda_devices == 0) {
+ printf("No Cuda hardware found. Exiting.\n");
+ return 0;
+ }
+
+ if(run_tests() != 0){
+ printf("CUDA tests failed! Exiting.\n");
+ return 0;
+ }
+
+ return 0;
+}
diff --git a/test cases/cuda/4 shared/meson.build b/test cases/cuda/4 shared/meson.build
new file mode 100644
index 0000000..532aaeb
--- /dev/null
+++ b/test cases/cuda/4 shared/meson.build
@@ -0,0 +1,6 @@
+project('simple', 'cuda', version : '1.0.0')
+
+subdir('shared')
+
+exe = executable('prog', 'main.cu', dependencies: libkernels)
+test('cudatest', exe)
diff --git a/test cases/cuda/4 shared/shared/kernels.cu b/test cases/cuda/4 shared/shared/kernels.cu
new file mode 100644
index 0000000..5cda629
--- /dev/null
+++ b/test cases/cuda/4 shared/shared/kernels.cu
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <cuda_runtime.h>
+#include "kernels.h"
+
+
+TAG_HIDDEN __global__ void kernel (void){
+}
+
+TAG_PUBLIC int run_tests(void) {
+ kernel<<<1,1>>>();
+
+ return (int)cudaDeviceSynchronize();
+}
diff --git a/test cases/cuda/4 shared/shared/kernels.h b/test cases/cuda/4 shared/shared/kernels.h
new file mode 100644
index 0000000..dbcb99d
--- /dev/null
+++ b/test cases/cuda/4 shared/shared/kernels.h
@@ -0,0 +1,86 @@
+/* Include Guard */
+#ifndef SHARED_KERNELS_H
+#define SHARED_KERNELS_H
+
+/**
+ * Includes
+ */
+
+#include <cuda_runtime.h>
+
+
+/**
+ * Defines
+ */
+
+/**
+ * When building a library, it is a good idea to expose as few as possible
+ * internal symbols (functions, objects, data structures). Not only does it
+ * prevent users from relying on private portions of the library that are
+ * subject to change without any notice, but it can have performance
+ * advantages:
+ *
+ * - It can make shared libraries link faster at dynamic-load time.
+ * - It can make internal function calls faster by bypassing the PLT.
+ *
+ * Thus, the compilation should by default hide all symbols, while the API
+ * headers will explicitly mark public the few symbols the users are permitted
+ * to use with a PUBLIC tag. We also define a HIDDEN tag, since it may be
+ * required to explicitly tag certain C++ types as visible in order for
+ * exceptions to function correctly.
+ *
+ * Additional complexity comes from non-POSIX-compliant systems, which
+ * artificially impose a requirement on knowing whether we are building or
+ * using a DLL.
+ *
+ * The above commentary and below code is inspired from
+ * 'https://gcc.gnu.org/wiki/Visibility'
+ */
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define TAG_ATTRIBUTE_EXPORT __declspec(dllexport)
+# define TAG_ATTRIBUTE_IMPORT __declspec(dllimport)
+# define TAG_ATTRIBUTE_HIDDEN
+#elif __GNUC__ >= 4
+# define TAG_ATTRIBUTE_EXPORT __attribute__((visibility("default")))
+# define TAG_ATTRIBUTE_IMPORT __attribute__((visibility("default")))
+# define TAG_ATTRIBUTE_HIDDEN __attribute__((visibility("hidden")))
+#else
+# define TAG_ATTRIBUTE_EXPORT
+# define TAG_ATTRIBUTE_IMPORT
+# define TAG_ATTRIBUTE_HIDDEN
+#endif
+
+#if TAG_IS_SHARED
+# if TAG_IS_BUILDING
+# define TAG_PUBLIC TAG_ATTRIBUTE_EXPORT
+# else
+# define TAG_PUBLIC TAG_ATTRIBUTE_IMPORT
+# endif
+# define TAG_HIDDEN TAG_ATTRIBUTE_HIDDEN
+#else
+# define TAG_PUBLIC
+# define TAG_HIDDEN
+#endif
+#define TAG_STATIC static
+
+
+
+
+/* Extern "C" Guard */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/* Function Prototypes */
+TAG_PUBLIC int run_tests(void);
+
+
+
+/* End Extern "C" and Include Guard */
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/test cases/cuda/4 shared/shared/meson.build b/test cases/cuda/4 shared/shared/meson.build
new file mode 100644
index 0000000..61cf1d3
--- /dev/null
+++ b/test cases/cuda/4 shared/shared/meson.build
@@ -0,0 +1,7 @@
+libkernels = shared_library('kernels', 'kernels.cu',
+ cuda_args: ['-DTAG_IS_SHARED=1', '-DTAG_IS_BUILDING=1'],
+ gnu_symbol_visibility: 'hidden',
+ soversion : 1,
+ version : '1.2.3')
+libkernels = declare_dependency(compile_args: ['-DTAG_IS_SHARED=1'],
+ link_with: libkernels)
diff --git a/test cases/cuda/5 threads/main.cu b/test cases/cuda/5 threads/main.cu
new file mode 100644
index 0000000..1235914
--- /dev/null
+++ b/test cases/cuda/5 threads/main.cu
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <cuda_runtime.h>
+#include "shared/kernels.h"
+
+
+int main(void) {
+ int cuda_devices = 0;
+ cudaGetDeviceCount(&cuda_devices);
+ if(cuda_devices == 0) {
+ printf("No Cuda hardware found. Exiting.\n");
+ return 0;
+ }
+
+ if(run_tests() != 0){
+ printf("CUDA tests failed! Exiting.\n");
+ return 0;
+ }
+
+ return 0;
+}
diff --git a/test cases/cuda/5 threads/meson.build b/test cases/cuda/5 threads/meson.build
new file mode 100644
index 0000000..2a804a3
--- /dev/null
+++ b/test cases/cuda/5 threads/meson.build
@@ -0,0 +1,7 @@
+project('simple', 'cuda', version : '1.0.0')
+
+subdir('shared')
+
+thread_dep = dependency('threads')
+exe = executable('prog', 'main.cu', dependencies: [libkernels, thread_dep])
+test('cudatest', exe)
diff --git a/test cases/cuda/5 threads/shared/kernels.cu b/test cases/cuda/5 threads/shared/kernels.cu
new file mode 100644
index 0000000..5cda629
--- /dev/null
+++ b/test cases/cuda/5 threads/shared/kernels.cu
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <cuda_runtime.h>
+#include "kernels.h"
+
+
+TAG_HIDDEN __global__ void kernel (void){
+}
+
+TAG_PUBLIC int run_tests(void) {
+ kernel<<<1,1>>>();
+
+ return (int)cudaDeviceSynchronize();
+}
diff --git a/test cases/cuda/5 threads/shared/kernels.h b/test cases/cuda/5 threads/shared/kernels.h
new file mode 100644
index 0000000..dbcb99d
--- /dev/null
+++ b/test cases/cuda/5 threads/shared/kernels.h
@@ -0,0 +1,86 @@
+/* Include Guard */
+#ifndef SHARED_KERNELS_H
+#define SHARED_KERNELS_H
+
+/**
+ * Includes
+ */
+
+#include <cuda_runtime.h>
+
+
+/**
+ * Defines
+ */
+
+/**
+ * When building a library, it is a good idea to expose as few as possible
+ * internal symbols (functions, objects, data structures). Not only does it
+ * prevent users from relying on private portions of the library that are
+ * subject to change without any notice, but it can have performance
+ * advantages:
+ *
+ * - It can make shared libraries link faster at dynamic-load time.
+ * - It can make internal function calls faster by bypassing the PLT.
+ *
+ * Thus, the compilation should by default hide all symbols, while the API
+ * headers will explicitly mark public the few symbols the users are permitted
+ * to use with a PUBLIC tag. We also define a HIDDEN tag, since it may be
+ * required to explicitly tag certain C++ types as visible in order for
+ * exceptions to function correctly.
+ *
+ * Additional complexity comes from non-POSIX-compliant systems, which
+ * artificially impose a requirement on knowing whether we are building or
+ * using a DLL.
+ *
+ * The above commentary and below code is inspired from
+ * 'https://gcc.gnu.org/wiki/Visibility'
+ */
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define TAG_ATTRIBUTE_EXPORT __declspec(dllexport)
+# define TAG_ATTRIBUTE_IMPORT __declspec(dllimport)
+# define TAG_ATTRIBUTE_HIDDEN
+#elif __GNUC__ >= 4
+# define TAG_ATTRIBUTE_EXPORT __attribute__((visibility("default")))
+# define TAG_ATTRIBUTE_IMPORT __attribute__((visibility("default")))
+# define TAG_ATTRIBUTE_HIDDEN __attribute__((visibility("hidden")))
+#else
+# define TAG_ATTRIBUTE_EXPORT
+# define TAG_ATTRIBUTE_IMPORT
+# define TAG_ATTRIBUTE_HIDDEN
+#endif
+
+#if TAG_IS_SHARED
+# if TAG_IS_BUILDING
+# define TAG_PUBLIC TAG_ATTRIBUTE_EXPORT
+# else
+# define TAG_PUBLIC TAG_ATTRIBUTE_IMPORT
+# endif
+# define TAG_HIDDEN TAG_ATTRIBUTE_HIDDEN
+#else
+# define TAG_PUBLIC
+# define TAG_HIDDEN
+#endif
+#define TAG_STATIC static
+
+
+
+
+/* Extern "C" Guard */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/* Function Prototypes */
+TAG_PUBLIC int run_tests(void);
+
+
+
+/* End Extern "C" and Include Guard */
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/test cases/cuda/5 threads/shared/meson.build b/test cases/cuda/5 threads/shared/meson.build
new file mode 100644
index 0000000..5987916
--- /dev/null
+++ b/test cases/cuda/5 threads/shared/meson.build
@@ -0,0 +1,5 @@
+libkernels = shared_library('kernels', 'kernels.cu',
+ cuda_args: ['-DTAG_IS_SHARED=1', '-DTAG_IS_BUILDING=1'],
+ gnu_symbol_visibility: 'hidden')
+libkernels = declare_dependency(compile_args: ['-DTAG_IS_SHARED=1'],
+ link_with: libkernels)
diff --git a/test cases/cuda/6 std/main.cu b/test cases/cuda/6 std/main.cu
new file mode 100644
index 0000000..a2ffba4
--- /dev/null
+++ b/test cases/cuda/6 std/main.cu
@@ -0,0 +1,20 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+auto cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << "Cuda devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/6 std/meson.build b/test cases/cuda/6 std/meson.build
new file mode 100644
index 0000000..69a6868
--- /dev/null
+++ b/test cases/cuda/6 std/meson.build
@@ -0,0 +1,4 @@
+project('C++ std', 'cuda', version : '1.0.0', default_options : ['cuda_std=c++14'])
+
+exe = executable('prog', 'main.cu')
+test('cudatest', exe)
diff --git a/test cases/cuda/7 static vs runtime/main.cu b/test cases/cuda/7 static vs runtime/main.cu
new file mode 100644
index 0000000..bd1dbc4
--- /dev/null
+++ b/test cases/cuda/7 static vs runtime/main.cu
@@ -0,0 +1,20 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << "Cuda devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/7 static vs runtime/meson.build b/test cases/cuda/7 static vs runtime/meson.build
new file mode 100644
index 0000000..ab13304
--- /dev/null
+++ b/test cases/cuda/7 static vs runtime/meson.build
@@ -0,0 +1,4 @@
+project('static msvc runtime', 'cuda', version : '1.0.0', default_options : ['b_vscrt=mtd'])
+
+exe = executable('prog', 'main.cu')
+test('cudatest', exe)
diff --git a/test cases/cuda/8 release/main.cu b/test cases/cuda/8 release/main.cu
new file mode 100644
index 0000000..2a98874
--- /dev/null
+++ b/test cases/cuda/8 release/main.cu
@@ -0,0 +1,24 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+#ifndef NDEBUG
+#error "NDEBUG not defined, this is a Meson bug"
+#endif
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << "Cuda devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/8 release/meson.build b/test cases/cuda/8 release/meson.build
new file mode 100644
index 0000000..c5cad32
--- /dev/null
+++ b/test cases/cuda/8 release/meson.build
@@ -0,0 +1,10 @@
+project('release', 'cpp', 'cuda', version : '1.0.0', default_options : ['buildtype=release', 'b_ndebug=if-release'])
+
+# We don't actually need boost, but it serves as a common dependency
+# that has the potential to add "-isystem/usr/include" to the compile
+# line. By making it optional, we test that system search paths get
+# removed without unnecessarily failing the test if boost is absent.
+boost_dep = dependency('boost', include_type : 'system', required : false)
+
+exe = executable('prog', 'main.cu', dependencies : boost_dep)
+test('cudatest', exe)
diff --git a/test cases/cuda/9 optimize for space/main.cu b/test cases/cuda/9 optimize for space/main.cu
new file mode 100644
index 0000000..bd1dbc4
--- /dev/null
+++ b/test cases/cuda/9 optimize for space/main.cu
@@ -0,0 +1,20 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+int cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << "Cuda devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/9 optimize for space/meson.build b/test cases/cuda/9 optimize for space/meson.build
new file mode 100644
index 0000000..cd6ac05
--- /dev/null
+++ b/test cases/cuda/9 optimize for space/meson.build
@@ -0,0 +1,4 @@
+project('optimize for space', 'cuda', version : '1.0.0', default_options : ['optimization=s'])
+
+exe = executable('prog', 'main.cu')
+test('cudatest', exe)
diff --git a/test cases/cython/1 basic/cytest.py b/test cases/cython/1 basic/cytest.py
new file mode 100755
index 0000000..c08ffee
--- /dev/null
+++ b/test cases/cython/1 basic/cytest.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+from storer import Storer
+
+s = Storer()
+
+if s.get_value() != 0:
+ raise SystemExit('Initial value incorrect.')
+
+s.set_value(42)
+
+if s.get_value() != 42:
+ raise SystemExit('Setting value failed.')
+
+try:
+ s.set_value('not a number')
+ raise SystemExit('Using wrong argument type did not fail.')
+except TypeError:
+ pass
diff --git a/test cases/cython/1 basic/libdir/cstorer.pxd b/test cases/cython/1 basic/libdir/cstorer.pxd
new file mode 100644
index 0000000..7b730fc
--- /dev/null
+++ b/test cases/cython/1 basic/libdir/cstorer.pxd
@@ -0,0 +1,9 @@
+
+cdef extern from "storer.h":
+ ctypedef struct Storer:
+ pass
+
+ Storer* storer_new();
+ void storer_destroy(Storer *s);
+ int storer_get_value(Storer *s);
+ void storer_set_value(Storer *s, int v);
diff --git a/test cases/cython/1 basic/libdir/meson.build b/test cases/cython/1 basic/libdir/meson.build
new file mode 100644
index 0000000..144bb1f
--- /dev/null
+++ b/test cases/cython/1 basic/libdir/meson.build
@@ -0,0 +1,8 @@
+slib = py3.extension_module(
+ 'storer',
+ 'storer.pyx',
+ 'storer.c',
+ dependencies : py3_dep
+)
+
+pydir = meson.current_build_dir()
diff --git a/test cases/cython/1 basic/libdir/storer.c b/test cases/cython/1 basic/libdir/storer.c
new file mode 100644
index 0000000..0199bb8
--- /dev/null
+++ b/test cases/cython/1 basic/libdir/storer.c
@@ -0,0 +1,24 @@
+#include"storer.h"
+#include<stdlib.h>
+
+struct _Storer {
+ int value;
+};
+
+Storer* storer_new() {
+ Storer *s = malloc(sizeof(struct _Storer));
+ s->value = 0;
+ return s;
+}
+
+void storer_destroy(Storer *s) {
+ free(s);
+}
+
+int storer_get_value(Storer *s) {
+ return s->value;
+}
+
+void storer_set_value(Storer *s, int v) {
+ s->value = v;
+}
diff --git a/test cases/cython/1 basic/libdir/storer.h b/test cases/cython/1 basic/libdir/storer.h
new file mode 100644
index 0000000..6f5bc6f
--- /dev/null
+++ b/test cases/cython/1 basic/libdir/storer.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _Storer Storer;
+
+Storer* storer_new();
+void storer_destroy(Storer *s);
+int storer_get_value(Storer *s);
+void storer_set_value(Storer *s, int v);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test cases/cython/1 basic/libdir/storer.pyx b/test cases/cython/1 basic/libdir/storer.pyx
new file mode 100644
index 0000000..ed551dc
--- /dev/null
+++ b/test cases/cython/1 basic/libdir/storer.pyx
@@ -0,0 +1,16 @@
+cimport cstorer
+
+cdef class Storer:
+ cdef cstorer.Storer* _c_storer
+
+ def __cinit__(self):
+ self._c_storer = cstorer.storer_new()
+
+ def __dealloc__(self):
+ cstorer.storer_destroy(self._c_storer)
+
+ cpdef int get_value(self):
+ return cstorer.storer_get_value(self._c_storer)
+
+ cpdef set_value(self, int value):
+ cstorer.storer_set_value(self._c_storer, value)
diff --git a/test cases/cython/1 basic/meson.build b/test cases/cython/1 basic/meson.build
new file mode 100644
index 0000000..8c24e23
--- /dev/null
+++ b/test cases/cython/1 basic/meson.build
@@ -0,0 +1,20 @@
+project(
+ 'basic cython project',
+ ['cython', 'c'],
+ default_options : ['warning_level=3']
+)
+
+py_mod = import('python')
+py3 = py_mod.find_installation()
+py3_dep = py3.dependency(required : false)
+if not py3_dep.found()
+ error('MESON_SKIP_TEST: Python library not found.')
+endif
+
+subdir('libdir')
+
+test('cython tester',
+ py3,
+ args : files('cytest.py'),
+ env : ['PYTHONPATH=' + pydir]
+)
diff --git a/test cases/cython/1 basic/test.json b/test cases/cython/1 basic/test.json
new file mode 100644
index 0000000..ed7ac2b
--- /dev/null
+++ b/test cases/cython/1 basic/test.json
@@ -0,0 +1,10 @@
+{
+ "matrix": {
+ "options": {
+ "cython_language": [
+ { "val": "c" },
+ { "val": "cpp" }
+ ]
+ }
+ }
+}
diff --git a/test cases/cython/2 generated sources/configure.pyx.in b/test cases/cython/2 generated sources/configure.pyx.in
new file mode 100644
index 0000000..1c44f6d
--- /dev/null
+++ b/test cases/cython/2 generated sources/configure.pyx.in
@@ -0,0 +1,2 @@
+cpdef func():
+ return "Hello, World!"
diff --git a/test cases/cython/2 generated sources/g.in b/test cases/cython/2 generated sources/g.in
new file mode 100644
index 0000000..1c44f6d
--- /dev/null
+++ b/test cases/cython/2 generated sources/g.in
@@ -0,0 +1,2 @@
+cpdef func():
+ return "Hello, World!"
diff --git a/test cases/cython/2 generated sources/gen.py b/test cases/cython/2 generated sources/gen.py
new file mode 100644
index 0000000..5c0a82d
--- /dev/null
+++ b/test cases/cython/2 generated sources/gen.py
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: Apache-2.0
+
+import argparse
+import textwrap
+
+parser = argparse.ArgumentParser()
+parser.add_argument('output')
+args = parser.parse_args()
+
+with open(args.output, 'w') as f:
+ f.write(textwrap.dedent('''\
+ cpdef func():
+ return "Hello, World!"
+ '''))
diff --git a/test cases/cython/2 generated sources/generator.py b/test cases/cython/2 generated sources/generator.py
new file mode 100755
index 0000000..9b0d94a
--- /dev/null
+++ b/test cases/cython/2 generated sources/generator.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
+
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument('input')
+parser.add_argument('output')
+args = parser.parse_args()
+
+with open(args.input) as i, open(args.output, 'w') as o:
+ o.write(i.read())
diff --git a/test cases/cython/2 generated sources/includestuff.pyx b/test cases/cython/2 generated sources/includestuff.pyx
new file mode 100644
index 0000000..83f881b
--- /dev/null
+++ b/test cases/cython/2 generated sources/includestuff.pyx
@@ -0,0 +1 @@
+include "stuff.pxi"
diff --git a/test cases/cython/2 generated sources/libdir/gen.py b/test cases/cython/2 generated sources/libdir/gen.py
new file mode 100644
index 0000000..5c0a82d
--- /dev/null
+++ b/test cases/cython/2 generated sources/libdir/gen.py
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: Apache-2.0
+
+import argparse
+import textwrap
+
+parser = argparse.ArgumentParser()
+parser.add_argument('output')
+args = parser.parse_args()
+
+with open(args.output, 'w') as f:
+ f.write(textwrap.dedent('''\
+ cpdef func():
+ return "Hello, World!"
+ '''))
diff --git a/test cases/cython/2 generated sources/libdir/meson.build b/test cases/cython/2 generated sources/libdir/meson.build
new file mode 100644
index 0000000..e9259bd
--- /dev/null
+++ b/test cases/cython/2 generated sources/libdir/meson.build
@@ -0,0 +1,10 @@
+ct2 = custom_target(
+ 'ct2',
+ input : 'gen.py',
+ output : 'ct2.pyx',
+ command : [py3, '@INPUT@', '@OUTPUT@'],
+)
+
+ct2_ext = py3.extension_module('ct2', ct2, dependencies : py3_dep)
+
+pydir = meson.current_build_dir()
diff --git a/test cases/cython/2 generated sources/meson.build b/test cases/cython/2 generated sources/meson.build
new file mode 100644
index 0000000..498e319
--- /dev/null
+++ b/test cases/cython/2 generated sources/meson.build
@@ -0,0 +1,105 @@
+project(
+ 'generated cython sources',
+ ['cython'],
+)
+
+py_mod = import('python')
+py3 = py_mod.find_installation('python3')
+py3_dep = py3.dependency(required : false)
+fs = import('fs')
+if not py3_dep.found()
+ error('MESON_SKIP_TEST: Python library not found.')
+endif
+
+ct = custom_target(
+ 'ct',
+ input : 'gen.py',
+ output : 'ct.pyx',
+ command : [py3, '@INPUT@', '@OUTPUT@'],
+)
+
+ct_ext = py3.extension_module('ct', ct, dependencies : py3_dep)
+
+test(
+ 'custom target',
+ py3,
+ args : [files('test.py'), 'ct'],
+ env : ['PYTHONPATH=' + meson.current_build_dir()]
+)
+
+# Test a CustomTargetIndex
+cti = custom_target(
+ 'cti',
+ input : 'gen.py',
+ output : 'cti.pyx',
+ command : [py3, '@INPUT@', '@OUTPUT@'],
+)
+
+cti_ext = py3.extension_module('cti', cti[0], dependencies : py3_dep)
+
+cf = configure_file(
+ input : 'configure.pyx.in',
+ output : 'cf.pyx',
+ copy : true,
+)
+
+cf_ext = py3.extension_module('cf', cf, dependencies : py3_dep)
+
+test(
+ 'configure file',
+ py3,
+ args : [files('test.py'), 'cf'],
+ env : ['PYTHONPATH=' + meson.current_build_dir()]
+)
+
+gen = generator(
+ find_program('generator.py'),
+ arguments : ['@INPUT@', '@OUTPUT@'],
+ output : '@BASENAME@.pyx',
+)
+
+g_ext = py3.extension_module(
+ 'g',
+ gen.process('g.in'),
+ dependencies : py3_dep,
+)
+
+test(
+ 'generator',
+ py3,
+ args : [files('test.py'), 'g'],
+ env : ['PYTHONPATH=' + meson.current_build_dir()]
+)
+
+stuff_pxi = fs.copyfile(
+ 'stuff.pxi.in',
+ 'stuff.pxi'
+)
+
+# Need to copy the cython source to the build directory
+# since meson can only generate the .pxi there
+includestuff_pyx = fs.copyfile(
+ 'includestuff.pyx'
+)
+
+stuff_pxi_dep = declare_dependency(sources: stuff_pxi)
+
+includestuff_ext = py3.extension_module(
+ 'includestuff',
+ includestuff_pyx,
+ dependencies: stuff_pxi_dep
+)
+
+simpleinclude_ext = py3.extension_module(
+ 'simpleinclude',
+ 'simpleinclude.pyx',
+)
+
+subdir('libdir')
+
+test(
+ 'custom target in subdir',
+ py3,
+ args : [files('test.py'), 'ct2'],
+ env : ['PYTHONPATH=' + pydir]
+)
diff --git a/test cases/cython/2 generated sources/simpleinclude.pyx b/test cases/cython/2 generated sources/simpleinclude.pyx
new file mode 100644
index 0000000..c110f75
--- /dev/null
+++ b/test cases/cython/2 generated sources/simpleinclude.pyx
@@ -0,0 +1 @@
+include "simplestuff.pxi"
diff --git a/test cases/cython/2 generated sources/simplestuff.pxi b/test cases/cython/2 generated sources/simplestuff.pxi
new file mode 100644
index 0000000..2645216
--- /dev/null
+++ b/test cases/cython/2 generated sources/simplestuff.pxi
@@ -0,0 +1,2 @@
+def func2():
+ print("Hello world")
diff --git a/test cases/cython/2 generated sources/stuff.pxi.in b/test cases/cython/2 generated sources/stuff.pxi.in
new file mode 100644
index 0000000..6417cbc
--- /dev/null
+++ b/test cases/cython/2 generated sources/stuff.pxi.in
@@ -0,0 +1,2 @@
+def func():
+ print("Hello world")
diff --git a/test cases/cython/2 generated sources/test.py b/test cases/cython/2 generated sources/test.py
new file mode 100644
index 0000000..307283f
--- /dev/null
+++ b/test cases/cython/2 generated sources/test.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
+
+import argparse
+import importlib
+
+parser = argparse.ArgumentParser()
+parser.add_argument('mod')
+args = parser.parse_args()
+
+mod = importlib.import_module(args.mod)
+
+assert mod.func() == 'Hello, World!'
diff --git a/test cases/cython/3 cython_args/cythonargs.pyx b/test cases/cython/3 cython_args/cythonargs.pyx
new file mode 100644
index 0000000..2b220a7
--- /dev/null
+++ b/test cases/cython/3 cython_args/cythonargs.pyx
@@ -0,0 +1,5 @@
+def test():
+ IF VALUE:
+ return 1
+ ELSE:
+ return 0
diff --git a/test cases/cython/3 cython_args/meson.build b/test cases/cython/3 cython_args/meson.build
new file mode 100644
index 0000000..e41d1b7
--- /dev/null
+++ b/test cases/cython/3 cython_args/meson.build
@@ -0,0 +1,30 @@
+project('cython_args', ['cython', 'c'])
+
+pymod = import('python')
+python = pymod.find_installation('python3')
+python_dep = python.dependency()
+if not python_dep.found()
+ error('MESON_SKIP_TEST: Python library not found.')
+endif
+
+mod = python.extension_module(
+ 'cythonargs',
+ files('cythonargs.pyx'),
+ cython_args: [
+ '--compile-time-env',
+ 'VALUE=1'
+ ],
+ dependencies: [python_dep]
+)
+
+test(
+ 'test',
+ python,
+ args: [
+ 'test.py'
+ ],
+ workdir: meson.current_source_dir(),
+ env: environment({
+ 'PYTHONPATH': meson.current_build_dir(),
+ })
+)
diff --git a/test cases/cython/3 cython_args/test.py b/test cases/cython/3 cython_args/test.py
new file mode 100644
index 0000000..bd8a152
--- /dev/null
+++ b/test cases/cython/3 cython_args/test.py
@@ -0,0 +1,3 @@
+import cythonargs
+
+assert cythonargs.test() == 1
diff --git a/test cases/d/1 simple/app.d b/test cases/d/1 simple/app.d
new file mode 100644
index 0000000..0be1d2c
--- /dev/null
+++ b/test cases/d/1 simple/app.d
@@ -0,0 +1,8 @@
+
+import std.stdio;
+import utils;
+
+void main ()
+{
+ printGreeting ("a Meson D test");
+}
diff --git a/test cases/d/1 simple/meson.build b/test cases/d/1 simple/meson.build
new file mode 100644
index 0000000..a10b67b
--- /dev/null
+++ b/test cases/d/1 simple/meson.build
@@ -0,0 +1,4 @@
+project('D Simple Test', 'd')
+
+e = executable('dsimpleapp', ['app.d', 'utils.d'], install : true)
+test('apptest', e)
diff --git a/test cases/d/1 simple/test.json b/test cases/d/1 simple/test.json
new file mode 100644
index 0000000..62f907a
--- /dev/null
+++ b/test cases/d/1 simple/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/dsimpleapp"},
+ {"type": "pdb", "file": "usr/bin/dsimpleapp", "language": "d"}
+ ]
+}
diff --git a/test cases/d/1 simple/utils.d b/test cases/d/1 simple/utils.d
new file mode 100644
index 0000000..8645548
--- /dev/null
+++ b/test cases/d/1 simple/utils.d
@@ -0,0 +1,8 @@
+
+import std.stdio;
+import std.string : format;
+
+void printGreeting (string name)
+{
+ writeln ("Hello, I am %s.".format (name));
+}
diff --git a/test cases/d/10 d cpp/cppmain.cpp b/test cases/d/10 d cpp/cppmain.cpp
new file mode 100644
index 0000000..bcd8c7a
--- /dev/null
+++ b/test cases/d/10 d cpp/cppmain.cpp
@@ -0,0 +1,18 @@
+extern "C" int rt_init();
+extern "C" int rt_term();
+extern void print_hello(int i);
+
+int main(int, char**) {
+ // initialize D runtime
+ if (!rt_init())
+ return 1;
+
+ print_hello(1);
+
+ // terminate D runtime, each initialize call
+ // must be paired with a terminate call.
+ if (!rt_term())
+ return 1;
+
+ return 0;
+}
diff --git a/test cases/d/10 d cpp/dmain.d b/test cases/d/10 d cpp/dmain.d
new file mode 100644
index 0000000..bece25f
--- /dev/null
+++ b/test cases/d/10 d cpp/dmain.d
@@ -0,0 +1,5 @@
+extern (C++) void print_hello(int i);
+
+void main() {
+ print_hello(1);
+}
diff --git a/test cases/d/10 d cpp/libfile.cpp b/test cases/d/10 d cpp/libfile.cpp
new file mode 100644
index 0000000..2ea67fc
--- /dev/null
+++ b/test cases/d/10 d cpp/libfile.cpp
@@ -0,0 +1,5 @@
+#include<iostream>
+
+void print_hello(int i) {
+ std::cout << "Hello. Here is a number printed with C++: " << i << ".\n";
+}
diff --git a/test cases/d/10 d cpp/libfile.d b/test cases/d/10 d cpp/libfile.d
new file mode 100644
index 0000000..88cb53e
--- /dev/null
+++ b/test cases/d/10 d cpp/libfile.d
@@ -0,0 +1,5 @@
+import std.stdio;
+
+extern (C++) void print_hello(int i) {
+ writefln("Hello. Here is a number printed with D: %d", i);
+}
diff --git a/test cases/d/10 d cpp/meson.build b/test cases/d/10 d cpp/meson.build
new file mode 100644
index 0000000..eecb151
--- /dev/null
+++ b/test cases/d/10 d cpp/meson.build
@@ -0,0 +1,13 @@
+project('d and c++', 'd', 'cpp')
+
+cpp = meson.get_compiler('cpp')
+
+if cpp.get_id() == 'clang'
+ error('MESON_SKIP_TEST combining Clang C++ with GDC produces broken executables.')
+endif
+
+e1 = executable('dcpp', 'dmain.d', 'libfile.cpp')
+test('dcpp', e1)
+
+e2 = executable('cppd', 'cppmain.cpp', 'libfile.d')
+test('cppd', e2)
diff --git a/test cases/d/11 dub/.gitignore b/test cases/d/11 dub/.gitignore
new file mode 100644
index 0000000..da3feeb
--- /dev/null
+++ b/test cases/d/11 dub/.gitignore
@@ -0,0 +1 @@
+dub.json
diff --git a/test cases/d/11 dub/meson.build b/test cases/d/11 dub/meson.build
new file mode 100644
index 0000000..d852ca0
--- /dev/null
+++ b/test cases/d/11 dub/meson.build
@@ -0,0 +1,23 @@
+project('dub-example', 'd')
+
+dub_exe = find_program('dub', required : false)
+if not dub_exe.found()
+ error('MESON_SKIP_TEST: Dub not found')
+endif
+
+urld_dep = dependency('urld', method: 'dub')
+
+test_exe = executable('test-urld', 'test.d', dependencies: urld_dep)
+test('test urld', test_exe)
+
+# If you want meson to generate/update a dub.json file
+dlang = import('dlang')
+dlang.generate_dub_file(meson.project_name().to_lower(), meson.source_root(),
+ authors: 'Meson Team',
+ description: 'Test executable',
+ copyright: 'Copyright © 2018, Meson Team',
+ license: 'MIT',
+ sourceFiles: 'test.d',
+ targetType: 'executable',
+ dependencies: urld_dep
+) \ No newline at end of file
diff --git a/test cases/d/11 dub/test.d b/test cases/d/11 dub/test.d
new file mode 100644
index 0000000..7cf7a1d
--- /dev/null
+++ b/test cases/d/11 dub/test.d
@@ -0,0 +1,14 @@
+import std.stdio;
+import url;
+
+void main() {
+ URL url;
+ with (url) {
+ scheme = "soap.beep";
+ host = "beep.example.net";
+ port = 1772;
+ path = "/serverinfo/info";
+ queryParams.add("token", "my-api-token");
+ }
+ writeln(url);
+} \ No newline at end of file
diff --git a/test cases/d/12 root include directory/meson.build b/test cases/d/12 root include directory/meson.build
new file mode 100644
index 0000000..9501615
--- /dev/null
+++ b/test cases/d/12 root include directory/meson.build
@@ -0,0 +1,7 @@
+project('some', 'd')
+
+project_dep = declare_dependency(
+ include_directories: ['.'],
+)
+subdir('some')
+
diff --git a/test cases/d/12 root include directory/some/dlang/code.d b/test cases/d/12 root include directory/some/dlang/code.d
new file mode 100644
index 0000000..0dd82a4
--- /dev/null
+++ b/test cases/d/12 root include directory/some/dlang/code.d
@@ -0,0 +1,7 @@
+void foo() {}
+
+version (Windows)
+{
+ import core.sys.windows.dll;
+ mixin SimpleDllMain;
+}
diff --git a/test cases/d/12 root include directory/some/dlang/meson.build b/test cases/d/12 root include directory/some/dlang/meson.build
new file mode 100644
index 0000000..3f958b1
--- /dev/null
+++ b/test cases/d/12 root include directory/some/dlang/meson.build
@@ -0,0 +1,8 @@
+code_lib = library('code',
+ ['code.d'],
+ dependencies: [project_dep])
+
+code_dep = declare_dependency(
+ link_with: code_lib,
+ dependencies: project_dep
+) \ No newline at end of file
diff --git a/test cases/d/12 root include directory/some/meson.build b/test cases/d/12 root include directory/some/meson.build
new file mode 100644
index 0000000..a549c09
--- /dev/null
+++ b/test cases/d/12 root include directory/some/meson.build
@@ -0,0 +1 @@
+subdir('dlang') \ No newline at end of file
diff --git a/test cases/d/13 declare dep/meson.build b/test cases/d/13 declare dep/meson.build
new file mode 100644
index 0000000..eef9816
--- /dev/null
+++ b/test cases/d/13 declare dep/meson.build
@@ -0,0 +1,13 @@
+project('meson-d-sample', 'd',
+ version: '0.1.0',
+)
+
+my_dep = declare_dependency(
+ d_module_versions: ['TestVersion', 1],
+ d_import_dirs: include_directories('views'),
+)
+
+test_exe = executable('test-dep', 'test.d',
+ dependencies: my_dep,
+)
+test('test d features in declare_dependency', test_exe)
diff --git a/test cases/d/13 declare dep/test.d b/test cases/d/13 declare dep/test.d
new file mode 100644
index 0000000..3a89921
--- /dev/null
+++ b/test cases/d/13 declare dep/test.d
@@ -0,0 +1,15 @@
+module test;
+
+
+int main()
+{
+ version(TestVersion)
+ {
+ enum testPhrase = import("test.txt");
+ return testPhrase == "TEST PHRASE" ? 0 : 1;
+ }
+ else
+ {
+ return 1;
+ }
+}
diff --git a/test cases/d/13 declare dep/views/test.txt b/test cases/d/13 declare dep/views/test.txt
new file mode 100644
index 0000000..19046d0
--- /dev/null
+++ b/test cases/d/13 declare dep/views/test.txt
@@ -0,0 +1 @@
+TEST PHRASE \ No newline at end of file
diff --git a/test cases/d/14 dub with deps/meson.build b/test cases/d/14 dub with deps/meson.build
new file mode 100644
index 0000000..08f3080
--- /dev/null
+++ b/test cases/d/14 dub with deps/meson.build
@@ -0,0 +1,34 @@
+project('dub-with-deps-example', ['d'])
+
+dub_exe = find_program('dub', required : false)
+if not dub_exe.found()
+ error('MESON_SKIP_TEST: Dub not found')
+endif
+
+if meson.get_compiler('d').get_id() == 'gcc'
+ error('MESON_SKIP_TEST: can\'t build dependencies with GDC')
+elif meson.get_compiler('d').get_id() == 'llvm'
+ dc = 'ldc2'
+elif meson.get_compiler('d').get_id() == 'dmd'
+ dc = 'dmd'
+endif
+
+arch = host_machine.cpu_family()
+
+if host_machine.system() == 'windows'
+ # check if toolchain is 32bits
+ sz = meson.get_compiler('d').sizeof('void*')
+ if arch == 'x86' or sz == 4
+ arch = 'x86_mscoff'
+ endif
+endif
+
+run_command('dub', 'run', 'dub-build-deep', '--yes', '--', 'xlsx', '--compiler', dc, '--arch', arch,
+ check: true,
+)
+
+xlsx_dep = dependency('xlsx', method: 'dub')
+
+test_exe = executable('test-test6', 'test.d', dependencies: xlsx_dep)
+
+test('test dub with deps', test_exe)
diff --git a/test cases/d/14 dub with deps/test.d b/test cases/d/14 dub with deps/test.d
new file mode 100644
index 0000000..61b5bda
--- /dev/null
+++ b/test cases/d/14 dub with deps/test.d
@@ -0,0 +1,59 @@
+module test;
+
+// testing import dirs
+import xlsx;
+
+// dependency of xlsx
+import dxml.dom;
+
+const xml = "<!-- comment -->\n" ~
+ "<root>\n" ~
+ " <foo>some text<whatever/></foo>\n" ~
+ " <bar/>\n" ~
+ " <baz></baz>\n" ~
+ "</root>";
+
+int main()
+{
+ // testing versions
+ version (Have_dxml)
+ {
+ import std.range.primitives : empty;
+
+ auto dom = parseDOM(xml);
+ assert(dom.type == EntityType.elementStart);
+ assert(dom.name.empty);
+ assert(dom.children.length == 2);
+
+ assert(dom.children[0].type == EntityType.comment);
+ assert(dom.children[0].text == " comment ");
+
+ auto root = dom.children[1];
+ assert(root.type == EntityType.elementStart);
+ assert(root.name == "root");
+ assert(root.children.length == 3);
+
+ auto foo = root.children[0];
+ assert(foo.type == EntityType.elementStart);
+ assert(foo.name == "foo");
+ assert(foo.children.length == 2);
+
+ assert(foo.children[0].type == EntityType.text);
+ assert(foo.children[0].text == "some text");
+
+ assert(foo.children[1].type == EntityType.elementEmpty);
+ assert(foo.children[1].name == "whatever");
+
+ assert(root.children[1].type == EntityType.elementEmpty);
+ assert(root.children[1].name == "bar");
+
+ assert(root.children[2].type == EntityType.elementStart);
+ assert(root.children[2].name == "baz");
+ assert(root.children[2].children.length == 0);
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
diff --git a/test cases/d/15 compiler run checks/meson.build b/test cases/d/15 compiler run checks/meson.build
new file mode 100644
index 0000000..a80e528
--- /dev/null
+++ b/test cases/d/15 compiler run checks/meson.build
@@ -0,0 +1,50 @@
+project('test-d-run-checks', 'd')
+
+dc = meson.get_compiler('d')
+
+run_sizeof = dc.run('int main() { return (void*).sizeof; }')
+if run_sizeof.returncode() == 8
+ run_versions = ['Is64bits']
+elif run_sizeof.returncode() == 4
+ run_versions = ['Is32bits']
+endif
+run_sizeof_exe = executable('run_sizeof', 'test_sizeof.d',
+ d_module_versions: run_versions,
+)
+test('test D compiler run', run_sizeof_exe)
+
+sizeof_sizeof = dc.sizeof('void*')
+if sizeof_sizeof == 8
+ run_versions = ['Is64bits']
+elif sizeof_sizeof == 4
+ run_versions = ['Is32bits']
+endif
+sizeof_sizeof_exe = executable('sizeof_sizeof', 'test_sizeof.d',
+ d_module_versions: run_versions,
+)
+test('test D compiler sizeof', sizeof_sizeof_exe)
+
+if not dc.has_header('std.stdio')
+ error('Could not find std.stdio import')
+endif
+
+if dc.has_header('not_a_d_module')
+ error('has_header inconsistent result')
+endif
+
+# same checks as C/C++ alignments (D has same alignment requirements as C)
+
+# These tests should return the same value on all
+# platforms. If (and when) they don't, fix 'em up.
+if dc.alignment('char') != 1
+error('Alignment of char misdetected.')
+endif
+
+dbl_alignment = dc.alignment('double')
+
+if dbl_alignment == 8 or dbl_alignment == 4
+message('Alignment of double ok.')
+else
+error('Alignment of double misdetected.')
+endif
+
diff --git a/test cases/d/15 compiler run checks/test_sizeof.d b/test cases/d/15 compiler run checks/test_sizeof.d
new file mode 100644
index 0000000..c7099d0
--- /dev/null
+++ b/test cases/d/15 compiler run checks/test_sizeof.d
@@ -0,0 +1,17 @@
+module test_sizeof;
+
+alias voidp = void*;
+
+int main()
+{
+ version(Is64bits) {
+ enum expectedSz = 8;
+ }
+ else version(Is32bits) {
+ enum expectedSz = 4;
+ }
+ else {
+ assert(false, "No version set!");
+ }
+ return expectedSz == voidp.sizeof ? 0 : 1;
+}
diff --git a/test cases/d/16 code generation/exe.d b/test cases/d/16 code generation/exe.d
new file mode 100644
index 0000000..0e24d6d
--- /dev/null
+++ b/test cases/d/16 code generation/exe.d
@@ -0,0 +1,9 @@
+module exe;
+
+import generated;
+import std.stdio;
+
+int main()
+{
+ return generatedString() == "Some text to be returned by generated code" ? 0 : 1;
+}
diff --git a/test cases/d/16 code generation/generator.d b/test cases/d/16 code generation/generator.d
new file mode 100644
index 0000000..f944dd3
--- /dev/null
+++ b/test cases/d/16 code generation/generator.d
@@ -0,0 +1,13 @@
+module generator;
+
+import std.file;
+import std.stdio;
+import std.string;
+
+void main(string[] args)
+{
+ const text = cast(string)read(args[1]);
+
+ writeln("module generated;");
+ writefln!`string generatedString() { return "%s"; }`(text.strip());
+}
diff --git a/test cases/d/16 code generation/input.txt b/test cases/d/16 code generation/input.txt
new file mode 100644
index 0000000..aebcda8
--- /dev/null
+++ b/test cases/d/16 code generation/input.txt
@@ -0,0 +1 @@
+Some text to be returned by generated code
diff --git a/test cases/d/16 code generation/meson.build b/test cases/d/16 code generation/meson.build
new file mode 100644
index 0000000..2418aca
--- /dev/null
+++ b/test cases/d/16 code generation/meson.build
@@ -0,0 +1,18 @@
+project('meson-dep-test', 'd')
+
+generator = executable('generator', 'generator.d')
+
+generated = custom_target('generated',
+ capture: true,
+ output: 'generated.d',
+ input: 'input.txt',
+ command: [
+ generator, '@INPUT@'
+ ]
+)
+
+exe = executable('exe', generated, 'exe.d',
+ include_directories: include_directories('.'),
+)
+
+test('test exe', exe)
diff --git a/test cases/d/2 static library/app.d b/test cases/d/2 static library/app.d
new file mode 100644
index 0000000..5d84a69
--- /dev/null
+++ b/test cases/d/2 static library/app.d
@@ -0,0 +1,8 @@
+
+import libstuff;
+
+void main ()
+{
+ immutable ret = printLibraryString ("foo");
+ assert (ret == 4);
+}
diff --git a/test cases/d/2 static library/libstuff.d b/test cases/d/2 static library/libstuff.d
new file mode 100644
index 0000000..fd3b4d0
--- /dev/null
+++ b/test cases/d/2 static library/libstuff.d
@@ -0,0 +1,9 @@
+
+import std.stdio;
+import std.string : format;
+
+int printLibraryString (string str)
+{
+ writeln ("Static Library says: %s".format (str));
+ return 4;
+}
diff --git a/test cases/d/2 static library/meson.build b/test cases/d/2 static library/meson.build
new file mode 100644
index 0000000..88ed2cb
--- /dev/null
+++ b/test cases/d/2 static library/meson.build
@@ -0,0 +1,5 @@
+project('D Static Library', 'd')
+
+lstatic = static_library('stuff', 'libstuff.d', install : true)
+es = executable('app_s', 'app.d', link_with : lstatic, install : true)
+test('linktest_static', es)
diff --git a/test cases/d/2 static library/test.json b/test cases/d/2 static library/test.json
new file mode 100644
index 0000000..6abb934
--- /dev/null
+++ b/test cases/d/2 static library/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/app_s"},
+ {"type": "pdb", "file": "usr/bin/app_s", "language": "d"},
+ {"type": "file", "file": "usr/lib/libstuff.a"}
+ ]
+}
diff --git a/test cases/d/3 shared library/app.d b/test cases/d/3 shared library/app.d
new file mode 100644
index 0000000..5d84a69
--- /dev/null
+++ b/test cases/d/3 shared library/app.d
@@ -0,0 +1,8 @@
+
+import libstuff;
+
+void main ()
+{
+ immutable ret = printLibraryString ("foo");
+ assert (ret == 4);
+}
diff --git a/test cases/d/3 shared library/libstuff.d b/test cases/d/3 shared library/libstuff.d
new file mode 100644
index 0000000..8205490
--- /dev/null
+++ b/test cases/d/3 shared library/libstuff.d
@@ -0,0 +1,14 @@
+import std.stdio;
+import std.string : format;
+
+export int printLibraryString (string str)
+{
+ writeln ("Library says: %s".format (str));
+ return 4;
+}
+
+version (Windows)
+{
+ import core.sys.windows.dll;
+ mixin SimpleDllMain;
+}
diff --git a/test cases/d/3 shared library/libstuff.di b/test cases/d/3 shared library/libstuff.di
new file mode 100644
index 0000000..b6454b1
--- /dev/null
+++ b/test cases/d/3 shared library/libstuff.di
@@ -0,0 +1,3 @@
+module libstuff;
+
+int printLibraryString (string str);
diff --git a/test cases/d/3 shared library/lld-test.py b/test cases/d/3 shared library/lld-test.py
new file mode 100644
index 0000000..3f32f59
--- /dev/null
+++ b/test cases/d/3 shared library/lld-test.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import argparse
+import subprocess
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('ldd')
+ parser.add_argument('bin')
+ args = parser.parse_args()
+
+ p, o, _ = subprocess.run([args.ldd, args.bin], stdout=subprocess.PIPE)
+ assert p == 0
+ o = o.decode()
+ assert 'libstuff.so =>' in o, 'libstuff so not in linker path.'
+ assert 'libstuff.so => not found' not in o, 'libstuff.so not found correctly'
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test cases/d/3 shared library/meson.build b/test cases/d/3 shared library/meson.build
new file mode 100644
index 0000000..fa41779
--- /dev/null
+++ b/test cases/d/3 shared library/meson.build
@@ -0,0 +1,26 @@
+project('D Shared Library', 'd')
+
+dc = meson.get_compiler('d')
+if dc.get_id() == 'gcc'
+ if dc.version().version_compare('< 8')
+ error('MESON_SKIP_TEST: GDC < 8.0 can not build shared libraries')
+ endif
+endif
+
+subdir('sub')
+ed = executable('app_d', 'app.d', link_with : ldyn, install : true)
+test('linktest_dyn', ed)
+
+# test D attributes for pkg-config
+pkgc = import('pkgconfig')
+pkgc.generate(name: 'test',
+ libraries: ldyn,
+ subdirs: 'd/stuff',
+ description: 'A test of D attributes to pkgconfig.generate.',
+ d_module_versions: ['Use_Static']
+)
+
+ldd = find_program('ldd', required : false)
+if ldd.found()
+ test('ldd-test.py', ed)
+endif
diff --git a/test cases/d/3 shared library/sub/libstuff.d b/test cases/d/3 shared library/sub/libstuff.d
new file mode 100644
index 0000000..8205490
--- /dev/null
+++ b/test cases/d/3 shared library/sub/libstuff.d
@@ -0,0 +1,14 @@
+import std.stdio;
+import std.string : format;
+
+export int printLibraryString (string str)
+{
+ writeln ("Library says: %s".format (str));
+ return 4;
+}
+
+version (Windows)
+{
+ import core.sys.windows.dll;
+ mixin SimpleDllMain;
+}
diff --git a/test cases/d/3 shared library/sub/meson.build b/test cases/d/3 shared library/sub/meson.build
new file mode 100644
index 0000000..1599a33
--- /dev/null
+++ b/test cases/d/3 shared library/sub/meson.build
@@ -0,0 +1 @@
+ldyn = shared_library('stuff', 'libstuff.d', install : true)
diff --git a/test cases/d/3 shared library/test.json b/test cases/d/3 shared library/test.json
new file mode 100644
index 0000000..50eb9cb
--- /dev/null
+++ b/test cases/d/3 shared library/test.json
@@ -0,0 +1,11 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/app_d"},
+ {"type": "pdb", "file": "usr/bin/app_d", "language": "d"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/stuff"},
+ {"type": "pdb", "file": "usr/bin/stuff", "language": "d"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/stuff"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.lib"},
+ {"type": "file", "file": "usr/lib/pkgconfig/test.pc"}
+ ]
+}
diff --git a/test cases/d/4 library versions/lib.d b/test cases/d/4 library versions/lib.d
new file mode 100644
index 0000000..f1e177d
--- /dev/null
+++ b/test cases/d/4 library versions/lib.d
@@ -0,0 +1,16 @@
+
+import std.stdio;
+import std.string : format;
+
+@safe
+export int printLibraryString (string str)
+{
+ writeln ("Library says: %s".format (str));
+ return 4;
+}
+
+version (Windows)
+{
+ import core.sys.windows.dll;
+ mixin SimpleDllMain;
+}
diff --git a/test cases/d/4 library versions/meson.build b/test cases/d/4 library versions/meson.build
new file mode 100644
index 0000000..c745b92
--- /dev/null
+++ b/test cases/d/4 library versions/meson.build
@@ -0,0 +1,25 @@
+project('D library versions', 'd')
+
+dc = meson.get_compiler('d')
+if dc.get_id() == 'gcc'
+ if dc.version().version_compare('< 8')
+ error('MESON_SKIP_TEST: GDC < 8.0 can not build shared libraries')
+ endif
+endif
+
+shared_library('some', 'lib.d',
+ version : '1.2.3',
+ soversion : '0',
+ install : true)
+
+shared_library('noversion', 'lib.d',
+ install : true)
+
+shared_library('onlyversion', 'lib.d',
+ version : '1.4.5',
+ install : true)
+
+shared_library('onlysoversion', 'lib.d',
+ # Also test that int soversion is acceptable
+ soversion : 5,
+ install : true)
diff --git a/test cases/d/4 library versions/test.json b/test cases/d/4 library versions/test.json
new file mode 100644
index 0000000..23c95dd
--- /dev/null
+++ b/test cases/d/4 library versions/test.json
@@ -0,0 +1,25 @@
+{
+ "installed": [
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/some"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/some", "version": "0"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/some", "version": "1.2.3"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/noversion"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/onlyversion"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/onlyversion", "version": "1"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/onlyversion", "version": "1.4.5"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/onlysoversion"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/onlysoversion", "version": "5"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/noversion"},
+ {"type": "pdb", "file": "usr/bin/noversion", "language": "d"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/onlysoversion", "version": "5"},
+ {"type": "pdb", "file": "usr/bin/onlysoversion", "version": "5", "language": "d"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/onlyversion", "version": "1"},
+ {"type": "pdb", "file": "usr/bin/onlyversion", "version": "1", "language": "d"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/some", "version": "0"},
+ {"type": "pdb", "file": "usr/bin/some", "version": "0", "language": "d"},
+ {"type": "implib", "file": "usr/lib/noversion"},
+ {"type": "implib", "file": "usr/lib/onlysoversion"},
+ {"type": "implib", "file": "usr/lib/onlyversion"},
+ {"type": "implib", "file": "usr/lib/some"}
+ ]
+}
diff --git a/test cases/d/5 mixed/app.d b/test cases/d/5 mixed/app.d
new file mode 100644
index 0000000..6ab5d97
--- /dev/null
+++ b/test cases/d/5 mixed/app.d
@@ -0,0 +1,8 @@
+
+extern(C) int printLibraryString(const char *str);
+
+void main ()
+{
+ immutable ret = printLibraryString ("C foo");
+ assert (ret == 3);
+}
diff --git a/test cases/d/5 mixed/libstuff.c b/test cases/d/5 mixed/libstuff.c
new file mode 100644
index 0000000..92d6600
--- /dev/null
+++ b/test cases/d/5 mixed/libstuff.c
@@ -0,0 +1,18 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+#include <stdio.h>
+
+int DLL_PUBLIC printLibraryString(const char *str)
+{
+ printf("C library says: %s", str);
+ return 3;
+}
diff --git a/test cases/d/5 mixed/meson.build b/test cases/d/5 mixed/meson.build
new file mode 100644
index 0000000..3dad66d
--- /dev/null
+++ b/test cases/d/5 mixed/meson.build
@@ -0,0 +1,9 @@
+project('Mixing C and D', 'd', 'c')
+
+ldyn = shared_library('stuff', 'libstuff.c', install : true)
+ed = executable('appdc_d', 'app.d', link_with : ldyn, install : true)
+test('linktest_cdyn', ed)
+
+lstatic = static_library('stuff', 'libstuff.c', install : true)
+es = executable('appdc_s', 'app.d', link_with : lstatic, install : true)
+test('linktest_cstatic', es)
diff --git a/test cases/d/5 mixed/test.json b/test cases/d/5 mixed/test.json
new file mode 100644
index 0000000..c95d0ca
--- /dev/null
+++ b/test cases/d/5 mixed/test.json
@@ -0,0 +1,13 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/appdc_d"},
+ {"type": "pdb", "file": "usr/bin/appdc_d", "language": "d"},
+ {"type": "exe", "file": "usr/bin/appdc_s"},
+ {"type": "pdb", "file": "usr/bin/appdc_s", "language": "d"},
+ {"type": "file", "file": "usr/lib/libstuff.a"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/stuff"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/stuff"},
+ {"type": "pdb", "file": "usr/bin/stuff", "language": "c"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.lib"}
+ ]
+}
diff --git a/test cases/d/6 unittest/app.d b/test cases/d/6 unittest/app.d
new file mode 100644
index 0000000..71c6414
--- /dev/null
+++ b/test cases/d/6 unittest/app.d
@@ -0,0 +1,38 @@
+
+import std.stdio;
+
+uint getFour ()
+{
+ auto getTwo ()
+ {
+ return 1 + 1;
+ }
+
+ return getTwo () + getTwo ();
+}
+
+void main ()
+{
+ import core.stdc.stdlib : exit;
+
+ writeln ("Four: ", getFour ());
+ exit (4);
+}
+
+unittest
+{
+ writeln ("TEST");
+ import core.stdc.stdlib : exit;
+ import second_unit;
+
+ assert (getFour () > 2);
+ assert (getFour () == 4);
+
+ // this is a regression test for https://github.com/mesonbuild/meson/issues/3337
+ secondModuleTestFunc ();
+
+ // we explicitly terminate here to give the unittest program a different exit
+ // code than the main application has.
+ // (this prevents the regular main() from being executed)
+ exit (0);
+}
diff --git a/test cases/d/6 unittest/meson.build b/test cases/d/6 unittest/meson.build
new file mode 100644
index 0000000..49a0700
--- /dev/null
+++ b/test cases/d/6 unittest/meson.build
@@ -0,0 +1,8 @@
+project('D Unittests', 'd')
+
+e = executable('dapp', ['app.d', 'second_unit.d'], install : true)
+test('dapp_run', e, should_fail: true)
+
+e_test = executable('dapp_test', ['app.d', 'second_unit.d'],
+ d_unittest: true)
+test('dapp_test', e_test)
diff --git a/test cases/d/6 unittest/second_unit.d b/test cases/d/6 unittest/second_unit.d
new file mode 100644
index 0000000..fdb62a9
--- /dev/null
+++ b/test cases/d/6 unittest/second_unit.d
@@ -0,0 +1,10 @@
+
+void secondModuleTestFunc ()
+{
+ import std.stdio : writeln;
+
+ version (unittest)
+ writeln ("Hello!");
+ else
+ assert (0);
+}
diff --git a/test cases/d/6 unittest/test.json b/test cases/d/6 unittest/test.json
new file mode 100644
index 0000000..adc4d75
--- /dev/null
+++ b/test cases/d/6 unittest/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/dapp"},
+ {"type": "pdb", "file": "usr/bin/dapp", "language": "d"}
+ ]
+}
diff --git a/test cases/d/7 multilib/app.d b/test cases/d/7 multilib/app.d
new file mode 100644
index 0000000..892596a
--- /dev/null
+++ b/test cases/d/7 multilib/app.d
@@ -0,0 +1,9 @@
+
+import say1;
+import say2;
+
+void main ()
+{
+ assert (sayHello1 ("Dave") == 4);
+ assert (sayHello2 ("HAL 9000") == 8);
+}
diff --git a/test cases/d/7 multilib/meson.build b/test cases/d/7 multilib/meson.build
new file mode 100644
index 0000000..1879c08
--- /dev/null
+++ b/test cases/d/7 multilib/meson.build
@@ -0,0 +1,24 @@
+project('D Multiple Versioned Shared Libraries', 'd')
+
+dc = meson.get_compiler('d')
+if dc.get_id() == 'gcc'
+ if dc.version().version_compare('< 8')
+ error('MESON_SKIP_TEST: GDC < 8.0 can not build shared libraries')
+ endif
+endif
+
+ldyn1 = shared_library('say1',
+ 'say1.d',
+ install: true,
+ version : '1.2.3',
+ soversion : '0'
+)
+ldyn2 = shared_library('say2',
+ 'say2.d',
+ install: true,
+ version : '1.2.4',
+ soversion : '1'
+)
+
+ed = executable('app_d', 'app.d', link_with: [ldyn1, ldyn2], install: true)
+test('multilink_test', ed)
diff --git a/test cases/d/7 multilib/say1.d b/test cases/d/7 multilib/say1.d
new file mode 100644
index 0000000..605fd23
--- /dev/null
+++ b/test cases/d/7 multilib/say1.d
@@ -0,0 +1,15 @@
+
+import std.stdio;
+import std.string : format;
+
+export int sayHello1 (string str)
+{
+ writeln ("Hello %s from library 1.".format (str));
+ return 4;
+}
+
+version (Windows)
+{
+ import core.sys.windows.dll;
+ mixin SimpleDllMain;
+}
diff --git a/test cases/d/7 multilib/say1.di b/test cases/d/7 multilib/say1.di
new file mode 100644
index 0000000..8a9ff02
--- /dev/null
+++ b/test cases/d/7 multilib/say1.di
@@ -0,0 +1 @@
+int sayHello1 (string str);
diff --git a/test cases/d/7 multilib/say2.d b/test cases/d/7 multilib/say2.d
new file mode 100644
index 0000000..7270ebd
--- /dev/null
+++ b/test cases/d/7 multilib/say2.d
@@ -0,0 +1,15 @@
+
+import std.stdio;
+import std.string : format;
+
+export int sayHello2 (string str)
+{
+ writeln ("Hello %s from library 2.".format (str));
+ return 8;
+}
+
+version (Windows)
+{
+ import core.sys.windows.dll;
+ mixin SimpleDllMain;
+}
diff --git a/test cases/d/7 multilib/say2.di b/test cases/d/7 multilib/say2.di
new file mode 100644
index 0000000..da712f0
--- /dev/null
+++ b/test cases/d/7 multilib/say2.di
@@ -0,0 +1 @@
+int sayHello2 (string str);
diff --git a/test cases/d/7 multilib/test.json b/test cases/d/7 multilib/test.json
new file mode 100644
index 0000000..5944ae0
--- /dev/null
+++ b/test cases/d/7 multilib/test.json
@@ -0,0 +1,18 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/app_d"},
+ {"type": "pdb", "file": "usr/bin/app_d", "language": "d"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/say1"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/say1", "version": "0"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/say1", "version": "1.2.3"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/say2"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/say2", "version": "1"},
+ {"type": "shared_lib", "platform": "gcc", "file": "usr/lib/say2", "version": "1.2.4"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/say1", "version": "0"},
+ {"type": "pdb", "file": "usr/bin/say1", "version": "0", "language": "d"},
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/say2", "version": "1"},
+ {"type": "pdb", "file": "usr/bin/say2", "version": "1", "language": "d"},
+ {"type": "implib", "file": "usr/lib/say1"},
+ {"type": "implib", "file": "usr/lib/say2"}
+ ]
+}
diff --git a/test cases/d/8 has multi arguments/meson.build b/test cases/d/8 has multi arguments/meson.build
new file mode 100644
index 0000000..0897057
--- /dev/null
+++ b/test cases/d/8 has multi arguments/meson.build
@@ -0,0 +1,8 @@
+project('D has arguments test', 'd')
+
+compiler = meson.get_compiler('d')
+
+assert(compiler.compiles('int i;'), 'Basic code test does not compile: ' + compiler.get_id())
+assert(compiler.has_multi_arguments(['-I.', '-J.']), 'Multi argument test does not work: ' + compiler.get_id())
+assert(compiler.has_argument('-I.'), 'Basic argument test does not work: ' + compiler.get_id())
+assert(compiler.has_argument('-flag_a_d_compiler_definitely_does_not_have') == false, 'Basic argument test does not work: ' + compiler.get_id())
diff --git a/test cases/d/9 features/app.d b/test cases/d/9 features/app.d
new file mode 100644
index 0000000..ae59be1
--- /dev/null
+++ b/test cases/d/9 features/app.d
@@ -0,0 +1,82 @@
+
+import std.stdio;
+import std.array : split;
+import std.string : strip;
+
+import extra;
+
+auto getMenu ()
+{
+ auto foods = import ("food.txt").strip.split ("\n");
+ return foods;
+}
+
+auto getPeople ()
+{
+ return import ("people.txt").strip.split ("\n");
+}
+
+void main (string[] args)
+{
+ import std.array : join;
+ import core.stdc.stdlib : exit;
+
+ immutable request = args[1];
+ if (request == "menu") {
+ version (No_Menu) {
+ } else {
+ writeln ("On the menu: ", getMenu.join (", "));
+ exit (0);
+ }
+ }
+
+ version (With_People) {
+ if (request == "people") {
+ writeln ("People: ", getPeople.join (", "));
+
+ // only exit successfully if the second module also had its module version set.
+ // this checks for issue https://github.com/mesonbuild/meson/issues/3337
+ if (secondModulePeopleVersionSet ())
+ exit (0);
+ exit (1);
+ }
+ }
+
+ version (With_VersionInteger)
+ version(3) exit(0);
+
+ version (With_Debug)
+ debug exit(0);
+
+ version (With_DebugInteger)
+ debug(3) exit(0);
+
+ version (With_DebugIdentifier)
+ debug(DebugIdentifier) exit(0);
+
+ version (With_DebugAll) {
+ int dbg = 0;
+ debug dbg++;
+ debug(2) dbg++;
+ debug(3) dbg++;
+ debug(4) dbg++;
+ debug(DebugIdentifier) dbg++;
+
+ if (dbg == 5)
+ exit(0);
+ }
+
+ // we fail here
+ exit (1);
+}
+
+unittest
+{
+ writeln ("TEST");
+ import core.stdc.stdlib : exit;
+
+ writeln(getMenu);
+ assert (getMenu () == ["Spam", "Eggs", "Spam", "Baked Beans", "Spam", "Spam"]);
+
+ exit (0);
+}
diff --git a/test cases/d/9 features/data/food.txt b/test cases/d/9 features/data/food.txt
new file mode 100644
index 0000000..8275dd0
--- /dev/null
+++ b/test cases/d/9 features/data/food.txt
@@ -0,0 +1,6 @@
+Spam
+Eggs
+Spam
+Baked Beans
+Spam
+Spam
diff --git a/test cases/d/9 features/data/people.txt b/test cases/d/9 features/data/people.txt
new file mode 100644
index 0000000..abbae06
--- /dev/null
+++ b/test cases/d/9 features/data/people.txt
@@ -0,0 +1,5 @@
+Rick
+Morty
+Summer
+Beth
+Jerry
diff --git a/test cases/d/9 features/extra.d b/test cases/d/9 features/extra.d
new file mode 100644
index 0000000..832b292
--- /dev/null
+++ b/test cases/d/9 features/extra.d
@@ -0,0 +1,9 @@
+
+auto secondModulePeopleVersionSet ()
+{
+ version (With_People) {
+ return true;
+ } else {
+ return false;
+ }
+}
diff --git a/test cases/d/9 features/meson.build b/test cases/d/9 features/meson.build
new file mode 100644
index 0000000..06f0341
--- /dev/null
+++ b/test cases/d/9 features/meson.build
@@ -0,0 +1,106 @@
+project('D Features', 'd', default_options : ['debug=false'])
+
+# ONLY FOR BACKWARDS COMPATIBILITY.
+# DO NOT DO THIS IN NEW CODE!
+# USE include_directories() INSTEAD OF BUILDING
+# STRINGS TO PATHS MANUALLY!
+data_dir = join_paths(meson.current_source_dir(), 'data')
+
+test_src = ['app.d', 'extra.d']
+
+e_plain_bcompat = executable('dapp_menu_bcompat',
+ test_src,
+ d_import_dirs: [data_dir]
+)
+test('dapp_menu_t_fail_bcompat', e_plain_bcompat, should_fail: true)
+test('dapp_menu_t_bcompat', e_plain_bcompat, args: ['menu'])
+
+# directory for data
+# This is the correct way to do this.
+data_dir = include_directories('data')
+
+e_plain = executable('dapp_menu',
+ test_src,
+ d_import_dirs: [data_dir]
+)
+test('dapp_menu_t_fail', e_plain, should_fail: true)
+test('dapp_menu_t', e_plain, args: ['menu'])
+
+
+# test feature versions and string imports
+e_versions = executable('dapp_versions',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['No_Menu', 'With_People']
+)
+test('dapp_versions_t_fail', e_versions, args: ['menu'], should_fail: true)
+test('dapp_versions_t', e_versions, args: ['people'])
+
+# test everything and unittests
+e_test = executable('dapp_test',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['No_Menu', 'With_People'],
+ d_unittest: true
+)
+test('dapp_test', e_test)
+
+# test version level
+e_version_int = executable('dapp_version_int',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_VersionInteger', 3],
+)
+test('dapp_version_int_t', e_version_int, args: ['debug'])
+
+# test version level failure
+e_version_int_fail = executable('dapp_version_int_fail',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_VersionInteger', 2],
+)
+test('dapp_version_int_t_fail', e_version_int_fail, args: ['debug'], should_fail: true)
+
+# test debug conditions: disabled
+e_no_debug = executable('dapp_no_debug',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_Debug'],
+)
+test('dapp_no_debug_t_fail', e_no_debug, args: ['debug'], should_fail: true)
+
+# test debug conditions: enabled
+e_debug = executable('dapp_debug',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_Debug'],
+ d_debug: 1,
+)
+test('dapp_debug_t', e_debug, args: ['debug'])
+
+# test debug conditions: integer
+e_debug_int = executable('dapp_debug_int',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_DebugInteger'],
+ d_debug: 3,
+)
+test('dapp_debug_int_t', e_debug_int, args: ['debug'])
+
+# test debug conditions: identifier
+e_debug_ident = executable('dapp_debug_ident',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_DebugIdentifier'],
+ d_debug: 'DebugIdentifier',
+)
+test('dapp_debug_ident_t', e_debug_ident, args: ['debug'])
+
+# test with all debug conditions at once, and with redundant values
+e_debug_all = executable('dapp_debug_all',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_DebugAll'],
+ d_debug: ['4', 'DebugIdentifier', 2, 'DebugIdentifierUnused'],
+)
+test('dapp_debug_all_t', e_debug_all, args: ['debug'])
diff --git a/test cases/failing build/1 vala c werror/meson.build b/test cases/failing build/1 vala c werror/meson.build
new file mode 100644
index 0000000..736d7aa
--- /dev/null
+++ b/test cases/failing build/1 vala c werror/meson.build
@@ -0,0 +1,10 @@
+project('valatest', 'c', default_options : 'werror=true')
+
+if find_program('valac', required : false).found()
+ add_languages('vala')
+ valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+ # Must fail due to -Werror and unused variable in C file
+ executable('valaprog', 'prog.vala', 'unused-var.c', dependencies : valadeps)
+else
+ executable('failprog', 'unused-var.c')
+endif
diff --git a/test cases/failing build/1 vala c werror/prog.vala b/test cases/failing build/1 vala c werror/prog.vala
new file mode 100644
index 0000000..638e776
--- /dev/null
+++ b/test cases/failing build/1 vala c werror/prog.vala
@@ -0,0 +1,7 @@
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ stdout.printf("Vala is working.\n");
+ return 0;
+ }
+}
diff --git a/test cases/failing build/1 vala c werror/unused-var.c b/test cases/failing build/1 vala c werror/unused-var.c
new file mode 100644
index 0000000..6b85078
--- /dev/null
+++ b/test cases/failing build/1 vala c werror/unused-var.c
@@ -0,0 +1,8 @@
+#warning "something"
+
+int
+somelib(void)
+{
+ int unused_var;
+ return 33;
+}
diff --git a/test cases/failing build/2 hidden symbol/bob.c b/test cases/failing build/2 hidden symbol/bob.c
new file mode 100644
index 0000000..9a3325a
--- /dev/null
+++ b/test cases/failing build/2 hidden symbol/bob.c
@@ -0,0 +1,5 @@
+#include"bob.h"
+
+int hidden_function() {
+ return 7;
+}
diff --git a/test cases/failing build/2 hidden symbol/bob.h b/test cases/failing build/2 hidden symbol/bob.h
new file mode 100644
index 0000000..947f6ee
--- /dev/null
+++ b/test cases/failing build/2 hidden symbol/bob.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int hidden_function();
diff --git a/test cases/failing build/2 hidden symbol/bobuser.c b/test cases/failing build/2 hidden symbol/bobuser.c
new file mode 100644
index 0000000..89272ed
--- /dev/null
+++ b/test cases/failing build/2 hidden symbol/bobuser.c
@@ -0,0 +1,5 @@
+#include"bob.h"
+
+int main(int argc, char **argv) {
+ return hidden_function();
+}
diff --git a/test cases/failing build/2 hidden symbol/meson.build b/test cases/failing build/2 hidden symbol/meson.build
new file mode 100644
index 0000000..f7c38e3
--- /dev/null
+++ b/test cases/failing build/2 hidden symbol/meson.build
@@ -0,0 +1,11 @@
+project('hidden symbol', 'c')
+
+if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST -fvisibility=hidden does not work for PE files.')
+endif
+
+l = shared_library('bob', 'bob.c',
+ gnu_symbol_visibility: 'hidden')
+
+executable('bobuser', 'bobuser.c',
+ link_with: l)
diff --git a/test cases/failing build/3 pch disabled/c/meson.build b/test cases/failing build/3 pch disabled/c/meson.build
new file mode 100644
index 0000000..1739126
--- /dev/null
+++ b/test cases/failing build/3 pch disabled/c/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', 'prog.c',
+c_pch : ['pch/prog_pch.c', 'pch/prog.h'])
diff --git a/test cases/failing build/3 pch disabled/c/pch/prog.h b/test cases/failing build/3 pch disabled/c/pch/prog.h
new file mode 100644
index 0000000..354499a
--- /dev/null
+++ b/test cases/failing build/3 pch disabled/c/pch/prog.h
@@ -0,0 +1 @@
+#include<stdio.h>
diff --git a/test cases/failing build/3 pch disabled/c/pch/prog_pch.c b/test cases/failing build/3 pch disabled/c/pch/prog_pch.c
new file mode 100644
index 0000000..4960505
--- /dev/null
+++ b/test cases/failing build/3 pch disabled/c/pch/prog_pch.c
@@ -0,0 +1,5 @@
+#if !defined(_MSC_VER)
+#error "This file is only for use with MSVC."
+#endif
+
+#include "prog.h"
diff --git a/test cases/failing build/3 pch disabled/c/prog.c b/test cases/failing build/3 pch disabled/c/prog.c
new file mode 100644
index 0000000..f17bc9e
--- /dev/null
+++ b/test cases/failing build/3 pch disabled/c/prog.c
@@ -0,0 +1,9 @@
+// No includes here, they need to come from the PCH
+
+void func() {
+ fprintf(stdout, "This is a function that fails if stdio is not #included.\n");
+}
+
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/failing build/3 pch disabled/meson.build b/test cases/failing build/3 pch disabled/meson.build
new file mode 100644
index 0000000..0a8fa67
--- /dev/null
+++ b/test cases/failing build/3 pch disabled/meson.build
@@ -0,0 +1,5 @@
+# Disable PCH usage to make sure backends respect this setting.
+# Since the .c file requires PCH usage (it does not include necessary
+# headers itself), the build should fail.
+project('pch test', 'c', default_options: ['b_pch=false'])
+subdir('c')
diff --git a/test cases/failing build/4 cmake subproject isolation/incDir/fileA.hpp b/test cases/failing build/4 cmake subproject isolation/incDir/fileA.hpp
new file mode 100644
index 0000000..a5f09be
--- /dev/null
+++ b/test cases/failing build/4 cmake subproject isolation/incDir/fileA.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+#define SOME_DEFINE " World"
diff --git a/test cases/failing build/4 cmake subproject isolation/main.cpp b/test cases/failing build/4 cmake subproject isolation/main.cpp
new file mode 100644
index 0000000..9507961
--- /dev/null
+++ b/test cases/failing build/4 cmake subproject isolation/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+#include <cmMod.hpp>
+
+using namespace std;
+
+int main(void) {
+ cmModClass obj("Hello");
+ cout << obj.getStr() << endl;
+ return 0;
+}
diff --git a/test cases/failing build/4 cmake subproject isolation/meson.build b/test cases/failing build/4 cmake subproject isolation/meson.build
new file mode 100644
index 0000000..e606335
--- /dev/null
+++ b/test cases/failing build/4 cmake subproject isolation/meson.build
@@ -0,0 +1,17 @@
+project('subproject isolation', ['c', 'cpp'])
+
+if not find_program('cmake', required: false).found()
+ error('MESON_SKIP_TEST CMake is not installed')
+endif
+
+incdir = meson.source_root() / 'incDir'
+
+cm = import('cmake')
+
+# This should generate a warning and the include dir should be skipped.
+sub_pro = cm.subproject('cmMod', cmake_options : [ '-DMESON_INC_DIR=' + incdir ])
+sub_dep = sub_pro.dependency('cmModLib++')
+
+# Since the include dir is skipped, the compilation of this project should fail.
+exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep])
+test('test1', exe1)
diff --git a/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/CMakeLists.txt b/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/CMakeLists.txt
new file mode 100644
index 0000000..852dd09
--- /dev/null
+++ b/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmMod)
+set (CMAKE_CXX_STANDARD 14)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${MESON_INC_DIR})
+
+add_library(cmModLib++ SHARED cmMod.cpp)
+include(GenerateExportHeader)
+generate_export_header(cmModLib++)
diff --git a/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.cpp b/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.cpp
new file mode 100644
index 0000000..a668203
--- /dev/null
+++ b/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.cpp
@@ -0,0 +1,12 @@
+#include "cmMod.hpp"
+#include "fileA.hpp"
+
+using namespace std;
+
+cmModClass::cmModClass(string foo) {
+ str = foo + SOME_DEFINE;
+}
+
+string cmModClass::getStr() const {
+ return str;
+}
diff --git a/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.hpp b/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.hpp
new file mode 100644
index 0000000..0e6dc04
--- /dev/null
+++ b/test cases/failing build/4 cmake subproject isolation/subprojects/cmMod/cmMod.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "cmmodlib++_export.h"
+#include <string>
+
+class CMMODLIB___EXPORT cmModClass {
+private:
+ std::string str;
+
+public:
+ cmModClass(std::string foo);
+
+ std::string getStr() const;
+};
diff --git a/test cases/failing build/4 cmake subproject isolation/test.json b/test cases/failing build/4 cmake subproject isolation/test.json
new file mode 100644
index 0000000..b48d78a
--- /dev/null
+++ b/test cases/failing build/4 cmake subproject isolation/test.json
@@ -0,0 +1,5 @@
+{
+ "tools": {
+ "cmake": ">=3.14"
+ }
+}
diff --git a/test cases/failing build/5 failed pickled/false.py b/test cases/failing build/5 failed pickled/false.py
new file mode 100644
index 0000000..865aeb9
--- /dev/null
+++ b/test cases/failing build/5 failed pickled/false.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+import sys
+sys.exit(1)
diff --git a/test cases/failing build/5 failed pickled/meson.build b/test cases/failing build/5 failed pickled/meson.build
new file mode 100644
index 0000000..9245020
--- /dev/null
+++ b/test cases/failing build/5 failed pickled/meson.build
@@ -0,0 +1,7 @@
+project('failed pickled command')
+
+custom_target('failure',
+ command: [find_program('false.py'), '\n'],
+ output: 'output.txt',
+ build_by_default: true,
+)
diff --git a/test cases/failing test/1 trivial/main.c b/test cases/failing test/1 trivial/main.c
new file mode 100644
index 0000000..3e70e50
--- /dev/null
+++ b/test cases/failing test/1 trivial/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 1;
+}
diff --git a/test cases/failing test/1 trivial/meson.build b/test cases/failing test/1 trivial/meson.build
new file mode 100644
index 0000000..ed5a3d2
--- /dev/null
+++ b/test cases/failing test/1 trivial/meson.build
@@ -0,0 +1,3 @@
+project('trivial', 'c')
+
+test('My Test', executable('main', 'main.c'))
diff --git a/test cases/failing test/2 signal/main.c b/test cases/failing test/2 signal/main.c
new file mode 100644
index 0000000..2ee1d80
--- /dev/null
+++ b/test cases/failing test/2 signal/main.c
@@ -0,0 +1,6 @@
+#include <signal.h>
+#include <unistd.h>
+
+int main(void) {
+ kill(getpid(), SIGSEGV);
+}
diff --git a/test cases/failing test/2 signal/meson.build b/test cases/failing test/2 signal/meson.build
new file mode 100644
index 0000000..9d84c26
--- /dev/null
+++ b/test cases/failing test/2 signal/meson.build
@@ -0,0 +1,7 @@
+project('signal', 'c')
+
+if build_machine.system() == 'windows'
+ error('MESON_SKIP_TEST test is not compatible with MS Windows.')
+else
+ test('My Signal Test', executable('main', 'main.c'))
+endif
diff --git a/test cases/failing test/3 ambiguous/main.c b/test cases/failing test/3 ambiguous/main.c
new file mode 100644
index 0000000..2ee1d80
--- /dev/null
+++ b/test cases/failing test/3 ambiguous/main.c
@@ -0,0 +1,6 @@
+#include <signal.h>
+#include <unistd.h>
+
+int main(void) {
+ kill(getpid(), SIGSEGV);
+}
diff --git a/test cases/failing test/3 ambiguous/meson.build b/test cases/failing test/3 ambiguous/meson.build
new file mode 100644
index 0000000..58f0de0
--- /dev/null
+++ b/test cases/failing test/3 ambiguous/meson.build
@@ -0,0 +1,10 @@
+project('ambiguous', 'c')
+
+if build_machine.system() == 'windows'
+ error('MESON_SKIP_TEST test is not compatible with MS Windows.')
+else
+ exe = executable('main', 'main.c')
+ test_runner = find_program('test_runner.sh')
+
+ test('My Ambiguous Status Test', test_runner, args : [exe.full_path()])
+endif
diff --git a/test cases/failing test/3 ambiguous/test_runner.sh b/test cases/failing test/3 ambiguous/test_runner.sh
new file mode 100755
index 0000000..08873ce
--- /dev/null
+++ b/test cases/failing test/3 ambiguous/test_runner.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# This tests that using a shell as an intermediary between Meson and the
+# actual unit test which dies due to a signal is still recorded correctly.
+#
+# The quotes are because the path may contain spaces.
+"$1"
diff --git a/test cases/failing test/4 hard error/main.c b/test cases/failing test/4 hard error/main.c
new file mode 100644
index 0000000..a1e705a
--- /dev/null
+++ b/test cases/failing test/4 hard error/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 99;
+}
diff --git a/test cases/failing test/4 hard error/meson.build b/test cases/failing test/4 hard error/meson.build
new file mode 100644
index 0000000..6979b04
--- /dev/null
+++ b/test cases/failing test/4 hard error/meson.build
@@ -0,0 +1,4 @@
+project('trivial', 'c')
+
+# Exit code 99 even overrides should_fail
+test('My Test', executable('main', 'main.c'), should_fail: true)
diff --git a/test cases/failing test/5 tap tests/meson.build b/test cases/failing test/5 tap tests/meson.build
new file mode 100644
index 0000000..664ac34
--- /dev/null
+++ b/test cases/failing test/5 tap tests/meson.build
@@ -0,0 +1,9 @@
+project('test features', 'c')
+
+tester = executable('tester', 'tester.c')
+test_with_status = executable('test-with-status', 'tester_with_status.c')
+test('nonzero return code no tests', tester, args : [], protocol: 'tap')
+test('nonzero return code with tests', test_with_status, protocol: 'tap')
+test('missing test', tester, args : ['1..1'], protocol: 'tap')
+test('incorrect skip', tester, args : ['1..1 # skip\nok 1'], protocol: 'tap')
+test('partially skipped', tester, args : ['not ok 1\nok 2 # skip'], protocol: 'tap')
diff --git a/test cases/failing test/5 tap tests/tester.c b/test cases/failing test/5 tap tests/tester.c
new file mode 100644
index 0000000..ac582e7
--- /dev/null
+++ b/test cases/failing test/5 tap tests/tester.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "Incorrect number of arguments, got %i\n", argc);
+ return 1;
+ }
+ puts(argv[1]);
+ return 0;
+}
diff --git a/test cases/failing test/5 tap tests/tester_with_status.c b/test cases/failing test/5 tap tests/tester_with_status.c
new file mode 100644
index 0000000..7613afe
--- /dev/null
+++ b/test cases/failing test/5 tap tests/tester_with_status.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+ puts("1..1");
+ puts("not ok 1 - some test");
+ return 2;
+}
diff --git a/test cases/failing test/6 xpass/meson.build b/test cases/failing test/6 xpass/meson.build
new file mode 100644
index 0000000..7649dde
--- /dev/null
+++ b/test cases/failing test/6 xpass/meson.build
@@ -0,0 +1,4 @@
+project('unexpected pass', 'c')
+
+test('should_fail_but_does_not', executable('xpass', 'xpass.c'),
+ should_fail: true)
diff --git a/test cases/failing test/6 xpass/xpass.c b/test cases/failing test/6 xpass/xpass.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/failing test/6 xpass/xpass.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/failing/1 project not first/meson.build b/test cases/failing/1 project not first/meson.build
new file mode 100644
index 0000000..f30e155
--- /dev/null
+++ b/test cases/failing/1 project not first/meson.build
@@ -0,0 +1,4 @@
+var = 'assignment before project() call'
+project('no worky', 'c')
+
+test('not run', executable('prog', 'prog.c'))
diff --git a/test cases/failing/1 project not first/prog.c b/test cases/failing/1 project not first/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/failing/1 project not first/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/failing/1 project not first/test.json b/test cases/failing/1 project not first/test.json
new file mode 100644
index 0000000..27bae02
--- /dev/null
+++ b/test cases/failing/1 project not first/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "ERROR: Invalid source tree: first statement must be a call to project()"
+ }
+ ]
+}
diff --git a/test cases/failing/10 out of bounds/meson.build b/test cases/failing/10 out of bounds/meson.build
new file mode 100644
index 0000000..6917f7a
--- /dev/null
+++ b/test cases/failing/10 out of bounds/meson.build
@@ -0,0 +1,4 @@
+project('out of bounds')
+
+x = []
+y = x[0]
diff --git a/test cases/failing/10 out of bounds/test.json b/test cases/failing/10 out of bounds/test.json
new file mode 100644
index 0000000..e27d990
--- /dev/null
+++ b/test cases/failing/10 out of bounds/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/10 out of bounds/meson.build:4:0: ERROR: Index 0 out of bounds of array of size 0."
+ }
+ ]
+}
diff --git a/test cases/failing/100 no glib-compile-resources/meson.build b/test cases/failing/100 no glib-compile-resources/meson.build
new file mode 100644
index 0000000..aae0569
--- /dev/null
+++ b/test cases/failing/100 no glib-compile-resources/meson.build
@@ -0,0 +1,8 @@
+project('no glib-compile-resources')
+
+if find_program('glib-compile-resources', required: false).found()
+ error('MESON_SKIP_TEST test only applicable when glib-compile-resources is missing.')
+endif
+
+gnome = import('gnome')
+res = gnome.compile_resources('resources', 'trivial.gresource.xml')
diff --git a/test cases/failing/100 no glib-compile-resources/test.json b/test cases/failing/100 no glib-compile-resources/test.json
new file mode 100644
index 0000000..ad9ba29
--- /dev/null
+++ b/test cases/failing/100 no glib-compile-resources/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/100 no glib-compile-resources/meson.build:8:0: ERROR: Program 'glib-compile-resources' not found or not executable"
+ }
+ ]
+}
diff --git a/test cases/failing/100 no glib-compile-resources/trivial.gresource.xml b/test cases/failing/100 no glib-compile-resources/trivial.gresource.xml
new file mode 100644
index 0000000..1447b98
--- /dev/null
+++ b/test cases/failing/100 no glib-compile-resources/trivial.gresource.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+</gresources>
diff --git a/test cases/failing/101 number in combo/meson.build b/test cases/failing/101 number in combo/meson.build
new file mode 100644
index 0000000..1a647df
--- /dev/null
+++ b/test cases/failing/101 number in combo/meson.build
@@ -0,0 +1 @@
+project('number in combo')
diff --git a/test cases/failing/101 number in combo/nativefile.ini b/test cases/failing/101 number in combo/nativefile.ini
new file mode 100644
index 0000000..55f10fc
--- /dev/null
+++ b/test cases/failing/101 number in combo/nativefile.ini
@@ -0,0 +1,2 @@
+[built-in options]
+optimization = 1
diff --git a/test cases/failing/101 number in combo/test.json b/test cases/failing/101 number in combo/test.json
new file mode 100644
index 0000000..4c30f98
--- /dev/null
+++ b/test cases/failing/101 number in combo/test.json
@@ -0,0 +1,5 @@
+{
+ "stdout": [
+ { "line": "test cases/failing/101 number in combo/meson.build:1:0: ERROR: Value \"1\" (of type \"number\") for combo option \"Optimization level\" is not one of the choices. Possible choices are (as string): \"plain\", \"0\", \"g\", \"1\", \"2\", \"3\", \"s\"." }
+ ]
+}
diff --git a/test cases/failing/102 bool in combo/meson.build b/test cases/failing/102 bool in combo/meson.build
new file mode 100644
index 0000000..c5efd67
--- /dev/null
+++ b/test cases/failing/102 bool in combo/meson.build
@@ -0,0 +1 @@
+project('bool in combo')
diff --git a/test cases/failing/102 bool in combo/meson_options.txt b/test cases/failing/102 bool in combo/meson_options.txt
new file mode 100644
index 0000000..0c8f5de
--- /dev/null
+++ b/test cases/failing/102 bool in combo/meson_options.txt
@@ -0,0 +1,5 @@
+option(
+ 'opt',
+ type : 'combo',
+ choices : ['true', 'false']
+)
diff --git a/test cases/failing/102 bool in combo/nativefile.ini b/test cases/failing/102 bool in combo/nativefile.ini
new file mode 100644
index 0000000..b423957
--- /dev/null
+++ b/test cases/failing/102 bool in combo/nativefile.ini
@@ -0,0 +1,2 @@
+[project options]
+opt = true
diff --git a/test cases/failing/102 bool in combo/test.json b/test cases/failing/102 bool in combo/test.json
new file mode 100644
index 0000000..c0041af
--- /dev/null
+++ b/test cases/failing/102 bool in combo/test.json
@@ -0,0 +1,5 @@
+{
+ "stdout": [
+ { "line": "test cases/failing/102 bool in combo/meson.build:1:0: ERROR: Value \"True\" (of type \"boolean\") for combo option \"opt\" is not one of the choices. Possible choices are (as string): \"true\", \"false\"." }
+ ]
+}
diff --git a/test cases/failing/103 compiler no lang/meson.build b/test cases/failing/103 compiler no lang/meson.build
new file mode 100644
index 0000000..366bbdd
--- /dev/null
+++ b/test cases/failing/103 compiler no lang/meson.build
@@ -0,0 +1,2 @@
+project('compiler without lang')
+meson.get_compiler('c')
diff --git a/test cases/failing/103 compiler no lang/test.json b/test cases/failing/103 compiler no lang/test.json
new file mode 100644
index 0000000..123dcb9
--- /dev/null
+++ b/test cases/failing/103 compiler no lang/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/103 compiler no lang/meson.build:2:6: ERROR: Tried to access compiler for language \"c\", not specified for host machine."
+ }
+ ]
+}
diff --git a/test cases/failing/104 no fallback/meson.build b/test cases/failing/104 no fallback/meson.build
new file mode 100644
index 0000000..91d6b93
--- /dev/null
+++ b/test cases/failing/104 no fallback/meson.build
@@ -0,0 +1,2 @@
+project('no fallback')
+foob_dep = dependency('foob', allow_fallback: false, required: true)
diff --git a/test cases/failing/104 no fallback/subprojects/foob/meson.build b/test cases/failing/104 no fallback/subprojects/foob/meson.build
new file mode 100644
index 0000000..b2c4814
--- /dev/null
+++ b/test cases/failing/104 no fallback/subprojects/foob/meson.build
@@ -0,0 +1,2 @@
+project('foob', 'c')
+meson.override_dependency('foob', declare_dependency())
diff --git a/test cases/failing/104 no fallback/test.json b/test cases/failing/104 no fallback/test.json
new file mode 100644
index 0000000..e034061
--- /dev/null
+++ b/test cases/failing/104 no fallback/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": ".*/meson\\.build:2:0: ERROR: (Pkg-config binary for machine MachineChoice\\.HOST not found\\. Giving up\\.|Dependency \"foob\" not found, tried .*)"
+ }
+ ]
+}
diff --git a/test cases/failing/105 feature require/meson.build b/test cases/failing/105 feature require/meson.build
new file mode 100644
index 0000000..8c47e37
--- /dev/null
+++ b/test cases/failing/105 feature require/meson.build
@@ -0,0 +1,2 @@
+project('no fallback')
+foo = get_option('reqfeature').require(false, error_message: 'frobnicator not available')
diff --git a/test cases/failing/105 feature require/meson_options.txt b/test cases/failing/105 feature require/meson_options.txt
new file mode 100644
index 0000000..5910a87
--- /dev/null
+++ b/test cases/failing/105 feature require/meson_options.txt
@@ -0,0 +1 @@
+option('reqfeature', type : 'feature', value : 'enabled', description : 'A required feature')
diff --git a/test cases/failing/105 feature require/test.json b/test cases/failing/105 feature require/test.json
new file mode 100644
index 0000000..7c4640d
--- /dev/null
+++ b/test cases/failing/105 feature require/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": ".*/meson\\.build:2:0: ERROR: Feature reqfeature cannot be enabled: frobnicator not available"
+ }
+ ]
+}
diff --git a/test cases/failing/106 feature require.bis/meson.build b/test cases/failing/106 feature require.bis/meson.build
new file mode 100644
index 0000000..4ea65e5
--- /dev/null
+++ b/test cases/failing/106 feature require.bis/meson.build
@@ -0,0 +1,2 @@
+project('no fallback')
+foo = get_option('reqfeature').require(false)
diff --git a/test cases/failing/106 feature require.bis/meson_options.txt b/test cases/failing/106 feature require.bis/meson_options.txt
new file mode 100644
index 0000000..5910a87
--- /dev/null
+++ b/test cases/failing/106 feature require.bis/meson_options.txt
@@ -0,0 +1 @@
+option('reqfeature', type : 'feature', value : 'enabled', description : 'A required feature')
diff --git a/test cases/failing/106 feature require.bis/test.json b/test cases/failing/106 feature require.bis/test.json
new file mode 100644
index 0000000..2583990
--- /dev/null
+++ b/test cases/failing/106 feature require.bis/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": ".*/meson\\.build:2:0: ERROR: Feature reqfeature cannot be enabled"
+ }
+ ]
+}
diff --git a/test cases/failing/107 no build get_external_property/meson.build b/test cases/failing/107 no build get_external_property/meson.build
new file mode 100644
index 0000000..8a4215c
--- /dev/null
+++ b/test cases/failing/107 no build get_external_property/meson.build
@@ -0,0 +1,3 @@
+project('missing property')
+
+message(meson.get_external_property('nonexisting', native : true))
diff --git a/test cases/failing/107 no build get_external_property/test.json b/test cases/failing/107 no build get_external_property/test.json
new file mode 100644
index 0000000..b95427e
--- /dev/null
+++ b/test cases/failing/107 no build get_external_property/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/107 no build get_external_property/meson.build:3:0: ERROR: Unknown property for build machine: nonexisting"
+ }
+ ]
+}
diff --git a/test cases/failing/108 enter subdir twice/meson.build b/test cases/failing/108 enter subdir twice/meson.build
new file mode 100644
index 0000000..d9bf9f5
--- /dev/null
+++ b/test cases/failing/108 enter subdir twice/meson.build
@@ -0,0 +1,3 @@
+project('subdir2')
+subdir('sub')
+subdir('sub')
diff --git a/test cases/failing/108 enter subdir twice/sub/meson.build b/test cases/failing/108 enter subdir twice/sub/meson.build
new file mode 100644
index 0000000..d036a3f
--- /dev/null
+++ b/test cases/failing/108 enter subdir twice/sub/meson.build
@@ -0,0 +1 @@
+message('Now in subdir')
diff --git a/test cases/failing/108 enter subdir twice/test.json b/test cases/failing/108 enter subdir twice/test.json
new file mode 100644
index 0000000..0a8e127
--- /dev/null
+++ b/test cases/failing/108 enter subdir twice/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/108 enter subdir twice/meson.build:3:0: ERROR: Tried to enter directory \"sub\", which has already been visited."
+ }
+ ]
+}
diff --git a/test cases/failing/109 invalid fstring/109 invalid fstring/meson.build b/test cases/failing/109 invalid fstring/109 invalid fstring/meson.build
new file mode 100644
index 0000000..dd22f56
--- /dev/null
+++ b/test cases/failing/109 invalid fstring/109 invalid fstring/meson.build
@@ -0,0 +1,4 @@
+project('invalid-fstring', 'c')
+
+dict = {'key': true}
+s = f'invalid fstring: @dict@'
diff --git a/test cases/failing/109 invalid fstring/109 invalid fstring/test.json b/test cases/failing/109 invalid fstring/109 invalid fstring/test.json
new file mode 100644
index 0000000..71d8f59
--- /dev/null
+++ b/test cases/failing/109 invalid fstring/109 invalid fstring/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/109 invalid fstring/meson.build:4:0: ERROR: Identifier \"dict\" does not name a formattable variable (has to be an integer, a string, a floating point number or a boolean)."
+ }
+ ]
+}
diff --git a/test cases/failing/109 invalid fstring/meson.build b/test cases/failing/109 invalid fstring/meson.build
new file mode 100644
index 0000000..7eb3ccf
--- /dev/null
+++ b/test cases/failing/109 invalid fstring/meson.build
@@ -0,0 +1,3 @@
+project('invalid-fstring')
+
+z = f'invalid fstring: @foo@'
diff --git a/test cases/failing/109 invalid fstring/test.json b/test cases/failing/109 invalid fstring/test.json
new file mode 100644
index 0000000..a095d62
--- /dev/null
+++ b/test cases/failing/109 invalid fstring/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/109 invalid fstring/meson.build:3:0: ERROR: Identifier \"foo\" does not name a variable."
+ }
+ ]
+}
diff --git a/test cases/failing/11 object arithmetic/meson.build b/test cases/failing/11 object arithmetic/meson.build
new file mode 100644
index 0000000..34e3a7a
--- /dev/null
+++ b/test cases/failing/11 object arithmetic/meson.build
@@ -0,0 +1,3 @@
+project('object arithmetic')
+
+foo = '5' + meson
diff --git a/test cases/failing/11 object arithmetic/test.json b/test cases/failing/11 object arithmetic/test.json
new file mode 100644
index 0000000..822e504
--- /dev/null
+++ b/test cases/failing/11 object arithmetic/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": "test cases/failing/11 object arithmetic/meson\\.build:3:0: ERROR: The `\\+` operator of str does not accept objects of type MesonMain .*"
+ }
+ ]
+}
diff --git a/test cases/failing/110 compiler argument checking/meson.build b/test cases/failing/110 compiler argument checking/meson.build
new file mode 100644
index 0000000..bb1f447
--- /dev/null
+++ b/test cases/failing/110 compiler argument checking/meson.build
@@ -0,0 +1,4 @@
+project('compiler argument checking test', 'c')
+
+cc = meson.get_compiler('c')
+add_project_arguments(cc.get_supported_arguments('-meson-goober-arg-for-testing', checked : 'require'), language : 'c')
diff --git a/test cases/failing/110 compiler argument checking/test.json b/test cases/failing/110 compiler argument checking/test.json
new file mode 100644
index 0000000..3de6acb
--- /dev/null
+++ b/test cases/failing/110 compiler argument checking/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/110 compiler argument checking/meson.build:4:0: ERROR: Compiler for C does not support \"-meson-goober-arg-for-testing\""
+ }
+ ]
+}
diff --git a/test cases/failing/111 empty fallback/meson.build b/test cases/failing/111 empty fallback/meson.build
new file mode 100644
index 0000000..f4eb5fe
--- /dev/null
+++ b/test cases/failing/111 empty fallback/meson.build
@@ -0,0 +1,6 @@
+project('empty fallback')
+
+# There is a subproject named 'foo' that overrides that dependency,
+# but `fallback: []` should not allow to use it. Same behaviour than with
+# `allow_fallback: false`
+dependency('foo', fallback: [])
diff --git a/test cases/failing/111 empty fallback/subprojects/foo/meson.build b/test cases/failing/111 empty fallback/subprojects/foo/meson.build
new file mode 100644
index 0000000..c9e134b
--- /dev/null
+++ b/test cases/failing/111 empty fallback/subprojects/foo/meson.build
@@ -0,0 +1,3 @@
+project('foo')
+
+meson.override_dependency('foo', declare_dependency())
diff --git a/test cases/failing/111 empty fallback/test.json b/test cases/failing/111 empty fallback/test.json
new file mode 100644
index 0000000..022e747
--- /dev/null
+++ b/test cases/failing/111 empty fallback/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": "test cases/failing/111 empty fallback/meson.build:6:0: ERROR: Dependency \"foo\" not found.*"
+ }
+ ]
+}
diff --git a/test cases/failing/112 cmake executable dependency/meson.build b/test cases/failing/112 cmake executable dependency/meson.build
new file mode 100644
index 0000000..48d8fcb
--- /dev/null
+++ b/test cases/failing/112 cmake executable dependency/meson.build
@@ -0,0 +1,9 @@
+project('cmake-executable-dependency', 'c')
+
+if not find_program('cmake', required: false).found()
+ error('MESON_SKIP_TEST CMake is not installed')
+endif
+
+cmake = import('cmake')
+cmlib = cmake.subproject('cmlib')
+maind = cmlib.dependency('main')
diff --git a/test cases/failing/112 cmake executable dependency/subprojects/cmlib/CMakeLists.txt b/test cases/failing/112 cmake executable dependency/subprojects/cmlib/CMakeLists.txt
new file mode 100644
index 0000000..0067879
--- /dev/null
+++ b/test cases/failing/112 cmake executable dependency/subprojects/cmlib/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmlib)
+
+add_executable(main main.c)
diff --git a/test cases/failing/112 cmake executable dependency/subprojects/cmlib/main.c b/test cases/failing/112 cmake executable dependency/subprojects/cmlib/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/failing/112 cmake executable dependency/subprojects/cmlib/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/failing/112 cmake executable dependency/test.json b/test cases/failing/112 cmake executable dependency/test.json
new file mode 100644
index 0000000..c1ccf6c
--- /dev/null
+++ b/test cases/failing/112 cmake executable dependency/test.json
@@ -0,0 +1,10 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/112 cmake executable dependency/meson.build:9:0: ERROR: main is an executable and does not support the dependency() method. Use target() instead."
+ }
+ ],
+ "tools": {
+ "cmake": ">=3.14"
+ }
+}
diff --git a/test cases/failing/113 allow_fallback with fallback/meson.build b/test cases/failing/113 allow_fallback with fallback/meson.build
new file mode 100644
index 0000000..2874e42
--- /dev/null
+++ b/test cases/failing/113 allow_fallback with fallback/meson.build
@@ -0,0 +1,3 @@
+project('fallback and allow_fallback')
+
+dependency('foo', fallback: 'foo', allow_fallback: false)
diff --git a/test cases/failing/113 allow_fallback with fallback/test.json b/test cases/failing/113 allow_fallback with fallback/test.json
new file mode 100644
index 0000000..58ed475
--- /dev/null
+++ b/test cases/failing/113 allow_fallback with fallback/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/113 allow_fallback with fallback/meson.build:3:0: ERROR: \"fallback\" and \"allow_fallback\" arguments are mutually exclusive"
+ }
+ ]
+}
+
diff --git a/test cases/failing/114 nonsensical bindgen/meson.build b/test cases/failing/114 nonsensical bindgen/meson.build
new file mode 100644
index 0000000..6995f67
--- /dev/null
+++ b/test cases/failing/114 nonsensical bindgen/meson.build
@@ -0,0 +1,20 @@
+# SPDX-license-identifer: Apache-2.0
+# Copyright © 2021 Intel Corporation
+
+project('rustmod bindgen', 'c')
+
+if not add_languages('rust', required: false)
+ error('MESON_SKIP_TEST test requires rust compiler')
+endif
+
+prog_bindgen = find_program('bindgen', required : false)
+if not prog_bindgen.found()
+ error('MESON_SKIP_TEST bindgen not found')
+endif
+
+c_lib = static_library('clib', 'src/source.c')
+
+import('unstable-rust').bindgen(
+ input : c_lib,
+ output : 'header.rs',
+)
diff --git a/test cases/failing/114 nonsensical bindgen/src/header.h b/test cases/failing/114 nonsensical bindgen/src/header.h
new file mode 100644
index 0000000..750621f
--- /dev/null
+++ b/test cases/failing/114 nonsensical bindgen/src/header.h
@@ -0,0 +1,8 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#pragma once
+
+#include <stdint.h>
+
+int32_t add(const int32_t, const int32_t);
diff --git a/test cases/failing/114 nonsensical bindgen/src/source.c b/test cases/failing/114 nonsensical bindgen/src/source.c
new file mode 100644
index 0000000..d652d28
--- /dev/null
+++ b/test cases/failing/114 nonsensical bindgen/src/source.c
@@ -0,0 +1,8 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#include "header.h"
+
+int32_t add(const int32_t first, const int32_t second) {
+ return first + second;
+}
diff --git a/test cases/failing/114 nonsensical bindgen/test.json b/test cases/failing/114 nonsensical bindgen/test.json
new file mode 100644
index 0000000..bc85311
--- /dev/null
+++ b/test cases/failing/114 nonsensical bindgen/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/114 nonsensical bindgen/meson.build:17:24: ERROR: bindgen source file must be a C header, not an object or build target"
+ }
+ ]
+}
+
diff --git a/test cases/failing/115 run_target in test/meson.build b/test cases/failing/115 run_target in test/meson.build
new file mode 100644
index 0000000..1d448ec
--- /dev/null
+++ b/test cases/failing/115 run_target in test/meson.build
@@ -0,0 +1,7 @@
+project('trivial test', 'c')
+
+py_inst = import('python').find_installation()
+
+exe = executable('trivialprog', 'trivial.c')
+runt = run_target('invalid', command: [py_inst, '--version'])
+test('runtest', exe, args: runt)
diff --git a/test cases/failing/115 run_target in test/test.json b/test cases/failing/115 run_target in test/test.json
new file mode 100644
index 0000000..6eddb7c
--- /dev/null
+++ b/test cases/failing/115 run_target in test/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/115 run_target in test/meson.build:7:0: ERROR: test keyword argument 'args' was of type array[RunTarget] but should have been array[str | File | BuildTarget | CustomTarget | CustomTargetIndex]"
+ }
+ ]
+}
+
diff --git a/test cases/failing/115 run_target in test/trivial.c b/test cases/failing/115 run_target in test/trivial.c
new file mode 100644
index 0000000..96612d4
--- /dev/null
+++ b/test cases/failing/115 run_target in test/trivial.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Trivial test is working.\n");
+ return 0;
+}
diff --git a/test cases/failing/116 run_target in add_install_script/meson.build b/test cases/failing/116 run_target in add_install_script/meson.build
new file mode 100644
index 0000000..f8ae3a1
--- /dev/null
+++ b/test cases/failing/116 run_target in add_install_script/meson.build
@@ -0,0 +1,7 @@
+project('trivial test', 'c')
+
+py_inst = import('python').find_installation()
+
+exe = executable('trivialprog', 'trivial.c')
+runt = run_target('invalid', command: [py_inst, '--version'])
+meson.add_install_script(exe, runt)
diff --git a/test cases/failing/116 run_target in add_install_script/test.json b/test cases/failing/116 run_target in add_install_script/test.json
new file mode 100644
index 0000000..03027e4
--- /dev/null
+++ b/test cases/failing/116 run_target in add_install_script/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/116 run_target in add_install_script/meson.build:7:6: ERROR: meson.add_install_script argument 2 was of type \"RunTarget\" but should have been one of: \"str\", \"File\", \"BuildTarget\", \"CustomTarget\", \"CustomTargetIndex\", \"ExternalProgram\""
+ }
+ ]
+}
+
diff --git a/test cases/failing/116 run_target in add_install_script/trivial.c b/test cases/failing/116 run_target in add_install_script/trivial.c
new file mode 100644
index 0000000..1b14571
--- /dev/null
+++ b/test cases/failing/116 run_target in add_install_script/trivial.c
@@ -0,0 +1,11 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ FILE *fp = fopen(argv[1], "r");
+ if (fp == NULL) {
+ perror("fopen");
+ return 1;
+ } else {
+ return 0;
+ }
+}
diff --git a/test cases/failing/117 pathsep in install_symlink/meson.build b/test cases/failing/117 pathsep in install_symlink/meson.build
new file mode 100644
index 0000000..cce82c2
--- /dev/null
+++ b/test cases/failing/117 pathsep in install_symlink/meson.build
@@ -0,0 +1,3 @@
+project('symlink_pathsep')
+
+install_symlink('foo/bar', pointing_to: '/usr/baz/bar', install_dir: '/usr')
diff --git a/test cases/failing/117 pathsep in install_symlink/test.json b/test cases/failing/117 pathsep in install_symlink/test.json
new file mode 100644
index 0000000..aa35619
--- /dev/null
+++ b/test cases/failing/117 pathsep in install_symlink/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/117 pathsep in install_symlink/meson.build:3:0: ERROR: Link name is \"foo/bar\", but link names cannot contain path separators. The dir part should be in install_dir."
+ }
+ ]
+}
diff --git a/test cases/failing/118 subproject version conflict/meson.build b/test cases/failing/118 subproject version conflict/meson.build
new file mode 100644
index 0000000..ffbcc13
--- /dev/null
+++ b/test cases/failing/118 subproject version conflict/meson.build
@@ -0,0 +1,4 @@
+project('120 subproject version conflict')
+
+A_dep = subproject('A').get_variable('A_dep')
+B_dep = subproject('B', version: '1').get_variable('B_dep')
diff --git a/test cases/failing/118 subproject version conflict/subprojects/A/meson.build b/test cases/failing/118 subproject version conflict/subprojects/A/meson.build
new file mode 100644
index 0000000..7da4df0
--- /dev/null
+++ b/test cases/failing/118 subproject version conflict/subprojects/A/meson.build
@@ -0,0 +1,4 @@
+project('A')
+
+B_dep = subproject('B').get_variable('B_dep')
+A_dep = declare_dependency(dependencies: B_dep)
diff --git a/test cases/failing/118 subproject version conflict/subprojects/B/meson.build b/test cases/failing/118 subproject version conflict/subprojects/B/meson.build
new file mode 100644
index 0000000..0ead934
--- /dev/null
+++ b/test cases/failing/118 subproject version conflict/subprojects/B/meson.build
@@ -0,0 +1,3 @@
+project('B', version: '100')
+
+B_dep = declare_dependency()
diff --git a/test cases/failing/118 subproject version conflict/test.json b/test cases/failing/118 subproject version conflict/test.json
new file mode 100644
index 0000000..a31511c
--- /dev/null
+++ b/test cases/failing/118 subproject version conflict/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/118 subproject version conflict/meson.build:4:0: ERROR: Subproject B version is 100 but ['1'] required."
+ }
+ ]
+}
diff --git a/test cases/failing/119 structured source empty string/main.rs b/test cases/failing/119 structured source empty string/main.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/119 structured source empty string/main.rs
diff --git a/test cases/failing/119 structured source empty string/meson.build b/test cases/failing/119 structured source empty string/meson.build
new file mode 100644
index 0000000..0715991
--- /dev/null
+++ b/test cases/failing/119 structured source empty string/meson.build
@@ -0,0 +1,13 @@
+project('structured_source with empty string key')
+
+if not add_languages(['rust'], required : false, native : false)
+ error('MESON_SKIP_TEST: Rust is required but not found.')
+endif
+
+executable(
+ 'main',
+ structured_sources(
+ 'main.rs',
+ {'' : 'main.rs'},
+ )
+)
diff --git a/test cases/failing/119 structured source empty string/test.json b/test cases/failing/119 structured source empty string/test.json
new file mode 100644
index 0000000..3d41fc2
--- /dev/null
+++ b/test cases/failing/119 structured source empty string/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/119 structured source empty string/meson.build:7:0: ERROR: structured_sources: keys to dictionary argument may not be an empty string."
+ }
+ ]
+}
diff --git a/test cases/failing/12 string arithmetic/meson.build b/test cases/failing/12 string arithmetic/meson.build
new file mode 100644
index 0000000..8bdd451
--- /dev/null
+++ b/test cases/failing/12 string arithmetic/meson.build
@@ -0,0 +1,3 @@
+project('string arithmetic')
+
+foo = 'a' + 3
diff --git a/test cases/failing/12 string arithmetic/test.json b/test cases/failing/12 string arithmetic/test.json
new file mode 100644
index 0000000..96595c8
--- /dev/null
+++ b/test cases/failing/12 string arithmetic/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/12 string arithmetic/meson.build:3:0: ERROR: The `+` operator of str does not accept objects of type int (3)"
+ }
+ ]
+}
diff --git a/test cases/failing/120 structured_sources conflicts/main.rs b/test cases/failing/120 structured_sources conflicts/main.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/120 structured_sources conflicts/main.rs
diff --git a/test cases/failing/120 structured_sources conflicts/meson.build b/test cases/failing/120 structured_sources conflicts/meson.build
new file mode 100644
index 0000000..561ad86
--- /dev/null
+++ b/test cases/failing/120 structured_sources conflicts/meson.build
@@ -0,0 +1,17 @@
+project('structured_source with empty string key')
+
+if not add_languages(['rust'], required : false, native : false)
+ error('MESON_SKIP_TEST: Rust is required but not found.')
+endif
+
+executable(
+ 'main',
+ [
+ structured_sources(
+ 'main.rs',
+ ),
+ structured_sources(
+ 'main.rs',
+ ),
+ ],
+)
diff --git a/test cases/failing/120 structured_sources conflicts/test.json b/test cases/failing/120 structured_sources conflicts/test.json
new file mode 100644
index 0000000..2f3d1ef
--- /dev/null
+++ b/test cases/failing/120 structured_sources conflicts/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/120 structured_sources conflicts/meson.build:7:0: ERROR: Conflicting sources in structured sources: main.rs"
+ }
+ ]
+}
diff --git a/test cases/failing/121 missing compiler/meson.build b/test cases/failing/121 missing compiler/meson.build
new file mode 100644
index 0000000..19bdd0c
--- /dev/null
+++ b/test cases/failing/121 missing compiler/meson.build
@@ -0,0 +1,3 @@
+project('main project', 'c')
+
+subproject('sub')
diff --git a/test cases/failing/121 missing compiler/subprojects/sub/main.c b/test cases/failing/121 missing compiler/subprojects/sub/main.c
new file mode 100644
index 0000000..44e82e2
--- /dev/null
+++ b/test cases/failing/121 missing compiler/subprojects/sub/main.c
@@ -0,0 +1 @@
+int main(int argc, char *argv[]) { return 0; }
diff --git a/test cases/failing/121 missing compiler/subprojects/sub/meson.build b/test cases/failing/121 missing compiler/subprojects/sub/meson.build
new file mode 100644
index 0000000..b60850c
--- /dev/null
+++ b/test cases/failing/121 missing compiler/subprojects/sub/meson.build
@@ -0,0 +1,4 @@
+project('sub')
+
+# Should fail because we did not add C language, even if parent project did.
+executable('app', 'main.c')
diff --git a/test cases/failing/121 missing compiler/test.json b/test cases/failing/121 missing compiler/test.json
new file mode 100644
index 0000000..442e331
--- /dev/null
+++ b/test cases/failing/121 missing compiler/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/121 missing compiler/subprojects/sub/meson.build:4:0: ERROR: No host machine compiler for 'subprojects/sub/main.c'"
+ }
+ ]
+}
diff --git a/test cases/failing/122 cmake subproject error/meson.build b/test cases/failing/122 cmake subproject error/meson.build
new file mode 100644
index 0000000..a308239
--- /dev/null
+++ b/test cases/failing/122 cmake subproject error/meson.build
@@ -0,0 +1,8 @@
+project('cmake-executable-dependency')
+
+if not find_program('cmake', required: false).found()
+ error('MESON_SKIP_TEST CMake is not installed')
+endif
+
+cmake = import('cmake')
+cmlib = cmake.subproject('cmlib')
diff --git a/test cases/failing/122 cmake subproject error/subprojects/cmlib/CMakeLists.txt b/test cases/failing/122 cmake subproject error/subprojects/cmlib/CMakeLists.txt
new file mode 100644
index 0000000..edbe395
--- /dev/null
+++ b/test cases/failing/122 cmake subproject error/subprojects/cmlib/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(cmlib)
+
+message(FATAL_ERROR "Fancy error message")
diff --git a/test cases/failing/122 cmake subproject error/test.json b/test cases/failing/122 cmake subproject error/test.json
new file mode 100644
index 0000000..1201da2
--- /dev/null
+++ b/test cases/failing/122 cmake subproject error/test.json
@@ -0,0 +1,10 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/122 cmake subproject error/meson.build:8:0: ERROR: Failed to configure the CMake subproject: Fancy error message"
+ }
+ ],
+ "tools": {
+ "cmake": ">=3.14"
+ }
+}
diff --git a/test cases/failing/123 pkgconfig not relocatable outside prefix/meson.build b/test cases/failing/123 pkgconfig not relocatable outside prefix/meson.build
new file mode 100644
index 0000000..7ebdfc3
--- /dev/null
+++ b/test cases/failing/123 pkgconfig not relocatable outside prefix/meson.build
@@ -0,0 +1,22 @@
+project(
+ 'pkgconfig-not-relocatable-outside-prefix',
+ version : '1.0',
+ default_options: [
+ 'pkgconfig.relocatable=true',
+ ])
+
+pkgg = import('pkgconfig')
+
+# A drive letter is needed on windows for this to be an absolute path.
+if host_machine.system() == 'windows'
+ install_dir = 'C:/opt/lib/pkgconfig'
+else
+ install_dir = '/opt/lib/pkgconfig'
+endif
+
+pkgg.generate(
+ name : 'libsimple',
+ version : '1.0',
+ description : 'A simple pkgconfig file.',
+ install_dir: install_dir,
+)
diff --git a/test cases/failing/123 pkgconfig not relocatable outside prefix/test.json b/test cases/failing/123 pkgconfig not relocatable outside prefix/test.json
new file mode 100644
index 0000000..2ca1320
--- /dev/null
+++ b/test cases/failing/123 pkgconfig not relocatable outside prefix/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/123 pkgconfig not relocatable outside prefix/meson\\.build:17:5: ERROR: Pkgconfig prefix cannot be outside of the prefix when pkgconfig\\.relocatable=true. Pkgconfig prefix is (C:)?/opt/lib/pkgconfig.",
+ "match": "re"
+ }
+ ]
+}
diff --git a/test cases/failing/124 subproject sandbox violation/meson.build b/test cases/failing/124 subproject sandbox violation/meson.build
new file mode 100644
index 0000000..d41994c
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/meson.build
@@ -0,0 +1,34 @@
+project('subproject-sandbox-violation')
+
+sub1_d = subproject('subproj1').get_variable('d')
+sub1_mustfail = sub1_d.get_variable('dir') / '..' / 'file.txt'
+
+sub2_d = subproject('subproj2').get_variable('d')
+sub2_mustfail = sub2_d.get_variable('dir') / 'file.txt'
+
+main_d = declare_dependency(
+ variables: [
+ 'dir=@0@'.format(meson.current_source_dir()),
+ ]
+)
+main_mustfail = main_d.get_variable('dir') / 'subprojects/subproj3/file.txt'
+
+if get_option('failmode') == 'parent-dir'
+ mustfail = sub1_mustfail
+elif get_option('failmode') == 'not-installed'
+ mustfail = sub2_mustfail
+elif get_option('failmode') == 'root-subdir'
+ mustfail = main_mustfail
+endif
+
+custom_target(
+ 'mustfail',
+ input: mustfail,
+ output: 'file.txt',
+ command: [
+ 'python3', '-c',
+ 'import os; shutil.copy(sys.argv[1], sys.argv[2])',
+ '@INPUT@',
+ '@OUTPUT@'
+ ],
+)
diff --git a/test cases/failing/124 subproject sandbox violation/meson_options.txt b/test cases/failing/124 subproject sandbox violation/meson_options.txt
new file mode 100644
index 0000000..e7b782d
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/meson_options.txt
@@ -0,0 +1 @@
+option('failmode', type: 'combo', choices: ['parent-dir', 'not-installed', 'root-subdir'])
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/file.txt b/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/file.txt
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/meson.build b/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/meson.build
new file mode 100644
index 0000000..bd33bf3
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/meson.build
@@ -0,0 +1,4 @@
+project('subproj1')
+
+install_data('file.txt')
+subdir('nested')
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/nested/meson.build b/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/nested/meson.build
new file mode 100644
index 0000000..038c139
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj1/nested/meson.build
@@ -0,0 +1,5 @@
+d = declare_dependency(
+ variables: [
+ 'dir=@0@'.format(meson.current_source_dir()),
+ ]
+)
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/file.txt b/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/file.txt
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/meson.build b/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/meson.build
new file mode 100644
index 0000000..a6032aa
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/meson.build
@@ -0,0 +1,7 @@
+project('subproj1')
+
+d = declare_dependency(
+ variables: [
+ 'dir=@0@'.format(meson.current_source_dir()),
+ ]
+)
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/nested/meson.build b/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/nested/meson.build
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj2/nested/meson.build
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj3/file.txt b/test cases/failing/124 subproject sandbox violation/subprojects/subproj3/file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj3/file.txt
diff --git a/test cases/failing/124 subproject sandbox violation/subprojects/subproj3/meson.build b/test cases/failing/124 subproject sandbox violation/subprojects/subproj3/meson.build
new file mode 100644
index 0000000..c4fa64c
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/subprojects/subproj3/meson.build
@@ -0,0 +1,3 @@
+project('subproj2')
+
+install_data('file.txt')
diff --git a/test cases/failing/124 subproject sandbox violation/test.json b/test cases/failing/124 subproject sandbox violation/test.json
new file mode 100644
index 0000000..ca3d142
--- /dev/null
+++ b/test cases/failing/124 subproject sandbox violation/test.json
@@ -0,0 +1,16 @@
+{
+ "matrix": {
+ "options": {
+ "failmode": [
+ { "val": "not-installed" },
+ { "val": "parent-dir" },
+ { "val": "root-subdir" }
+ ]
+ }
+ },
+ "stdout": [
+ {
+ "line": "test cases/failing/124 subproject sandbox violation/meson.build:24:0: ERROR: Sandbox violation: Tried to grab file file.txt from a nested subproject."
+ }
+ ]
+}
diff --git a/test cases/failing/125 override and add_project_dependency/inc/lib.h b/test cases/failing/125 override and add_project_dependency/inc/lib.h
new file mode 100644
index 0000000..4cfc47e
--- /dev/null
+++ b/test cases/failing/125 override and add_project_dependency/inc/lib.h
@@ -0,0 +1,2 @@
+#pragma once
+void f(void);
diff --git a/test cases/failing/125 override and add_project_dependency/lib.c b/test cases/failing/125 override and add_project_dependency/lib.c
new file mode 100644
index 0000000..b8b22a3
--- /dev/null
+++ b/test cases/failing/125 override and add_project_dependency/lib.c
@@ -0,0 +1,3 @@
+#include <stdio.h>
+#include "lib.h"
+void f() {puts("hello");}
diff --git a/test cases/failing/125 override and add_project_dependency/meson.build b/test cases/failing/125 override and add_project_dependency/meson.build
new file mode 100644
index 0000000..c878b01
--- /dev/null
+++ b/test cases/failing/125 override and add_project_dependency/meson.build
@@ -0,0 +1,8 @@
+project('super', 'c')
+
+inc = include_directories('inc')
+lib = static_library('sneaky', 'lib.c', include_directories: inc)
+meson.override_dependency('sneaky',
+ declare_dependency(link_with: lib, include_directories: inc))
+
+subproject('a')
diff --git a/test cases/failing/125 override and add_project_dependency/subprojects/a/meson.build b/test cases/failing/125 override and add_project_dependency/subprojects/a/meson.build
new file mode 100644
index 0000000..4f6f070
--- /dev/null
+++ b/test cases/failing/125 override and add_project_dependency/subprojects/a/meson.build
@@ -0,0 +1,10 @@
+project('a', 'c')
+
+dep = dependency('sneaky')
+
+# does not work
+add_project_dependencies(dep, language: 'c')
+executable('prog', 'prog.c')
+
+# this would work instead:
+# executable('prog', 'prog.c', dependencies: dep)
diff --git a/test cases/failing/125 override and add_project_dependency/subprojects/a/prog.c b/test cases/failing/125 override and add_project_dependency/subprojects/a/prog.c
new file mode 100644
index 0000000..ce60f81
--- /dev/null
+++ b/test cases/failing/125 override and add_project_dependency/subprojects/a/prog.c
@@ -0,0 +1,6 @@
+#include "lib.h"
+
+int main() {
+ f();
+ return 0;
+}
diff --git a/test cases/failing/125 override and add_project_dependency/test.json b/test cases/failing/125 override and add_project_dependency/test.json
new file mode 100644
index 0000000..df749ec
--- /dev/null
+++ b/test cases/failing/125 override and add_project_dependency/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/125 override and add_project_dependency/subprojects/a/meson.build:6:0: ERROR: Dependencies must be external dependencies"
+ }
+ ]
+}
diff --git a/test cases/failing/126 targets before add_project_dependency/inc/lib.h b/test cases/failing/126 targets before add_project_dependency/inc/lib.h
new file mode 100644
index 0000000..4cfc47e
--- /dev/null
+++ b/test cases/failing/126 targets before add_project_dependency/inc/lib.h
@@ -0,0 +1,2 @@
+#pragma once
+void f(void);
diff --git a/test cases/failing/126 targets before add_project_dependency/lib.c b/test cases/failing/126 targets before add_project_dependency/lib.c
new file mode 100644
index 0000000..b8b22a3
--- /dev/null
+++ b/test cases/failing/126 targets before add_project_dependency/lib.c
@@ -0,0 +1,3 @@
+#include <stdio.h>
+#include "lib.h"
+void f() {puts("hello");}
diff --git a/test cases/failing/126 targets before add_project_dependency/meson.build b/test cases/failing/126 targets before add_project_dependency/meson.build
new file mode 100644
index 0000000..38fe102
--- /dev/null
+++ b/test cases/failing/126 targets before add_project_dependency/meson.build
@@ -0,0 +1,5 @@
+project('test', 'c')
+
+static_library('lib', 'lib.c')
+inc = include_directories('inc')
+add_project_dependencies(declare_dependency(include_directories: inc), language: 'c')
diff --git a/test cases/failing/126 targets before add_project_dependency/test.json b/test cases/failing/126 targets before add_project_dependency/test.json
new file mode 100644
index 0000000..d467914
--- /dev/null
+++ b/test cases/failing/126 targets before add_project_dependency/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/126 targets before add_project_dependency/meson.build:5:0: ERROR: Tried to use 'add_project_dependencies' after a build target has been declared."
+ }
+ ]
+}
diff --git a/test cases/failing/127 extract from unity/meson.build b/test cases/failing/127 extract from unity/meson.build
new file mode 100644
index 0000000..9e3e65f
--- /dev/null
+++ b/test cases/failing/127 extract from unity/meson.build
@@ -0,0 +1,4 @@
+project('extract nonexisting gen', 'c')
+
+lib1 = library('lib1', 'src1.c', 'src2.c', override_options: ['unity=on'])
+lib2 = library('lib2', objects: lib1.extract_objects('src1.c'))
diff --git a/test cases/failing/127 extract from unity/src1.c b/test cases/failing/127 extract from unity/src1.c
new file mode 100644
index 0000000..da971bb
--- /dev/null
+++ b/test cases/failing/127 extract from unity/src1.c
@@ -0,0 +1,3 @@
+int sub_lib_method1() {
+ return 1337;
+}
diff --git a/test cases/failing/127 extract from unity/src2.c b/test cases/failing/127 extract from unity/src2.c
new file mode 100644
index 0000000..a461669
--- /dev/null
+++ b/test cases/failing/127 extract from unity/src2.c
@@ -0,0 +1,3 @@
+int sub_lib_method2() {
+ return 1337;
+}
diff --git a/test cases/failing/127 extract from unity/test.json b/test cases/failing/127 extract from unity/test.json
new file mode 100644
index 0000000..e27599d
--- /dev/null
+++ b/test cases/failing/127 extract from unity/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/127 extract from unity/meson.build:4:0: ERROR: Single object files can not be extracted in Unity builds. You can only extract all the object files for each compiler at once."
+ }
+ ]
+}
diff --git a/test cases/failing/128 subproject object as a dependency/main.c b/test cases/failing/128 subproject object as a dependency/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/failing/128 subproject object as a dependency/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/failing/128 subproject object as a dependency/meson.build b/test cases/failing/128 subproject object as a dependency/meson.build
new file mode 100644
index 0000000..0114b9a
--- /dev/null
+++ b/test cases/failing/128 subproject object as a dependency/meson.build
@@ -0,0 +1,4 @@
+project('test', 'c')
+
+executable(
+ 'main', 'main.c', dependencies: subproject('sub'))
diff --git a/test cases/failing/128 subproject object as a dependency/subprojects/sub/meson.build b/test cases/failing/128 subproject object as a dependency/subprojects/sub/meson.build
new file mode 100644
index 0000000..0adfd6a
--- /dev/null
+++ b/test cases/failing/128 subproject object as a dependency/subprojects/sub/meson.build
@@ -0,0 +1 @@
+project('sub')
diff --git a/test cases/failing/128 subproject object as a dependency/test.json b/test cases/failing/128 subproject object as a dependency/test.json
new file mode 100644
index 0000000..b04bf37
--- /dev/null
+++ b/test cases/failing/128 subproject object as a dependency/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/128 subproject object as a dependency/meson.build:3:0: ERROR: Tried to use subproject object as a dependency."
+ }
+ ]
+}
diff --git a/test cases/failing/129 generator host binary/exe.c b/test cases/failing/129 generator host binary/exe.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/failing/129 generator host binary/exe.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/failing/129 generator host binary/lib.in b/test cases/failing/129 generator host binary/lib.in
new file mode 100644
index 0000000..d0b6ab7
--- /dev/null
+++ b/test cases/failing/129 generator host binary/lib.in
@@ -0,0 +1 @@
+int foo(void) { return 7; }
diff --git a/test cases/failing/129 generator host binary/meson.build b/test cases/failing/129 generator host binary/meson.build
new file mode 100644
index 0000000..fc1f9be
--- /dev/null
+++ b/test cases/failing/129 generator host binary/meson.build
@@ -0,0 +1,14 @@
+project('generator host binary no exe_wrapper')
+
+if meson.can_run_host_binaries()
+ error('MESON_SKIP_TEST: test requires that build machine cannot run host binaries')
+endif
+
+add_languages('c', native : false)
+
+exe = executable('exe', 'exe.c', native : false)
+
+gen = generator(exe, output : '@BASENAME@.c', arguments : ['@INPUT@', '@OUTPU@'])
+foo = gen.process('lib.in')
+
+library('foo', foo)
diff --git a/test cases/failing/129 generator host binary/test.json b/test cases/failing/129 generator host binary/test.json
new file mode 100644
index 0000000..7e354d6
--- /dev/null
+++ b/test cases/failing/129 generator host binary/test.json
@@ -0,0 +1,5 @@
+{
+ "stdout": [
+ { "line": "ERROR: An exe_wrapper is needed but was not found. Please define one in cross file and check the command and/or add it to PATH." }
+ ]
+}
diff --git a/test cases/failing/13 array arithmetic/meson.build b/test cases/failing/13 array arithmetic/meson.build
new file mode 100644
index 0000000..f43f81c
--- /dev/null
+++ b/test cases/failing/13 array arithmetic/meson.build
@@ -0,0 +1,3 @@
+project('array arithmetic')
+
+foo = ['a', 'b'] * 3
diff --git a/test cases/failing/13 array arithmetic/test.json b/test cases/failing/13 array arithmetic/test.json
new file mode 100644
index 0000000..8904775
--- /dev/null
+++ b/test cases/failing/13 array arithmetic/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/13 array arithmetic/meson.build:3:0: ERROR: Object <[ArrayHolder] holds [list]: ['a', 'b']> of type array does not support the `*` operator."
+ }
+ ]
+}
diff --git a/test cases/failing/14 invalid option name/meson.build b/test cases/failing/14 invalid option name/meson.build
new file mode 100644
index 0000000..6312312
--- /dev/null
+++ b/test cases/failing/14 invalid option name/meson.build
@@ -0,0 +1 @@
+project('foo')
diff --git a/test cases/failing/14 invalid option name/meson_options.txt b/test cases/failing/14 invalid option name/meson_options.txt
new file mode 100644
index 0000000..aab6ae8
--- /dev/null
+++ b/test cases/failing/14 invalid option name/meson_options.txt
@@ -0,0 +1 @@
+option('invalid:name', type : 'boolean', value : false)
diff --git a/test cases/failing/14 invalid option name/test.json b/test cases/failing/14 invalid option name/test.json
new file mode 100644
index 0000000..71e685d
--- /dev/null
+++ b/test cases/failing/14 invalid option name/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/14 invalid option name/meson_options.txt:1:0: ERROR: Option names can only contain letters, numbers or dashes."
+ }
+ ]
+}
diff --git a/test cases/failing/15 kwarg before arg/meson.build b/test cases/failing/15 kwarg before arg/meson.build
new file mode 100644
index 0000000..f07d950
--- /dev/null
+++ b/test cases/failing/15 kwarg before arg/meson.build
@@ -0,0 +1,3 @@
+project('kwarg before arg', 'c')
+
+executable(sources : 'prog.c', 'prog')
diff --git a/test cases/failing/15 kwarg before arg/prog.c b/test cases/failing/15 kwarg before arg/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/failing/15 kwarg before arg/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/failing/15 kwarg before arg/test.json b/test cases/failing/15 kwarg before arg/test.json
new file mode 100644
index 0000000..c7f72c3
--- /dev/null
+++ b/test cases/failing/15 kwarg before arg/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/15 kwarg before arg/meson.build:3:0: ERROR: All keyword arguments must be after positional arguments."
+ }
+ ]
+}
diff --git a/test cases/failing/16 extract from subproject/main.c b/test cases/failing/16 extract from subproject/main.c
new file mode 100644
index 0000000..6c8ecae
--- /dev/null
+++ b/test cases/failing/16 extract from subproject/main.c
@@ -0,0 +1,5 @@
+int sub_lib_method(void);
+
+int main(void) {
+ return 1337 - sub_lib_method();
+}
diff --git a/test cases/failing/16 extract from subproject/meson.build b/test cases/failing/16 extract from subproject/meson.build
new file mode 100644
index 0000000..286aaa1
--- /dev/null
+++ b/test cases/failing/16 extract from subproject/meson.build
@@ -0,0 +1,9 @@
+project('extract subproject object', 'c')
+
+sub = subproject('sub_project')
+lib = sub.get_variable('lib')
+
+exe = executable('exe', 'main.c',
+ objects : lib.extract_objects('sub_lib.c'))
+
+test('extraction test', exe)
diff --git a/test cases/failing/16 extract from subproject/subprojects/sub_project/meson.build b/test cases/failing/16 extract from subproject/subprojects/sub_project/meson.build
new file mode 100644
index 0000000..0810df5
--- /dev/null
+++ b/test cases/failing/16 extract from subproject/subprojects/sub_project/meson.build
@@ -0,0 +1,3 @@
+project('extract subproject object -- subproject', 'c')
+
+lib = library('sub_lib', 'sub_lib.c')
diff --git a/test cases/failing/16 extract from subproject/subprojects/sub_project/sub_lib.c b/test cases/failing/16 extract from subproject/subprojects/sub_project/sub_lib.c
new file mode 100644
index 0000000..be3c9aa
--- /dev/null
+++ b/test cases/failing/16 extract from subproject/subprojects/sub_project/sub_lib.c
@@ -0,0 +1,3 @@
+int sub_lib_method() {
+ return 1337;
+}
diff --git a/test cases/failing/16 extract from subproject/test.json b/test cases/failing/16 extract from subproject/test.json
new file mode 100644
index 0000000..2e32904
--- /dev/null
+++ b/test cases/failing/16 extract from subproject/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/16 extract from subproject/meson.build:6:0: ERROR: Tried to extract objects from a different subproject."
+ }
+ ]
+}
diff --git a/test cases/failing/17 same target/file.c b/test cases/failing/17 same target/file.c
new file mode 100644
index 0000000..7412372
--- /dev/null
+++ b/test cases/failing/17 same target/file.c
@@ -0,0 +1 @@
+int func() { return 0; }
diff --git a/test cases/failing/17 same target/meson.build b/test cases/failing/17 same target/meson.build
new file mode 100644
index 0000000..ee586d0
--- /dev/null
+++ b/test cases/failing/17 same target/meson.build
@@ -0,0 +1,4 @@
+project('same target', 'c')
+
+static_library('foo', 'file.c')
+static_library('foo', 'file.c')
diff --git a/test cases/failing/17 same target/test.json b/test cases/failing/17 same target/test.json
new file mode 100644
index 0000000..0005ba4
--- /dev/null
+++ b/test cases/failing/17 same target/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/17 same target/meson.build:4:0: ERROR: Tried to create target \"foo\", but a target of that name already exists."
+ }
+ ]
+}
diff --git a/test cases/failing/18 wrong plusassign/meson.build b/test cases/failing/18 wrong plusassign/meson.build
new file mode 100644
index 0000000..af7727a
--- /dev/null
+++ b/test cases/failing/18 wrong plusassign/meson.build
@@ -0,0 +1,3 @@
+project('false plusassign')
+
+3 += 4
diff --git a/test cases/failing/18 wrong plusassign/test.json b/test cases/failing/18 wrong plusassign/test.json
new file mode 100644
index 0000000..c698f85
--- /dev/null
+++ b/test cases/failing/18 wrong plusassign/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/18 wrong plusassign/meson.build:3:0: ERROR: Plusassignment target must be an id."
+ }
+ ]
+}
diff --git a/test cases/failing/19 target clash/clash.c b/test cases/failing/19 target clash/clash.c
new file mode 100644
index 0000000..2daa06c
--- /dev/null
+++ b/test cases/failing/19 target clash/clash.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("Clash 2.\n");
+ return 0;
+}
diff --git a/test cases/failing/19 target clash/meson.build b/test cases/failing/19 target clash/meson.build
new file mode 100644
index 0000000..4fd0934
--- /dev/null
+++ b/test cases/failing/19 target clash/meson.build
@@ -0,0 +1,15 @@
+project('clash', 'c')
+
+# This setup causes a namespace clash when two Meson targets would
+# produce a Ninja targets with the same name. It only works on
+# unix, because on Windows the target has a '.exe' suffix.
+#
+# This test might fail to work on different backends or when
+# output location is redirected.
+
+if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST test only works on platforms where executables have no suffix.')
+endif
+
+executable('clash', 'clash.c')
+run_target('clash', command: ['echo', 'clash 1'])
diff --git a/test cases/failing/19 target clash/test.json b/test cases/failing/19 target clash/test.json
new file mode 100644
index 0000000..d22b894
--- /dev/null
+++ b/test cases/failing/19 target clash/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "ERROR: Multiple producers for Ninja target \"clash\". Please rename your targets."
+ }
+ ]
+}
diff --git a/test cases/failing/2 missing file/meson.build b/test cases/failing/2 missing file/meson.build
new file mode 100644
index 0000000..6b9133d
--- /dev/null
+++ b/test cases/failing/2 missing file/meson.build
@@ -0,0 +1,3 @@
+project('missing file', 'c')
+
+executable('prog', 'missing.c')
diff --git a/test cases/failing/2 missing file/test.json b/test cases/failing/2 missing file/test.json
new file mode 100644
index 0000000..b95b8b0
--- /dev/null
+++ b/test cases/failing/2 missing file/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/2 missing file/meson.build:3:0: ERROR: File missing.c does not exist."
+ }
+ ]
+}
diff --git a/test cases/failing/20 version/meson.build b/test cases/failing/20 version/meson.build
new file mode 100644
index 0000000..d25a395
--- /dev/null
+++ b/test cases/failing/20 version/meson.build
@@ -0,0 +1 @@
+project('version mismatch', meson_version : '>100.0.0')
diff --git a/test cases/failing/20 version/test.json b/test cases/failing/20 version/test.json
new file mode 100644
index 0000000..f330624
--- /dev/null
+++ b/test cases/failing/20 version/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": "test cases/failing/20 version/meson\\.build:1:0: ERROR: Meson version is .* but project requires >100\\.0\\.0"
+ }
+ ]
+}
diff --git a/test cases/failing/21 subver/meson.build b/test cases/failing/21 subver/meson.build
new file mode 100644
index 0000000..ea0f914
--- /dev/null
+++ b/test cases/failing/21 subver/meson.build
@@ -0,0 +1,3 @@
+project('master')
+
+x = subproject('foo', version : '>1.0.0')
diff --git a/test cases/failing/21 subver/subprojects/foo/meson.build b/test cases/failing/21 subver/subprojects/foo/meson.build
new file mode 100644
index 0000000..615ee92
--- /dev/null
+++ b/test cases/failing/21 subver/subprojects/foo/meson.build
@@ -0,0 +1 @@
+project('foo', version : '1.0.0')
diff --git a/test cases/failing/21 subver/test.json b/test cases/failing/21 subver/test.json
new file mode 100644
index 0000000..a197b36
--- /dev/null
+++ b/test cases/failing/21 subver/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/21 subver/meson.build:3:0: ERROR: Subproject foo version is 1.0.0 but ['>1.0.0'] required."
+ }
+ ]
+}
diff --git a/test cases/failing/22 assert/meson.build b/test cases/failing/22 assert/meson.build
new file mode 100644
index 0000000..45cff07
--- /dev/null
+++ b/test cases/failing/22 assert/meson.build
@@ -0,0 +1,3 @@
+project('failing assert')
+
+assert(false, 'I am fail.')
diff --git a/test cases/failing/22 assert/test.json b/test cases/failing/22 assert/test.json
new file mode 100644
index 0000000..edae999
--- /dev/null
+++ b/test cases/failing/22 assert/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/22 assert/meson.build:3:0: ERROR: Assert failed: I am fail."
+ }
+ ]
+}
diff --git a/test cases/failing/23 rel testdir/meson.build b/test cases/failing/23 rel testdir/meson.build
new file mode 100644
index 0000000..c10558b
--- /dev/null
+++ b/test cases/failing/23 rel testdir/meson.build
@@ -0,0 +1,4 @@
+project('nonabs workdir', 'c')
+
+exe = executable('simple', 'simple.c')
+test('simple', exe, workdir : '.')
diff --git a/test cases/failing/23 rel testdir/simple.c b/test cases/failing/23 rel testdir/simple.c
new file mode 100644
index 0000000..11b7fad
--- /dev/null
+++ b/test cases/failing/23 rel testdir/simple.c
@@ -0,0 +1,3 @@
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/failing/23 rel testdir/test.json b/test cases/failing/23 rel testdir/test.json
new file mode 100644
index 0000000..bc80bc6
--- /dev/null
+++ b/test cases/failing/23 rel testdir/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/23 rel testdir/meson.build:4:0: ERROR: test keyword argument \"workdir\" must be an absolute path"
+ }
+ ]
+}
diff --git a/test cases/failing/24 int conversion/meson.build b/test cases/failing/24 int conversion/meson.build
new file mode 100644
index 0000000..8db72f3
--- /dev/null
+++ b/test cases/failing/24 int conversion/meson.build
@@ -0,0 +1,3 @@
+project('int conversion')
+
+'notanumber'.to_int()
diff --git a/test cases/failing/24 int conversion/test.json b/test cases/failing/24 int conversion/test.json
new file mode 100644
index 0000000..e749928
--- /dev/null
+++ b/test cases/failing/24 int conversion/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/24 int conversion/meson.build:3:13: ERROR: String 'notanumber' cannot be converted to int"
+ }
+ ]
+}
diff --git a/test cases/failing/25 badlang/meson.build b/test cases/failing/25 badlang/meson.build
new file mode 100644
index 0000000..a31059b
--- /dev/null
+++ b/test cases/failing/25 badlang/meson.build
@@ -0,0 +1,3 @@
+project('badlang')
+
+add_languages('nonexisting')
diff --git a/test cases/failing/25 badlang/test.json b/test cases/failing/25 badlang/test.json
new file mode 100644
index 0000000..0b23fd7
--- /dev/null
+++ b/test cases/failing/25 badlang/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/25 badlang/meson.build:3:0: ERROR: Tried to use unknown language \"nonexisting\"."
+ }
+ ]
+}
diff --git a/test cases/failing/26 output subdir/foo.in b/test cases/failing/26 output subdir/foo.in
new file mode 100644
index 0000000..3d1bf19
--- /dev/null
+++ b/test cases/failing/26 output subdir/foo.in
@@ -0,0 +1 @@
+Nothing here.
diff --git a/test cases/failing/26 output subdir/meson.build b/test cases/failing/26 output subdir/meson.build
new file mode 100644
index 0000000..c4bd806
--- /dev/null
+++ b/test cases/failing/26 output subdir/meson.build
@@ -0,0 +1,5 @@
+project('outdir path')
+
+configure_file(input : 'foo.in',
+ output : 'subdir/foo',
+ copy: true)
diff --git a/test cases/failing/26 output subdir/subdir/dummy.txt b/test cases/failing/26 output subdir/subdir/dummy.txt
new file mode 100644
index 0000000..7e907f1
--- /dev/null
+++ b/test cases/failing/26 output subdir/subdir/dummy.txt
@@ -0,0 +1 @@
+I'm only here because Git is stupid about empty dirs.
diff --git a/test cases/failing/26 output subdir/test.json b/test cases/failing/26 output subdir/test.json
new file mode 100644
index 0000000..df09726
--- /dev/null
+++ b/test cases/failing/26 output subdir/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/26 output subdir/meson.build:3:0: ERROR: configure_file keyword argument \"output\" Output 'subdir/foo' must not contain a path segment."
+ }
+ ]
+}
diff --git a/test cases/failing/27 noprog use/meson.build b/test cases/failing/27 noprog use/meson.build
new file mode 100644
index 0000000..af31ece
--- /dev/null
+++ b/test cases/failing/27 noprog use/meson.build
@@ -0,0 +1,9 @@
+project('using not found exe')
+
+nope = find_program('nonexisting', required : false)
+
+custom_target( 'aa',
+ input: 'meson.build',
+ output: 'foobar',
+ command: [nope, '@INPUT@', '@OUTPUT@']
+)
diff --git a/test cases/failing/27 noprog use/test.json b/test cases/failing/27 noprog use/test.json
new file mode 100644
index 0000000..b84562e
--- /dev/null
+++ b/test cases/failing/27 noprog use/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/27 noprog use/meson.build:5:0: ERROR: Tried to use not-found external program in \"command\""
+ }
+ ]
+}
diff --git a/test cases/failing/28 no crossprop/meson.build b/test cases/failing/28 no crossprop/meson.build
new file mode 100644
index 0000000..9152077
--- /dev/null
+++ b/test cases/failing/28 no crossprop/meson.build
@@ -0,0 +1,3 @@
+project('no crossprop')
+
+message(meson.get_cross_property('nonexisting'))
diff --git a/test cases/failing/28 no crossprop/test.json b/test cases/failing/28 no crossprop/test.json
new file mode 100644
index 0000000..6fb9dce
--- /dev/null
+++ b/test cases/failing/28 no crossprop/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/28 no crossprop/meson.build:3:0: ERROR: Unknown property for host machine: nonexisting"
+ }
+ ]
+}
diff --git a/test cases/failing/29 nested ternary/meson.build b/test cases/failing/29 nested ternary/meson.build
new file mode 100644
index 0000000..76364ce
--- /dev/null
+++ b/test cases/failing/29 nested ternary/meson.build
@@ -0,0 +1,3 @@
+project('nested ternary')
+
+x = true ? (false ? 1 : 0) : 2
diff --git a/test cases/failing/29 nested ternary/test.json b/test cases/failing/29 nested ternary/test.json
new file mode 100644
index 0000000..ba05013
--- /dev/null
+++ b/test cases/failing/29 nested ternary/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/29 nested ternary/meson.build:3:12: ERROR: Nested ternary operators are not allowed."
+ }
+ ]
+}
diff --git a/test cases/failing/3 missing subdir/meson.build b/test cases/failing/3 missing subdir/meson.build
new file mode 100644
index 0000000..9301c1e
--- /dev/null
+++ b/test cases/failing/3 missing subdir/meson.build
@@ -0,0 +1,3 @@
+project('subdir')
+
+subdir('missing')
diff --git a/test cases/failing/3 missing subdir/test.json b/test cases/failing/3 missing subdir/test.json
new file mode 100644
index 0000000..562de25
--- /dev/null
+++ b/test cases/failing/3 missing subdir/test.json
@@ -0,0 +1,9 @@
+{
+ "stdout": [
+ {
+ "comment": "'missing/meson.build' gets transformed with os.path.sep separators",
+ "match": "re",
+ "line": "test cases/failing/3 missing subdir/meson\\.build:3:0: ERROR: Non\\-existent build file 'missing[\\\\/]meson\\.build'"
+ }
+ ]
+}
diff --git a/test cases/failing/30 invalid man extension/foo.a1 b/test cases/failing/30 invalid man extension/foo.a1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/30 invalid man extension/foo.a1
diff --git a/test cases/failing/30 invalid man extension/meson.build b/test cases/failing/30 invalid man extension/meson.build
new file mode 100644
index 0000000..b3694d5
--- /dev/null
+++ b/test cases/failing/30 invalid man extension/meson.build
@@ -0,0 +1,2 @@
+project('man install')
+m1 = install_man('foo.a1')
diff --git a/test cases/failing/30 invalid man extension/test.json b/test cases/failing/30 invalid man extension/test.json
new file mode 100644
index 0000000..3e5f45d
--- /dev/null
+++ b/test cases/failing/30 invalid man extension/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/30 invalid man extension/meson.build:2:0: ERROR: Man file must have a file extension of a number between 1 and 9"
+ }
+ ]
+}
diff --git a/test cases/failing/31 no man extension/foo b/test cases/failing/31 no man extension/foo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/31 no man extension/foo
diff --git a/test cases/failing/31 no man extension/meson.build b/test cases/failing/31 no man extension/meson.build
new file mode 100644
index 0000000..33fdd3e
--- /dev/null
+++ b/test cases/failing/31 no man extension/meson.build
@@ -0,0 +1,2 @@
+project('man install')
+m1 = install_man('foo')
diff --git a/test cases/failing/31 no man extension/test.json b/test cases/failing/31 no man extension/test.json
new file mode 100644
index 0000000..0972da1
--- /dev/null
+++ b/test cases/failing/31 no man extension/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/31 no man extension/meson.build:2:0: ERROR: Man file must have a file extension of a number between 1 and 9"
+ }
+ ]
+}
diff --git a/test cases/failing/32 exe static shared/meson.build b/test cases/failing/32 exe static shared/meson.build
new file mode 100644
index 0000000..2ae5125
--- /dev/null
+++ b/test cases/failing/32 exe static shared/meson.build
@@ -0,0 +1,11 @@
+project('statchain', 'c')
+
+host_system = host_machine.system()
+if host_system == 'windows' or host_system == 'darwin'
+ error('MESON_SKIP_TEST test only fails on Linux and BSD')
+endif
+
+statlib = static_library('stat', 'stat.c', pic : false)
+shlib2 = shared_library('shr2', 'shlib2.c', link_with : statlib)
+exe = executable('prog', 'prog.c', link_with : shlib2)
+test('runtest', exe)
diff --git a/test cases/failing/32 exe static shared/prog.c b/test cases/failing/32 exe static shared/prog.c
new file mode 100644
index 0000000..26603b6
--- /dev/null
+++ b/test cases/failing/32 exe static shared/prog.c
@@ -0,0 +1,10 @@
+int shlibfunc2();
+int statlibfunc();
+
+int main(int argc, char **argv) {
+ if (statlibfunc() != 42)
+ return 1;
+ if (shlibfunc2() != 24)
+ return 1;
+ return 0;
+}
diff --git a/test cases/failing/32 exe static shared/shlib2.c b/test cases/failing/32 exe static shared/shlib2.c
new file mode 100644
index 0000000..5b68843
--- /dev/null
+++ b/test cases/failing/32 exe static shared/shlib2.c
@@ -0,0 +1,16 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int statlibfunc(void);
+
+int DLL_PUBLIC shlibfunc2(void) {
+ return 24;
+}
diff --git a/test cases/failing/32 exe static shared/stat.c b/test cases/failing/32 exe static shared/stat.c
new file mode 100644
index 0000000..56ec66c
--- /dev/null
+++ b/test cases/failing/32 exe static shared/stat.c
@@ -0,0 +1,3 @@
+int statlibfunc() {
+ return 42;
+}
diff --git a/test cases/failing/32 exe static shared/test.json b/test cases/failing/32 exe static shared/test.json
new file mode 100644
index 0000000..51d3804
--- /dev/null
+++ b/test cases/failing/32 exe static shared/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/32 exe static shared/meson.build:9:0: ERROR: Can't link non-PIC static library 'stat' into shared library 'shr2'. Use the 'pic' option to static_library to build with PIC."
+ }
+ ]
+}
diff --git a/test cases/failing/33 non-root subproject/meson.build b/test cases/failing/33 non-root subproject/meson.build
new file mode 100644
index 0000000..65b1d23
--- /dev/null
+++ b/test cases/failing/33 non-root subproject/meson.build
@@ -0,0 +1,3 @@
+project('non-root subproject')
+
+subdir('some')
diff --git a/test cases/failing/33 non-root subproject/some/meson.build b/test cases/failing/33 non-root subproject/some/meson.build
new file mode 100644
index 0000000..d82f451
--- /dev/null
+++ b/test cases/failing/33 non-root subproject/some/meson.build
@@ -0,0 +1 @@
+dependency('definitely-doesnt-exist', fallback : ['someproj', 'some_dep'])
diff --git a/test cases/failing/33 non-root subproject/test.json b/test cases/failing/33 non-root subproject/test.json
new file mode 100644
index 0000000..52baf6a
--- /dev/null
+++ b/test cases/failing/33 non-root subproject/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/33 non-root subproject/some/meson.build:1:0: ERROR: Neither a subproject directory nor a someproj.wrap file was found."
+ }
+ ]
+}
diff --git a/test cases/failing/34 dependency not-required then required/meson.build b/test cases/failing/34 dependency not-required then required/meson.build
new file mode 100644
index 0000000..54f5a58
--- /dev/null
+++ b/test cases/failing/34 dependency not-required then required/meson.build
@@ -0,0 +1,4 @@
+project('dep-test', version : '1.0')
+
+foo_dep = dependency('foo-bar-xyz-12.3', required : false)
+bar_dep = dependency('foo-bar-xyz-12.3')
diff --git a/test cases/failing/34 dependency not-required then required/test.json b/test cases/failing/34 dependency not-required then required/test.json
new file mode 100644
index 0000000..3cf35f5
--- /dev/null
+++ b/test cases/failing/34 dependency not-required then required/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": ".*/meson\\.build:4:0: ERROR: (Pkg-config binary for machine MachineChoice\\.HOST not found\\. Giving up\\.|Dependency \"foo\\-bar\\-xyz\\-12\\.3\" not found, tried .*)"
+ }
+ ]
+}
diff --git a/test cases/failing/35 project argument after target/exe.c b/test cases/failing/35 project argument after target/exe.c
new file mode 100644
index 0000000..11b7fad
--- /dev/null
+++ b/test cases/failing/35 project argument after target/exe.c
@@ -0,0 +1,3 @@
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/failing/35 project argument after target/meson.build b/test cases/failing/35 project argument after target/meson.build
new file mode 100644
index 0000000..5402c67
--- /dev/null
+++ b/test cases/failing/35 project argument after target/meson.build
@@ -0,0 +1,7 @@
+project('project argument after target failing', 'c',
+ version : '2.3.4',
+ license : 'mylicense')
+
+add_project_arguments('-DPROJECT_OPTION', language: 'c')
+e = executable('exe', 'exe.c')
+add_project_arguments('-DPROJECT_OPTION1', language: 'c')
diff --git a/test cases/failing/35 project argument after target/test.json b/test cases/failing/35 project argument after target/test.json
new file mode 100644
index 0000000..f5efd9b
--- /dev/null
+++ b/test cases/failing/35 project argument after target/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/35 project argument after target/meson.build:7:0: ERROR: Tried to use 'add_project_arguments' after a build target has been declared."
+ }
+ ]
+}
diff --git a/test cases/failing/36 pkgconfig dependency impossible conditions/meson.build b/test cases/failing/36 pkgconfig dependency impossible conditions/meson.build
new file mode 100644
index 0000000..874b581
--- /dev/null
+++ b/test cases/failing/36 pkgconfig dependency impossible conditions/meson.build
@@ -0,0 +1,7 @@
+project('impossible-dep-test', 'c', version : '1.0')
+
+if not dependency('zlib', required: false).found()
+ error('MESON_SKIP_TEST test requires zlib')
+endif
+
+dependency('zlib', version : ['>=1.0', '<1.0'])
diff --git a/test cases/failing/36 pkgconfig dependency impossible conditions/test.json b/test cases/failing/36 pkgconfig dependency impossible conditions/test.json
new file mode 100644
index 0000000..6deddbe
--- /dev/null
+++ b/test cases/failing/36 pkgconfig dependency impossible conditions/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/36 pkgconfig dependency impossible conditions/meson.build:7:0: ERROR: Dependency 'zlib' is required but not found."
+ }
+ ]
+}
diff --git a/test cases/failing/37 has function external dependency/meson.build b/test cases/failing/37 has function external dependency/meson.build
new file mode 100644
index 0000000..45a3bc2
--- /dev/null
+++ b/test cases/failing/37 has function external dependency/meson.build
@@ -0,0 +1,8 @@
+project('has function ext dep', 'c')
+
+cc = meson.get_compiler('c')
+
+mylib = shared_library('mylib', 'mylib.c')
+mylib_dep = declare_dependency(link_with : mylib)
+# Only external dependencies can work here
+cc.has_function('malloc', dependencies : mylib_dep)
diff --git a/test cases/failing/37 has function external dependency/mylib.c b/test cases/failing/37 has function external dependency/mylib.c
new file mode 100644
index 0000000..d9fbd34
--- /dev/null
+++ b/test cases/failing/37 has function external dependency/mylib.c
@@ -0,0 +1 @@
+int testfunc(void) { return 0; }
diff --git a/test cases/failing/37 has function external dependency/test.json b/test cases/failing/37 has function external dependency/test.json
new file mode 100644
index 0000000..81d6f91
--- /dev/null
+++ b/test cases/failing/37 has function external dependency/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/37 has function external dependency/meson.build:8:3: ERROR: Dependencies must be external dependencies"
+ }
+ ]
+}
diff --git a/test cases/failing/38 prefix absolute/meson.build b/test cases/failing/38 prefix absolute/meson.build
new file mode 100644
index 0000000..6d0114b
--- /dev/null
+++ b/test cases/failing/38 prefix absolute/meson.build
@@ -0,0 +1,2 @@
+project('prefix-abs',
+ default_options : ['prefix=some/path/notabs'])
diff --git a/test cases/failing/38 prefix absolute/test.json b/test cases/failing/38 prefix absolute/test.json
new file mode 100644
index 0000000..859906c
--- /dev/null
+++ b/test cases/failing/38 prefix absolute/test.json
@@ -0,0 +1,11 @@
+{
+ "do_not_set_opts": [
+ "prefix"
+ ],
+ "stdout": [
+ {
+ "comment": "literal 'some/path/notabs' appears in output, irrespective of os.path.sep, as that's the prefix",
+ "line": "test cases/failing/38 prefix absolute/meson.build:1:0: ERROR: prefix value 'some/path/notabs' must be an absolute path"
+ }
+ ]
+}
diff --git a/test cases/failing/39 kwarg assign/dummy.c b/test cases/failing/39 kwarg assign/dummy.c
new file mode 100644
index 0000000..16fcdd9
--- /dev/null
+++ b/test cases/failing/39 kwarg assign/dummy.c
@@ -0,0 +1,3 @@
+const char* dummy() {
+ return "I do nothing.";
+}
diff --git a/test cases/failing/39 kwarg assign/meson.build b/test cases/failing/39 kwarg assign/meson.build
new file mode 100644
index 0000000..7d42521
--- /dev/null
+++ b/test cases/failing/39 kwarg assign/meson.build
@@ -0,0 +1,3 @@
+project('assign in kwarg', 'c')
+
+executable('prog', 'dummy.c', args = 'prog.c')
diff --git a/test cases/failing/39 kwarg assign/prog.c b/test cases/failing/39 kwarg assign/prog.c
new file mode 100644
index 0000000..11b7fad
--- /dev/null
+++ b/test cases/failing/39 kwarg assign/prog.c
@@ -0,0 +1,3 @@
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/failing/39 kwarg assign/test.json b/test cases/failing/39 kwarg assign/test.json
new file mode 100644
index 0000000..8fd9d0f
--- /dev/null
+++ b/test cases/failing/39 kwarg assign/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/39 kwarg assign/meson.build:3:0: ERROR: Tried to assign values inside an argument list."
+ }
+ ]
+}
diff --git a/test cases/failing/4 missing meson.build/meson.build b/test cases/failing/4 missing meson.build/meson.build
new file mode 100644
index 0000000..20f754c
--- /dev/null
+++ b/test cases/failing/4 missing meson.build/meson.build
@@ -0,0 +1,3 @@
+project('missing meson.build')
+
+subdir('subdir')
diff --git a/test cases/failing/4 missing meson.build/subdir/dummy.txt b/test cases/failing/4 missing meson.build/subdir/dummy.txt
new file mode 100644
index 0000000..03327bd
--- /dev/null
+++ b/test cases/failing/4 missing meson.build/subdir/dummy.txt
@@ -0,0 +1 @@
+This needs to be here because Git can't handle empty dirs.
diff --git a/test cases/failing/4 missing meson.build/test.json b/test cases/failing/4 missing meson.build/test.json
new file mode 100644
index 0000000..3857090
--- /dev/null
+++ b/test cases/failing/4 missing meson.build/test.json
@@ -0,0 +1,9 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "comment": "'subdir/meson.build' gets transformed with os.path.sep separators",
+ "line": "test cases/failing/4 missing meson\\.build/meson\\.build:3:0: ERROR: Non\\-existent build file 'subdir[\\\\/]meson\\.build'"
+ }
+ ]
+}
diff --git a/test cases/failing/40 custom target plainname many inputs/1.txt b/test cases/failing/40 custom target plainname many inputs/1.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/test cases/failing/40 custom target plainname many inputs/1.txt
@@ -0,0 +1 @@
+1
diff --git a/test cases/failing/40 custom target plainname many inputs/2.txt b/test cases/failing/40 custom target plainname many inputs/2.txt
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/test cases/failing/40 custom target plainname many inputs/2.txt
@@ -0,0 +1 @@
+2
diff --git a/test cases/failing/40 custom target plainname many inputs/catfiles.py b/test cases/failing/40 custom target plainname many inputs/catfiles.py
new file mode 100644
index 0000000..1c53e24
--- /dev/null
+++ b/test cases/failing/40 custom target plainname many inputs/catfiles.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import sys
+
+out = sys.argv[-1]
+with open(out, 'wb') as o:
+ for infile in sys.argv[1:-1]:
+ with open(infile, 'rb') as f:
+ o.write(f.read())
diff --git a/test cases/failing/40 custom target plainname many inputs/meson.build b/test cases/failing/40 custom target plainname many inputs/meson.build
new file mode 100644
index 0000000..8513bf8
--- /dev/null
+++ b/test cases/failing/40 custom target plainname many inputs/meson.build
@@ -0,0 +1,8 @@
+project('plain name many inputs')
+
+catfiles = find_program('catfiles.py')
+
+custom_target('plainname-inputs',
+ input : ['1.txt', '2.txt'],
+ output : '@PLAINNAME@.dat',
+ command : [catfiles, '@INPUT@', '@OUTPUT@'])
diff --git a/test cases/failing/40 custom target plainname many inputs/test.json b/test cases/failing/40 custom target plainname many inputs/test.json
new file mode 100644
index 0000000..f5c3abf
--- /dev/null
+++ b/test cases/failing/40 custom target plainname many inputs/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/40 custom target plainname many inputs/meson.build:5:0: ERROR: custom_target: output cannot contain \"@PLAINNAME@\" or \"@BASENAME@\" when there is more than one input (we can't know which to use)"
+ }
+ ]
+}
diff --git a/test cases/failing/41 custom target outputs not matching install_dirs/generator.py b/test cases/failing/41 custom target outputs not matching install_dirs/generator.py
new file mode 100755
index 0000000..4ac6179
--- /dev/null
+++ b/test cases/failing/41 custom target outputs not matching install_dirs/generator.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import sys, os
+
+if len(sys.argv) != 3:
+ print(sys.argv[0], '<namespace>', '<output dir>')
+
+name = sys.argv[1]
+odir = sys.argv[2]
+
+with open(os.path.join(odir, name + '.h'), 'w') as f:
+ f.write('int func();\n')
+with open(os.path.join(odir, name + '.c'), 'w') as f:
+ f.write('int main(int argc, char *argv[]) { return 0; }')
+with open(os.path.join(odir, name + '.sh'), 'w') as f:
+ f.write('#!/bin/bash')
diff --git a/test cases/failing/41 custom target outputs not matching install_dirs/meson.build b/test cases/failing/41 custom target outputs not matching install_dirs/meson.build
new file mode 100644
index 0000000..ed99dba
--- /dev/null
+++ b/test cases/failing/41 custom target outputs not matching install_dirs/meson.build
@@ -0,0 +1,13 @@
+project('outputs not matching install_dirs')
+
+gen = find_program('generator.py')
+
+if meson.backend() != 'ninja'
+ error('MESON_SKIP_TEST test is only for the ninja backend')
+endif
+
+custom_target('too-few-install-dirs',
+ output : ['toofew.h', 'toofew.c', 'toofew.sh'],
+ command : [gen, 'toofew', '@OUTDIR@'],
+ install : true,
+ install_dir : [join_paths(get_option('prefix'), get_option('includedir')), false])
diff --git a/test cases/failing/41 custom target outputs not matching install_dirs/test.json b/test cases/failing/41 custom target outputs not matching install_dirs/test.json
new file mode 100644
index 0000000..f9e2ba7
--- /dev/null
+++ b/test cases/failing/41 custom target outputs not matching install_dirs/test.json
@@ -0,0 +1,33 @@
+{
+ "installed": [
+ {
+ "type": "file",
+ "file": "usr/include/diff.h"
+ },
+ {
+ "type": "file",
+ "file": "usr/include/first.h"
+ },
+ {
+ "type": "file",
+ "file": "usr/bin/diff.sh"
+ },
+ {
+ "type": "file",
+ "file": "usr/bin/second.sh"
+ },
+ {
+ "type": "file",
+ "file": "opt/same.h"
+ },
+ {
+ "type": "file",
+ "file": "opt/same.sh"
+ }
+ ],
+ "stdout": [
+ {
+ "line": "ERROR: Target 'too-few-install-dirs' has 3 outputs: ['toofew.h', 'toofew.c', 'toofew.sh'], but only 2 \"install_dir\"s were found."
+ }
+ ]
+}
diff --git a/test cases/failing/42 project name colon/meson.build b/test cases/failing/42 project name colon/meson.build
new file mode 100644
index 0000000..53e947e
--- /dev/null
+++ b/test cases/failing/42 project name colon/meson.build
@@ -0,0 +1 @@
+project('name with :')
diff --git a/test cases/failing/42 project name colon/test.json b/test cases/failing/42 project name colon/test.json
new file mode 100644
index 0000000..c3b880e
--- /dev/null
+++ b/test cases/failing/42 project name colon/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/42 project name colon/meson.build:1:0: ERROR: Project name 'name with :' must not contain ':'"
+ }
+ ]
+}
diff --git a/test cases/failing/43 abs subdir/bob/meson.build b/test cases/failing/43 abs subdir/bob/meson.build
new file mode 100644
index 0000000..7bbf4b2
--- /dev/null
+++ b/test cases/failing/43 abs subdir/bob/meson.build
@@ -0,0 +1,2 @@
+# This file is never reached.
+x = 3
diff --git a/test cases/failing/43 abs subdir/meson.build b/test cases/failing/43 abs subdir/meson.build
new file mode 100644
index 0000000..a8534d0
--- /dev/null
+++ b/test cases/failing/43 abs subdir/meson.build
@@ -0,0 +1,5 @@
+project('abs subdir')
+
+# For some reason people insist on doing this, probably
+# because Make has taught them to never rely on anything.
+subdir(join_paths(meson.source_root(), 'bob'))
diff --git a/test cases/failing/43 abs subdir/test.json b/test cases/failing/43 abs subdir/test.json
new file mode 100644
index 0000000..201ed44
--- /dev/null
+++ b/test cases/failing/43 abs subdir/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/43 abs subdir/meson.build:5:0: ERROR: Subdir argument must be a relative path."
+ }
+ ]
+}
diff --git a/test cases/failing/44 abspath to srcdir/meson.build b/test cases/failing/44 abspath to srcdir/meson.build
new file mode 100644
index 0000000..78c6124
--- /dev/null
+++ b/test cases/failing/44 abspath to srcdir/meson.build
@@ -0,0 +1,3 @@
+project('meson')
+
+include_directories(meson.current_source_dir())
diff --git a/test cases/failing/44 abspath to srcdir/test.json b/test cases/failing/44 abspath to srcdir/test.json
new file mode 100644
index 0000000..c64ecfb
--- /dev/null
+++ b/test cases/failing/44 abspath to srcdir/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/44 abspath to srcdir/meson.build:3:0: ERROR: Tried to form an absolute path to a dir in the source tree."
+ }
+ ]
+}
diff --git a/test cases/failing/45 pkgconfig variables reserved/meson.build b/test cases/failing/45 pkgconfig variables reserved/meson.build
new file mode 100644
index 0000000..82ae995
--- /dev/null
+++ b/test cases/failing/45 pkgconfig variables reserved/meson.build
@@ -0,0 +1,16 @@
+project('variables-reserved-test', 'c', version : '1.0')
+
+pkgg = import('pkgconfig')
+lib = shared_library('simple', 'simple.c')
+libver = '1.0'
+h = install_headers('simple.h')
+
+pkgg.generate(
+ libraries : [lib, '-lz'],
+ subdirs : '.',
+ version : libver,
+ name : 'libsimple',
+ filebase : 'simple',
+ description : 'A simple demo library.',
+ variables : [ 'prefix=/tmp/' ]
+)
diff --git a/test cases/failing/45 pkgconfig variables reserved/simple.c b/test cases/failing/45 pkgconfig variables reserved/simple.c
new file mode 100644
index 0000000..e8a6d83
--- /dev/null
+++ b/test cases/failing/45 pkgconfig variables reserved/simple.c
@@ -0,0 +1,5 @@
+#include"simple.h"
+
+int simple_function() {
+ return 42;
+}
diff --git a/test cases/failing/45 pkgconfig variables reserved/simple.h b/test cases/failing/45 pkgconfig variables reserved/simple.h
new file mode 100644
index 0000000..bb52e6d
--- /dev/null
+++ b/test cases/failing/45 pkgconfig variables reserved/simple.h
@@ -0,0 +1,6 @@
+#ifndef SIMPLE_H_
+#define SIMPLE_H_
+
+int simple_function();
+
+#endif
diff --git a/test cases/failing/45 pkgconfig variables reserved/test.json b/test cases/failing/45 pkgconfig variables reserved/test.json
new file mode 100644
index 0000000..853eb82
--- /dev/null
+++ b/test cases/failing/45 pkgconfig variables reserved/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/45 pkgconfig variables reserved/meson.build:8:5: ERROR: Variable \"prefix\" is reserved"
+ }
+ ]
+}
diff --git a/test cases/failing/46 pkgconfig variables zero length/meson.build b/test cases/failing/46 pkgconfig variables zero length/meson.build
new file mode 100644
index 0000000..65d3344
--- /dev/null
+++ b/test cases/failing/46 pkgconfig variables zero length/meson.build
@@ -0,0 +1,16 @@
+project('variables-zero-length-test', 'c', version : '1.0')
+
+pkgg = import('pkgconfig')
+lib = shared_library('simple', 'simple.c')
+libver = '1.0'
+h = install_headers('simple.h')
+
+pkgg.generate(
+ libraries : [lib, '-lz'],
+ subdirs : '.',
+ version : libver,
+ name : 'libsimple',
+ filebase : 'simple',
+ description : 'A simple demo library.',
+ variables : [ '=value' ]
+)
diff --git a/test cases/failing/46 pkgconfig variables zero length/simple.c b/test cases/failing/46 pkgconfig variables zero length/simple.c
new file mode 100644
index 0000000..e8a6d83
--- /dev/null
+++ b/test cases/failing/46 pkgconfig variables zero length/simple.c
@@ -0,0 +1,5 @@
+#include"simple.h"
+
+int simple_function() {
+ return 42;
+}
diff --git a/test cases/failing/46 pkgconfig variables zero length/simple.h b/test cases/failing/46 pkgconfig variables zero length/simple.h
new file mode 100644
index 0000000..bb52e6d
--- /dev/null
+++ b/test cases/failing/46 pkgconfig variables zero length/simple.h
@@ -0,0 +1,6 @@
+#ifndef SIMPLE_H_
+#define SIMPLE_H_
+
+int simple_function();
+
+#endif
diff --git a/test cases/failing/46 pkgconfig variables zero length/test.json b/test cases/failing/46 pkgconfig variables zero length/test.json
new file mode 100644
index 0000000..b174065
--- /dev/null
+++ b/test cases/failing/46 pkgconfig variables zero length/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/46 pkgconfig variables zero length/meson.build:8:5: ERROR: pkgconfig.generate keyword argument \"variables\" empty variable name"
+ }
+ ]
+}
diff --git a/test cases/failing/47 pkgconfig variables zero length value/meson.build b/test cases/failing/47 pkgconfig variables zero length value/meson.build
new file mode 100644
index 0000000..33977b2
--- /dev/null
+++ b/test cases/failing/47 pkgconfig variables zero length value/meson.build
@@ -0,0 +1,16 @@
+project('variables-zero-length-value-test', 'c', version : '1.0')
+
+pkgg = import('pkgconfig')
+lib = shared_library('simple', 'simple.c')
+libver = '1.0'
+h = install_headers('simple.h')
+
+pkgg.generate(
+ libraries : [lib, '-lz'],
+ subdirs : '.',
+ version : libver,
+ name : 'libsimple',
+ filebase : 'simple',
+ description : 'A simple demo library.',
+ variables : [ 'key=' ]
+)
diff --git a/test cases/failing/47 pkgconfig variables zero length value/simple.c b/test cases/failing/47 pkgconfig variables zero length value/simple.c
new file mode 100644
index 0000000..e8a6d83
--- /dev/null
+++ b/test cases/failing/47 pkgconfig variables zero length value/simple.c
@@ -0,0 +1,5 @@
+#include"simple.h"
+
+int simple_function() {
+ return 42;
+}
diff --git a/test cases/failing/47 pkgconfig variables zero length value/simple.h b/test cases/failing/47 pkgconfig variables zero length value/simple.h
new file mode 100644
index 0000000..bb52e6d
--- /dev/null
+++ b/test cases/failing/47 pkgconfig variables zero length value/simple.h
@@ -0,0 +1,6 @@
+#ifndef SIMPLE_H_
+#define SIMPLE_H_
+
+int simple_function();
+
+#endif
diff --git a/test cases/failing/47 pkgconfig variables zero length value/test.json b/test cases/failing/47 pkgconfig variables zero length value/test.json
new file mode 100644
index 0000000..0be5725
--- /dev/null
+++ b/test cases/failing/47 pkgconfig variables zero length value/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/47 pkgconfig variables zero length value/meson.build:8:5: ERROR: pkgconfig.generate keyword argument \"variables\" empty variable value"
+ }
+ ]
+}
diff --git a/test cases/failing/48 pkgconfig variables not key value/meson.build b/test cases/failing/48 pkgconfig variables not key value/meson.build
new file mode 100644
index 0000000..02fa737
--- /dev/null
+++ b/test cases/failing/48 pkgconfig variables not key value/meson.build
@@ -0,0 +1,16 @@
+project('variables-not-key-value-test', 'c', version : '1.0')
+
+pkgg = import('pkgconfig')
+lib = shared_library('simple', 'simple.c')
+libver = '1.0'
+h = install_headers('simple.h')
+
+pkgg.generate(
+ libraries : [lib, '-lz'],
+ subdirs : '.',
+ version : libver,
+ name : 'libsimple',
+ filebase : 'simple',
+ description : 'A simple demo library.',
+ variables : [ 'this_should_be_key_value' ]
+)
diff --git a/test cases/failing/48 pkgconfig variables not key value/simple.c b/test cases/failing/48 pkgconfig variables not key value/simple.c
new file mode 100644
index 0000000..e8a6d83
--- /dev/null
+++ b/test cases/failing/48 pkgconfig variables not key value/simple.c
@@ -0,0 +1,5 @@
+#include"simple.h"
+
+int simple_function() {
+ return 42;
+}
diff --git a/test cases/failing/48 pkgconfig variables not key value/simple.h b/test cases/failing/48 pkgconfig variables not key value/simple.h
new file mode 100644
index 0000000..bb52e6d
--- /dev/null
+++ b/test cases/failing/48 pkgconfig variables not key value/simple.h
@@ -0,0 +1,6 @@
+#ifndef SIMPLE_H_
+#define SIMPLE_H_
+
+int simple_function();
+
+#endif
diff --git a/test cases/failing/48 pkgconfig variables not key value/test.json b/test cases/failing/48 pkgconfig variables not key value/test.json
new file mode 100644
index 0000000..96422a9
--- /dev/null
+++ b/test cases/failing/48 pkgconfig variables not key value/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/48 pkgconfig variables not key value/meson.build:8:5: ERROR: pkgconfig.generate keyword argument \"variables\" variable 'this_should_be_key_value' must have a value separated by equals sign."
+ }
+ ]
+}
diff --git a/test cases/failing/49 executable comparison/meson.build b/test cases/failing/49 executable comparison/meson.build
new file mode 100644
index 0000000..041bcf3
--- /dev/null
+++ b/test cases/failing/49 executable comparison/meson.build
@@ -0,0 +1,6 @@
+project('executable comparison', 'c')
+
+exe1 = executable('prog1', sources : 'prog.c')
+exe2 = executable('prog2', sources : 'prog.c')
+
+assert(exe1 < exe2, 'should fail')
diff --git a/test cases/failing/49 executable comparison/prog.c b/test cases/failing/49 executable comparison/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/failing/49 executable comparison/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/failing/49 executable comparison/test.json b/test cases/failing/49 executable comparison/test.json
new file mode 100644
index 0000000..a37002e
--- /dev/null
+++ b/test cases/failing/49 executable comparison/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": "test cases/failing/49 executable comparison/meson.build:6:0: ERROR: Object <ExecutableHolder prog1@exe: prog1(.exe)?> of type Executable does not support the `<` operator."
+ }
+ ]
+}
diff --git a/test cases/failing/5 misplaced option/meson.build b/test cases/failing/5 misplaced option/meson.build
new file mode 100644
index 0000000..a992de5
--- /dev/null
+++ b/test cases/failing/5 misplaced option/meson.build
@@ -0,0 +1,3 @@
+project('misplaced option')
+
+option('dummy', type : 'string')
diff --git a/test cases/failing/5 misplaced option/test.json b/test cases/failing/5 misplaced option/test.json
new file mode 100644
index 0000000..12afdf0
--- /dev/null
+++ b/test cases/failing/5 misplaced option/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/5 misplaced option/meson.build:3:0: ERROR: Tried to call option() in build description file. All options must be in the option file."
+ }
+ ]
+}
diff --git a/test cases/failing/50 inconsistent comparison/meson.build b/test cases/failing/50 inconsistent comparison/meson.build
new file mode 100644
index 0000000..237a157
--- /dev/null
+++ b/test cases/failing/50 inconsistent comparison/meson.build
@@ -0,0 +1,7 @@
+project('kwarg before arg')
+
+# All of these should fail, though only the first one will error out if
+# everything's working correctly.
+assert([] < 'st', 'should fail')
+assert([] < 1, 'should fail')
+assert(2 < 'st', 'should fail')
diff --git a/test cases/failing/50 inconsistent comparison/test.json b/test cases/failing/50 inconsistent comparison/test.json
new file mode 100644
index 0000000..171bfa6
--- /dev/null
+++ b/test cases/failing/50 inconsistent comparison/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/50 inconsistent comparison/meson.build:5:0: ERROR: Object <[ArrayHolder] holds [list]: []> of type array does not support the `<` operator."
+ }
+ ]
+}
diff --git a/test cases/failing/51 slashname/meson.build b/test cases/failing/51 slashname/meson.build
new file mode 100644
index 0000000..29fe1fc
--- /dev/null
+++ b/test cases/failing/51 slashname/meson.build
@@ -0,0 +1,11 @@
+project('slashname', 'c')
+
+# Traverse this subdir so the corresponding dir
+# is created inside the build dir.
+subdir('sub')
+
+# Try to create an executable that would go in the "sub" dir
+# inside the build dir. This is prohibited.
+executable('sub/prog', pf)
+
+error('Re-enable me once slash in name is finally prohibited.')
diff --git a/test cases/failing/51 slashname/sub/meson.build b/test cases/failing/51 slashname/sub/meson.build
new file mode 100644
index 0000000..3baacf6
--- /dev/null
+++ b/test cases/failing/51 slashname/sub/meson.build
@@ -0,0 +1 @@
+pf = files('prog.c')
diff --git a/test cases/failing/51 slashname/sub/prog.c b/test cases/failing/51 slashname/sub/prog.c
new file mode 100644
index 0000000..722de0a
--- /dev/null
+++ b/test cases/failing/51 slashname/sub/prog.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("I should not be run ever.\n");
+ return 1;
+}
diff --git a/test cases/failing/51 slashname/test.json b/test cases/failing/51 slashname/test.json
new file mode 100644
index 0000000..39346a9
--- /dev/null
+++ b/test cases/failing/51 slashname/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/51 slashname/meson.build:9:0: ERROR: Target \"sub/prog\" has a path segment pointing to directory \"sub\". This is an error."
+ }
+ ]
+}
diff --git a/test cases/failing/52 reserved meson prefix/meson-foo/meson.build b/test cases/failing/52 reserved meson prefix/meson-foo/meson.build
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/52 reserved meson prefix/meson-foo/meson.build
diff --git a/test cases/failing/52 reserved meson prefix/meson.build b/test cases/failing/52 reserved meson prefix/meson.build
new file mode 100644
index 0000000..1339035
--- /dev/null
+++ b/test cases/failing/52 reserved meson prefix/meson.build
@@ -0,0 +1,3 @@
+project('test')
+
+subdir('meson-foo')
diff --git a/test cases/failing/52 reserved meson prefix/test.json b/test cases/failing/52 reserved meson prefix/test.json
new file mode 100644
index 0000000..707cd73
--- /dev/null
+++ b/test cases/failing/52 reserved meson prefix/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/52 reserved meson prefix/meson.build:3:0: ERROR: The \"meson-\" prefix is reserved and cannot be used for top-level subdir()."
+ }
+ ]
+}
diff --git a/test cases/failing/53 wrong shared crate type/foo.rs b/test cases/failing/53 wrong shared crate type/foo.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/53 wrong shared crate type/foo.rs
diff --git a/test cases/failing/53 wrong shared crate type/meson.build b/test cases/failing/53 wrong shared crate type/meson.build
new file mode 100644
index 0000000..90020fa
--- /dev/null
+++ b/test cases/failing/53 wrong shared crate type/meson.build
@@ -0,0 +1,7 @@
+project('test')
+
+if not add_languages('rust', required: false)
+ error('MESON_SKIP_TEST test requires rust compiler')
+endif
+
+shared_library('mytest', 'foo.rs', rust_crate_type : 'staticlib')
diff --git a/test cases/failing/53 wrong shared crate type/test.json b/test cases/failing/53 wrong shared crate type/test.json
new file mode 100644
index 0000000..5faaece
--- /dev/null
+++ b/test cases/failing/53 wrong shared crate type/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/53 wrong shared crate type/meson.build:7:0: ERROR: Crate type \"staticlib\" invalid for dynamic libraries; must be \"dylib\", \"cdylib\", or \"proc-macro\""
+ }
+ ]
+}
diff --git a/test cases/failing/54 wrong static crate type/foo.rs b/test cases/failing/54 wrong static crate type/foo.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/54 wrong static crate type/foo.rs
diff --git a/test cases/failing/54 wrong static crate type/meson.build b/test cases/failing/54 wrong static crate type/meson.build
new file mode 100644
index 0000000..179d7cd
--- /dev/null
+++ b/test cases/failing/54 wrong static crate type/meson.build
@@ -0,0 +1,7 @@
+project('test')
+
+if not add_languages('rust', required: false)
+ error('MESON_SKIP_TEST test requires rust compiler')
+endif
+
+static_library('mytest', 'foo.rs', rust_crate_type : 'cdylib')
diff --git a/test cases/failing/54 wrong static crate type/test.json b/test cases/failing/54 wrong static crate type/test.json
new file mode 100644
index 0000000..83ae5e1
--- /dev/null
+++ b/test cases/failing/54 wrong static crate type/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/54 wrong static crate type/meson.build:7:0: ERROR: Crate type \"cdylib\" invalid for static libraries; must be \"rlib\" or \"staticlib\""
+ }
+ ]
+}
diff --git a/test cases/failing/55 or on new line/meson.build b/test cases/failing/55 or on new line/meson.build
new file mode 100644
index 0000000..b0bd08e
--- /dev/null
+++ b/test cases/failing/55 or on new line/meson.build
@@ -0,0 +1,7 @@
+project('silent_or')
+
+if get_option('foo') == 'true'
+ or get_option('foo') == 'auto'
+else
+ message('If this message is printed then something is wrong. The or above should give a syntax error.')
+endif
diff --git a/test cases/failing/55 or on new line/meson_options.txt b/test cases/failing/55 or on new line/meson_options.txt
new file mode 100644
index 0000000..3302cf4
--- /dev/null
+++ b/test cases/failing/55 or on new line/meson_options.txt
@@ -0,0 +1 @@
+option('foo', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto')
diff --git a/test cases/failing/55 or on new line/test.json b/test cases/failing/55 or on new line/test.json
new file mode 100644
index 0000000..f1b8a67
--- /dev/null
+++ b/test cases/failing/55 or on new line/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/55 or on new line/meson.build:4:8: ERROR: Invalid or clause."
+ }
+ ]
+}
diff --git a/test cases/failing/56 link with executable/meson.build b/test cases/failing/56 link with executable/meson.build
new file mode 100644
index 0000000..186b3e5
--- /dev/null
+++ b/test cases/failing/56 link with executable/meson.build
@@ -0,0 +1,4 @@
+project('link with exe', 'c')
+
+e = executable('prog', 'prog.c')
+m = shared_module('module', 'module.c', link_with: e)
diff --git a/test cases/failing/56 link with executable/module.c b/test cases/failing/56 link with executable/module.c
new file mode 100644
index 0000000..dc0124a
--- /dev/null
+++ b/test cases/failing/56 link with executable/module.c
@@ -0,0 +1,4 @@
+
+int func(void) {
+ return 42;
+}
diff --git a/test cases/failing/56 link with executable/prog.c b/test cases/failing/56 link with executable/prog.c
new file mode 100644
index 0000000..f3836d7
--- /dev/null
+++ b/test cases/failing/56 link with executable/prog.c
@@ -0,0 +1,5 @@
+int
+main (int argc, char **argv)
+{
+ return 0;
+}
diff --git a/test cases/failing/56 link with executable/test.json b/test cases/failing/56 link with executable/test.json
new file mode 100644
index 0000000..2288783
--- /dev/null
+++ b/test cases/failing/56 link with executable/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/56 link with executable/meson.build:4:0: ERROR: Link target 'prog' is not linkable."
+ }
+ ]
+}
diff --git a/test cases/failing/57 assign custom target index/meson.build b/test cases/failing/57 assign custom target index/meson.build
new file mode 100644
index 0000000..7f2a820
--- /dev/null
+++ b/test cases/failing/57 assign custom target index/meson.build
@@ -0,0 +1,24 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+prog_python = import('python3').find_python()
+
+target = custom_target(
+ 'target',
+ output : ['1', '2'],
+ command : [prog_python, '-c',
+ 'with open("1", "w") as f: f.write("foo"); with open("2", "w") as f: f.write("foo")'],
+)
+
+target[0] = 'foo'
diff --git a/test cases/failing/57 assign custom target index/test.json b/test cases/failing/57 assign custom target index/test.json
new file mode 100644
index 0000000..392137a
--- /dev/null
+++ b/test cases/failing/57 assign custom target index/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/57 assign custom target index/meson.build:24:0: ERROR: Assignment target must be an id."
+ }
+ ]
+}
diff --git a/test cases/failing/58 getoption prefix/meson.build b/test cases/failing/58 getoption prefix/meson.build
new file mode 100644
index 0000000..8f85cff
--- /dev/null
+++ b/test cases/failing/58 getoption prefix/meson.build
@@ -0,0 +1,5 @@
+project('getopt prefix')
+
+subproject('abc')
+
+get_option('abc:foo')
diff --git a/test cases/failing/58 getoption prefix/subprojects/abc/meson.build b/test cases/failing/58 getoption prefix/subprojects/abc/meson.build
new file mode 100644
index 0000000..aa9c3df
--- /dev/null
+++ b/test cases/failing/58 getoption prefix/subprojects/abc/meson.build
@@ -0,0 +1 @@
+project('abc', 'c')
diff --git a/test cases/failing/58 getoption prefix/subprojects/abc/meson_options.txt b/test cases/failing/58 getoption prefix/subprojects/abc/meson_options.txt
new file mode 100644
index 0000000..89e624e
--- /dev/null
+++ b/test cases/failing/58 getoption prefix/subprojects/abc/meson_options.txt
@@ -0,0 +1 @@
+option('foo', type : 'boolean')
diff --git a/test cases/failing/58 getoption prefix/test.json b/test cases/failing/58 getoption prefix/test.json
new file mode 100644
index 0000000..630dcd9
--- /dev/null
+++ b/test cases/failing/58 getoption prefix/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/58 getoption prefix/meson.build:5:0: ERROR: Having a colon in option name is forbidden, projects are not allowed to directly access options of other subprojects."
+ }
+ ]
+}
diff --git a/test cases/failing/59 bad option argument/meson.build b/test cases/failing/59 bad option argument/meson.build
new file mode 100644
index 0000000..5219cfb
--- /dev/null
+++ b/test cases/failing/59 bad option argument/meson.build
@@ -0,0 +1,3 @@
+project('bad option')
+
+get_option('name')
diff --git a/test cases/failing/59 bad option argument/meson_options.txt b/test cases/failing/59 bad option argument/meson_options.txt
new file mode 100644
index 0000000..de1fff6
--- /dev/null
+++ b/test cases/failing/59 bad option argument/meson_options.txt
@@ -0,0 +1 @@
+option('name', type : 'string', vaule : 'foo')
diff --git a/test cases/failing/59 bad option argument/test.json b/test cases/failing/59 bad option argument/test.json
new file mode 100644
index 0000000..3c5df1b
--- /dev/null
+++ b/test cases/failing/59 bad option argument/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/59 bad option argument/meson_options.txt:1:0: ERROR: option got unknown keyword arguments \"vaule\""
+ }
+ ]
+}
diff --git a/test cases/failing/6 missing incdir/meson.build b/test cases/failing/6 missing incdir/meson.build
new file mode 100644
index 0000000..eb5ba2a
--- /dev/null
+++ b/test cases/failing/6 missing incdir/meson.build
@@ -0,0 +1,3 @@
+project('missing incdir')
+
+inc = include_directories('nosuchdir')
diff --git a/test cases/failing/6 missing incdir/test.json b/test cases/failing/6 missing incdir/test.json
new file mode 100644
index 0000000..172d8a9
--- /dev/null
+++ b/test cases/failing/6 missing incdir/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/6 missing incdir/meson.build:3:0: ERROR: Include dir nosuchdir does not exist."
+ }
+ ]
+}
diff --git a/test cases/failing/60 subproj filegrab/meson.build b/test cases/failing/60 subproj filegrab/meson.build
new file mode 100644
index 0000000..b5c484c
--- /dev/null
+++ b/test cases/failing/60 subproj filegrab/meson.build
@@ -0,0 +1,5 @@
+project('mainproj')
+
+# Try to grab a file from a parent project.
+
+subproject('a')
diff --git a/test cases/failing/60 subproj filegrab/prog.c b/test cases/failing/60 subproj filegrab/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/failing/60 subproj filegrab/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/failing/60 subproj filegrab/subprojects/a/meson.build b/test cases/failing/60 subproj filegrab/subprojects/a/meson.build
new file mode 100644
index 0000000..80b9888
--- /dev/null
+++ b/test cases/failing/60 subproj filegrab/subprojects/a/meson.build
@@ -0,0 +1,3 @@
+project('a', 'c')
+
+executable('prog', '../../prog.c')
diff --git a/test cases/failing/60 subproj filegrab/test.json b/test cases/failing/60 subproj filegrab/test.json
new file mode 100644
index 0000000..04a6dbb
--- /dev/null
+++ b/test cases/failing/60 subproj filegrab/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/60 subproj filegrab/subprojects/a/meson.build:3:0: ERROR: Sandbox violation: Tried to grab file prog.c outside current (sub)project."
+ }
+ ]
+}
diff --git a/test cases/failing/61 grab subproj/meson.build b/test cases/failing/61 grab subproj/meson.build
new file mode 100644
index 0000000..30fc690
--- /dev/null
+++ b/test cases/failing/61 grab subproj/meson.build
@@ -0,0 +1,7 @@
+project('grabber', 'c')
+
+# Try to grab a file from a child subproject.
+
+subproject('foo')
+
+executable('foo', 'subprojects/foo/sub.c')
diff --git a/test cases/failing/61 grab subproj/subprojects/foo/meson.build b/test cases/failing/61 grab subproj/subprojects/foo/meson.build
new file mode 100644
index 0000000..b346f6d
--- /dev/null
+++ b/test cases/failing/61 grab subproj/subprojects/foo/meson.build
@@ -0,0 +1,3 @@
+project('foo', 'c')
+
+message('I do nothing.')
diff --git a/test cases/failing/61 grab subproj/subprojects/foo/sub.c b/test cases/failing/61 grab subproj/subprojects/foo/sub.c
new file mode 100644
index 0000000..a94b1f5
--- /dev/null
+++ b/test cases/failing/61 grab subproj/subprojects/foo/sub.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("I am a subproject executable file.\n");
+ return 0;
+}
diff --git a/test cases/failing/61 grab subproj/test.json b/test cases/failing/61 grab subproj/test.json
new file mode 100644
index 0000000..873ec6c
--- /dev/null
+++ b/test cases/failing/61 grab subproj/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/61 grab subproj/meson.build:7:0: ERROR: Sandbox violation: Tried to grab file sub.c from a nested subproject."
+ }
+ ]
+}
diff --git a/test cases/failing/62 grab sibling/meson.build b/test cases/failing/62 grab sibling/meson.build
new file mode 100644
index 0000000..5ddc295
--- /dev/null
+++ b/test cases/failing/62 grab sibling/meson.build
@@ -0,0 +1,3 @@
+project('master')
+
+subproject('a')
diff --git a/test cases/failing/62 grab sibling/subprojects/a/meson.build b/test cases/failing/62 grab sibling/subprojects/a/meson.build
new file mode 100644
index 0000000..6dd9f61
--- /dev/null
+++ b/test cases/failing/62 grab sibling/subprojects/a/meson.build
@@ -0,0 +1,3 @@
+project('a', 'c')
+
+executable('sneaky', '../b/sneaky.c')
diff --git a/test cases/failing/62 grab sibling/subprojects/b/meson.build b/test cases/failing/62 grab sibling/subprojects/b/meson.build
new file mode 100644
index 0000000..57f261a
--- /dev/null
+++ b/test cases/failing/62 grab sibling/subprojects/b/meson.build
@@ -0,0 +1,3 @@
+projecT('b')
+
+message('I do nothing.')
diff --git a/test cases/failing/62 grab sibling/subprojects/b/sneaky.c b/test cases/failing/62 grab sibling/subprojects/b/sneaky.c
new file mode 100644
index 0000000..46718c6
--- /dev/null
+++ b/test cases/failing/62 grab sibling/subprojects/b/sneaky.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("I can only come into existence via trickery.\n");
+ return 0;
+}
diff --git a/test cases/failing/62 grab sibling/test.json b/test cases/failing/62 grab sibling/test.json
new file mode 100644
index 0000000..9e7c4bb
--- /dev/null
+++ b/test cases/failing/62 grab sibling/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/62 grab sibling/subprojects/a/meson.build:3:0: ERROR: Sandbox violation: Tried to grab file sneaky.c outside current (sub)project."
+ }
+ ]
+}
diff --git a/test cases/failing/63 string as link target/meson.build b/test cases/failing/63 string as link target/meson.build
new file mode 100644
index 0000000..cb83fff
--- /dev/null
+++ b/test cases/failing/63 string as link target/meson.build
@@ -0,0 +1,2 @@
+project('string as link argument', 'c')
+executable('myprog', 'prog.c', link_with: [ '' ])
diff --git a/test cases/failing/63 string as link target/prog.c b/test cases/failing/63 string as link target/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/failing/63 string as link target/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/failing/63 string as link target/test.json b/test cases/failing/63 string as link target/test.json
new file mode 100644
index 0000000..a531d64
--- /dev/null
+++ b/test cases/failing/63 string as link target/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/63 string as link target/meson.build:2:0: ERROR: '' is not a target."
+ }
+ ]
+}
diff --git a/test cases/failing/64 dependency not-found and required/meson.build b/test cases/failing/64 dependency not-found and required/meson.build
new file mode 100644
index 0000000..1ce5747
--- /dev/null
+++ b/test cases/failing/64 dependency not-found and required/meson.build
@@ -0,0 +1,2 @@
+project('dep-test')
+dep = dependency('', required:true)
diff --git a/test cases/failing/64 dependency not-found and required/test.json b/test cases/failing/64 dependency not-found and required/test.json
new file mode 100644
index 0000000..84d14b4
--- /dev/null
+++ b/test cases/failing/64 dependency not-found and required/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/64 dependency not-found and required/meson.build:2:0: ERROR: Dependency is required but has no candidates."
+ }
+ ]
+}
diff --git a/test cases/failing/65 subproj different versions/main.c b/test cases/failing/65 subproj different versions/main.c
new file mode 100644
index 0000000..8793c62
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/main.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "a.h"
+#include "b.h"
+
+int main(int argc, char **argv) {
+ int life = a_fun() + b_fun();
+ printf("%d\n", life);
+ return 0;
+}
diff --git a/test cases/failing/65 subproj different versions/meson.build b/test cases/failing/65 subproj different versions/meson.build
new file mode 100644
index 0000000..e964e42
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/meson.build
@@ -0,0 +1,9 @@
+project('super', 'c')
+
+# A will use version 1 of C
+a_dep = dependency('a', fallback: ['a', 'a_dep'])
+
+# B will fail because it requests version 2 of C
+b_dep = dependency('b', fallback: ['b', 'b_dep'])
+
+main = executable('main', files('main.c'), dependencies: [a_dep, b_dep])
diff --git a/test cases/failing/65 subproj different versions/subprojects/a/a.c b/test cases/failing/65 subproj different versions/subprojects/a/a.c
new file mode 100644
index 0000000..cd41a65
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/a/a.c
@@ -0,0 +1,5 @@
+#include "c.h"
+
+int a_fun() {
+ return c_fun();
+}
diff --git a/test cases/failing/65 subproj different versions/subprojects/a/a.h b/test cases/failing/65 subproj different versions/subprojects/a/a.h
new file mode 100644
index 0000000..8f1d49e
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/a/a.h
@@ -0,0 +1 @@
+int a_fun();
diff --git a/test cases/failing/65 subproj different versions/subprojects/a/meson.build b/test cases/failing/65 subproj different versions/subprojects/a/meson.build
new file mode 100644
index 0000000..e84182a
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/a/meson.build
@@ -0,0 +1,11 @@
+project('a', 'c')
+
+c_dep = dependency('c', version:'1', fallback: ['c', 'c_dep'])
+
+alib = library('a', 'a.c',
+ dependencies: c_dep)
+
+a_dep = declare_dependency(
+ link_with: alib,
+ include_directories: include_directories('.'),
+)
diff --git a/test cases/failing/65 subproj different versions/subprojects/b/b.c b/test cases/failing/65 subproj different versions/subprojects/b/b.c
new file mode 100644
index 0000000..f85f8c3
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/b/b.c
@@ -0,0 +1,5 @@
+#include "c.h"
+
+int b_fun(){
+return c_fun();
+}
diff --git a/test cases/failing/65 subproj different versions/subprojects/b/b.h b/test cases/failing/65 subproj different versions/subprojects/b/b.h
new file mode 100644
index 0000000..eced786
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/b/b.h
@@ -0,0 +1 @@
+int b_fun();
diff --git a/test cases/failing/65 subproj different versions/subprojects/b/meson.build b/test cases/failing/65 subproj different versions/subprojects/b/meson.build
new file mode 100644
index 0000000..0398340
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/b/meson.build
@@ -0,0 +1,11 @@
+project('b', 'c')
+
+c_dep = dependency('c', version:'2', fallback: ['c', 'c_dep'])
+
+blib = library('b', 'b.c',
+ dependencies: c_dep)
+
+b_dep = declare_dependency(
+ link_with: blib,
+ include_directories: include_directories('.'),
+)
diff --git a/test cases/failing/65 subproj different versions/subprojects/c/c.h b/test cases/failing/65 subproj different versions/subprojects/c/c.h
new file mode 100644
index 0000000..2b15f60
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/c/c.h
@@ -0,0 +1,3 @@
+static int c_fun(){
+ return 3;
+}
diff --git a/test cases/failing/65 subproj different versions/subprojects/c/meson.build b/test cases/failing/65 subproj different versions/subprojects/c/meson.build
new file mode 100644
index 0000000..7184933
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/subprojects/c/meson.build
@@ -0,0 +1,5 @@
+project('c', 'c', version:'1')
+
+c_dep = declare_dependency(
+ include_directories: include_directories('.')
+)
diff --git a/test cases/failing/65 subproj different versions/test.json b/test cases/failing/65 subproj different versions/test.json
new file mode 100644
index 0000000..2f9f70d
--- /dev/null
+++ b/test cases/failing/65 subproj different versions/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/65 subproj different versions/subprojects/b/meson.build:3:0: ERROR: Dependency 'c' is required but not found."
+ }
+ ]
+}
diff --git a/test cases/failing/66 wrong boost module/meson.build b/test cases/failing/66 wrong boost module/meson.build
new file mode 100644
index 0000000..937e587
--- /dev/null
+++ b/test cases/failing/66 wrong boost module/meson.build
@@ -0,0 +1,9 @@
+project('boosttest', 'cpp',
+ default_options : ['cpp_std=c++11'])
+
+if not dependency('boost', required: false).found()
+ error('MESON_SKIP_TEST test requires boost')
+endif
+
+# abc doesn't exist
+linkdep = dependency('boost', modules : ['thread', 'system', 'test', 'abc'])
diff --git a/test cases/failing/66 wrong boost module/test.json b/test cases/failing/66 wrong boost module/test.json
new file mode 100644
index 0000000..c65a78c
--- /dev/null
+++ b/test cases/failing/66 wrong boost module/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/66 wrong boost module/meson.build:9:0: ERROR: Dependency \"boost\" not found, tried system"
+ }
+ ]
+}
diff --git a/test cases/failing/67 install_data rename bad size/file1.txt b/test cases/failing/67 install_data rename bad size/file1.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/67 install_data rename bad size/file1.txt
diff --git a/test cases/failing/67 install_data rename bad size/file2.txt b/test cases/failing/67 install_data rename bad size/file2.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/67 install_data rename bad size/file2.txt
diff --git a/test cases/failing/67 install_data rename bad size/meson.build b/test cases/failing/67 install_data rename bad size/meson.build
new file mode 100644
index 0000000..849bb9a
--- /dev/null
+++ b/test cases/failing/67 install_data rename bad size/meson.build
@@ -0,0 +1,3 @@
+project('data install test')
+
+install_data(['file1.txt', 'file2.txt'], rename : 'just one name')
diff --git a/test cases/failing/67 install_data rename bad size/test.json b/test cases/failing/67 install_data rename bad size/test.json
new file mode 100644
index 0000000..af1f0d9
--- /dev/null
+++ b/test cases/failing/67 install_data rename bad size/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/67 install_data rename bad size/meson.build:3:0: ERROR: \"rename\" and \"sources\" argument lists must be the same length if \"rename\" is given. Rename has 1 elements and sources has 2."
+ }
+ ]
+}
diff --git a/test cases/failing/68 skip only subdir/meson.build b/test cases/failing/68 skip only subdir/meson.build
new file mode 100644
index 0000000..4832bd4
--- /dev/null
+++ b/test cases/failing/68 skip only subdir/meson.build
@@ -0,0 +1,8 @@
+# Check that skip_rest only exits subdir, not the whole script.
+# Should create an error because main.cpp does not exists.
+project('example exit', 'cpp')
+
+subdir('subdir')
+
+message('Good')
+executable('main', 'main.cpp')
diff --git a/test cases/failing/68 skip only subdir/subdir/meson.build b/test cases/failing/68 skip only subdir/subdir/meson.build
new file mode 100644
index 0000000..1ba447b
--- /dev/null
+++ b/test cases/failing/68 skip only subdir/subdir/meson.build
@@ -0,0 +1,3 @@
+subdir_done()
+
+error('Unreachable')
diff --git a/test cases/failing/68 skip only subdir/test.json b/test cases/failing/68 skip only subdir/test.json
new file mode 100644
index 0000000..4558847
--- /dev/null
+++ b/test cases/failing/68 skip only subdir/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/68 skip only subdir/meson.build:8:0: ERROR: File main.cpp does not exist."
+ }
+ ]
+}
diff --git a/test cases/failing/69 dual override/meson.build b/test cases/failing/69 dual override/meson.build
new file mode 100644
index 0000000..999b8bc
--- /dev/null
+++ b/test cases/failing/69 dual override/meson.build
@@ -0,0 +1,5 @@
+project('yo dawg')
+
+p = find_program('overrides.py')
+meson.override_find_program('override', p)
+meson.override_find_program('override', p)
diff --git a/test cases/failing/69 dual override/overrides.py b/test cases/failing/69 dual override/overrides.py
new file mode 100644
index 0000000..49e9b7a
--- /dev/null
+++ b/test cases/failing/69 dual override/overrides.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+print('Yo dawg, we put overrides in your overrides,')
+print('so now you can override when you override.')
diff --git a/test cases/failing/69 dual override/test.json b/test cases/failing/69 dual override/test.json
new file mode 100644
index 0000000..784d6b2
--- /dev/null
+++ b/test cases/failing/69 dual override/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/69 dual override/meson.build:5:6: ERROR: Tried to override executable \"override\" which has already been overridden."
+ }
+ ]
+}
diff --git a/test cases/failing/7 go to subproject/meson.build b/test cases/failing/7 go to subproject/meson.build
new file mode 100644
index 0000000..0354ce0
--- /dev/null
+++ b/test cases/failing/7 go to subproject/meson.build
@@ -0,0 +1,3 @@
+project('fff')
+
+subdir('subprojects')
diff --git a/test cases/failing/7 go to subproject/subprojects/meson.build b/test cases/failing/7 go to subproject/subprojects/meson.build
new file mode 100644
index 0000000..120344f
--- /dev/null
+++ b/test cases/failing/7 go to subproject/subprojects/meson.build
@@ -0,0 +1 @@
+x = 'x'
diff --git a/test cases/failing/7 go to subproject/test.json b/test cases/failing/7 go to subproject/test.json
new file mode 100644
index 0000000..c254757
--- /dev/null
+++ b/test cases/failing/7 go to subproject/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/7 go to subproject/meson.build:3:0: ERROR: Must not go into subprojects dir with subdir(), use subproject() instead."
+ }
+ ]
+}
diff --git a/test cases/failing/70 override used/meson.build b/test cases/failing/70 override used/meson.build
new file mode 100644
index 0000000..128108e
--- /dev/null
+++ b/test cases/failing/70 override used/meson.build
@@ -0,0 +1,5 @@
+project('overridde an already found exe')
+
+old = find_program('something.py')
+replacement = find_program('other.py')
+meson.override_find_program('something.py', replacement)
diff --git a/test cases/failing/70 override used/other.py b/test cases/failing/70 override used/other.py
new file mode 100755
index 0000000..f62ba96
--- /dev/null
+++ b/test cases/failing/70 override used/other.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('Doing something else.')
diff --git a/test cases/failing/70 override used/something.py b/test cases/failing/70 override used/something.py
new file mode 100755
index 0000000..64c9454
--- /dev/null
+++ b/test cases/failing/70 override used/something.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('Doing something.')
diff --git a/test cases/failing/70 override used/test.json b/test cases/failing/70 override used/test.json
new file mode 100644
index 0000000..adb60aa
--- /dev/null
+++ b/test cases/failing/70 override used/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/70 override used/meson.build:5:6: ERROR: Tried to override finding of executable \"something.py\" which has already been found."
+ }
+ ]
+}
diff --git a/test cases/failing/71 run_command unclean exit/meson.build b/test cases/failing/71 run_command unclean exit/meson.build
new file mode 100644
index 0000000..f6bf895
--- /dev/null
+++ b/test cases/failing/71 run_command unclean exit/meson.build
@@ -0,0 +1,4 @@
+project('run_command unclean exit')
+
+rcprog = find_program('./returncode.py')
+run_command(rcprog, '1', check : true)
diff --git a/test cases/failing/71 run_command unclean exit/returncode.py b/test cases/failing/71 run_command unclean exit/returncode.py
new file mode 100755
index 0000000..84dbc5d
--- /dev/null
+++ b/test cases/failing/71 run_command unclean exit/returncode.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+import sys
+exit(int(sys.argv[1]))
diff --git a/test cases/failing/71 run_command unclean exit/test.json b/test cases/failing/71 run_command unclean exit/test.json
new file mode 100644
index 0000000..ca5fcba
--- /dev/null
+++ b/test cases/failing/71 run_command unclean exit/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": "test cases/failing/71 run_command unclean exit/meson\\.build:4:0: ERROR: Command `.*['\"].*[\\\\/]test cases[\\\\/]failing[\\\\/]71 run_command unclean exit[\\\\/]\\.[\\\\/]returncode\\.py['\"] 1` failed with status 1\\."
+ }
+ ]
+}
diff --git a/test cases/failing/72 int literal leading zero/meson.build b/test cases/failing/72 int literal leading zero/meson.build
new file mode 100644
index 0000000..87c776f
--- /dev/null
+++ b/test cases/failing/72 int literal leading zero/meson.build
@@ -0,0 +1,5 @@
+
+# This should fail.
+# Decimal syntax is 123.
+# Octal syntax is 0o123.
+fail_0123 = 0123
diff --git a/test cases/failing/72 int literal leading zero/test.json b/test cases/failing/72 int literal leading zero/test.json
new file mode 100644
index 0000000..556e492
--- /dev/null
+++ b/test cases/failing/72 int literal leading zero/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "comment": "this error message is not very informative",
+ "line": "test cases/failing/72 int literal leading zero/meson.build:5:13: ERROR: Expecting eof got number."
+ }
+ ]
+}
diff --git a/test cases/failing/73 configuration immutable/input b/test cases/failing/73 configuration immutable/input
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/73 configuration immutable/input
diff --git a/test cases/failing/73 configuration immutable/meson.build b/test cases/failing/73 configuration immutable/meson.build
new file mode 100644
index 0000000..b6cac41
--- /dev/null
+++ b/test cases/failing/73 configuration immutable/meson.build
@@ -0,0 +1,12 @@
+project('configuration_data is immutable')
+
+a = configuration_data()
+
+configure_file(
+ configuration : a,
+ input : 'input',
+ output : 'output',
+)
+
+still_immutable = a
+still_immutable.set('hello', 'world')
diff --git a/test cases/failing/73 configuration immutable/test.json b/test cases/failing/73 configuration immutable/test.json
new file mode 100644
index 0000000..32d9427
--- /dev/null
+++ b/test cases/failing/73 configuration immutable/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/73 configuration immutable/meson.build:12:16: ERROR: Can not set values on configuration object that has been used."
+ }
+ ]
+}
diff --git a/test cases/failing/74 link with shared module on osx/meson.build b/test cases/failing/74 link with shared module on osx/meson.build
new file mode 100644
index 0000000..bf18b36
--- /dev/null
+++ b/test cases/failing/74 link with shared module on osx/meson.build
@@ -0,0 +1,8 @@
+project('link with shared module', 'c')
+
+if host_machine.system() != 'darwin'
+ error('MESON_SKIP_TEST test only fails on OSX')
+endif
+
+m = shared_module('mymodule', 'module.c')
+e = executable('prog', 'prog.c', link_with : m)
diff --git a/test cases/failing/74 link with shared module on osx/module.c b/test cases/failing/74 link with shared module on osx/module.c
new file mode 100644
index 0000000..81b0d5a
--- /dev/null
+++ b/test cases/failing/74 link with shared module on osx/module.c
@@ -0,0 +1,3 @@
+int func(void) {
+ return 1496;
+}
diff --git a/test cases/failing/74 link with shared module on osx/prog.c b/test cases/failing/74 link with shared module on osx/prog.c
new file mode 100644
index 0000000..8164d8d
--- /dev/null
+++ b/test cases/failing/74 link with shared module on osx/prog.c
@@ -0,0 +1,4 @@
+
+int main(int argc, char **argv) {
+ return func();
+}
diff --git a/test cases/failing/74 link with shared module on osx/test.json b/test cases/failing/74 link with shared module on osx/test.json
new file mode 100644
index 0000000..9ca1b9d
--- /dev/null
+++ b/test cases/failing/74 link with shared module on osx/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/74 link with shared module on osx/meson.build:8:0: ERROR: target prog links against shared module mymodule. This is not permitted on OSX"
+ }
+ ]
+}
diff --git a/test cases/failing/75 non ascii in ascii encoded configure file/config9.h.in b/test cases/failing/75 non ascii in ascii encoded configure file/config9.h.in
new file mode 100644
index 0000000..323bec6
--- /dev/null
+++ b/test cases/failing/75 non ascii in ascii encoded configure file/config9.h.in
@@ -0,0 +1 @@
+#define MESSAGE "@var@"
diff --git a/test cases/failing/75 non ascii in ascii encoded configure file/meson.build b/test cases/failing/75 non ascii in ascii encoded configure file/meson.build
new file mode 100644
index 0000000..26da80e
--- /dev/null
+++ b/test cases/failing/75 non ascii in ascii encoded configure file/meson.build
@@ -0,0 +1,10 @@
+project('non acsii to ascii encoding')
+# Writing a non ASCII character with a ASCII encoding should fail
+conf9 = configuration_data()
+conf9.set('var', 'д')
+configure_file(
+ input : 'config9.h.in',
+ output : '@BASENAME@',
+ encoding : 'ascii',
+ configuration : conf9
+)
diff --git a/test cases/failing/75 non ascii in ascii encoded configure file/test.json b/test cases/failing/75 non ascii in ascii encoded configure file/test.json
new file mode 100644
index 0000000..27cb0ab
--- /dev/null
+++ b/test cases/failing/75 non ascii in ascii encoded configure file/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "match": "re",
+ "line": "test cases/failing/75 non ascii in ascii encoded configure file/meson\\.build:5:0: ERROR: Could not write output file .*[\\\\/]config9\\.h: 'ascii' codec can't encode character '\\\\u0434' in position 17: ordinal not in range\\(128\\)"
+ }
+ ]
+}
diff --git a/test cases/failing/76 subproj dependency not-found and required/meson.build b/test cases/failing/76 subproj dependency not-found and required/meson.build
new file mode 100644
index 0000000..c5a2961
--- /dev/null
+++ b/test cases/failing/76 subproj dependency not-found and required/meson.build
@@ -0,0 +1,2 @@
+project('dep-test')
+missing = dependency('', fallback: ['missing', 'missing_dep'], required: true)
diff --git a/test cases/failing/76 subproj dependency not-found and required/test.json b/test cases/failing/76 subproj dependency not-found and required/test.json
new file mode 100644
index 0000000..3b98436
--- /dev/null
+++ b/test cases/failing/76 subproj dependency not-found and required/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/76 subproj dependency not-found and required/meson.build:2:0: ERROR: Neither a subproject directory nor a missing.wrap file was found."
+ }
+ ]
+}
diff --git a/test cases/failing/77 unfound run/meson.build b/test cases/failing/77 unfound run/meson.build
new file mode 100644
index 0000000..3f37e9a
--- /dev/null
+++ b/test cases/failing/77 unfound run/meson.build
@@ -0,0 +1,4 @@
+project('unfound runtarget')
+
+exe = find_program('nonexisting_prog', required : false)
+run_target('invoke_fail', command : [exe])
diff --git a/test cases/failing/77 unfound run/test.json b/test cases/failing/77 unfound run/test.json
new file mode 100644
index 0000000..99464bd
--- /dev/null
+++ b/test cases/failing/77 unfound run/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/77 unfound run/meson.build:4:0: ERROR: Tried to use non-existing executable 'nonexisting_prog'"
+ }
+ ]
+}
diff --git a/test cases/failing/78 framework dependency with version/meson.build b/test cases/failing/78 framework dependency with version/meson.build
new file mode 100644
index 0000000..b7e04ba
--- /dev/null
+++ b/test cases/failing/78 framework dependency with version/meson.build
@@ -0,0 +1,8 @@
+project('framework dependency with version', 'c')
+
+if host_machine.system() != 'darwin'
+ error('MESON_SKIP_TEST test only applicable on darwin')
+endif
+
+# do individual frameworks have a meaningful version to test? And multiple frameworks might be listed...
+dep = dependency('appleframeworks', modules: 'foundation', version: '>0')
diff --git a/test cases/failing/78 framework dependency with version/test.json b/test cases/failing/78 framework dependency with version/test.json
new file mode 100644
index 0000000..d43a498
--- /dev/null
+++ b/test cases/failing/78 framework dependency with version/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/78 framework dependency with version/meson.build:8:0: ERROR: Dependency lookup for appleframeworks with method 'framework' failed: Unknown version, but need ['>0']."
+ }
+ ]
+}
diff --git a/test cases/failing/79 override exe config/foo.c b/test cases/failing/79 override exe config/foo.c
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/test cases/failing/79 override exe config/foo.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/failing/79 override exe config/meson.build b/test cases/failing/79 override exe config/meson.build
new file mode 100644
index 0000000..a5d0924
--- /dev/null
+++ b/test cases/failing/79 override exe config/meson.build
@@ -0,0 +1,6 @@
+project('myexe', 'c')
+
+foo = executable('foo', 'foo.c')
+meson.override_find_program('bar', foo)
+bar = find_program('bar')
+run_command(bar, check: true)
diff --git a/test cases/failing/79 override exe config/test.json b/test cases/failing/79 override exe config/test.json
new file mode 100644
index 0000000..1a671a3
--- /dev/null
+++ b/test cases/failing/79 override exe config/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/79 override exe config/meson.build:6:0: ERROR: Program 'bar' was overridden with the compiled executable 'foo' and therefore cannot be used during configuration"
+ }
+ ]
+}
diff --git a/test cases/failing/8 recursive/meson.build b/test cases/failing/8 recursive/meson.build
new file mode 100644
index 0000000..0cf9c47
--- /dev/null
+++ b/test cases/failing/8 recursive/meson.build
@@ -0,0 +1,3 @@
+project('recursive')
+
+a = subproject('a')
diff --git a/test cases/failing/8 recursive/subprojects/a/meson.build b/test cases/failing/8 recursive/subprojects/a/meson.build
new file mode 100644
index 0000000..c368b5c
--- /dev/null
+++ b/test cases/failing/8 recursive/subprojects/a/meson.build
@@ -0,0 +1,3 @@
+project('a')
+
+b = subproject('b')
diff --git a/test cases/failing/8 recursive/subprojects/b/meson.build b/test cases/failing/8 recursive/subprojects/b/meson.build
new file mode 100644
index 0000000..93b46c0
--- /dev/null
+++ b/test cases/failing/8 recursive/subprojects/b/meson.build
@@ -0,0 +1,3 @@
+project('b')
+
+a = subproject('a')
diff --git a/test cases/failing/8 recursive/test.json b/test cases/failing/8 recursive/test.json
new file mode 100644
index 0000000..b4c964c
--- /dev/null
+++ b/test cases/failing/8 recursive/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/8 recursive/subprojects/b/meson.build:3:0: ERROR: Recursive include of subprojects: a => b => a."
+ }
+ ]
+}
diff --git a/test cases/failing/80 gl dependency with version/meson.build b/test cases/failing/80 gl dependency with version/meson.build
new file mode 100644
index 0000000..0127093
--- /dev/null
+++ b/test cases/failing/80 gl dependency with version/meson.build
@@ -0,0 +1,9 @@
+project('gl dependency with version', 'c')
+
+host_system = host_machine.system()
+if host_system != 'windows' and host_system != 'darwin'
+ error('MESON_SKIP_TEST: test only fails on Windows and OSX')
+endif
+
+# gl dependency found via system method doesn't have a meaningful version to check
+dep = dependency('gl', method: 'system', version: '>0')
diff --git a/test cases/failing/80 gl dependency with version/test.json b/test cases/failing/80 gl dependency with version/test.json
new file mode 100644
index 0000000..3d39bc3
--- /dev/null
+++ b/test cases/failing/80 gl dependency with version/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/80 gl dependency with version/meson.build:9:0: ERROR: Dependency lookup for gl with method 'system' failed: Unknown version, but need ['>0']."
+ }
+ ]
+}
diff --git a/test cases/failing/81 threads dependency with version/meson.build b/test cases/failing/81 threads dependency with version/meson.build
new file mode 100644
index 0000000..6023fae
--- /dev/null
+++ b/test cases/failing/81 threads dependency with version/meson.build
@@ -0,0 +1,3 @@
+project('threads dependency with version', 'c')
+# threads dependency doesn't have a meaningful version to check
+dep = dependency('threads', version: '>0')
diff --git a/test cases/failing/81 threads dependency with version/test.json b/test cases/failing/81 threads dependency with version/test.json
new file mode 100644
index 0000000..308ac66
--- /dev/null
+++ b/test cases/failing/81 threads dependency with version/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/81 threads dependency with version/meson.build:3:0: ERROR: Dependency lookup for threads with method 'system' failed: Unknown version, but need ['>0']."
+ }
+ ]
+}
diff --git a/test cases/failing/82 gtest dependency with version/meson.build b/test cases/failing/82 gtest dependency with version/meson.build
new file mode 100644
index 0000000..efbffe1
--- /dev/null
+++ b/test cases/failing/82 gtest dependency with version/meson.build
@@ -0,0 +1,8 @@
+project('gtest dependency with version', 'cpp')
+
+if not dependency('gtest', method: 'system', required: false).found()
+ error('MESON_SKIP_TEST test requires gtest')
+endif
+
+# discovering gtest version is not yet implemented
+dep = dependency('gtest', method: 'system', version: '>0')
diff --git a/test cases/failing/82 gtest dependency with version/test.json b/test cases/failing/82 gtest dependency with version/test.json
new file mode 100644
index 0000000..7cf397b
--- /dev/null
+++ b/test cases/failing/82 gtest dependency with version/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/82 gtest dependency with version/meson.build:8:0: ERROR: Dependency 'gtest' is required but not found."
+ }
+ ]
+}
diff --git a/test cases/failing/83 dub libray/meson.build b/test cases/failing/83 dub libray/meson.build
new file mode 100644
index 0000000..306d5b3
--- /dev/null
+++ b/test cases/failing/83 dub libray/meson.build
@@ -0,0 +1,11 @@
+project('dub')
+
+if not add_languages('d', required: false)
+ error('MESON_SKIP_TEST test requires D compiler')
+endif
+
+if not find_program('dub', required: false).found()
+ error('MESON_SKIP_TEST test requires dub')
+endif
+
+dependency('dubtestproject', method: 'dub') # Not library (none)
diff --git a/test cases/failing/83 dub libray/test.json b/test cases/failing/83 dub libray/test.json
new file mode 100644
index 0000000..4dcbbed
--- /dev/null
+++ b/test cases/failing/83 dub libray/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/83 dub libray/meson.build:11:0: ERROR: Dependency \"dubtestproject\" not found"
+ }
+ ]
+}
diff --git a/test cases/failing/84 dub executable/meson.build b/test cases/failing/84 dub executable/meson.build
new file mode 100644
index 0000000..9a134ea
--- /dev/null
+++ b/test cases/failing/84 dub executable/meson.build
@@ -0,0 +1,11 @@
+project('dub')
+
+if not add_languages('d', required: false)
+ error('MESON_SKIP_TEST test requires D compiler')
+endif
+
+if not find_program('dub', required: false).found()
+ error('MESON_SKIP_TEST test requires dub')
+endif
+
+dependency('dubtestproject:test1', method: 'dub') # Not library (executable)
diff --git a/test cases/failing/84 dub executable/test.json b/test cases/failing/84 dub executable/test.json
new file mode 100644
index 0000000..6dfff62
--- /dev/null
+++ b/test cases/failing/84 dub executable/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/84 dub executable/meson.build:11:0: ERROR: Dependency \"dubtestproject:test1\" not found"
+ }
+ ]
+}
diff --git a/test cases/failing/85 dub compiler/meson.build b/test cases/failing/85 dub compiler/meson.build
new file mode 100644
index 0000000..36f1849
--- /dev/null
+++ b/test cases/failing/85 dub compiler/meson.build
@@ -0,0 +1,17 @@
+project('dub')
+
+if not add_languages('d', required: false)
+ error('MESON_SKIP_TEST test requires D compiler')
+endif
+
+if meson.get_compiler('d').get_id() == 'dmd'
+ if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST Windows test environment lacks multiple D compilers.')
+ endif
+endif
+
+if not find_program('dub', required: false).found()
+ error('MESON_SKIP_TEST test requires dub')
+endif
+
+dependency('dubtestproject:test2', method: 'dub') # Compiler mismatch
diff --git a/test cases/failing/85 dub compiler/test.json b/test cases/failing/85 dub compiler/test.json
new file mode 100644
index 0000000..50ee39b
--- /dev/null
+++ b/test cases/failing/85 dub compiler/test.json
@@ -0,0 +1,19 @@
+{
+ "matrix": {
+ "options": {
+ "warning_level": [
+ {
+ "val": "1",
+ "skip_on_env": [
+ "SINGLE_DUB_COMPILER"
+ ]
+ }
+ ]
+ }
+ },
+ "stdout": [
+ {
+ "line": "test cases/failing/85 dub compiler/meson.build:17:0: ERROR: Dependency \"dubtestproject:test2\" not found"
+ }
+ ]
+}
diff --git a/test cases/failing/86 subproj not-found dep/meson.build b/test cases/failing/86 subproj not-found dep/meson.build
new file mode 100644
index 0000000..2b17df1
--- /dev/null
+++ b/test cases/failing/86 subproj not-found dep/meson.build
@@ -0,0 +1,2 @@
+project('dep-test')
+missing = dependency('', fallback: ['somesubproj', 'notfound_dep'], required: true)
diff --git a/test cases/failing/86 subproj not-found dep/subprojects/somesubproj/meson.build b/test cases/failing/86 subproj not-found dep/subprojects/somesubproj/meson.build
new file mode 100644
index 0000000..5f451f4
--- /dev/null
+++ b/test cases/failing/86 subproj not-found dep/subprojects/somesubproj/meson.build
@@ -0,0 +1,3 @@
+project('dep', 'c')
+
+notfound_dep = dependency('', required : false)
diff --git a/test cases/failing/86 subproj not-found dep/test.json b/test cases/failing/86 subproj not-found dep/test.json
new file mode 100644
index 0000000..b662643
--- /dev/null
+++ b/test cases/failing/86 subproj not-found dep/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/86 subproj not-found dep/meson.build:2:0: ERROR: Dependency '(anonymous)' is required but not found."
+ }
+ ]
+}
diff --git a/test cases/failing/87 invalid configure file/input b/test cases/failing/87 invalid configure file/input
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/87 invalid configure file/input
diff --git a/test cases/failing/87 invalid configure file/meson.build b/test cases/failing/87 invalid configure file/meson.build
new file mode 100644
index 0000000..08eca2b
--- /dev/null
+++ b/test cases/failing/87 invalid configure file/meson.build
@@ -0,0 +1,9 @@
+project('invalid configura file')
+
+configure_file(
+ configuration : configuration_data(),
+ input : 'input',
+ output : 'output',
+ install_dir : '',
+ install : true,
+)
diff --git a/test cases/failing/87 invalid configure file/test.json b/test cases/failing/87 invalid configure file/test.json
new file mode 100644
index 0000000..d8ea73d
--- /dev/null
+++ b/test cases/failing/87 invalid configure file/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/87 invalid configure file/meson.build:3:0: ERROR: \"install_dir\" must be specified when \"install\" in a configure_file is true"
+ }
+ ]
+}
diff --git a/test cases/failing/88 kwarg dupe/meson.build b/test cases/failing/88 kwarg dupe/meson.build
new file mode 100644
index 0000000..06821a2
--- /dev/null
+++ b/test cases/failing/88 kwarg dupe/meson.build
@@ -0,0 +1,6 @@
+project('dupe kwarg', 'c')
+
+dupedict = {'install': true}
+
+executable('prog', 'prog.c', install: true,
+ kwargs: dupedict)
diff --git a/test cases/failing/88 kwarg dupe/prog.c b/test cases/failing/88 kwarg dupe/prog.c
new file mode 100644
index 0000000..5f3fbe6
--- /dev/null
+++ b/test cases/failing/88 kwarg dupe/prog.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("I don't get built. It makes me saaaaaad. :(\n");
+ return 0;
+}
diff --git a/test cases/failing/88 kwarg dupe/test.json b/test cases/failing/88 kwarg dupe/test.json
new file mode 100644
index 0000000..cfd68eb
--- /dev/null
+++ b/test cases/failing/88 kwarg dupe/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/88 kwarg dupe/meson.build:5:0: ERROR: Entry \"install\" defined both as a keyword argument and in a \"kwarg\" entry."
+ }
+ ]
+}
diff --git a/test cases/failing/89 missing pch file/meson.build b/test cases/failing/89 missing pch file/meson.build
new file mode 100644
index 0000000..a67b798
--- /dev/null
+++ b/test cases/failing/89 missing pch file/meson.build
@@ -0,0 +1,3 @@
+project('pch test', 'c')
+exe = executable('prog', 'prog.c',
+c_pch : ['pch/prog_pch.c', 'pch/prog.h'])
diff --git a/test cases/failing/89 missing pch file/prog.c b/test cases/failing/89 missing pch file/prog.c
new file mode 100644
index 0000000..11b7fad
--- /dev/null
+++ b/test cases/failing/89 missing pch file/prog.c
@@ -0,0 +1,3 @@
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/failing/89 missing pch file/test.json b/test cases/failing/89 missing pch file/test.json
new file mode 100644
index 0000000..638d2e7
--- /dev/null
+++ b/test cases/failing/89 missing pch file/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "comment": "literal 'pch/prog.h' from meson.build appears in output, irrespective of os.path.sep",
+ "line": "test cases/failing/89 missing pch file/meson.build:2:0: ERROR: File pch/prog.h does not exist."
+ }
+ ]
+}
diff --git a/test cases/failing/9 missing extra file/meson.build b/test cases/failing/9 missing extra file/meson.build
new file mode 100644
index 0000000..725bec8
--- /dev/null
+++ b/test cases/failing/9 missing extra file/meson.build
@@ -0,0 +1,3 @@
+project('missing extra file', 'c')
+
+executable('myprog', 'prog.c', extra_files : 'missing.txt')
diff --git a/test cases/failing/9 missing extra file/prog.c b/test cases/failing/9 missing extra file/prog.c
new file mode 100644
index 0000000..11b7fad
--- /dev/null
+++ b/test cases/failing/9 missing extra file/prog.c
@@ -0,0 +1,3 @@
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/failing/9 missing extra file/test.json b/test cases/failing/9 missing extra file/test.json
new file mode 100644
index 0000000..188b6a6
--- /dev/null
+++ b/test cases/failing/9 missing extra file/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/9 missing extra file/meson.build:3:0: ERROR: File missing.txt does not exist."
+ }
+ ]
+}
diff --git a/test cases/failing/90 pch source different folder/include/pch.h b/test cases/failing/90 pch source different folder/include/pch.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/90 pch source different folder/include/pch.h
diff --git a/test cases/failing/90 pch source different folder/meson.build b/test cases/failing/90 pch source different folder/meson.build
new file mode 100644
index 0000000..d320717
--- /dev/null
+++ b/test cases/failing/90 pch source different folder/meson.build
@@ -0,0 +1,5 @@
+project('pch', 'c')
+# It is not allowed to have the PCH implementation in a different
+# folder than the header.
+exe = executable('prog', 'prog.c',
+ c_pch : ['include/pch.h', 'src/pch.c'])
diff --git a/test cases/failing/90 pch source different folder/prog.c b/test cases/failing/90 pch source different folder/prog.c
new file mode 100644
index 0000000..3fb1295
--- /dev/null
+++ b/test cases/failing/90 pch source different folder/prog.c
@@ -0,0 +1 @@
+int main(void) {} \ No newline at end of file
diff --git a/test cases/failing/90 pch source different folder/src/pch.c b/test cases/failing/90 pch source different folder/src/pch.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/failing/90 pch source different folder/src/pch.c
diff --git a/test cases/failing/90 pch source different folder/test.json b/test cases/failing/90 pch source different folder/test.json
new file mode 100644
index 0000000..cbbac3d
--- /dev/null
+++ b/test cases/failing/90 pch source different folder/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/90 pch source different folder/meson.build:4:0: ERROR: PCH files must be stored in the same folder."
+ }
+ ]
+}
diff --git a/test cases/failing/91 unknown config tool/meson.build b/test cases/failing/91 unknown config tool/meson.build
new file mode 100644
index 0000000..536976e
--- /dev/null
+++ b/test cases/failing/91 unknown config tool/meson.build
@@ -0,0 +1,2 @@
+project('no-such-config-tool')
+dependency('no-such-config-tool', method:'config-tool')
diff --git a/test cases/failing/91 unknown config tool/test.json b/test cases/failing/91 unknown config tool/test.json
new file mode 100644
index 0000000..e225167
--- /dev/null
+++ b/test cases/failing/91 unknown config tool/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/91 unknown config tool/meson.build:2:0: ERROR: Dependency \"no-such-config-tool\" not found"
+ }
+ ]
+}
diff --git a/test cases/failing/92 custom target install data/Info.plist.cpp b/test cases/failing/92 custom target install data/Info.plist.cpp
new file mode 100644
index 0000000..9ca2fcb
--- /dev/null
+++ b/test cases/failing/92 custom target install data/Info.plist.cpp
@@ -0,0 +1 @@
+Some data which gets processed before installation
diff --git a/test cases/failing/92 custom target install data/meson.build b/test cases/failing/92 custom target install data/meson.build
new file mode 100644
index 0000000..00d348c
--- /dev/null
+++ b/test cases/failing/92 custom target install data/meson.build
@@ -0,0 +1,11 @@
+project('custom target install data')
+
+preproc = find_program('preproc.py')
+
+t = custom_target('Info.plist',
+ command: [preproc, '@INPUT@', '@OUTPUT@'],
+ input: 'Info.plist.cpp',
+ output: 'Info.plist',
+)
+
+install_data(t)
diff --git a/test cases/failing/92 custom target install data/preproc.py b/test cases/failing/92 custom target install data/preproc.py
new file mode 100644
index 0000000..e6eba4c
--- /dev/null
+++ b/test cases/failing/92 custom target install data/preproc.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import sys
+
+if len(sys.argv) != 3:
+ print(sys.argv[0], '<input>', '<output>')
+
+inf = sys.argv[1]
+outf = sys.argv[2]
+
+with open(outf, 'wb') as o:
+ with open(inf, 'rb') as i:
+ o.write(i.read())
diff --git a/test cases/failing/92 custom target install data/test.json b/test cases/failing/92 custom target install data/test.json
new file mode 100644
index 0000000..46ab013
--- /dev/null
+++ b/test cases/failing/92 custom target install data/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/92 custom target install data/meson.build:11:0: ERROR: install_data argument 1 was of type \"CustomTarget\" but should have been one of: \"str\", \"File\""
+ }
+ ]
+}
diff --git a/test cases/failing/93 add dict non string key/meson.build b/test cases/failing/93 add dict non string key/meson.build
new file mode 100644
index 0000000..c81a3f7
--- /dev/null
+++ b/test cases/failing/93 add dict non string key/meson.build
@@ -0,0 +1,9 @@
+project('add dictionary entry using non-string key')
+
+dict = {}
+
+# An integer variable to be used as a key
+key = 1
+
+# Add new entry using integer variable as key should fail
+dict += {key : 'myValue'} \ No newline at end of file
diff --git a/test cases/failing/93 add dict non string key/test.json b/test cases/failing/93 add dict non string key/test.json
new file mode 100644
index 0000000..3ef2dde
--- /dev/null
+++ b/test cases/failing/93 add dict non string key/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/93 add dict non string key/meson.build:9:0: ERROR: Key must be a string"
+ }
+ ]
+}
diff --git a/test cases/failing/94 add dict duplicate keys/meson.build b/test cases/failing/94 add dict duplicate keys/meson.build
new file mode 100644
index 0000000..7a9b523
--- /dev/null
+++ b/test cases/failing/94 add dict duplicate keys/meson.build
@@ -0,0 +1,9 @@
+project('add dictionary entries with duplicate keys')
+
+dict = {}
+
+# A variable to be used as a key
+key = 'myKey'
+
+# Add two entries with duplicate keys should fail
+dict += {key : 'myValue1', key : 'myValue2'} \ No newline at end of file
diff --git a/test cases/failing/94 add dict duplicate keys/test.json b/test cases/failing/94 add dict duplicate keys/test.json
new file mode 100644
index 0000000..5b2d7d6
--- /dev/null
+++ b/test cases/failing/94 add dict duplicate keys/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/94 add dict duplicate keys/meson.build:9:0: ERROR: Duplicate dictionary key: myKey"
+ }
+ ]
+}
diff --git a/test cases/failing/95 no host get_external_property/meson.build b/test cases/failing/95 no host get_external_property/meson.build
new file mode 100644
index 0000000..c956754
--- /dev/null
+++ b/test cases/failing/95 no host get_external_property/meson.build
@@ -0,0 +1,3 @@
+project('missing property')
+
+message(meson.get_external_property('nonexisting'))
diff --git a/test cases/failing/95 no host get_external_property/test.json b/test cases/failing/95 no host get_external_property/test.json
new file mode 100644
index 0000000..0ef6dd2
--- /dev/null
+++ b/test cases/failing/95 no host get_external_property/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/95 no host get_external_property/meson.build:3:0: ERROR: Unknown property for host machine: nonexisting"
+ }
+ ]
+}
diff --git a/test cases/failing/96 no native compiler/main.c b/test cases/failing/96 no native compiler/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/failing/96 no native compiler/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/failing/96 no native compiler/meson.build b/test cases/failing/96 no native compiler/meson.build
new file mode 100644
index 0000000..f0126ac
--- /dev/null
+++ b/test cases/failing/96 no native compiler/meson.build
@@ -0,0 +1,12 @@
+project('no native compiler')
+
+if not meson.is_cross_build()
+ error('MESON_SKIP_TEST test only applicable when cross building.')
+endif
+
+if add_languages('c', required: false, native: true)
+ error('MESON_SKIP_TEST test only applicable when native compiler not available.')
+endif
+
+add_languages('c')
+executable('main', 'main.c', native: true)
diff --git a/test cases/failing/96 no native compiler/test.json b/test cases/failing/96 no native compiler/test.json
new file mode 100644
index 0000000..0107727
--- /dev/null
+++ b/test cases/failing/96 no native compiler/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/96 no native compiler/meson.build:12:0: ERROR: No host machine compiler for \"main.c\""
+ }
+ ]
+}
diff --git a/test cases/failing/97 subdir parse error/meson.build b/test cases/failing/97 subdir parse error/meson.build
new file mode 100644
index 0000000..a744396
--- /dev/null
+++ b/test cases/failing/97 subdir parse error/meson.build
@@ -0,0 +1,2 @@
+project('subdir false plusassign')
+subdir('subdir')
diff --git a/test cases/failing/97 subdir parse error/subdir/meson.build b/test cases/failing/97 subdir parse error/subdir/meson.build
new file mode 100644
index 0000000..3ac5ef9
--- /dev/null
+++ b/test cases/failing/97 subdir parse error/subdir/meson.build
@@ -0,0 +1 @@
+3 += 4
diff --git a/test cases/failing/97 subdir parse error/test.json b/test cases/failing/97 subdir parse error/test.json
new file mode 100644
index 0000000..414789e
--- /dev/null
+++ b/test cases/failing/97 subdir parse error/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/97 subdir parse error/subdir/meson.build:1:0: ERROR: Plusassignment target must be an id."
+ }
+ ]
+}
diff --git a/test cases/failing/98 invalid option file/meson.build b/test cases/failing/98 invalid option file/meson.build
new file mode 100644
index 0000000..b0347c3
--- /dev/null
+++ b/test cases/failing/98 invalid option file/meson.build
@@ -0,0 +1 @@
+project('invalid option file')
diff --git a/test cases/failing/98 invalid option file/meson_options.txt b/test cases/failing/98 invalid option file/meson_options.txt
new file mode 100644
index 0000000..eef843b
--- /dev/null
+++ b/test cases/failing/98 invalid option file/meson_options.txt
@@ -0,0 +1 @@
+'
diff --git a/test cases/failing/98 invalid option file/test.json b/test cases/failing/98 invalid option file/test.json
new file mode 100644
index 0000000..6ab5393
--- /dev/null
+++ b/test cases/failing/98 invalid option file/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/98 invalid option file/meson_options.txt:1:0: ERROR: lexer"
+ }
+ ]
+}
diff --git a/test cases/failing/99 no lang/main.c b/test cases/failing/99 no lang/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/failing/99 no lang/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/failing/99 no lang/meson.build b/test cases/failing/99 no lang/meson.build
new file mode 100644
index 0000000..85c5db8
--- /dev/null
+++ b/test cases/failing/99 no lang/meson.build
@@ -0,0 +1,2 @@
+project('target without lang')
+executable('main', 'main.c')
diff --git a/test cases/failing/99 no lang/test.json b/test cases/failing/99 no lang/test.json
new file mode 100644
index 0000000..48c6dd7
--- /dev/null
+++ b/test cases/failing/99 no lang/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/failing/99 no lang/meson.build:2:0: ERROR: No host machine compiler for 'main.c'"
+ }
+ ]
+}
diff --git a/test cases/fortran/1 basic/meson.build b/test cases/fortran/1 basic/meson.build
new file mode 100644
index 0000000..52e2d6f
--- /dev/null
+++ b/test cases/fortran/1 basic/meson.build
@@ -0,0 +1,13 @@
+project('simple fortran', 'fortran')
+
+fc = meson.get_compiler('fortran')
+if fc.get_id() == 'gcc'
+ add_global_arguments('-fbounds-check', language : 'fortran')
+endif
+
+args = fc.first_supported_argument(['-ffree-form', '-free', '/free'])
+assert(args != [], 'No arguments found?')
+
+e = executable('simple', 'simple.f90',
+ fortran_args : args)
+test('Simple Fortran', e)
diff --git a/test cases/fortran/1 basic/simple.f90 b/test cases/fortran/1 basic/simple.f90
new file mode 100644
index 0000000..2160d56
--- /dev/null
+++ b/test cases/fortran/1 basic/simple.f90
@@ -0,0 +1,3 @@
+program main
+print *, "Fortran compilation is working."
+end program
diff --git a/test cases/fortran/10 find library/gzip.f90 b/test cases/fortran/10 find library/gzip.f90
new file mode 100644
index 0000000..32f21d7
--- /dev/null
+++ b/test cases/fortran/10 find library/gzip.f90
@@ -0,0 +1,32 @@
+module gzip
+
+use iso_c_binding, only: c_char, c_ptr, c_int
+implicit none
+
+interface
+type(c_ptr) function gzopen(path, mode) bind(C)
+import c_char, c_ptr
+
+character(kind=c_char), intent(in) :: path(*), mode(*)
+end function gzopen
+end interface
+
+interface
+integer(c_int) function gzwrite(file, buf, len) bind(C)
+import c_int, c_ptr, c_char
+
+type(c_ptr), value, intent(in) :: file
+character(kind=c_char), intent(in) :: buf
+integer(c_int), value, intent(in) :: len
+end function gzwrite
+end interface
+
+interface
+integer(c_int) function gzclose(file) bind(C)
+import c_int, c_ptr
+
+type(c_ptr), value, intent(in) :: file
+end function gzclose
+end interface
+
+end module gzip
diff --git a/test cases/fortran/10 find library/main.f90 b/test cases/fortran/10 find library/main.f90
new file mode 100644
index 0000000..e885d30
--- /dev/null
+++ b/test cases/fortran/10 find library/main.f90
@@ -0,0 +1,38 @@
+program main
+use iso_fortran_env, only: stderr=>error_unit
+use iso_c_binding, only: c_int, c_char, c_null_char, c_ptr
+use gzip, only: gzopen, gzwrite, gzclose
+
+implicit none
+
+character(kind=c_char,len=*), parameter :: path = c_char_"test.gz"//c_null_char
+character(kind=c_char,len=*), parameter :: mode = c_char_"wb9"//c_null_char
+integer(c_int), parameter :: buffer_size = 512
+
+type(c_ptr) :: file
+character(kind=c_char, len=buffer_size) :: buffer
+integer(c_int) :: ret
+integer :: i
+
+! open file
+file = gzopen(path, mode)
+
+! fill buffer with data
+do i=1,buffer_size/4
+ write(buffer(4*(i-1)+1:4*i), '(i3.3, a)') i, new_line('')
+end do
+ret = gzwrite(file, buffer, buffer_size)
+if (ret /= buffer_size) then
+ write(stderr,'(a, i3, a, i3, a)') 'Error: ', ret, ' / ', buffer_size, &
+ ' bytes written.'
+ stop 1
+end if
+
+! close file
+ret = gzclose(file)
+if (ret /= 0) then
+ write(stderr,*) 'Error: failure to close file with error code ', ret
+ stop 1
+end if
+
+end program
diff --git a/test cases/fortran/10 find library/meson.build b/test cases/fortran/10 find library/meson.build
new file mode 100644
index 0000000..2a2ef31
--- /dev/null
+++ b/test cases/fortran/10 find library/meson.build
@@ -0,0 +1,13 @@
+project('find fortran library', 'fortran')
+
+fc = meson.get_compiler('fortran')
+
+sources = ['main.f90', 'gzip.f90']
+zlib = fc.find_library('z', required: false)
+
+if not zlib.found()
+ error('MESON_SKIP_TEST: Z library not available.')
+endif
+
+exe = executable('zlibtest', sources, dependencies : zlib)
+test('testzlib', exe)
diff --git a/test cases/fortran/11 compiles links runs/meson.build b/test cases/fortran/11 compiles links runs/meson.build
new file mode 100644
index 0000000..150c1a4
--- /dev/null
+++ b/test cases/fortran/11 compiles links runs/meson.build
@@ -0,0 +1,17 @@
+project('compiles_links_runs', 'fortran')
+
+fc = meson.get_compiler('fortran')
+
+code = '''error stop 123; end'''
+
+if not fc.compiles(code)
+ error('Fortran 2008 code failed to compile')
+endif
+
+if not fc.links(code)
+ error('Fortran 2008 code failed to link')
+endif
+
+if fc.run(code).returncode() != 123
+ error('Fortran 2008 code failed to run')
+endif
diff --git a/test cases/fortran/12 submodule/a1.f90 b/test cases/fortran/12 submodule/a1.f90
new file mode 100644
index 0000000..c4b4555
--- /dev/null
+++ b/test cases/fortran/12 submodule/a1.f90
@@ -0,0 +1,26 @@
+module a1
+implicit none
+
+interface
+module elemental real function pi2tau(pi)
+ real, intent(in) :: pi
+end function pi2tau
+
+module real function get_pi()
+end function get_pi
+end interface
+
+end module a1
+
+program hierN
+
+use a1
+real :: tau, pi
+
+pi = get_pi()
+
+tau = pi2tau(pi)
+
+print *,'pi=',pi,'tau=',tau
+
+end program
diff --git a/test cases/fortran/12 submodule/a2.f90 b/test cases/fortran/12 submodule/a2.f90
new file mode 100644
index 0000000..ba8a0dd
--- /dev/null
+++ b/test cases/fortran/12 submodule/a2.f90
@@ -0,0 +1,10 @@
+! testing no space between submodule()
+submodule(a1) a2
+
+contains
+
+module procedure pi2tau
+ pi2tau = 2*pi
+end procedure pi2tau
+
+end submodule a2
diff --git a/test cases/fortran/12 submodule/a3.f90 b/test cases/fortran/12 submodule/a3.f90
new file mode 100644
index 0000000..3881675
--- /dev/null
+++ b/test cases/fortran/12 submodule/a3.f90
@@ -0,0 +1,13 @@
+! submodule (bogus) foo
+! testing don't detect commented submodule
+
+submodule (a1:a2) a3 ! testing inline comment
+
+contains
+
+module procedure get_pi
+ get_pi = 4.*atan(1.)
+end procedure get_pi
+
+
+end submodule a3
diff --git a/test cases/fortran/12 submodule/child.f90 b/test cases/fortran/12 submodule/child.f90
new file mode 100644
index 0000000..baf1fef
--- /dev/null
+++ b/test cases/fortran/12 submodule/child.f90
@@ -0,0 +1,13 @@
+submodule (parent) child
+
+contains
+
+module procedure pi2tau
+ pi2tau = 2*pi
+end procedure pi2tau
+
+module procedure good
+print *, 'Good!'
+end procedure good
+
+end submodule child
diff --git a/test cases/fortran/12 submodule/meson.build b/test cases/fortran/12 submodule/meson.build
new file mode 100644
index 0000000..204a36b
--- /dev/null
+++ b/test cases/fortran/12 submodule/meson.build
@@ -0,0 +1,13 @@
+project('submodule single level', 'fortran',
+ meson_version: '>= 0.50.0')
+
+fortc = meson.get_compiler('fortran')
+if fortc.get_id() == 'gcc' and fortc.version().version_compare('<6.0')
+ error('MESON_SKIP_TEST need gfortran >= 6.0 for submodule support')
+endif
+
+hier2 = executable('single', 'parent.f90', 'child.f90')
+test('single-level hierarchy', hier2)
+
+hierN = executable('multi', 'a1.f90', 'a2.f90', 'a3.f90')
+test('multi-level hierarchy', hierN)
diff --git a/test cases/fortran/12 submodule/parent.f90 b/test cases/fortran/12 submodule/parent.f90
new file mode 100644
index 0000000..efc7cf6
--- /dev/null
+++ b/test cases/fortran/12 submodule/parent.f90
@@ -0,0 +1,26 @@
+module parent
+real, parameter :: pi = 4.*atan(1.)
+real :: tau
+
+interface
+module elemental real function pi2tau(pi)
+ real, intent(in) :: pi
+end function pi2tau
+
+module subroutine good()
+end subroutine good
+end interface
+
+end module parent
+
+program main
+
+use parent
+
+tau = pi2tau(pi)
+
+print *,'pi=',pi, 'tau=', tau
+
+call good()
+
+end program
diff --git a/test cases/fortran/13 coarray/main.f90 b/test cases/fortran/13 coarray/main.f90
new file mode 100644
index 0000000..eee03ea
--- /dev/null
+++ b/test cases/fortran/13 coarray/main.f90
@@ -0,0 +1,10 @@
+program main
+implicit none
+
+if (this_image() == 1) print *, 'number of Fortran coarray images:', num_images()
+
+sync all ! semaphore, ensures message above is printed at top.
+
+print *, 'Process ', this_image()
+
+end program
diff --git a/test cases/fortran/13 coarray/meson.build b/test cases/fortran/13 coarray/meson.build
new file mode 100644
index 0000000..893cec9
--- /dev/null
+++ b/test cases/fortran/13 coarray/meson.build
@@ -0,0 +1,24 @@
+project('Fortran coarray', 'fortran',
+ meson_version: '>=0.50')
+
+fc = meson.get_compiler('fortran')
+
+if ['pgi', 'flang'].contains(fc.get_id())
+ error('MESON_SKIP_TEST: At least through PGI 19.10 and Flang 7.1 do not support Fortran Coarrays.')
+endif
+
+# coarray is required because single-image fallback is an intrinsic feature
+coarray = dependency('coarray')
+
+# check coarray, because user might not have all the library stack installed correctly
+# for example, conflicting library/compiler versions on PATH
+# this has to invoke a run of "sync all" to verify the MPI stack is functioning,
+# particularly for dynamic linking
+if fc.run('sync all; end', dependencies: coarray, name: 'Coarray link & run').returncode() != 0
+ error('MESON_SKIP_TEST: coarray stack (including MPI) did not link correctly so that a simple test could run.')
+endif
+
+exe = executable('hello', 'main.f90',
+ dependencies : coarray)
+
+test('Coarray hello world', exe, timeout: 10)
diff --git a/test cases/fortran/14 fortran links c/clib.c b/test cases/fortran/14 fortran links c/clib.c
new file mode 100644
index 0000000..81b2e0c
--- /dev/null
+++ b/test cases/fortran/14 fortran links c/clib.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void hello(void){
+
+ printf("hello from C\n");
+
+}
diff --git a/test cases/fortran/14 fortran links c/clib.def b/test cases/fortran/14 fortran links c/clib.def
new file mode 100644
index 0000000..4caeb24
--- /dev/null
+++ b/test cases/fortran/14 fortran links c/clib.def
@@ -0,0 +1,2 @@
+EXPORTS
+ hello
diff --git a/test cases/fortran/14 fortran links c/f_call_c.f90 b/test cases/fortran/14 fortran links c/f_call_c.f90
new file mode 100644
index 0000000..b3f70a7
--- /dev/null
+++ b/test cases/fortran/14 fortran links c/f_call_c.f90
@@ -0,0 +1,11 @@
+program main
+implicit none
+
+interface
+subroutine hello() bind (c)
+end subroutine hello
+end interface
+
+call hello()
+
+end program
diff --git a/test cases/fortran/14 fortran links c/meson.build b/test cases/fortran/14 fortran links c/meson.build
new file mode 100644
index 0000000..380a85a
--- /dev/null
+++ b/test cases/fortran/14 fortran links c/meson.build
@@ -0,0 +1,17 @@
+project('Fortran calling C', 'fortran', 'c',
+ meson_version: '>= 0.51.0',
+ default_options : ['default_library=static'])
+
+ccid = meson.get_compiler('c').get_id()
+fcid = meson.get_compiler('fortran').get_id()
+
+if fcid == 'gcc' and ccid in ['msvc', 'clang-cl']
+ error('MESON_SKIP_TEST: MSVC and GCC do not interoperate like this.')
+endif
+
+c_lib = library('clib', 'clib.c', vs_module_defs : 'clib.def')
+
+f_call_c = executable('f_call_c', 'f_call_c.f90',
+ link_with: c_lib,
+ link_language: 'fortran')
+test('Fortran calling C', f_call_c)
diff --git a/test cases/fortran/15 include/inc1.f90 b/test cases/fortran/15 include/inc1.f90
new file mode 100644
index 0000000..163f586
--- /dev/null
+++ b/test cases/fortran/15 include/inc1.f90
@@ -0,0 +1,5 @@
+
+real :: pi = 4.*atan(1.)
+real :: tau
+
+include "inc2.f90" ! testing inline comment
diff --git a/test cases/fortran/15 include/inc2.f90 b/test cases/fortran/15 include/inc2.f90
new file mode 100644
index 0000000..065b990
--- /dev/null
+++ b/test cases/fortran/15 include/inc2.f90
@@ -0,0 +1,2 @@
+
+tau = 2*pi
diff --git a/test cases/fortran/15 include/include_hierarchy.f90 b/test cases/fortran/15 include/include_hierarchy.f90
new file mode 100644
index 0000000..0598d87
--- /dev/null
+++ b/test cases/fortran/15 include/include_hierarchy.f90
@@ -0,0 +1,9 @@
+program test_include_hier
+
+implicit none
+
+include "inc1.f90"
+
+print *, '2*pi:', tau
+
+end program
diff --git a/test cases/fortran/15 include/include_syntax.f90 b/test cases/fortran/15 include/include_syntax.f90
new file mode 100644
index 0000000..5f7eb9f
--- /dev/null
+++ b/test cases/fortran/15 include/include_syntax.f90
@@ -0,0 +1,25 @@
+program test_include_syntax
+
+implicit none
+
+integer :: x, y
+
+x = 1
+y = 0
+
+! include "timestwo.f90"
+
+include "timestwo.f90" ! inline comment check
+if (x/=2) error stop 'failed on first include'
+
+! leading space check
+ include 'timestwo.f90'
+if (x/=4) error stop 'failed on second include'
+
+! Most Fortran compilers can't handle the non-standard #include,
+! including (ha!) Flang, Gfortran, Ifort and PGI.
+! #include "timestwo.f90"
+
+print *, 'OK: Fortran include tests: x=',x
+
+end program
diff --git a/test cases/fortran/15 include/meson.build b/test cases/fortran/15 include/meson.build
new file mode 100644
index 0000000..e19c47f
--- /dev/null
+++ b/test cases/fortran/15 include/meson.build
@@ -0,0 +1,19 @@
+project('Inclusive', 'fortran',
+ meson_version: '>= 0.51.1')
+
+cm = import('cmake')
+
+hier_exe = executable('include_hierarchy', 'include_hierarchy.f90')
+test('Fortran include file hierarchy', hier_exe)
+
+syntax_exe = executable('include_syntax', 'include_syntax.f90')
+test('Fortran include file syntax', syntax_exe)
+
+# older CI runs into problems with too-old Ninja and CMake and Fortran
+ninja_version = run_command('ninja', '--version', check: true).stdout().strip()
+cmake_version = run_command('cmake', '--version', check: true).stdout().split()[2]
+if ninja_version.version_compare('>=1.10.0') and cmake_version.version_compare('>=3.17.0')
+ cm.subproject('cmake_inc')
+else
+ message('SKIP: CMake Fortran subproject with include. Ninja >= 1.10 and CMake >= 3.17 needed. You have Ninja ' + ninja_version + ' and CMake ' + cmake_version)
+endif
diff --git a/test cases/fortran/15 include/subprojects/cmake_inc/CMakeLists.txt b/test cases/fortran/15 include/subprojects/cmake_inc/CMakeLists.txt
new file mode 100644
index 0000000..1ffe882
--- /dev/null
+++ b/test cases/fortran/15 include/subprojects/cmake_inc/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.17)
+project(cmake_inc LANGUAGES Fortran)
+
+add_executable(main main.f90)
diff --git a/test cases/fortran/15 include/subprojects/cmake_inc/main.f90 b/test cases/fortran/15 include/subprojects/cmake_inc/main.f90
new file mode 100644
index 0000000..dd2991d
--- /dev/null
+++ b/test cases/fortran/15 include/subprojects/cmake_inc/main.f90
@@ -0,0 +1,9 @@
+program test_subproject_inc
+
+implicit none
+
+include 'thousand.f90'
+
+if (thousand /= 1000) error stop 'did not include properly'
+
+end program
diff --git a/test cases/fortran/15 include/subprojects/cmake_inc/thousand.f90 b/test cases/fortran/15 include/subprojects/cmake_inc/thousand.f90
new file mode 100644
index 0000000..08a4048
--- /dev/null
+++ b/test cases/fortran/15 include/subprojects/cmake_inc/thousand.f90
@@ -0,0 +1 @@
+integer, parameter :: thousand = 1000
diff --git a/test cases/fortran/15 include/timestwo.f90 b/test cases/fortran/15 include/timestwo.f90
new file mode 100644
index 0000000..0e2d5ac
--- /dev/null
+++ b/test cases/fortran/15 include/timestwo.f90
@@ -0,0 +1,2 @@
+x = 2*x
+y = y+1 \ No newline at end of file
diff --git a/test cases/fortran/16 openmp/main.f90 b/test cases/fortran/16 openmp/main.f90
new file mode 100644
index 0000000..26b792f
--- /dev/null
+++ b/test cases/fortran/16 openmp/main.f90
@@ -0,0 +1,18 @@
+program main
+use, intrinsic :: iso_fortran_env, only: stderr=>error_unit
+use omp_lib, only: omp_get_max_threads
+implicit none
+
+integer :: N, ierr
+character(80) :: buf ! can't be allocatable in this use case. Just set arbitrarily large.
+
+call get_environment_variable('OMP_NUM_THREADS', buf, status=ierr)
+if (ierr/=0) error stop 'environment variable OMP_NUM_THREADS could not be read'
+read(buf,*) N
+
+if (omp_get_max_threads() /= N) then
+ write(stderr, *) 'Max Fortran threads: ', omp_get_max_threads(), '!=', N
+ error stop
+endif
+
+end program
diff --git a/test cases/fortran/16 openmp/meson.build b/test cases/fortran/16 openmp/meson.build
new file mode 100644
index 0000000..f021ce2
--- /dev/null
+++ b/test cases/fortran/16 openmp/meson.build
@@ -0,0 +1,34 @@
+# This test is complementary to and extends "common/190 openmp" so that
+# we can examine more compilers and options than would be warranted in
+# the common test where C/C++ must also be handled.
+project('openmp', 'fortran',
+ meson_version: '>= 0.46')
+
+
+fc = meson.get_compiler('fortran')
+if fc.get_id() == 'gcc' and fc.version().version_compare('<4.2.0')
+ error('MESON_SKIP_TEST gcc is too old to support OpenMP.')
+endif
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST macOS does not support OpenMP.')
+endif
+
+openmp = dependency('openmp')
+
+env = environment()
+env.set('OMP_NUM_THREADS', '2')
+
+exef = executable('exef',
+ 'main.f90',
+ dependencies : [openmp])
+test('OpenMP Fortran', exef, env : env)
+
+openmp_f = dependency('openmp', language : 'fortran')
+exe_f = executable('exe_f',
+ 'main.f90',
+ dependencies : [openmp_f])
+test('OpenMP Fortran-specific', exe_f, env : env)
+
+
+# Check we can apply a version constraint
+dependency('openmp', version: '>=@0@'.format(openmp.version()))
diff --git a/test cases/fortran/17 add_languages/meson.build b/test cases/fortran/17 add_languages/meson.build
new file mode 100644
index 0000000..e7de180
--- /dev/null
+++ b/test cases/fortran/17 add_languages/meson.build
@@ -0,0 +1,5 @@
+project('add_lang_fortran')
+
+# catch bug where Fortran compiler is found with project('foo', 'fortran') but
+# not by add_languages('fortran')
+assert(add_languages('fortran'), 'these tests assume Fortran compiler can be found') \ No newline at end of file
diff --git a/test cases/fortran/18 first_arg/main.f90 b/test cases/fortran/18 first_arg/main.f90
new file mode 100644
index 0000000..6ea28b1
--- /dev/null
+++ b/test cases/fortran/18 first_arg/main.f90
@@ -0,0 +1,3 @@
+program main
+i = 3
+end program
diff --git a/test cases/fortran/18 first_arg/meson.build b/test cases/fortran/18 first_arg/meson.build
new file mode 100644
index 0000000..63021f2
--- /dev/null
+++ b/test cases/fortran/18 first_arg/meson.build
@@ -0,0 +1,46 @@
+project('fortran_args', 'fortran')
+
+fc = meson.get_compiler('fortran')
+
+if fc.get_id() == 'intel-cl'
+ is_arg = '/O2'
+ useless = '/DFOO'
+else
+ is_arg = '-O2'
+ useless = '-DFOO'
+endif
+
+isnt_arg = '-fiambroken'
+
+assert(fc.has_argument(is_arg), 'Arg that should have worked does not work.')
+assert(not fc.has_argument(isnt_arg), 'Arg that should be broken is not.')
+
+assert(fc.get_supported_arguments([is_arg, isnt_arg, useless]) == [is_arg, useless], 'Arg filtering returned different result.')
+
+# Have useless at the end to ensure that the search goes from front to back.
+l1 = fc.first_supported_argument([isnt_arg, is_arg, isnt_arg, useless])
+l2 = fc.first_supported_argument(isnt_arg, isnt_arg, isnt_arg)
+
+assert(l1.length() == 1, 'First supported returned wrong result.')
+assert(l1.get(0) == is_arg, 'First supported returned wrong argument.')
+assert(l2.length() == 0, 'First supported did not return empty array.')
+
+# --- test with an actual program, here for implicit none
+
+in0 = fc.first_supported_argument('-fimplicit-none', '-Mdclchk', '/warn:declarations', '-warn').get(0, '')
+impnone = {
+'intel-cl': '/warn:declarations',
+'intel': '-warn',
+'gcc': '-fimplicit-none',
+'pgi': '-Mdclchk',
+}
+
+arg = impnone.get(fc.get_id(), '')
+if arg != ''
+ assert(in0 == arg, 'implicit none argument ' + arg + ' not matching ' + in0)
+endif
+
+in1 = fc.get_supported_arguments('-fimplicit-none', '/warn:declarations', '/warn:errors', '-Mdclchk')
+if in1.length() > 0
+ assert(not fc.compiles(files('main.f90'), args: in1, name:'will fail implicit none'), 'implicit none should have failed')
+endif
diff --git a/test cases/fortran/19 fortran_std/legacy.f b/test cases/fortran/19 fortran_std/legacy.f
new file mode 100644
index 0000000..014bcc1
--- /dev/null
+++ b/test cases/fortran/19 fortran_std/legacy.f
@@ -0,0 +1,8 @@
+ program main
+ ! non-integer loop indices are deleted in Fortran 95 standard
+ real a
+
+ do 10 a=0,0.5,0.1
+10 continue
+
+ end program
diff --git a/test cases/fortran/19 fortran_std/meson.build b/test cases/fortran/19 fortran_std/meson.build
new file mode 100644
index 0000000..f46f8ff
--- /dev/null
+++ b/test cases/fortran/19 fortran_std/meson.build
@@ -0,0 +1,27 @@
+project('FortranStd', 'fortran',
+ default_options: ['warning_level=0'])
+# As with C and C++, each Fortran compiler + version has a subset of supported Fortran standards
+# Additionally, a necessary option for non-standard Fortran projects is the "legacy"
+# option, which allows non-standard syntax and behavior quirks.
+# Thus "legacy" is a necessity for some old but important Fortran projects.
+# By default, popular Fortran compilers disallow these quirks without "legacy" option.
+
+fc = meson.get_compiler('fortran')
+
+executable('stdnone', 'std95.f90')
+
+executable('std_legacy', 'legacy.f', override_options : ['fortran_std=legacy'])
+
+executable('std_95', 'std95.f90', override_options : ['fortran_std=f95'])
+
+executable('std_f2003', 'std2003.f90', override_options : ['fortran_std=f2003'])
+
+executable('std_f2008', 'std2008.f90', override_options : ['fortran_std=f2008'])
+
+if fc.get_id() == 'gcc'
+ if fc.version().version_compare('>=8.0')
+ executable('std_f2018', 'std2018.f90', override_options : ['fortran_std=f2018'])
+ endif
+else
+ executable('std_f2018', 'std2018.f90', override_options : ['fortran_std=f2018'])
+endif \ No newline at end of file
diff --git a/test cases/fortran/19 fortran_std/std2003.f90 b/test cases/fortran/19 fortran_std/std2003.f90
new file mode 100644
index 0000000..0382192
--- /dev/null
+++ b/test cases/fortran/19 fortran_std/std2003.f90
@@ -0,0 +1,37 @@
+program main
+use, intrinsic :: iso_fortran_env, only : error_unit
+implicit none
+
+! http://fortranwiki.org/fortran/show/Real+precision
+integer, parameter :: sp = selected_real_kind(6, 37)
+integer, parameter :: dp = selected_real_kind(15, 307)
+
+real(sp) :: a32
+real(dp) :: a64
+
+real(sp), parameter :: pi32 = 4*atan(1._sp)
+real(dp), parameter :: pi64 = 4*atan(1._dp)
+
+if (pi32 == pi64) stop 1
+
+call timestwo(a32)
+call timestwo(a64)
+
+contains
+
+elemental subroutine timestwo(a)
+
+class(*), intent(inout) :: a
+
+select type (a)
+ type is (real(sp))
+ a = 2*a
+ type is (real(dp))
+ a = 2*a
+ type is (integer)
+ a = 2*a
+end select
+
+end subroutine timestwo
+
+end program
diff --git a/test cases/fortran/19 fortran_std/std2008.f90 b/test cases/fortran/19 fortran_std/std2008.f90
new file mode 100644
index 0000000..750173e
--- /dev/null
+++ b/test cases/fortran/19 fortran_std/std2008.f90
@@ -0,0 +1,33 @@
+program main
+use, intrinsic :: iso_fortran_env, only : error_unit, sp=>real32, dp=>real64
+implicit none
+
+real(sp) :: a32
+real(dp) :: a64
+
+real(sp), parameter :: pi32 = 4*atan(1._sp)
+real(dp), parameter :: pi64 = 4*atan(1._dp)
+
+if (pi32 == pi64) error stop 'real32 values generally do not exactly equal real64 values'
+
+call timestwo(a32)
+call timestwo(a64)
+
+contains
+
+elemental subroutine timestwo(a)
+
+class(*), intent(inout) :: a
+
+select type (a)
+ type is (real(sp))
+ a = 2*a
+ type is (real(dp))
+ a = 2*a
+ type is (integer)
+ a = 2*a
+end select
+
+end subroutine timestwo
+
+end program
diff --git a/test cases/fortran/19 fortran_std/std2018.f90 b/test cases/fortran/19 fortran_std/std2018.f90
new file mode 100644
index 0000000..34fad50
--- /dev/null
+++ b/test cases/fortran/19 fortran_std/std2018.f90
@@ -0,0 +1,35 @@
+program main
+use, intrinsic :: iso_fortran_env, only : error_unit, sp=>real32, dp=>real64
+implicit none
+
+real(sp) :: a32
+real(dp) :: a64
+
+real(sp), parameter :: pi32 = 4*atan(1._sp)
+real(dp), parameter :: pi64 = 4*atan(1._dp)
+
+if (pi32 == pi64) error stop 'real32 values generally do not exactly equal real64 values'
+
+call timestwo(a32)
+call timestwo(a64)
+
+contains
+
+elemental subroutine timestwo(a)
+
+class(*), intent(inout) :: a
+
+select type (a)
+ type is (real(sp))
+ a = 2*a
+ type is (real(dp))
+ a = 2*a
+ type is (integer)
+ a = 2*a
+ class default
+ error stop 'requires real32, real64 or integer'
+end select
+
+end subroutine timestwo
+
+end program
diff --git a/test cases/fortran/19 fortran_std/std95.f90 b/test cases/fortran/19 fortran_std/std95.f90
new file mode 100644
index 0000000..2837da8
--- /dev/null
+++ b/test cases/fortran/19 fortran_std/std95.f90
@@ -0,0 +1,14 @@
+program main
+implicit none
+
+integer :: i, j
+integer, parameter :: N=3
+real :: A(N,N)
+
+A = 0
+
+forall (i=1:N, j=1:N)
+ A(i,j) = 1
+end forall
+
+end program
diff --git a/test cases/fortran/2 modules/comment_mod.f90 b/test cases/fortran/2 modules/comment_mod.f90
new file mode 100644
index 0000000..917f6be
--- /dev/null
+++ b/test cases/fortran/2 modules/comment_mod.f90
@@ -0,0 +1,6 @@
+module line ! inline comment
+implicit none
+
+real :: length
+
+end module line
diff --git a/test cases/fortran/2 modules/meson.build b/test cases/fortran/2 modules/meson.build
new file mode 100644
index 0000000..c9bfd8d
--- /dev/null
+++ b/test cases/fortran/2 modules/meson.build
@@ -0,0 +1,9 @@
+project('modules', 'fortran',
+ default_options : ['default_library=static'])
+
+commented = library('commented', 'comment_mod.f90')
+
+# Have one file with an upper case file extension.
+e = executable('modprog', 'mymod.F90', 'prog.f90',
+ link_with: commented)
+test('moduletest', e)
diff --git a/test cases/fortran/2 modules/mymod.F90 b/test cases/fortran/2 modules/mymod.F90
new file mode 100644
index 0000000..a45f5c9
--- /dev/null
+++ b/test cases/fortran/2 modules/mymod.F90
@@ -0,0 +1,8 @@
+! module circle to be sure module regex doesn't allow commented modules
+
+module circle
+implicit none
+
+real, parameter :: pi = 4.*atan(1.)
+real :: radius
+end module circle
diff --git a/test cases/fortran/2 modules/prog.f90 b/test cases/fortran/2 modules/prog.f90
new file mode 100644
index 0000000..ef72d11
--- /dev/null
+++ b/test cases/fortran/2 modules/prog.f90
@@ -0,0 +1,11 @@
+program main
+use circle, only: pi
+use line, only: length
+implicit none
+
+print *,'pi=',pi
+
+length = pi
+print *, length
+
+end program
diff --git a/test cases/fortran/20 buildtype/main.f90 b/test cases/fortran/20 buildtype/main.f90
new file mode 100644
index 0000000..ecc7d61
--- /dev/null
+++ b/test cases/fortran/20 buildtype/main.f90
@@ -0,0 +1,2 @@
+program main
+end program
diff --git a/test cases/fortran/20 buildtype/meson.build b/test cases/fortran/20 buildtype/meson.build
new file mode 100644
index 0000000..2be6337
--- /dev/null
+++ b/test cases/fortran/20 buildtype/meson.build
@@ -0,0 +1,5 @@
+# checks for unexpected behavior on non-default buildtype and warning_level
+project('build type Fortran', 'fortran',
+ default_options: ['buildtype=release', 'warning_level=3'])
+
+executable('main', 'main.f90')
diff --git a/test cases/fortran/21 install static/main.f90 b/test cases/fortran/21 install static/main.f90
new file mode 100644
index 0000000..d0c67fe
--- /dev/null
+++ b/test cases/fortran/21 install static/main.f90
@@ -0,0 +1,5 @@
+program main
+use main_lib
+implicit none
+call main_hello()
+end program
diff --git a/test cases/fortran/21 install static/main_lib.f90 b/test cases/fortran/21 install static/main_lib.f90
new file mode 100644
index 0000000..874584d
--- /dev/null
+++ b/test cases/fortran/21 install static/main_lib.f90
@@ -0,0 +1,16 @@
+module main_lib
+
+ use static_hello
+ implicit none
+
+ private
+ public :: main_hello
+
+ contains
+
+ subroutine main_hello
+ call static_say_hello()
+ print *, "Main hello routine finished."
+ end subroutine main_hello
+
+end module main_lib
diff --git a/test cases/fortran/21 install static/meson.build b/test cases/fortran/21 install static/meson.build
new file mode 100644
index 0000000..b4d3e40
--- /dev/null
+++ b/test cases/fortran/21 install static/meson.build
@@ -0,0 +1,20 @@
+# Based on 'fortran/5 static', but:
+# - Uses a subproject dependency
+# - Is an install:true static library to trigger certain codepath (promotion to link_whole)
+# - Does fortran code 'generation' with configure_file
+# - Uses .F90 ext (capital F typically denotes a dependence on preprocessor treatment, which however is not used)
+project('try-static-subproject-dependency', 'fortran')
+
+static_dep = dependency('static_hello', fallback: ['static_hello', 'static_hello_dep'])
+
+mainsrc = 'main_lib.f90'
+mainsrc = configure_file(
+ copy: true,
+ input: mainsrc,
+ output: 'main_lib_output.F90'
+)
+main_lib = library('mainstatic', mainsrc, dependencies: static_dep, install: true)
+main_dep = declare_dependency(link_with: main_lib)
+
+main_exe = executable('main_exe', 'main.f90', dependencies: main_dep)
+test('static_subproject_test', main_exe)
diff --git a/test cases/fortran/21 install static/subprojects/static_hello/meson.build b/test cases/fortran/21 install static/subprojects/static_hello/meson.build
new file mode 100644
index 0000000..5e13bae
--- /dev/null
+++ b/test cases/fortran/21 install static/subprojects/static_hello/meson.build
@@ -0,0 +1,12 @@
+project('static-hello', 'fortran')
+
+# staticlibsource = 'static_hello.f90'
+staticlibsource = configure_file(
+ copy: true,
+ input: 'static_hello.f90',
+ output: 'static_hello_output.F90'
+)
+
+static_hello_lib = static_library('static_hello', staticlibsource, install: false)
+
+static_hello_dep = declare_dependency(link_with: static_hello_lib)
diff --git a/test cases/fortran/21 install static/subprojects/static_hello/static_hello.f90 b/test cases/fortran/21 install static/subprojects/static_hello/static_hello.f90
new file mode 100644
index 0000000..5407560
--- /dev/null
+++ b/test cases/fortran/21 install static/subprojects/static_hello/static_hello.f90
@@ -0,0 +1,17 @@
+module static_hello
+implicit none
+
+private
+public :: static_say_hello
+
+interface static_say_hello
+ module procedure say_hello
+end interface static_say_hello
+
+contains
+
+subroutine say_hello
+ print *, "Static library called."
+end subroutine say_hello
+
+end module static_hello
diff --git a/test cases/fortran/21 install static/test.json b/test cases/fortran/21 install static/test.json
new file mode 100644
index 0000000..aff7147
--- /dev/null
+++ b/test cases/fortran/21 install static/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"file": "usr/lib/libmainstatic.a", "type": "file"}
+ ],
+ "matrix": {
+ "options": {
+ "default_library": [ { "val": "static" } ]
+ }
+ }
+}
diff --git a/test cases/fortran/3 module procedure/meson.build b/test cases/fortran/3 module procedure/meson.build
new file mode 100644
index 0000000..a590015
--- /dev/null
+++ b/test cases/fortran/3 module procedure/meson.build
@@ -0,0 +1,5 @@
+project('Fortran 2003 use statement, in same file', 'fortran',
+ meson_version: '>= 0.50.0')
+
+e = executable('use_syntax', 'use_syntax.f90')
+test('Fortran 2003 use syntax', e)
diff --git a/test cases/fortran/3 module procedure/use_syntax.f90 b/test cases/fortran/3 module procedure/use_syntax.f90
new file mode 100644
index 0000000..2f3a9e6
--- /dev/null
+++ b/test cases/fortran/3 module procedure/use_syntax.f90
@@ -0,0 +1,31 @@
+module circle
+implicit none
+
+integer :: x
+real :: radius
+
+interface default
+ module procedure timestwo
+end interface
+
+contains
+
+elemental integer function timestwo(x) result(y)
+ integer, intent(in) :: x
+ y = 2*x
+end function
+end module circle
+
+program prog
+
+use, non_intrinsic :: circle, only: timestwo, x
+
+implicit none
+
+x = 3
+
+if (timestwo(x) /= 6) error stop 'fortran module procedure problem'
+
+print *,'OK: Fortran module procedure'
+
+end program prog
diff --git a/test cases/fortran/4 self dependency/meson.build b/test cases/fortran/4 self dependency/meson.build
new file mode 100644
index 0000000..e791284
--- /dev/null
+++ b/test cases/fortran/4 self dependency/meson.build
@@ -0,0 +1,8 @@
+project('selfdep', 'fortran')
+
+e = executable('selfdep', 'selfdep.f90')
+test('selfdep', e)
+
+library('selfmod', 'src/selfdep_mod.f90')
+
+subproject('sub1')
diff --git a/test cases/fortran/4 self dependency/selfdep.f90 b/test cases/fortran/4 self dependency/selfdep.f90
new file mode 100644
index 0000000..1a71353
--- /dev/null
+++ b/test cases/fortran/4 self dependency/selfdep.f90
@@ -0,0 +1,18 @@
+MODULE geom
+
+type :: circle
+ REAL :: Pi = 4.*atan(1.)
+ REAL :: radius
+end type circle
+END MODULE geom
+
+PROGRAM prog
+
+use geom, only : circle
+IMPLICIT NONE
+
+type(circle) :: ell
+
+ell%radius = 3.
+
+END PROGRAM prog
diff --git a/test cases/fortran/4 self dependency/src/selfdep_mod.f90 b/test cases/fortran/4 self dependency/src/selfdep_mod.f90
new file mode 100644
index 0000000..4aa0057
--- /dev/null
+++ b/test cases/fortran/4 self dependency/src/selfdep_mod.f90
@@ -0,0 +1,6 @@
+module a
+end module a
+
+module b
+use a
+end module b
diff --git a/test cases/fortran/4 self dependency/subprojects/sub1/main.f90 b/test cases/fortran/4 self dependency/subprojects/sub1/main.f90
new file mode 100644
index 0000000..873427d
--- /dev/null
+++ b/test cases/fortran/4 self dependency/subprojects/sub1/main.f90
@@ -0,0 +1,6 @@
+module a
+end
+
+program b
+ use a
+end
diff --git a/test cases/fortran/4 self dependency/subprojects/sub1/meson.build b/test cases/fortran/4 self dependency/subprojects/sub1/meson.build
new file mode 100644
index 0000000..606f338
--- /dev/null
+++ b/test cases/fortran/4 self dependency/subprojects/sub1/meson.build
@@ -0,0 +1,3 @@
+project('subproject self-def', 'fortran')
+
+library('subself', 'main.f90')
diff --git a/test cases/fortran/5 static/main.f90 b/test cases/fortran/5 static/main.f90
new file mode 100644
index 0000000..4db2861
--- /dev/null
+++ b/test cases/fortran/5 static/main.f90
@@ -0,0 +1,6 @@
+program main
+use static_hello
+implicit none
+
+call static_say_hello()
+end program
diff --git a/test cases/fortran/5 static/meson.build b/test cases/fortran/5 static/meson.build
new file mode 100644
index 0000000..ab9d3c4
--- /dev/null
+++ b/test cases/fortran/5 static/meson.build
@@ -0,0 +1,6 @@
+project('try-static-library', 'fortran')
+
+static_hello = static_library('static_hello', 'static_hello.f90')
+
+exe = executable('test_exe', 'main.f90', link_with : static_hello)
+test('static-fortran', exe)
diff --git a/test cases/fortran/5 static/static_hello.f90 b/test cases/fortran/5 static/static_hello.f90
new file mode 100644
index 0000000..5407560
--- /dev/null
+++ b/test cases/fortran/5 static/static_hello.f90
@@ -0,0 +1,17 @@
+module static_hello
+implicit none
+
+private
+public :: static_say_hello
+
+interface static_say_hello
+ module procedure say_hello
+end interface static_say_hello
+
+contains
+
+subroutine say_hello
+ print *, "Static library called."
+end subroutine say_hello
+
+end module static_hello
diff --git a/test cases/fortran/6 dynamic/dynamic.f90 b/test cases/fortran/6 dynamic/dynamic.f90
new file mode 100644
index 0000000..6a1f359
--- /dev/null
+++ b/test cases/fortran/6 dynamic/dynamic.f90
@@ -0,0 +1,17 @@
+module dynamic
+implicit none
+
+private
+public :: hello
+
+interface hello
+ module procedure say
+end interface hello
+
+contains
+
+subroutine say
+ print *, "Hello from shared library."
+end subroutine say
+
+end module dynamic
diff --git a/test cases/fortran/6 dynamic/main.f90 b/test cases/fortran/6 dynamic/main.f90
new file mode 100644
index 0000000..ba2e2d2
--- /dev/null
+++ b/test cases/fortran/6 dynamic/main.f90
@@ -0,0 +1,6 @@
+program main
+use dynamic, only: hello
+implicit none
+
+call hello()
+end program
diff --git a/test cases/fortran/6 dynamic/meson.build b/test cases/fortran/6 dynamic/meson.build
new file mode 100644
index 0000000..413223b
--- /dev/null
+++ b/test cases/fortran/6 dynamic/meson.build
@@ -0,0 +1,13 @@
+project('dynamic_fortran', 'fortran')
+
+fcid = meson.get_compiler('fortran').get_id()
+if fcid == 'intel-cl' or (host_machine.system() == 'windows' and fcid == 'pgi')
+ error('MESON_SKIP_TEST: non-Gfortran Windows Fortran compilers do not do shared libraries in a Fortran standard way')
+ # !DEC$ ATTRIBUTES DLLEXPORT must be used!
+ # https://software.intel.com/en-us/node/535306
+ # https://www.pgroup.com/resources/docs/19.4/x86/pgi-user-guide/index.htm#lib-dynlnk-bld-dll-fort
+endif
+
+dynamic = shared_library('dynamic', 'dynamic.f90')
+exe = executable('test_exe', 'main.f90', link_with : dynamic)
+test('dynamic-fortran', exe)
diff --git a/test cases/fortran/7 generated/meson.build b/test cases/fortran/7 generated/meson.build
new file mode 100644
index 0000000..f021309
--- /dev/null
+++ b/test cases/fortran/7 generated/meson.build
@@ -0,0 +1,39 @@
+# Tests whether fortran sources files created during configuration are properly
+# scanned for dependency information
+
+project('generated', 'fortran',
+ default_options : ['default_library=static'])
+
+conf_data = configuration_data()
+conf_data.set('ONE', 1)
+conf_data.set('TWO', 2)
+
+mod3_f = custom_target(
+ 'mod3.f',
+ input : 'mod3.f90',
+ output : 'mod3.f90',
+ # We need a platform agnostic way to do a copy a file, using a custom_target
+ # and we need to use the @OUTDIR@, not @OUTPUT@ in order to exercise
+ # https://github.com/mesonbuild/meson/issues/9258
+ command : [
+ find_program('python', 'python3'), '-c',
+ 'import sys, shutil; shutil.copy(sys.argv[1], sys.argv[2])',
+ '@INPUT@', '@OUTDIR@',
+ ],
+)
+
+three = library('mod3', mod3_f)
+
+templates_basenames = ['mod2', 'mod1']
+generated_sources = []
+foreach template_basename : templates_basenames
+ infilename = '@0@.fpp'.format(template_basename)
+ outfilename = '@0@.f90'.format(template_basename)
+ outfile = configure_file(
+ input : infilename, output : outfilename, configuration : conf_data)
+ generated_sources += [outfile]
+endforeach
+
+sources = ['prog.f90'] + generated_sources
+exe = executable('generated', sources, link_with: three)
+test('generated', exe)
diff --git a/test cases/fortran/7 generated/mod1.fpp b/test cases/fortran/7 generated/mod1.fpp
new file mode 100644
index 0000000..c4decf6
--- /dev/null
+++ b/test cases/fortran/7 generated/mod1.fpp
@@ -0,0 +1,6 @@
+module mod1
+implicit none
+
+integer, parameter :: modval1 = @ONE@
+
+end module mod1
diff --git a/test cases/fortran/7 generated/mod2.fpp b/test cases/fortran/7 generated/mod2.fpp
new file mode 100644
index 0000000..78ceae4
--- /dev/null
+++ b/test cases/fortran/7 generated/mod2.fpp
@@ -0,0 +1,7 @@
+module mod2
+use mod1, only : modval1
+implicit none
+
+integer, parameter :: modval2 = @TWO@
+
+end module mod2
diff --git a/test cases/fortran/7 generated/mod3.f90 b/test cases/fortran/7 generated/mod3.f90
new file mode 100644
index 0000000..5e4b417
--- /dev/null
+++ b/test cases/fortran/7 generated/mod3.f90
@@ -0,0 +1,6 @@
+module mod3
+implicit none
+
+integer, parameter :: modval3 = 3
+
+end module mod3
diff --git a/test cases/fortran/7 generated/prog.f90 b/test cases/fortran/7 generated/prog.f90
new file mode 100644
index 0000000..6ee0bca
--- /dev/null
+++ b/test cases/fortran/7 generated/prog.f90
@@ -0,0 +1,8 @@
+program generated
+use mod2, only : modval1, modval2
+use mod3, only : modval3
+implicit none
+
+if (modval1 + modval2 + modval3 /= 6) error stop
+
+end program generated
diff --git a/test cases/fortran/8 module names/meson.build b/test cases/fortran/8 module names/meson.build
new file mode 100644
index 0000000..632c597
--- /dev/null
+++ b/test cases/fortran/8 module names/meson.build
@@ -0,0 +1,6 @@
+project('mod_name_case', 'fortran')
+
+sources = ['test.f90', 'mod1.f90', 'mod2.f90']
+
+exe = executable('mod_name_case', sources)
+test('mod_name_case', exe)
diff --git a/test cases/fortran/8 module names/mod1.f90 b/test cases/fortran/8 module names/mod1.f90
new file mode 100644
index 0000000..29cd9f4
--- /dev/null
+++ b/test cases/fortran/8 module names/mod1.f90
@@ -0,0 +1,6 @@
+module MyMod1
+implicit none
+
+integer, parameter :: myModVal1 = 1
+
+end module MyMod1
diff --git a/test cases/fortran/8 module names/mod2.f90 b/test cases/fortran/8 module names/mod2.f90
new file mode 100644
index 0000000..2087750
--- /dev/null
+++ b/test cases/fortran/8 module names/mod2.f90
@@ -0,0 +1,6 @@
+module mymod2
+implicit none
+
+integer, parameter :: myModVal2 = 2
+
+end module mymod2
diff --git a/test cases/fortran/8 module names/test.f90 b/test cases/fortran/8 module names/test.f90
new file mode 100644
index 0000000..60ff16e
--- /dev/null
+++ b/test cases/fortran/8 module names/test.f90
@@ -0,0 +1,9 @@
+program main
+use mymod1
+use MyMod2 ! test inline comment
+
+implicit none
+
+integer, parameter :: testVar = myModVal1 + myModVal2
+
+end program
diff --git a/test cases/fortran/9 cpp/fortran.f b/test cases/fortran/9 cpp/fortran.f
new file mode 100644
index 0000000..255872c
--- /dev/null
+++ b/test cases/fortran/9 cpp/fortran.f
@@ -0,0 +1,11 @@
+ function fortran() bind(C)
+ use, intrinsic :: iso_c_binding, only: dp=>c_double
+ implicit none
+
+ real(dp) :: r, fortran
+
+ call random_number(r)
+
+ fortran = 2._dp**r
+
+ end function fortran
diff --git a/test cases/fortran/9 cpp/main.c b/test cases/fortran/9 cpp/main.c
new file mode 100644
index 0000000..c1750ad
--- /dev/null
+++ b/test cases/fortran/9 cpp/main.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+double fortran(void);
+
+int main(void) {
+ printf("FORTRAN gave us this number: %lf.\n", fortran());
+ return 0;
+}
diff --git a/test cases/fortran/9 cpp/main.cpp b/test cases/fortran/9 cpp/main.cpp
new file mode 100644
index 0000000..534a23a
--- /dev/null
+++ b/test cases/fortran/9 cpp/main.cpp
@@ -0,0 +1,8 @@
+#include <iostream>
+
+extern "C" double fortran();
+
+int main(void) {
+ std::cout << "FORTRAN gave us this number: " << fortran() << '\n';
+ return 0;
+}
diff --git a/test cases/fortran/9 cpp/meson.build b/test cases/fortran/9 cpp/meson.build
new file mode 100644
index 0000000..2afa864
--- /dev/null
+++ b/test cases/fortran/9 cpp/meson.build
@@ -0,0 +1,29 @@
+project('C, C++ and Fortran', 'c', 'cpp', 'fortran')
+
+cpp = meson.get_compiler('cpp')
+fc = meson.get_compiler('fortran')
+
+if build_machine.system() == 'windows' and fc.get_id() == 'gcc' and cpp.get_id() != 'gcc'
+ error('MESON_SKIP_TEST mixing gfortran with non-GNU C++ does not work.')
+endif
+
+link_with = []
+if fc.get_id() == 'intel'
+ link_with += fc.find_library('ifport')
+endif
+
+e = executable(
+ 'cfort',
+ ['main.c', 'fortran.f'],
+ dependencies : link_with,
+)
+
+test('C and Fortran', e)
+
+e2 = executable(
+ 'cppfort',
+ ['main.cpp', 'fortran.f'],
+ dependencies : link_with,
+)
+
+test('C++ and Fortran', e2)
diff --git a/test cases/fpga/1 simple/meson.build b/test cases/fpga/1 simple/meson.build
new file mode 100644
index 0000000..536244e
--- /dev/null
+++ b/test cases/fpga/1 simple/meson.build
@@ -0,0 +1,8 @@
+project('lattice', 'c')
+
+is = import('unstable-icestorm')
+
+is.project('spin',
+ 'spin.v',
+ constraint_file : 'spin.pcf',
+)
diff --git a/test cases/fpga/1 simple/spin.pcf b/test cases/fpga/1 simple/spin.pcf
new file mode 100644
index 0000000..de06f5d
--- /dev/null
+++ b/test cases/fpga/1 simple/spin.pcf
@@ -0,0 +1,6 @@
+set_io LED1 99
+set_io LED2 98
+set_io LED3 97
+set_io LED4 96
+set_io LED5 95
+set_io clk 21
diff --git a/test cases/fpga/1 simple/spin.v b/test cases/fpga/1 simple/spin.v
new file mode 100644
index 0000000..2143d30
--- /dev/null
+++ b/test cases/fpga/1 simple/spin.v
@@ -0,0 +1,32 @@
+
+module top(input clk, output LED1, output LED2, output LED3, output LED4, output LED5);
+
+ reg ready = 0;
+ reg [23:0] divider;
+ reg [3:0] spin;
+
+ always @(posedge clk) begin
+ if (ready)
+ begin
+ if (divider == 6000000)
+ begin
+ divider <= 0;
+ spin <= {spin[2], spin[3], spin[0], spin[1]};
+ end
+ else
+ divider <= divider + 1;
+ end
+ else
+ begin
+ ready <= 1;
+ spin <= 4'b1010;
+ divider <= 0;
+ end
+ end
+
+ assign LED1 = spin[0];
+ assign LED2 = spin[1];
+ assign LED3 = spin[2];
+ assign LED4 = spin[3];
+ assign LED5 = 1;
+endmodule
diff --git a/test cases/frameworks/1 boost/extralib.cpp b/test cases/frameworks/1 boost/extralib.cpp
new file mode 100644
index 0000000..e5ab1b0
--- /dev/null
+++ b/test cases/frameworks/1 boost/extralib.cpp
@@ -0,0 +1,27 @@
+#define _XOPEN_SOURCE 500
+
+#include <iostream>
+#include <boost/log/trivial.hpp>
+#include <boost/log/expressions.hpp>
+#include <boost/log/utility/setup/console.hpp>
+#include <boost/log/utility/setup/common_attributes.hpp>
+
+using namespace std;
+namespace logging = boost::log;
+
+void InitLogger() {
+ logging::add_common_attributes();
+ logging::register_simple_formatter_factory<logging::trivial::severity_level, char>("Severity");
+ string log_format = "%TimeStamp% [%Severity%] - %Message%";
+
+ logging::add_console_log(
+ cout,
+ logging::keywords::format = log_format
+ );
+}
+
+int main(int argc, char **argv) {
+ InitLogger();
+ BOOST_LOG_TRIVIAL(trace) << "SOMETHING";
+ return 0;
+}
diff --git a/test cases/frameworks/1 boost/linkexe.cc b/test cases/frameworks/1 boost/linkexe.cc
new file mode 100644
index 0000000..e00edee
--- /dev/null
+++ b/test cases/frameworks/1 boost/linkexe.cc
@@ -0,0 +1,18 @@
+#define _XOPEN_SOURCE 500
+
+#include<boost/thread.hpp>
+
+boost::recursive_mutex m;
+
+struct callable {
+ void operator()() {
+ boost::recursive_mutex::scoped_lock l(m);
+ };
+};
+
+int main(int argc, char **argv) {
+ callable x;
+ boost::thread thr(x);
+ thr.join();
+ return 0;
+}
diff --git a/test cases/frameworks/1 boost/meson.build b/test cases/frameworks/1 boost/meson.build
new file mode 100644
index 0000000..821bb62
--- /dev/null
+++ b/test cases/frameworks/1 boost/meson.build
@@ -0,0 +1,74 @@
+# this test requires the following on Ubuntu: libboost-{system,python,log,thread,test}-dev
+project('boosttest', 'cpp',
+ default_options : ['cpp_std=c++14'])
+
+s = get_option('static')
+
+dep = dependency('boost', static: s, required: false)
+if not dep.found()
+ error('MESON_SKIP_TEST boost not found.')
+endif
+
+# We want to have multiple separate configurations of Boost
+# within one project. The need to be independent of each other.
+# Use one without a library dependency and one with it.
+
+linkdep = dependency('boost', static: s, modules : ['thread', 'system', 'date_time'])
+testdep = dependency('boost', static: s, modules : ['unit_test_framework'])
+nomoddep = dependency('boost', static: s)
+extralibdep = dependency('boost', static: s, modules : ['thread', 'system', 'date_time', 'log_setup', 'log', 'filesystem', 'regex'])
+notfound = dependency('boost', static: s, modules : ['this_should_not_exist_on_any_systen'], required: false)
+
+assert(not notfound.found())
+
+require_bp = host_machine.system() in ['linux', 'darwin']
+pymod = import('python')
+python2 = pymod.find_installation('python2', required: false , disabler: true)
+python3 = pymod.find_installation('python3', required: require_bp , disabler: true)
+python2dep = python2.dependency(required: false , embed: true, disabler: true)
+python3dep = python3.dependency(required: require_bp, embed: true, disabler: true)
+
+# compile python 2/3 modules only if we found a corresponding python version
+if(python2dep.found() and require_bp and not s)
+ bpython2dep = dependency('boost', static: s, modules : ['python'], required: false, disabler: true)
+else
+ python2dep = disabler()
+ bpython2dep = disabler()
+endif
+
+if(python3dep.found() and require_bp and not s)
+ bpython3dep = dependency('boost', static: s, modules : ['python3'])
+else
+ python3dep = disabler()
+ bpython3dep = disabler()
+endif
+
+linkexe = executable('linkedexe', 'linkexe.cc', dependencies : linkdep)
+unitexe = executable('utf', 'unit_test.cpp', dependencies: testdep)
+nomodexe = executable('nomod', 'nomod.cpp', dependencies : nomoddep)
+extralibexe = executable('extralibexe', 'extralib.cpp', dependencies : extralibdep)
+
+# python modules are shared libraries
+python2module = python2.extension_module('python2_module', ['python_module.cpp'], dependencies: [python2dep, bpython2dep], cpp_args: ['-DMOD_NAME=python2_module'])
+python3module = python3.extension_module('python3_module', ['python_module.cpp'], dependencies: [python3dep, bpython3dep], cpp_args: ['-DMOD_NAME=python3_module'])
+
+
+test('Boost linktest', linkexe, timeout: 60)
+test('Boost UTF test', unitexe, timeout: 60)
+test('Boost nomod', nomodexe)
+if host_machine.system() != 'darwin' or s
+ # Segfaults on macOS with dynamic linking since Boost 1.73
+ # https://github.com/mesonbuild/meson/issues/7535
+ test('Boost extralib test', extralibexe)
+endif
+
+# explicitly use the correct python interpreter so that we don't have to provide two different python scripts that have different shebang lines
+python2interpreter = find_program(python2.path(), required: false, disabler: true)
+test('Boost Python2', python2interpreter, args: ['./test_python_module.py', meson.current_build_dir()], workdir: meson.current_source_dir(), depends: python2module)
+python3interpreter = find_program(python3.path(), required: false, disabler: true)
+test('Boost Python3', python3interpreter, args: ['./test_python_module.py', meson.current_build_dir()], workdir: meson.current_source_dir(), depends: python3module)
+
+subdir('partial_dep')
+
+# check we can apply a version constraint
+dependency('boost', static: s, version: '>=@0@'.format(dep.version()))
diff --git a/test cases/frameworks/1 boost/meson_options.txt b/test cases/frameworks/1 boost/meson_options.txt
new file mode 100644
index 0000000..019feaf
--- /dev/null
+++ b/test cases/frameworks/1 boost/meson_options.txt
@@ -0,0 +1 @@
+option('static', type: 'boolean', value: false)
diff --git a/test cases/frameworks/1 boost/nomod.cpp b/test cases/frameworks/1 boost/nomod.cpp
new file mode 100644
index 0000000..55c95b2
--- /dev/null
+++ b/test cases/frameworks/1 boost/nomod.cpp
@@ -0,0 +1,18 @@
+#include<boost/any.hpp>
+#include<iostream>
+
+boost::any get_any() {
+ boost::any foobar = 3;
+ return foobar;
+}
+
+int main(int argc, char **argv) {
+ boost::any result = get_any();
+ if(boost::any_cast<int>(result) == 3) {
+ std::cout << "Everything is fine in the world.\n";
+ return 0;
+ } else {
+ std::cout << "Mathematics stopped working.\n";
+ return 1;
+ }
+}
diff --git a/test cases/frameworks/1 boost/partial_dep/foo.cpp b/test cases/frameworks/1 boost/partial_dep/foo.cpp
new file mode 100644
index 0000000..da58703
--- /dev/null
+++ b/test cases/frameworks/1 boost/partial_dep/foo.cpp
@@ -0,0 +1,20 @@
+/* Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "foo.hpp"
+
+vec Foo::vector() {
+ return myvec;
+}
diff --git a/test cases/frameworks/1 boost/partial_dep/foo.hpp b/test cases/frameworks/1 boost/partial_dep/foo.hpp
new file mode 100644
index 0000000..393d3f6
--- /dev/null
+++ b/test cases/frameworks/1 boost/partial_dep/foo.hpp
@@ -0,0 +1,27 @@
+/* Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <boost/fusion/container/vector.hpp>
+
+typedef boost::fusion::vector<int> vec;
+
+
+class Foo {
+ public:
+ Foo() {};
+ vec vector();
+ private:
+ const vec myvec = vec(4);
+};
diff --git a/test cases/frameworks/1 boost/partial_dep/main.cpp b/test cases/frameworks/1 boost/partial_dep/main.cpp
new file mode 100644
index 0000000..b22ce3a
--- /dev/null
+++ b/test cases/frameworks/1 boost/partial_dep/main.cpp
@@ -0,0 +1,27 @@
+/* Copyright © 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <boost/fusion/include/at_c.hpp>
+#include "foo.hpp"
+
+
+int main(void) {
+ auto foo = Foo();
+ vec v = foo.vector();
+ std::cout << boost::fusion::at_c<0>(v) << std::endl;
+
+ return 0;
+}
diff --git a/test cases/frameworks/1 boost/partial_dep/meson.build b/test cases/frameworks/1 boost/partial_dep/meson.build
new file mode 100644
index 0000000..9d481bb
--- /dev/null
+++ b/test cases/frameworks/1 boost/partial_dep/meson.build
@@ -0,0 +1,31 @@
+# Copyright © 2018 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+dep_boost = dependency('boost')
+dep_boost_headers = dep_boost.partial_dependency(compile_args : true)
+
+libfoo = static_library(
+ 'foo',
+ 'foo.cpp',
+ dependencies : dep_boost_headers,
+)
+
+exe_external_dep = executable(
+ 'external_dep',
+ 'main.cpp',
+ dependencies : dep_boost,
+ link_with : libfoo
+)
+
+test('External Dependency', exe_external_dep)
diff --git a/test cases/frameworks/1 boost/python_module.cpp b/test cases/frameworks/1 boost/python_module.cpp
new file mode 100644
index 0000000..a0f010b
--- /dev/null
+++ b/test cases/frameworks/1 boost/python_module.cpp
@@ -0,0 +1,22 @@
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <boost/python.hpp>
+
+struct World
+{
+ void set(std::string msg) { this->msg = msg; }
+ std::string greet() { return msg; }
+ std::string version() { return std::to_string(PY_MAJOR_VERSION) + "." + std::to_string(PY_MINOR_VERSION); }
+ std::string msg;
+};
+
+
+BOOST_PYTHON_MODULE(MOD_NAME)
+{
+ using namespace boost::python;
+ class_<World>("World")
+ .def("greet", &World::greet)
+ .def("set", &World::set)
+ .def("version", &World::version)
+ ;
+}
diff --git a/test cases/frameworks/1 boost/test.json b/test cases/frameworks/1 boost/test.json
new file mode 100644
index 0000000..2c5b857
--- /dev/null
+++ b/test cases/frameworks/1 boost/test.json
@@ -0,0 +1,22 @@
+{
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": "true", "skip_on_env": [ "SKIP_STATIC_BOOST" ] },
+ { "val": "false" }
+ ],
+ "b_vscrt": [
+ { "val": null },
+ { "val": "md", "compilers": { "cpp": "msvc" } },
+ { "val": "mdd", "compilers": { "cpp": "msvc" } },
+ { "val": "mt", "compilers": { "cpp": "msvc" } },
+ { "val": "mtd", "compilers": { "cpp": "msvc" } }
+ ]
+ },
+ "exclude": [
+ { "static": "false", "b_vscrt": "mt" },
+ { "static": "false", "b_vscrt": "mtd" }
+ ]
+ },
+ "skip_on_jobname": ["azure", "msys2"]
+}
diff --git a/test cases/frameworks/1 boost/test_python_module.py b/test cases/frameworks/1 boost/test_python_module.py
new file mode 100644
index 0000000..8ef96d2
--- /dev/null
+++ b/test cases/frameworks/1 boost/test_python_module.py
@@ -0,0 +1,27 @@
+import sys
+sys.path.append(sys.argv[1])
+
+# import compiled python module depending on version of python we are running with
+if sys.version_info[0] == 2:
+ import python2_module
+
+if sys.version_info[0] == 3:
+ import python3_module
+
+
+def run():
+ msg = 'howdy'
+ if sys.version_info[0] == 2:
+ w = python2_module.World()
+
+ if sys.version_info[0] == 3:
+ w = python3_module.World()
+
+ w.set(msg)
+
+ assert msg == w.greet()
+ version_string = str(sys.version_info[0]) + "." + str(sys.version_info[1])
+ assert version_string == w.version()
+
+if __name__ == '__main__':
+ run()
diff --git a/test cases/frameworks/1 boost/unit_test.cpp b/test cases/frameworks/1 boost/unit_test.cpp
new file mode 100644
index 0000000..fa1fbaa
--- /dev/null
+++ b/test cases/frameworks/1 boost/unit_test.cpp
@@ -0,0 +1,9 @@
+#define BOOST_TEST_MODULE "MesonTest"
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_CASE(m_test) {
+ int x = 2+2;
+ BOOST_CHECK(true);
+ BOOST_CHECK_EQUAL(x, 4);
+}
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar-docs.sgml b/test cases/frameworks/10 gtk-doc/doc/foobar-docs.sgml
new file mode 100644
index 0000000..3894317
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar-docs.sgml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Foolib Reference Manual</title>
+ <releaseinfo>
+ for Foobar &version;
+ </releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Jonny</firstname>
+ <surname>Example</surname>
+ <affiliation>
+ <address>
+ <email>unknown@example.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+ <copyright>
+ <year>2015</year>
+ <holder>Foobar corporation holdings ltd</holder>
+ </copyright>
+ </bookinfo>
+
+ <reference id="foobar">
+ <title>Foobar library</title>
+ <partintro>
+ <para>
+ This part documents Foobar libs.
+ </para>
+ </partintro>
+ <xi:include href="xml/foo.xml"/>
+ <xi:include href="../include/bar.xml"/>
+ <xi:include href="xml/foo-version.xml"/>
+ </reference>
+
+</book>
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/baz.jpg b/test cases/frameworks/10 gtk-doc/doc/foobar1/baz.jpg
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/baz.jpg
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/baz.png.in b/test cases/frameworks/10 gtk-doc/doc/foobar1/baz.png.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/baz.png.in
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml
new file mode 100644
index 0000000..6ccd087
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "../version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Foolib Reference Manual</title>
+ <releaseinfo>
+ for Foobar &version;
+ </releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Jonny</firstname>
+ <surname>Example</surname>
+ <affiliation>
+ <address>
+ <email>unknown@example.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+ <copyright>
+ <year>2015</year>
+ <holder>Foobar corporation holdings ltd</holder>
+ </copyright>
+ </bookinfo>
+
+ <reference id="foobar">
+ <title>Foobar library</title>
+ <partintro>
+ <para>
+ This part documents Foobar libs.
+ </para>
+ </partintro>
+ <xi:include href="xml/foo.xml"/>
+ <xi:include href="../../include/bar.xml"/>
+ <xi:include href="xml/version.xml"/>
+ </reference>
+
+</book>
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt
new file mode 100644
index 0000000..e9ca2d6
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt
@@ -0,0 +1,15 @@
+<SECTION>
+<FILE>foo</FILE>
+<TITLE>FooObj</TITLE>
+FooObj
+FooObjClass
+foo_do_something
+</SECTION>
+
+<SECTION>
+<FILE>version</FILE>
+<TITLE>version</TITLE>
+FOO_MAJOR_VERSION
+FOO_MINOR_VERSION
+FOO_MICRO_VERSION
+</SECTION>
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types
new file mode 100644
index 0000000..0a9c046
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types
@@ -0,0 +1,4 @@
+% This include is useless it's a regression test for https://github.com/mesonbuild/meson/issues/8744
+#include <foo.h>
+
+foo_obj_get_type
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build b/test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build
new file mode 100644
index 0000000..2af9670
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build
@@ -0,0 +1,15 @@
+png = configure_file(input: 'baz.png.in',
+ output: 'baz.png',
+ copy: true)
+
+gnome.gtkdoc('foobar',
+ src_dir : [inc, '.'],
+ main_sgml : 'foobar-docs.sgml',
+ content_files : [docbook, version_xml],
+ dependencies: foo_dep,
+ html_assets: ['baz.jpg', png],
+ # Manually written types file for regression test:
+ # https://github.com/mesonbuild/meson/issues/8744
+ gobject_typesfile: 'foobar.types',
+ install : true,
+ check: false)
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar2/foobar-docs.sgml b/test cases/frameworks/10 gtk-doc/doc/foobar2/foobar-docs.sgml
new file mode 100644
index 0000000..95f73ef
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar2/foobar-docs.sgml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "../version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Foolib Reference Manual</title>
+ <releaseinfo>
+ for Foobar &version;
+ </releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Jonny</firstname>
+ <surname>Example</surname>
+ <affiliation>
+ <address>
+ <email>unknown@example.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+ <copyright>
+ <year>2015</year>
+ <holder>Foobar corporation holdings ltd</holder>
+ </copyright>
+ </bookinfo>
+
+ <reference id="foobar">
+ <title>Foobar library</title>
+ <partintro>
+ <para>
+ This part documents Foobar libs.
+ </para>
+ </partintro>
+ <xi:include href="xml/foo.xml"/>
+ <xi:include href="../../include/bar.xml"/>
+ <xi:include href="xml/foo-version.xml"/>
+ </reference>
+
+</book>
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar2/meson.build b/test cases/frameworks/10 gtk-doc/doc/foobar2/meson.build
new file mode 100644
index 0000000..5f860ef
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar2/meson.build
@@ -0,0 +1,13 @@
+types = configure_file(input: '../foobar1/foobar.types',
+ output: 'foobar.types',
+ copy: true
+)
+
+gnome.gtkdoc('foobar2',
+ src_dir : inc,
+ main_sgml : 'foobar-docs.sgml',
+ content_files : [docbook, version_xml],
+ gobject_typesfile: types,
+ dependencies: foo_dep,
+ install : true,
+ install_dir : 'foobar2')
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar3/foobar-docs.sgml b/test cases/frameworks/10 gtk-doc/doc/foobar3/foobar-docs.sgml
new file mode 100644
index 0000000..95f73ef
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar3/foobar-docs.sgml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "../version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Foolib Reference Manual</title>
+ <releaseinfo>
+ for Foobar &version;
+ </releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Jonny</firstname>
+ <surname>Example</surname>
+ <affiliation>
+ <address>
+ <email>unknown@example.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+ <copyright>
+ <year>2015</year>
+ <holder>Foobar corporation holdings ltd</holder>
+ </copyright>
+ </bookinfo>
+
+ <reference id="foobar">
+ <title>Foobar library</title>
+ <partintro>
+ <para>
+ This part documents Foobar libs.
+ </para>
+ </partintro>
+ <xi:include href="xml/foo.xml"/>
+ <xi:include href="../../include/bar.xml"/>
+ <xi:include href="xml/foo-version.xml"/>
+ </reference>
+
+</book>
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar3/meson.build b/test cases/frameworks/10 gtk-doc/doc/foobar3/meson.build
new file mode 100644
index 0000000..0dce2f8
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar3/meson.build
@@ -0,0 +1,6 @@
+gnome.gtkdoc('foobar',
+ module_version : '3.0',
+ src_dir : inc,
+ main_sgml : 'foobar-docs.sgml',
+ content_files : [docbook, version_xml],
+ install : true)
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar4/foobar-docs.sgml b/test cases/frameworks/10 gtk-doc/doc/foobar4/foobar-docs.sgml
new file mode 100644
index 0000000..95f73ef
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar4/foobar-docs.sgml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "../version.xml">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>Foolib Reference Manual</title>
+ <releaseinfo>
+ for Foobar &version;
+ </releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Jonny</firstname>
+ <surname>Example</surname>
+ <affiliation>
+ <address>
+ <email>unknown@example.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+ <copyright>
+ <year>2015</year>
+ <holder>Foobar corporation holdings ltd</holder>
+ </copyright>
+ </bookinfo>
+
+ <reference id="foobar">
+ <title>Foobar library</title>
+ <partintro>
+ <para>
+ This part documents Foobar libs.
+ </para>
+ </partintro>
+ <xi:include href="xml/foo.xml"/>
+ <xi:include href="../../include/bar.xml"/>
+ <xi:include href="xml/foo-version.xml"/>
+ </reference>
+
+</book>
diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar4/meson.build b/test cases/frameworks/10 gtk-doc/doc/foobar4/meson.build
new file mode 100644
index 0000000..959e507
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/foobar4/meson.build
@@ -0,0 +1,7 @@
+gnome.gtkdoc('foobar2',
+ module_version : '3.0',
+ src_dir : inc,
+ main_sgml : 'foobar-docs.sgml',
+ content_files : [docbook, version_xml],
+ install : true,
+ install_dir : 'foobar3')
diff --git a/test cases/frameworks/10 gtk-doc/doc/meson.build b/test cases/frameworks/10 gtk-doc/doc/meson.build
new file mode 100644
index 0000000..c001f89
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/meson.build
@@ -0,0 +1,10 @@
+cdata = configuration_data()
+cdata.set('VERSION', '1.0')
+version_xml = configure_file(input : 'version.xml.in',
+ output : 'version.xml',
+ configuration : cdata)
+
+subdir('foobar1')
+subdir('foobar2')
+subdir('foobar3')
+subdir('foobar4')
diff --git a/test cases/frameworks/10 gtk-doc/doc/version.xml.in b/test cases/frameworks/10 gtk-doc/doc/version.xml.in
new file mode 100644
index 0000000..d78bda9
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/doc/version.xml.in
@@ -0,0 +1 @@
+@VERSION@
diff --git a/test cases/frameworks/10 gtk-doc/foo.c b/test cases/frameworks/10 gtk-doc/foo.c
new file mode 100644
index 0000000..36c0639
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/foo.c
@@ -0,0 +1,30 @@
+#include <foo.h>
+
+
+struct _FooObj {
+ GObject parent;
+ int dummy;
+};
+
+G_DEFINE_TYPE(FooObj, foo_obj, G_TYPE_OBJECT)
+
+static void foo_obj_init (FooObj *self)
+{
+}
+
+static void foo_obj_class_init (FooObjClass *klass)
+{
+}
+
+/**
+ * foo_do_something:
+ * @self: self
+ *
+ * Useless function.
+ *
+ * Returns: 0.
+ */
+int foo_do_something(FooObj *self)
+{
+ return 0;
+}
diff --git a/test cases/frameworks/10 gtk-doc/include/foo-version.h.in b/test cases/frameworks/10 gtk-doc/include/foo-version.h.in
new file mode 100644
index 0000000..30751cd
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/include/foo-version.h.in
@@ -0,0 +1,29 @@
+#pragma once
+
+/**
+ * SECTION:version
+ * @section_id: foo-version
+ * @short_description: <filename>foo-version.h</filename>
+ * @title: Foo Versioning
+ */
+
+/**
+ * FOO_MAJOR_VERSION:
+ *
+ * The major version of foo.
+ */
+#define FOO_MAJOR_VERSION (@FOO_MAJOR_VERSION@)
+
+/**
+ * FOO_MINOR_VERSION:
+ *
+ * The minor version of foo.
+ */
+#define FOO_MINOR_VERSION (@FOO_MINOR_VERSION@)
+
+/**
+ * FOO_MICRO_VERSION:
+ *
+ * The micro version of foo.
+ */
+#define FOO_MICRO_VERSION (@FOO_MICRO_VERSION@)
diff --git a/test cases/frameworks/10 gtk-doc/include/foo.h b/test cases/frameworks/10 gtk-doc/include/foo.h
new file mode 100644
index 0000000..510f3d1
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/include/foo.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <glib-object.h>
+
+/**
+ * FooIndecision:
+ * @FOO_MAYBE: Something maybe
+ * @FOO_POSSIBLY: Something possible
+ *
+ * The indecision type.
+ **/
+
+typedef enum {
+ FOO_MAYBE,
+ FOO_POSSIBLY,
+} FooIndecision;
+
+/**
+ * FooObjClass:
+ *
+ * The class
+ */
+
+/**
+ * FooObj:
+ *
+ * The instance
+ */
+
+#define FOO_TYPE_OBJ foo_obj_get_type()
+G_DECLARE_FINAL_TYPE(FooObj, foo_obj, FOO, OBJ, GObject)
+
+int foo_do_something(FooObj *self);
diff --git a/test cases/frameworks/10 gtk-doc/include/generate-enums-docbook.py b/test cases/frameworks/10 gtk-doc/include/generate-enums-docbook.py
new file mode 100644
index 0000000..41c6121
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/include/generate-enums-docbook.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+
+import sys
+
+DOC_HEADER = '''<?xml version='1.0'?>
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<refentry id="{0}">
+ <refmeta>
+ <refentrytitle role="top_of_page" id="{0}.top_of_page">{0}</refentrytitle>
+ <refmiscinfo>{0}</refmiscinfo>
+ </refmeta>
+ <refnamediv>
+ <refname>{0}</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+
+ <refsect2 id="{1}" role="enum">
+ <title>enum {1}</title>
+ <indexterm zone="{1}">
+ <primary>{1}</primary>
+ </indexterm>
+ <para><link linkend="{1}">{1}</link></para>
+ <refsect3 role="enum_members">
+ <title>Values</title>
+ <informaltable role="enum_members_table" pgwide="1" frame="none">
+ <tgroup cols="4">
+ <colspec colname="enum_members_name" colwidth="300px" />
+ <colspec colname="enum_members_value" colwidth="100px"/>
+ <colspec colname="enum_members_description" />
+ <tbody>
+'''
+
+DOC_ENUM = ''' <row role="constant">
+ <entry role="enum_member_name"><para>{0}</para><para></para></entry>
+ <entry role="enum_member_value"><para>= <literal>{1}</literal></para><para></para></entry>
+ <entry role="enum_member_description"></entry>
+ </row>'''
+
+DOC_FOOTER = '''
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </refsect3>
+ </refsect2>
+</refentry>
+'''
+
+if __name__ == '__main__':
+ if len(sys.argv) >= 4:
+ with open(sys.argv[1], 'w') as doc_out:
+ enum_name = sys.argv[2]
+ enum_type = sys.argv[3]
+
+ doc_out.write(DOC_HEADER.format(enum_name, enum_type))
+ for i, enum in enumerate(sys.argv[4:]):
+ doc_out.write(DOC_ENUM.format(enum, i))
+ doc_out.write(DOC_FOOTER)
+ else:
+ print('Use: ' + sys.argv[0] + ' out name type [enums]')
+
+ sys.exit(0)
diff --git a/test cases/frameworks/10 gtk-doc/include/meson.build b/test cases/frameworks/10 gtk-doc/include/meson.build
new file mode 100644
index 0000000..aa32885
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/include/meson.build
@@ -0,0 +1,17 @@
+cdata = configuration_data()
+parts = meson.project_version().split('.')
+cdata.set('FOO_MAJOR_VERSION', parts[0])
+cdata.set('FOO_MINOR_VERSION', parts[1])
+cdata.set('FOO_MICRO_VERSION', parts[2])
+configure_file(input : 'foo-version.h.in',
+ output : 'foo-version.h',
+ configuration : cdata,
+ install : true,
+ install_dir : get_option('includedir'))
+
+generate_enums_docbook = find_program('generate-enums-docbook.py')
+
+docbook = custom_target('enum-docbook',
+ output : 'bar.xml',
+ command : [generate_enums_docbook, '@OUTPUT@', 'BAR', 'BAR_TYPE', 'BAR_FOO'],
+ build_by_default : true)
diff --git a/test cases/frameworks/10 gtk-doc/meson.build b/test cases/frameworks/10 gtk-doc/meson.build
new file mode 100644
index 0000000..b49efc0
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/meson.build
@@ -0,0 +1,45 @@
+project('gtkdoctest', 'c', version : '1.0.0')
+
+gtkdoc = find_program('gtkdoc-scan', required: false)
+if not gtkdoc.found()
+ error('MESON_SKIP_TEST gtkdoc not found.')
+endif
+
+gnome = import('gnome')
+
+assert(gnome.gtkdoc_html_dir('foobar') == 'share/gtk-doc/html/foobar', 'Gtkdoc install dir is incorrect.')
+
+inc = include_directories('include')
+
+subdir('include')
+
+# disable this test unless a bug fix for spaces in pathnames is present
+# https://bugzilla.gnome.org/show_bug.cgi?id=753145
+result = run_command(gtkdoc, ['--version'], check: true)
+gtkdoc_ver = result.stdout().strip()
+if gtkdoc_ver == ''
+ gtkdoc_ver = result.stderr().strip()
+endif
+if gtkdoc_ver.version_compare('<1.26')
+ error('MESON_SKIP_TEST gtk-doc test requires gtkdoc >= 1.26.')
+endif
+
+gobject = dependency('gobject-2.0')
+
+libfoo = shared_library('foo', 'foo.c',
+ include_directories: inc,
+ dependencies: gobject,
+)
+
+deps = []
+if host_machine.system() == 'darwin'
+ deps += dependency('appleframeworks', modules : ['Foundation', 'CoreFoundation'])
+endif
+
+foo_dep = declare_dependency(
+ link_with: libfoo,
+ include_directories: inc,
+ dependencies: deps,
+)
+
+subdir('doc')
diff --git a/test cases/frameworks/10 gtk-doc/test.json b/test cases/frameworks/10 gtk-doc/test.json
new file mode 100644
index 0000000..1085b55
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/test.json
@@ -0,0 +1,64 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/foo-version.h"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/baz.jpg"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/baz.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/FooObj.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/up-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar2.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar2-foo.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar2-foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/up-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar-3.0.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar-foo.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar-foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/up-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar2-3.0.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar2-foo.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar2-foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/up-insensitive.png"}
+ ],
+ "skip_on_jobname": ["azure", "msys2"]
+}
diff --git a/test cases/frameworks/11 gir subproject/gir/meson-subsample.c b/test cases/frameworks/11 gir subproject/gir/meson-subsample.c
new file mode 100644
index 0000000..2d58a10
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/gir/meson-subsample.c
@@ -0,0 +1,124 @@
+#include "meson-subsample.h"
+
+struct _MesonSubSample
+{
+ MesonSample parent_instance;
+
+ gchar *msg;
+};
+
+G_DEFINE_TYPE (MesonSubSample, meson_sub_sample, MESON_TYPE_SAMPLE)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_sub_sample_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonSubSample.
+ *
+ * Returns: (transfer full): a #MesonSubSample.
+ */
+MesonSubSample *
+meson_sub_sample_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_SUB_SAMPLE,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_sub_sample_finalize (GObject *object)
+{
+ MesonSubSample *self = (MesonSubSample *)object;
+
+ g_clear_pointer (&self->msg, g_free);
+
+ G_OBJECT_CLASS (meson_sub_sample_parent_class)->finalize (object);
+}
+
+static void
+meson_sub_sample_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSubSample *self = MESON_SUB_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, self->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sub_sample_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSubSample *self = MESON_SUB_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ self->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sub_sample_class_init (MesonSubSampleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_sub_sample_finalize;
+ object_class->get_property = meson_sub_sample_get_property;
+ object_class->set_property = meson_sub_sample_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_sub_sample_init (MesonSubSample *self)
+{
+}
+
+/**
+ * meson_sub_sample_print_message:
+ * @self: a #MesonSubSample.
+ *
+ * Prints the message.
+ *
+ * Returns: Nothing.
+ */
+void
+meson_sub_sample_print_message (MesonSubSample *self)
+{
+ g_return_if_fail (MESON_IS_SUB_SAMPLE (self));
+
+ g_print ("Message: %s\n", self->msg);
+}
diff --git a/test cases/frameworks/11 gir subproject/gir/meson-subsample.h b/test cases/frameworks/11 gir subproject/gir/meson-subsample.h
new file mode 100644
index 0000000..666d59f
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/gir/meson-subsample.h
@@ -0,0 +1,21 @@
+#ifndef MESON_SUB_SAMPLE_H
+#define MESON_SUB_SAMPLE_H
+
+#if !defined (MESON_TEST)
+#error "MESON_TEST not defined."
+#endif
+
+#include <glib-object.h>
+#include <meson-sample.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SUB_SAMPLE (meson_sub_sample_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonSubSample, meson_sub_sample, MESON, SUB_SAMPLE, MesonSample)
+
+MesonSubSample *meson_sub_sample_new (const gchar *msg);
+
+G_END_DECLS
+
+#endif /* MESON_SUB_SAMPLE_H */
diff --git a/test cases/frameworks/11 gir subproject/gir/meson.build b/test cases/frameworks/11 gir subproject/gir/meson.build
new file mode 100644
index 0000000..fe40dc6
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/gir/meson.build
@@ -0,0 +1,40 @@
+libsources = ['meson-subsample.c', 'meson-subsample.h']
+
+girsubproject = shared_library(
+ 'girsubproject',
+ sources : libsources,
+ dependencies : [gobj, meson_gir],
+ install : true
+)
+
+girexe = executable(
+ 'girprog',
+ sources : 'prog.c',
+ dependencies : [gobj, meson_gir],
+ link_with : girsubproject
+)
+
+gnome.generate_gir(
+ girsubproject,
+ sources : libsources,
+ dependencies : [gobj, meson_gir],
+ nsversion : '1.0',
+ namespace : 'MesonSub',
+ symbol_prefix : 'meson_sub_',
+ identifier_prefix : 'MesonSub',
+ includes : ['GObject-2.0', 'Meson-1.0'],
+ install : true
+)
+
+message('TEST: ' + girsubproject.outdir())
+
+envdata = environment()
+envdata.append('GI_TYPELIB_PATH', girsubproject.outdir(), 'subprojects/mesongir', separator : ':')
+envdata.append('LD_LIBRARY_PATH', girsubproject.outdir(), 'subprojects/mesongir')
+if ['windows', 'cygwin'].contains(host_machine.system())
+ envdata.append('PATH', girsubproject.outdir(), 'subprojects/mesongir')
+endif
+
+test('gobject introspection/subproject/c', girexe)
+test('gobject introspection/subproject/py', find_program('prog.py'),
+ env : envdata)
diff --git a/test cases/frameworks/11 gir subproject/gir/prog.c b/test cases/frameworks/11 gir subproject/gir/prog.c
new file mode 100644
index 0000000..f25c9d8
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/gir/prog.c
@@ -0,0 +1,12 @@
+#include "meson-subsample.h"
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ MesonSample * i = (MesonSample*) meson_sub_sample_new ("Hello, sub/meson/c!");
+ meson_sample_print_message (i);
+ g_object_unref (i);
+
+ return 0;
+}
diff --git a/test cases/frameworks/11 gir subproject/gir/prog.py b/test cases/frameworks/11 gir subproject/gir/prog.py
new file mode 100755
index 0000000..ea4da5b
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/gir/prog.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+from gi.repository import MesonSub
+
+if __name__ == "__main__":
+ s = MesonSub.Sample.new("Hello, sub/meson/py!")
+ s.print_message()
diff --git a/test cases/frameworks/11 gir subproject/meson.build b/test cases/frameworks/11 gir subproject/meson.build
new file mode 100644
index 0000000..3714daa
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/meson.build
@@ -0,0 +1,20 @@
+project('gobject-introspection-with-subproject', 'c')
+
+gir = find_program('g-ir-scanner', required: false)
+if not gir.found()
+ error('MESON_SKIP_TEST g-ir-scanner not found.')
+endif
+
+python3 = import('python3')
+py3 = python3.find_python()
+if run_command(py3, '-c', 'import gi;', check: false).returncode() != 0
+ error('MESON_SKIP_TEST python3-gi not found')
+endif
+
+gnome = import('gnome')
+gobj = dependency('gobject-2.0')
+
+add_global_arguments('-DMESON_TEST', language : 'c')
+meson_gir = dependency('meson-gir', fallback : ['mesongir', 'meson_gir'])
+
+subdir('gir')
diff --git a/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.c b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.c
new file mode 100644
index 0000000..2e78b07
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.c
@@ -0,0 +1,127 @@
+#include "meson-sample.h"
+
+typedef struct _MesonSamplePrivate
+{
+ gchar *msg;
+} MesonSamplePrivate;
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (MesonSample, meson_sample, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_sample_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonSample.
+ *
+ * Returns: (transfer full): a #MesonSample.
+ */
+MesonSample *
+meson_sample_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_SAMPLE,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_sample_finalize (GObject *object)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ g_clear_pointer (&priv->msg, g_free);
+
+ G_OBJECT_CLASS (meson_sample_parent_class)->finalize (object);
+}
+
+static void
+meson_sample_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, priv->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ priv->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_class_init (MesonSampleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_sample_finalize;
+ object_class->get_property = meson_sample_get_property;
+ object_class->set_property = meson_sample_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_sample_init (MesonSample *self)
+{
+}
+
+/**
+ * meson_sample_print_message:
+ * @self: a #MesonSample.
+ *
+ * Prints the message.
+ *
+ * Returns: Nothing.
+ */
+void
+meson_sample_print_message (MesonSample *self)
+{
+ MesonSamplePrivate *priv;
+
+ g_return_if_fail (MESON_IS_SAMPLE (self));
+
+ priv = meson_sample_get_instance_private (self);
+
+ g_print ("Message: %s\n", priv->msg);
+}
diff --git a/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.h b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.h
new file mode 100644
index 0000000..e4c07a8
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.h
@@ -0,0 +1,26 @@
+#ifndef MESON_SAMPLE_H
+#define MESON_SAMPLE_H
+
+#if !defined (MESON_TEST)
+#error "MESON_TEST not defined."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SAMPLE (meson_sample_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject)
+
+struct _MesonSampleClass {
+ GObjectClass parent_class;
+};
+
+
+MesonSample *meson_sample_new (const gchar *msg);
+void meson_sample_print_message (MesonSample *self);
+
+G_END_DECLS
+
+#endif /* MESON_SAMPLE_H */
diff --git a/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson.build b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson.build
new file mode 100644
index 0000000..027b4ee
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson.build
@@ -0,0 +1,31 @@
+project('gobject-introspection-subproject', 'c')
+
+gnome = import('gnome')
+gobj = dependency('gobject-2.0')
+
+libsources = ['meson-sample.c', 'meson-sample.h']
+
+girlib = shared_library(
+ 'girlib',
+ sources : libsources,
+ dependencies : gobj,
+ install : true
+)
+
+girtarget = gnome.generate_gir(
+ girlib,
+ sources : libsources,
+ nsversion : '1.0',
+ namespace : 'Meson',
+ symbol_prefix : 'meson_',
+ identifier_prefix : 'Meson',
+ includes : ['GObject-2.0'],
+ install : true
+)
+
+meson_gir = declare_dependency(link_with : girlib,
+ include_directories : [include_directories('.')],
+ dependencies : [gobj],
+ # Everything that uses libgst needs this built to compile
+ sources : girtarget,
+)
diff --git a/test cases/frameworks/11 gir subproject/test.json b/test cases/frameworks/11 gir subproject/test.json
new file mode 100644
index 0000000..aed0a1c
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/test.json
@@ -0,0 +1,13 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonSub-1.0.typelib"},
+ {"type": "file", "file": "usr/share/gir-1.0/Meson-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonSub-1.0.gir"},
+ {"type": "expr", "file": "usr/lib/?libgirsubproject.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirlib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libgirlib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirsubproject.dll.a"}
+ ],
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2", "pypy"]
+}
diff --git a/test cases/frameworks/12 multiple gir/gir/meson-subsample.c b/test cases/frameworks/12 multiple gir/gir/meson-subsample.c
new file mode 100644
index 0000000..2d58a10
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/gir/meson-subsample.c
@@ -0,0 +1,124 @@
+#include "meson-subsample.h"
+
+struct _MesonSubSample
+{
+ MesonSample parent_instance;
+
+ gchar *msg;
+};
+
+G_DEFINE_TYPE (MesonSubSample, meson_sub_sample, MESON_TYPE_SAMPLE)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_sub_sample_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonSubSample.
+ *
+ * Returns: (transfer full): a #MesonSubSample.
+ */
+MesonSubSample *
+meson_sub_sample_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_SUB_SAMPLE,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_sub_sample_finalize (GObject *object)
+{
+ MesonSubSample *self = (MesonSubSample *)object;
+
+ g_clear_pointer (&self->msg, g_free);
+
+ G_OBJECT_CLASS (meson_sub_sample_parent_class)->finalize (object);
+}
+
+static void
+meson_sub_sample_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSubSample *self = MESON_SUB_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, self->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sub_sample_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSubSample *self = MESON_SUB_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ self->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sub_sample_class_init (MesonSubSampleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_sub_sample_finalize;
+ object_class->get_property = meson_sub_sample_get_property;
+ object_class->set_property = meson_sub_sample_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_sub_sample_init (MesonSubSample *self)
+{
+}
+
+/**
+ * meson_sub_sample_print_message:
+ * @self: a #MesonSubSample.
+ *
+ * Prints the message.
+ *
+ * Returns: Nothing.
+ */
+void
+meson_sub_sample_print_message (MesonSubSample *self)
+{
+ g_return_if_fail (MESON_IS_SUB_SAMPLE (self));
+
+ g_print ("Message: %s\n", self->msg);
+}
diff --git a/test cases/frameworks/12 multiple gir/gir/meson-subsample.h b/test cases/frameworks/12 multiple gir/gir/meson-subsample.h
new file mode 100644
index 0000000..9d34a08
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/gir/meson-subsample.h
@@ -0,0 +1,17 @@
+#ifndef MESON_SUB_SAMPLE_H
+#define MESON_SUB_SAMPLE_H
+
+#include <glib-object.h>
+#include <meson-sample.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SUB_SAMPLE (meson_sub_sample_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonSubSample, meson_sub_sample, MESON, SUB_SAMPLE, MesonSample)
+
+MesonSubSample *meson_sub_sample_new (const gchar *msg);
+
+G_END_DECLS
+
+#endif /* MESON_SUB_SAMPLE_H */
diff --git a/test cases/frameworks/12 multiple gir/gir/meson.build b/test cases/frameworks/12 multiple gir/gir/meson.build
new file mode 100644
index 0000000..5a52c9c
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/gir/meson.build
@@ -0,0 +1,31 @@
+libsources = ['meson-subsample.c', 'meson-subsample.h']
+
+girsubproject = shared_library(
+ 'girsubproject',
+ sources : libsources,
+ dependencies : [gobj, girlib_dep],
+ install : true
+)
+
+girexe = executable(
+ 'girprog',
+ sources : 'prog.c',
+ dependencies : [gobj, girlib_dep],
+ link_with : girsubproject
+)
+
+gnome.generate_gir(
+ girsubproject,
+ sources : libsources,
+ nsversion : '1.0',
+ namespace : 'MesonSub',
+ symbol_prefix : 'meson_sub_',
+ identifier_prefix : 'MesonSub',
+ includes : ['GObject-2.0', meson_gir],
+ install : true,
+ install_dir_gir: false,
+)
+
+message('TEST: ' + girsubproject.outdir())
+
+test('gobject introspection/subproject/c', girexe)
diff --git a/test cases/frameworks/12 multiple gir/gir/prog.c b/test cases/frameworks/12 multiple gir/gir/prog.c
new file mode 100644
index 0000000..f25c9d8
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/gir/prog.c
@@ -0,0 +1,12 @@
+#include "meson-subsample.h"
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ MesonSample * i = (MesonSample*) meson_sub_sample_new ("Hello, sub/meson/c!");
+ meson_sample_print_message (i);
+ g_object_unref (i);
+
+ return 0;
+}
diff --git a/test cases/frameworks/12 multiple gir/meson.build b/test cases/frameworks/12 multiple gir/meson.build
new file mode 100644
index 0000000..6391937
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/meson.build
@@ -0,0 +1,12 @@
+project('multiple-gobject-introspection', 'c', meson_version: '>=0.50.0')
+
+gir = find_program('g-ir-scanner', required: false)
+if not gir.found()
+ error('MESON_SKIP_TEST g-ir-scanner not found.')
+endif
+
+gnome = import('gnome')
+gobj = dependency('gobject-2.0')
+
+subdir('mesongir')
+subdir('gir')
diff --git a/test cases/frameworks/12 multiple gir/mesongir/meson-sample.c b/test cases/frameworks/12 multiple gir/mesongir/meson-sample.c
new file mode 100644
index 0000000..2ed9cdf
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/mesongir/meson-sample.c
@@ -0,0 +1,126 @@
+#include "meson-sample.h"
+
+typedef struct _MesonSamplePrivate
+{
+ gchar *msg;
+} MesonSamplePrivate;
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (MesonSample, meson_sample, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_sample_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonSample.
+ *
+ * Returns: (transfer full): a #MesonSample.
+ */
+MesonSample *
+meson_sample_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_SAMPLE,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_sample_finalize (GObject *object)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ g_clear_pointer (&priv->msg, g_free);
+
+ G_OBJECT_CLASS (meson_sample_parent_class)->finalize (object);
+}
+
+static void
+meson_sample_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, priv->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ priv->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_class_init (MesonSampleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_sample_finalize;
+ object_class->get_property = meson_sample_get_property;
+ object_class->set_property = meson_sample_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_sample_init (MesonSample *self)
+{
+}
+
+/**
+ * meson_sample_print_message:
+ * @self: a #MesonSample.
+ *
+ * Prints the message.
+ *
+ */
+void
+meson_sample_print_message (MesonSample *self)
+{
+ MesonSamplePrivate *priv;
+
+ g_return_if_fail (MESON_IS_SAMPLE (self));
+
+ priv = meson_sample_get_instance_private (self);
+
+ g_print ("Message: %s\n", priv->msg);
+}
diff --git a/test cases/frameworks/12 multiple gir/mesongir/meson-sample.h.in b/test cases/frameworks/12 multiple gir/mesongir/meson-sample.h.in
new file mode 100644
index 0000000..d0ab29e
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/mesongir/meson-sample.h.in
@@ -0,0 +1,22 @@
+#ifndef MESON_SAMPLE_H
+#define MESON_SAMPLE_H
+
+#include <@HEADER@>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SAMPLE (meson_sample_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject)
+
+struct _MesonSampleClass {
+ GObjectClass parent_class;
+};
+
+
+MesonSample *meson_sample_new (const gchar *msg);
+void meson_sample_print_message (MesonSample *self);
+
+G_END_DECLS
+
+#endif /* MESON_SAMPLE_H */
diff --git a/test cases/frameworks/12 multiple gir/mesongir/meson.build b/test cases/frameworks/12 multiple gir/mesongir/meson.build
new file mode 100644
index 0000000..1ae3f03
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/mesongir/meson.build
@@ -0,0 +1,39 @@
+conf = configuration_data()
+conf.set('HEADER', 'glib-object.h')
+
+meson_sample_header = configure_file(
+ input : 'meson-sample.h.in',
+ output : 'meson-sample.h',
+ configuration : conf)
+
+libsources = ['meson-sample.c', meson_sample_header]
+
+girlib = shared_library(
+ 'girlib',
+ sources : libsources,
+ dependencies : gobj,
+ install : true
+)
+
+girtarget = gnome.generate_gir(
+ girlib,
+ sources : libsources,
+ nsversion : '1.0',
+ namespace : 'Meson',
+ symbol_prefix : 'meson_',
+ identifier_prefix : 'Meson',
+ includes : ['GObject-2.0'],
+ export_packages : 'meson',
+ install : true,
+ install_gir: false,
+)
+meson_gir = girtarget[0]
+meson_typelib = girtarget[1]
+
+girlib_inc = include_directories('.')
+girlib_dep = declare_dependency(link_with : girlib,
+ include_directories : [girlib_inc],
+ dependencies : [gobj],
+ # Everything that uses libgst needs this built to compile
+ sources : girtarget,
+)
diff --git a/test cases/frameworks/12 multiple gir/test.json b/test cases/frameworks/12 multiple gir/test.json
new file mode 100644
index 0000000..e59c3e6
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/test.json
@@ -0,0 +1,17 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonSub-1.0.typelib"},
+ {"type": "expr", "file": "usr/lib/?libgirlib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirlib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libgirsubproject.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirsubproject.dll.a"}
+ ],
+ "skip_on_jobname": ["azure", "macos", "msys2"],
+ "stdout": [
+ {
+ "comment": "This will either match in the future-deprecated notice summary, or match the warning summary",
+ "line": " * 0.61.0: {'\"gnome.generate_gir\" keyword argument \"install_dir_gir\" value \"False\"'}"
+ }
+ ]
+}
diff --git a/test cases/frameworks/13 yelp/help/C/index.page b/test cases/frameworks/13 yelp/help/C/index.page
new file mode 100644
index 0000000..1b367e6
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/C/index.page
@@ -0,0 +1,8 @@
+<page xmlns="http://projectmallard.org/1.0/"
+ xmlns:its="http://www.w3.org/2005/11/its"
+ type="guide"
+ id="index">
+ <title>
+ Hello!
+ </title>
+</page>
diff --git a/test cases/frameworks/13 yelp/help/C/index2.page b/test cases/frameworks/13 yelp/help/C/index2.page
new file mode 100644
index 0000000..14b6b51
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/C/index2.page
@@ -0,0 +1,8 @@
+<page xmlns="http://projectmallard.org/1.0/"
+ xmlns:its="http://www.w3.org/2005/11/its"
+ type="guide"
+ id="index2">
+ <title>
+ Hello!
+ </title>
+</page>
diff --git a/test cases/frameworks/13 yelp/help/C/index3.page b/test cases/frameworks/13 yelp/help/C/index3.page
new file mode 100644
index 0000000..c0c21c1
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/C/index3.page
@@ -0,0 +1,8 @@
+<page xmlns="http://projectmallard.org/1.0/"
+ xmlns:its="http://www.w3.org/2005/11/its"
+ type="guide"
+ id="index3">
+ <title>
+ Hello!
+ </title>
+</page>
diff --git a/test cases/frameworks/13 yelp/help/C/media/test.txt b/test cases/frameworks/13 yelp/help/C/media/test.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/C/media/test.txt
@@ -0,0 +1 @@
+hello
diff --git a/test cases/frameworks/13 yelp/help/LINGUAS b/test cases/frameworks/13 yelp/help/LINGUAS
new file mode 100644
index 0000000..173f978
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/LINGUAS
@@ -0,0 +1,2 @@
+de
+es
diff --git a/test cases/frameworks/13 yelp/help/de/de.po b/test cases/frameworks/13 yelp/help/de/de.po
new file mode 100644
index 0000000..a54ce7f
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/de/de.po
@@ -0,0 +1,13 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: meson master\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. (itstool) path: page/title
+#: C/index.page:5
+msgid "Hello!"
+msgstr "Hallo!"
diff --git a/test cases/frameworks/13 yelp/help/es/es.po b/test cases/frameworks/13 yelp/help/es/es.po
new file mode 100644
index 0000000..b69ce7f
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/es/es.po
@@ -0,0 +1,13 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: meson master\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. (itstool) path: page/title
+#: C/index.page:5
+msgid "Hello!"
+msgstr "¡Hola!"
diff --git a/test cases/frameworks/13 yelp/help/es/media/test.txt b/test cases/frameworks/13 yelp/help/es/media/test.txt
new file mode 100644
index 0000000..3453b00
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/es/media/test.txt
@@ -0,0 +1 @@
+Hola.
diff --git a/test cases/frameworks/13 yelp/help/meson.build b/test cases/frameworks/13 yelp/help/meson.build
new file mode 100644
index 0000000..d6dbe10
--- /dev/null
+++ b/test cases/frameworks/13 yelp/help/meson.build
@@ -0,0 +1,21 @@
+gnome = import('gnome')
+
+gnome.yelp('meson',
+ sources: 'index.page',
+ media: 'media/test.txt',
+ symlink_media: false,
+ languages: ['de', 'es'],
+)
+
+gnome.yelp('meson-symlink',
+ sources: 'index2.page',
+ media: 'media/test.txt',
+ symlink_media: true,
+ languages: ['de', 'es'],
+)
+
+gnome.yelp('meson-linguas',
+ sources: 'index3.page',
+ media: 'media/test.txt',
+ symlink_media: false,
+)
diff --git a/test cases/frameworks/13 yelp/meson.build b/test cases/frameworks/13 yelp/meson.build
new file mode 100644
index 0000000..9fdde25
--- /dev/null
+++ b/test cases/frameworks/13 yelp/meson.build
@@ -0,0 +1,8 @@
+project('yelp', 'c')
+
+itstool = find_program('itstool', required: false)
+if not itstool.found()
+ error('MESON_SKIP_TEST itstool not found.')
+endif
+
+subdir('help')
diff --git a/test cases/frameworks/13 yelp/test.json b/test cases/frameworks/13 yelp/test.json
new file mode 100644
index 0000000..22e34d2
--- /dev/null
+++ b/test cases/frameworks/13 yelp/test.json
@@ -0,0 +1,23 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/help/C/meson/index.page"},
+ {"type": "file", "file": "usr/share/help/C/meson/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson/index.page"},
+ {"type": "file", "file": "usr/share/help/es/meson/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/de/meson/index.page"},
+ {"type": "file", "file": "usr/share/help/de/meson/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/C/meson-symlink/index2.page"},
+ {"type": "file", "file": "usr/share/help/C/meson-symlink/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson-symlink/index2.page"},
+ {"type": "file", "file": "usr/share/help/es/meson-symlink/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/de/meson-symlink/index2.page"},
+ {"type": "file", "file": "usr/share/help/de/meson-symlink/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/C/meson-linguas/index3.page"},
+ {"type": "file", "file": "usr/share/help/C/meson-linguas/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson-linguas/index3.page"},
+ {"type": "file", "file": "usr/share/help/es/meson-linguas/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/de/meson-linguas/index3.page"},
+ {"type": "file", "file": "usr/share/help/de/meson-linguas/media/test.txt"}
+ ],
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/14 doxygen/doc/Doxyfile.in b/test cases/frameworks/14 doxygen/doc/Doxyfile.in
new file mode 100644
index 0000000..69fb4aa
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/doc/Doxyfile.in
@@ -0,0 +1,2473 @@
+# Doxyfile 1.8.13
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "The Vast Comedian Project"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER = @VERSION@
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF = Comedy generator
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = YES
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = "@TOP_SRCDIR@/include" "@TOP_SRCDIR@/src"
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.idl \
+ *.ddl \
+ *.odl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.cs \
+ *.d \
+ *.php \
+ *.php4 \
+ *.php5 \
+ *.phtml \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.pyw \
+ *.f90 \
+ *.f95 \
+ *.f03 \
+ *.f08 \
+ *.f \
+ *.for \
+ *.tcl \
+ *.vhd \
+ *.vhdl \
+ *.ucf \
+ *.qsf
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH = "@TOP_SRCDIR@/include" "@TOP_BUILDDIR@/include"
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT = @HAVE_DOT@
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/test cases/frameworks/14 doxygen/doc/meson.build b/test cases/frameworks/14 doxygen/doc/meson.build
new file mode 100644
index 0000000..bde2d7c
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/doc/meson.build
@@ -0,0 +1,16 @@
+cdata.set('TOP_SRCDIR', meson.source_root())
+cdata.set('TOP_BUILDDIR', meson.build_root())
+
+doxyfile = configure_file(input: 'Doxyfile.in',
+ output: 'Doxyfile',
+ configuration: cdata,
+ install: false)
+
+datadir = join_paths(get_option('datadir'), 'doc', 'spede')
+
+html_target = custom_target('spede-docs',
+ input: doxyfile,
+ output: 'html',
+ command: [doxygen, doxyfile],
+ install: true,
+ install_dir: datadir)
diff --git a/test cases/frameworks/14 doxygen/include/comedian.h b/test cases/frameworks/14 doxygen/include/comedian.h
new file mode 100644
index 0000000..d62b283
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/include/comedian.h
@@ -0,0 +1,17 @@
+#pragma once
+
+namespace Comedy {
+
+ /**
+ * Interface for a funnyperson.
+ */
+ class Comedian {
+ public:
+ /**
+ * Do the thing people want to happen.
+ */
+ virtual void tell_joke() = 0;
+ virtual ~Comedian(){};
+ };
+
+}
diff --git a/test cases/frameworks/14 doxygen/include/spede.h b/test cases/frameworks/14 doxygen/include/spede.h
new file mode 100644
index 0000000..380708a
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/include/spede.h
@@ -0,0 +1,35 @@
+#pragma once
+#include<comedian.h>
+#include<stdexcept>
+
+/**
+ * \file spede.h
+ *
+ * Spede definition.
+ */
+
+namespace Comedy {
+
+ /**
+ * Spede is the funniest person in the world.
+ */
+ class Spede : public Comedian {
+ public:
+ /**
+ * Creates a new spede.
+ */
+ Spede();
+
+ /**
+ * Make him do the funny thing he is known for.
+ */
+ void slap_forehead();
+
+ virtual void tell_joke() {
+ throw std::runtime_error("Not implemented");
+ }
+
+ private:
+ int num_movies; ///< How many movies has he done.
+ };
+}
diff --git a/test cases/frameworks/14 doxygen/meson.build b/test cases/frameworks/14 doxygen/meson.build
new file mode 100644
index 0000000..517cef2
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/meson.build
@@ -0,0 +1,27 @@
+project('doxygen test', 'cpp', version : '0.1.0')
+
+spede_inc = include_directories('include')
+
+spede_src = [ 'src/spede.cpp' ]
+
+spede_lib = library('spede', spede_src, include_directories: spede_inc)
+
+doxygen = find_program('doxygen', required : false)
+if not doxygen.found()
+ error('MESON_SKIP_TEST doxygen not found.')
+endif
+
+cdata = configuration_data()
+cdata.set('VERSION', meson.project_version())
+
+if find_program('dot', required : false).found()
+ # In the real world this would set the variable
+ # to YES. However we set it to NO so that the
+ # list of generated files is always the same
+ # so tests always pass.
+ cdata.set('HAVE_DOT', 'NO')
+else
+ cdata.set('HAVE_DOT', 'NO')
+endif
+
+subdir('doc')
diff --git a/test cases/frameworks/14 doxygen/src/spede.cpp b/test cases/frameworks/14 doxygen/src/spede.cpp
new file mode 100644
index 0000000..d382902
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/src/spede.cpp
@@ -0,0 +1,49 @@
+#include<spede.h>
+
+/**
+ * \file spede.cpp
+ *
+ * This file contains the implementation of the king of comedy.
+ */
+
+/**
+ * \mainpage The Vast Comedian Project
+ *
+ * \section intro Introduction
+ *
+ * The purpose of this project is to model every single comedian
+ * who has ever lived.
+ *
+ * \section sched Project schedule
+ *
+ * There is no real estimate on when this will be finished.
+ */
+
+/**
+ * \namespace Comedy
+ *
+ * This contains everything that is funny.
+ */
+
+namespace Comedy {
+
+/**
+ * Do all the delicate movements that lead to a comical sound
+ * emanating from a person.
+ *
+ * \param force how hard to move the hand.
+ * \return something or another
+ */
+int gesticulate(int force) {
+ // FIXME add implementation.
+ return 0;
+}
+
+Spede::Spede() : num_movies(100) {
+}
+
+void Spede::slap_forehead() {
+ gesticulate(42);
+}
+
+}
diff --git a/test cases/frameworks/14 doxygen/test.json b/test cases/frameworks/14 doxygen/test.json
new file mode 100644
index 0000000..c8c4fb0
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "dir", "file": "usr/share/doc/spede/html"}
+ ],
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/15 llvm/meson.build b/test cases/frameworks/15 llvm/meson.build
new file mode 100644
index 0000000..3855fae
--- /dev/null
+++ b/test cases/frameworks/15 llvm/meson.build
@@ -0,0 +1,51 @@
+project('llvmtest', ['c', 'cpp'], default_options : ['c_std=c99'])
+
+method = get_option('method')
+static = get_option('link-static')
+d = dependency('llvm', required : false, method : method, static : static)
+if not d.found()
+ error('MESON_SKIP_TEST llvm not found.')
+endif
+
+d = dependency('llvm', modules : 'not-found', required : false, static : static, method : method)
+assert(d.found() == false, 'not-found llvm module found')
+
+d = dependency('llvm', version : '<0.1', required : false, static : static, method : method)
+assert(d.found() == false, 'ancient llvm module found')
+
+d = dependency('llvm', optional_modules : 'not-found', required : false, static : static, method : method)
+assert(d.found() == true, 'optional module stopped llvm from being found.')
+
+# Check we can apply a version constraint
+d = dependency('llvm', version : ['< 500', '>=@0@'.format(d.version())], required: false, static : static, method : method)
+assert(d.found() == true, 'Cannot set version constraints')
+
+dep_tinfo = dependency('tinfo', required : false)
+if not dep_tinfo.found()
+ cpp = meson.get_compiler('cpp')
+ dep_tinfo = cpp.find_library('tinfo', required: false)
+endif
+
+llvm_dep = dependency(
+ 'llvm',
+ modules : ['bitwriter', 'asmprinter', 'executionengine', 'target',
+ 'mcjit', 'nativecodegen', 'amdgpu'],
+ required : false,
+ static : static,
+ method : method,
+)
+
+if not llvm_dep.found()
+ error('MESON_SKIP_TEST required llvm modules not found.')
+endif
+
+executable(
+ 'sum',
+ 'sum.c',
+ dependencies : [
+ llvm_dep, dep_tinfo,
+ # zlib will be statically linked on windows
+ dependency('zlib', required : host_machine.system() != 'windows'),
+ meson.get_compiler('c').find_library('dl', required : false),
+ ]
+ )
diff --git a/test cases/frameworks/15 llvm/meson_options.txt b/test cases/frameworks/15 llvm/meson_options.txt
new file mode 100644
index 0000000..de3d172
--- /dev/null
+++ b/test cases/frameworks/15 llvm/meson_options.txt
@@ -0,0 +1,10 @@
+option(
+ 'method',
+ type : 'combo',
+ choices : ['config-tool', 'cmake']
+)
+option(
+ 'link-static',
+ type : 'boolean',
+ value : false,
+)
diff --git a/test cases/frameworks/15 llvm/sum.c b/test cases/frameworks/15 llvm/sum.c
new file mode 100644
index 0000000..e35fe95
--- /dev/null
+++ b/test cases/frameworks/15 llvm/sum.c
@@ -0,0 +1,76 @@
+/** This code is public domain, and taken from
+ * https://github.com/paulsmith/getting-started-llvm-c-api/blob/master/sum.c
+ */
+/**
+ * LLVM equivalent of:
+ *
+ * int sum(int a, int b) {
+ * return a + b;
+ * }
+ */
+
+#include <llvm-c/Core.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm-c/Target.h>
+#include <llvm-c/Analysis.h>
+#include <llvm-c/BitWriter.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char const *argv[]) {
+ LLVMModuleRef mod = LLVMModuleCreateWithName("my_module");
+
+ LLVMTypeRef param_types[] = { LLVMInt32Type(), LLVMInt32Type() };
+ LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), param_types, 2, 0);
+ LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type);
+
+ LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry");
+
+ LLVMBuilderRef builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, entry);
+ LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp");
+ LLVMBuildRet(builder, tmp);
+
+ char *error = NULL;
+ LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
+ LLVMDisposeMessage(error);
+
+ LLVMExecutionEngineRef engine;
+ error = NULL;
+ LLVMLinkInMCJIT();
+ LLVMInitializeNativeAsmPrinter();
+ LLVMInitializeNativeTarget();
+ if (LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0) {
+ fprintf(stderr, "failed to create execution engine\n");
+ abort();
+ }
+ if (error) {
+ fprintf(stderr, "error: %s\n", error);
+ LLVMDisposeMessage(error);
+ exit(EXIT_FAILURE);
+ }
+
+ if (argc < 3) {
+ fprintf(stderr, "usage: %s x y\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ long long x = strtoll(argv[1], NULL, 10);
+ long long y = strtoll(argv[2], NULL, 10);
+
+ LLVMGenericValueRef args[] = {
+ LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0),
+ LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0)
+ };
+ LLVMGenericValueRef res = LLVMRunFunction(engine, sum, 2, args);
+ printf("%d\n", (int)LLVMGenericValueToInt(res, 0));
+
+ // Write out bitcode to file
+ if (LLVMWriteBitcodeToFile(mod, "sum.bc") != 0) {
+ fprintf(stderr, "error writing bitcode to file, skipping\n");
+ }
+
+ LLVMDisposeBuilder(builder);
+ LLVMDisposeExecutionEngine(engine);
+}
diff --git a/test cases/frameworks/15 llvm/test.json b/test cases/frameworks/15 llvm/test.json
new file mode 100644
index 0000000..e70edd5
--- /dev/null
+++ b/test cases/frameworks/15 llvm/test.json
@@ -0,0 +1,18 @@
+{
+ "matrix": {
+ "options": {
+ "method": [
+ { "val": "config-tool", "skip_on_jobname": ["msys2-gcc"]},
+ { "val": "cmake", "skip_on_jobname": ["msys2-gcc"] }
+ ],
+ "link-static": [
+ { "val": true, "skip_on_jobname": ["opensuse"] },
+ { "val": false }
+ ]
+ },
+ "exclude": [
+ { "method": "cmake", "link-static": false }
+ ]
+ },
+ "skip_on_jobname": ["azure", "cygwin"]
+}
diff --git a/test cases/frameworks/16 sdl2/meson.build b/test cases/frameworks/16 sdl2/meson.build
new file mode 100644
index 0000000..fc98010
--- /dev/null
+++ b/test cases/frameworks/16 sdl2/meson.build
@@ -0,0 +1,13 @@
+project('sdl2 test', 'c')
+
+method = get_option('method')
+
+sdl2_dep = dependency('sdl2', version : '>=2.0.0', required : false, method : method)
+
+if not sdl2_dep.found()
+ error('MESON_SKIP_TEST sdl2 not found.')
+endif
+
+e = executable('sdl2prog', 'sdl2prog.c', dependencies : sdl2_dep)
+
+test('sdl2test', e)
diff --git a/test cases/frameworks/16 sdl2/meson_options.txt b/test cases/frameworks/16 sdl2/meson_options.txt
new file mode 100644
index 0000000..176af17
--- /dev/null
+++ b/test cases/frameworks/16 sdl2/meson_options.txt
@@ -0,0 +1,6 @@
+option(
+ 'method',
+ type : 'combo',
+ choices : ['auto', 'pkg-config', 'config-tool', 'sdlconfig', 'extraframework'],
+ value : 'auto',
+)
diff --git a/test cases/frameworks/16 sdl2/sdl2prog.c b/test cases/frameworks/16 sdl2/sdl2prog.c
new file mode 100644
index 0000000..b67aab4
--- /dev/null
+++ b/test cases/frameworks/16 sdl2/sdl2prog.c
@@ -0,0 +1,33 @@
+/* vim: set sts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <SDL_version.h>
+
+int main(int argc, char *argv[]) {
+ SDL_version compiled;
+ SDL_version linked;
+
+ SDL_VERSION(&compiled);
+ SDL_GetVersion(&linked);
+
+ if (compiled.major != linked.major) {
+ fprintf(stderr, "Compiled major '%u' != linked major '%u'",
+ compiled.major, linked.major);
+ return -1;
+ }
+
+ if (compiled.minor != linked.minor) {
+ fprintf(stderr, "Compiled minor '%u' != linked minor '%u'",
+ compiled.minor, linked.minor);
+ return -2;
+ }
+#if 0
+ /* Disabled because sometimes this is 'micro' and sometimes 'patch' */
+ if (compiled.micro != linked.micro) {
+ fprintf(stderr, "Compiled micro '%u' != linked micro '%u'",
+ compiled.micro, linked.micro);
+ return -3;
+ }
+#endif
+ return 0;
+}
diff --git a/test cases/frameworks/16 sdl2/test.json b/test cases/frameworks/16 sdl2/test.json
new file mode 100644
index 0000000..57a3f21
--- /dev/null
+++ b/test cases/frameworks/16 sdl2/test.json
@@ -0,0 +1,14 @@
+{
+ "matrix": {
+ "options": {
+ "method": [
+ { "val": "auto" },
+ { "val": "pkg-config" },
+ { "val": "config-tool" },
+ { "val": "sdlconfig" },
+ { "val": "extraframework", "skip_on_os": ["!darwin"], "skip_on_jobname": ["macos"] }
+ ]
+ }
+ },
+ "skip_on_jobname": ["azure", "cygwin", "msys2"]
+}
diff --git a/test cases/frameworks/17 mpi/main.c b/test cases/frameworks/17 mpi/main.c
new file mode 100644
index 0000000..e44357a
--- /dev/null
+++ b/test cases/frameworks/17 mpi/main.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <mpi.h>
+
+int main(int argc, char **argv)
+{
+ int ier, flag;
+ ier = MPI_Init(&argc, &argv);
+ if (ier) {
+ printf("Unable to initialize MPI: %d\n", ier);
+ return 1;
+ }
+ ier = MPI_Initialized(&flag);
+ if (ier) {
+ printf("Unable to check MPI initialization state: %d\n", ier);
+ return 1;
+ }
+ if (!flag) {
+ printf("MPI did not initialize!\n");
+ return 1;
+ }
+ ier = MPI_Finalize();
+ if (ier) {
+ printf("Unable to finalize MPI: %d\n", ier);
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/frameworks/17 mpi/main.cpp b/test cases/frameworks/17 mpi/main.cpp
new file mode 100644
index 0000000..199d913
--- /dev/null
+++ b/test cases/frameworks/17 mpi/main.cpp
@@ -0,0 +1,12 @@
+#include <mpi.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ MPI::Init(argc, argv);
+ if (!MPI::Is_initialized()) {
+ printf("MPI did not initialize!\n");
+ return 1;
+ }
+ MPI::Finalize();
+}
diff --git a/test cases/frameworks/17 mpi/main.f90 b/test cases/frameworks/17 mpi/main.f90
new file mode 100644
index 0000000..b5666e8
--- /dev/null
+++ b/test cases/frameworks/17 mpi/main.f90
@@ -0,0 +1,30 @@
+use, intrinsic :: iso_fortran_env, only: stderr=>error_unit
+use mpi
+
+implicit none
+
+logical :: flag
+integer :: ier
+
+call MPI_Init(ier)
+
+if (ier /= 0) then
+ write(stderr,*) 'Unable to initialize MPI', ier
+ stop 1
+endif
+
+call MPI_Initialized(flag, ier)
+if (ier /= 0) then
+ write(stderr,*) 'Unable to check MPI initialization state: ', ier
+ stop 1
+endif
+
+call MPI_Finalize(ier)
+if (ier /= 0) then
+ write(stderr,*) 'Unable to finalize MPI: ', ier
+ stop 1
+endif
+
+print *, "OK: Fortran MPI"
+
+end program
diff --git a/test cases/frameworks/17 mpi/meson.build b/test cases/frameworks/17 mpi/meson.build
new file mode 100644
index 0000000..d1d8991
--- /dev/null
+++ b/test cases/frameworks/17 mpi/meson.build
@@ -0,0 +1,52 @@
+project('mpi', 'c', 'cpp', default_options: ['b_asneeded=false'])
+
+method = get_option('method')
+
+cc = meson.get_compiler('c')
+mpic = dependency('mpi', language : 'c', required : false, method : method)
+if not mpic.found()
+ error('MESON_SKIP_TEST: MPI not found, skipping.')
+endif
+exec = executable('exec',
+ 'main.c',
+ dependencies : [mpic])
+
+test('MPI C', exec, timeout: 20)
+
+
+# C++ MPI not supported by MS-MPI
+cpp = meson.get_compiler('cpp')
+mpicpp = dependency('mpi', language : 'cpp', required: false, method : method)
+if not cpp.links('''
+#include <mpi.h>
+#include <stdio.h>
+int main(int argc, char **argv) {MPI::Init(argc, argv);}
+''', dependencies: mpicpp, name: 'C++ MPI')
+ mpicpp = disabler()
+endif
+execpp = executable('execpp',
+ 'main.cpp',
+ dependencies : [mpicpp])
+
+test('MPI C++', execpp, timeout: 20)
+
+
+if add_languages('fortran', required : false)
+ fc = meson.get_compiler('fortran')
+ mpif = dependency('mpi', language : 'fortran', required: false, method : method)
+ if not fc.links('use mpi; end', dependencies: mpif, name: 'Fortran MPI')
+ mpif = disabler()
+ endif
+
+ exef = executable('exef',
+ 'main.f90',
+ dependencies : mpif)
+
+ test('MPI Fortran', exef, timeout: 20)
+endif
+
+
+# Check we can apply a version constraint
+if mpic.version() != 'unknown'
+ dependency('mpi', version: '>=@0@'.format(mpic.version()), method : method)
+endif
diff --git a/test cases/frameworks/17 mpi/meson_options.txt b/test cases/frameworks/17 mpi/meson_options.txt
new file mode 100644
index 0000000..7e9363e
--- /dev/null
+++ b/test cases/frameworks/17 mpi/meson_options.txt
@@ -0,0 +1,6 @@
+option(
+ 'method',
+ type : 'combo',
+ choices : ['auto', 'pkg-config', 'config-tool', 'system'],
+ value : 'auto',
+)
diff --git a/test cases/frameworks/17 mpi/test.json b/test cases/frameworks/17 mpi/test.json
new file mode 100644
index 0000000..115f6f6
--- /dev/null
+++ b/test cases/frameworks/17 mpi/test.json
@@ -0,0 +1,17 @@
+{
+ "matrix": {
+ "options": {
+ "method": [
+ { "val": "auto" },
+ { "val": "pkg-config" },
+ { "val": "config-tool",
+ "skip_on_jobname": ["fedora"] },
+ {
+ "val": "system",
+ "compilers": { "c" :"msvc", "cpp": "msvc" }
+ }
+ ]
+ }
+ },
+ "skip_on_jobname": ["azure", "cygwin", "msys2", "opensuse"]
+}
diff --git a/test cases/frameworks/18 vulkan/meson.build b/test cases/frameworks/18 vulkan/meson.build
new file mode 100644
index 0000000..5cfe89f
--- /dev/null
+++ b/test cases/frameworks/18 vulkan/meson.build
@@ -0,0 +1,13 @@
+project('vulkan test', 'c')
+
+vulkan_dep = dependency('vulkan', required : false)
+if not vulkan_dep.found()
+ error('MESON_SKIP_TEST: vulkan not found.')
+endif
+
+e = executable('vulkanprog', 'vulkanprog.c', dependencies : vulkan_dep)
+
+test('vulkantest', e)
+
+# Check we can apply a version constraint
+dependency('vulkan', version: '>=@0@'.format(vulkan_dep.version()))
diff --git a/test cases/frameworks/18 vulkan/test.json b/test cases/frameworks/18 vulkan/test.json
new file mode 100644
index 0000000..6ace9de
--- /dev/null
+++ b/test cases/frameworks/18 vulkan/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/18 vulkan/vulkanprog.c b/test cases/frameworks/18 vulkan/vulkanprog.c
new file mode 100644
index 0000000..c6b8803
--- /dev/null
+++ b/test cases/frameworks/18 vulkan/vulkanprog.c
@@ -0,0 +1,26 @@
+#include <vulkan/vulkan.h>
+#include <stdio.h>
+
+int main(void)
+{
+ VkInstanceCreateInfo instance_create_info = {
+ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ };
+
+ // we don't actually require instance creation to succeed since
+ // we cannot expect test environments to have a vulkan driver installed.
+ // As long as this does not produce as segmentation fault or similar,
+ // everything's alright.
+ VkInstance instance;
+ if(vkCreateInstance(&instance_create_info, NULL, &instance) == VK_SUCCESS)
+ vkDestroyInstance(instance, NULL);
+
+ return 0;
+}
diff --git a/test cases/frameworks/19 pcap/meson.build b/test cases/frameworks/19 pcap/meson.build
new file mode 100644
index 0000000..051e49e
--- /dev/null
+++ b/test cases/frameworks/19 pcap/meson.build
@@ -0,0 +1,22 @@
+project('pcap test', 'c')
+
+pcap_dep = dependency('pcap', version : '>=1.0', required: false)
+
+if not pcap_dep.found()
+ error('MESON_SKIP_TEST pcap not found.')
+endif
+
+pcap_ver = pcap_dep.version()
+assert(pcap_ver.split('.').length() > 1, 'pcap version is "@0@"'.format(pcap_ver))
+
+e = executable('pcap_prog', 'pcap_prog.c', dependencies : pcap_dep)
+
+test('pcaptest', e)
+
+# Ensure discovery via the configuration tools work also
+pcap_dep = dependency('pcap', version : '>=1.0', method : 'pcap-config')
+pcap_dep = dependency('pcap', version : '>=1.0', method : 'config-tool')
+
+# Check we can apply a version constraint
+dependency('pcap', version: '>=@0@'.format(pcap_dep.version()), method: 'pkg-config', required: false)
+dependency('pcap', version: '>=@0@'.format(pcap_dep.version()), method: 'config-tool')
diff --git a/test cases/frameworks/19 pcap/pcap_prog.c b/test cases/frameworks/19 pcap/pcap_prog.c
new file mode 100644
index 0000000..0fca16c
--- /dev/null
+++ b/test cases/frameworks/19 pcap/pcap_prog.c
@@ -0,0 +1,15 @@
+#include <pcap/pcap.h>
+
+int
+main()
+{
+ char errbuf[PCAP_ERRBUF_SIZE];
+#ifdef __APPLE__
+ // source = NULL for "any" doesn't work on macOS (linux only?)
+ char *source = "en0";
+#else
+ char *source = NULL;
+#endif
+ pcap_t *p = pcap_create(source, errbuf);
+ return p == NULL;
+}
diff --git a/test cases/frameworks/19 pcap/test.json b/test cases/frameworks/19 pcap/test.json
new file mode 100644
index 0000000..8ee026a
--- /dev/null
+++ b/test cases/frameworks/19 pcap/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "msys2"]
+}
diff --git a/test cases/frameworks/2 gtest/meson.build b/test cases/frameworks/2 gtest/meson.build
new file mode 100644
index 0000000..ea3ef48
--- /dev/null
+++ b/test cases/frameworks/2 gtest/meson.build
@@ -0,0 +1,14 @@
+# on Ubuntu this test requires libgtest-dev
+project('gtest', 'cpp')
+
+gtest = dependency('gtest', main : true, required : false)
+if not gtest.found()
+ error('MESON_SKIP_TEST: gtest not installed.')
+endif
+gtest_nomain = dependency('gtest', main : false, method : 'system')
+
+e = executable('testprog', 'test.cc', dependencies : gtest)
+test('gtest test', e, protocol : 'gtest')
+
+e = executable('testprog_nomain', 'test_nomain.cc', dependencies : gtest_nomain)
+test('gtest nomain test', e, protocol : 'gtest')
diff --git a/test cases/frameworks/2 gtest/test.cc b/test cases/frameworks/2 gtest/test.cc
new file mode 100644
index 0000000..21efd68
--- /dev/null
+++ b/test cases/frameworks/2 gtest/test.cc
@@ -0,0 +1,9 @@
+#include<gtest/gtest.h>
+
+TEST(basic_test, eq_works) {
+ ASSERT_EQ(0, 1-1) << "Equality is broken. Mass panic!";
+}
+
+TEST(basic_test, neq_works) {
+ ASSERT_NE(15, 106) << "Inequal is equal. The foundations of space and time are in jeopardy.";
+}
diff --git a/test cases/frameworks/2 gtest/test.json b/test cases/frameworks/2 gtest/test.json
new file mode 100644
index 0000000..6ace9de
--- /dev/null
+++ b/test cases/frameworks/2 gtest/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/2 gtest/test_nomain.cc b/test cases/frameworks/2 gtest/test_nomain.cc
new file mode 100644
index 0000000..bd0bcfe
--- /dev/null
+++ b/test cases/frameworks/2 gtest/test_nomain.cc
@@ -0,0 +1,14 @@
+#include<gtest/gtest.h>
+
+TEST(basic_test, eq_works) {
+ ASSERT_EQ(0, 1-1) << "Equality is broken. Mass panic!";
+}
+
+TEST(basic_test, neq_works) {
+ ASSERT_NE(15, 106) << "Inequal is equal. The foundations of space and time are in jeopardy.";
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test cases/frameworks/20 cups/cups_prog.c b/test cases/frameworks/20 cups/cups_prog.c
new file mode 100644
index 0000000..d6b6dcc
--- /dev/null
+++ b/test cases/frameworks/20 cups/cups_prog.c
@@ -0,0 +1,8 @@
+#include <cups/cups.h>
+
+int
+main()
+{
+ cupsGetDefault();
+ return 0;
+}
diff --git a/test cases/frameworks/20 cups/meson.build b/test cases/frameworks/20 cups/meson.build
new file mode 100644
index 0000000..c533980
--- /dev/null
+++ b/test cases/frameworks/20 cups/meson.build
@@ -0,0 +1,21 @@
+project('cups test', 'c')
+
+cups_dep = dependency('cups', version : '>=1.4', required: false)
+
+if not cups_dep.found()
+ error('MESON_SKIP_TEST cups not found.')
+endif
+
+e = executable('cups_prog', 'cups_prog.c', dependencies : cups_dep)
+
+test('cupstest', e)
+
+# ensure we can find the cups dependency via the legacy and modern config-tool
+# options
+depCC = dependency('cups', version : '>=1.4', method : 'cups-config')
+depCT = dependency('cups', version : '>=1.4', method : 'config-tool')
+depCM = dependency('cups', version : '>=1.4', method : 'cmake')
+
+# check we can apply a version constraint
+dependency('cups', version: '>=@0@'.format(depCT.version()), method: 'pkg-config', required: false)
+dependency('cups', version: '>=@0@'.format(depCT.version()), method: 'config-tool')
diff --git a/test cases/frameworks/20 cups/test.json b/test cases/frameworks/20 cups/test.json
new file mode 100644
index 0000000..8ee026a
--- /dev/null
+++ b/test cases/frameworks/20 cups/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "msys2"]
+}
diff --git a/test cases/frameworks/21 libwmf/libwmf_prog.c b/test cases/frameworks/21 libwmf/libwmf_prog.c
new file mode 100644
index 0000000..4e6294c
--- /dev/null
+++ b/test cases/frameworks/21 libwmf/libwmf_prog.c
@@ -0,0 +1,8 @@
+#include <libwmf/api.h>
+
+int
+main()
+{
+ wmf_help();
+ return 0;
+}
diff --git a/test cases/frameworks/21 libwmf/meson.build b/test cases/frameworks/21 libwmf/meson.build
new file mode 100644
index 0000000..9dbab6a
--- /dev/null
+++ b/test cases/frameworks/21 libwmf/meson.build
@@ -0,0 +1,27 @@
+project('libwmf test', 'c')
+
+wm = find_program('libwmf-config', required : false)
+if not wm.found() or meson.is_cross_build()
+ error('MESON_SKIP_TEST: libwmf-config not installed')
+endif
+
+libwmf_dep = dependency('libwmf', version : '>= 0.2.8')
+libwmf_ver = libwmf_dep.version()
+assert(libwmf_ver.split('.').length() > 1, 'libwmf version is "@0@"'.format(libwmf_ver))
+message('libwmf version is "@0@"'.format(libwmf_ver))
+# Workaround for Debian bug 912563 where libwmf-devel returns cflags
+# that do not not have Freetype include paths but their headers
+# use them unconditionally.
+ft_dep = dependency('freetype2')
+e = executable('libwmf_prog', 'libwmf_prog.c', dependencies : [libwmf_dep, ft_dep])
+
+test('libwmftest', e)
+
+# Test using the method keyword:
+
+dependency('libwmf', method : 'config-tool')
+dependency('libwmf', method : 'libwmf-config')
+
+# Check we can apply a version constraint
+dependency('libwmf', version: '>=@0@'.format(libwmf_dep.version()), method: 'pkg-config', required: false)
+dependency('libwmf', version: '>=@0@'.format(libwmf_dep.version()), method: 'config-tool')
diff --git a/test cases/frameworks/21 libwmf/test.json b/test cases/frameworks/21 libwmf/test.json
new file mode 100644
index 0000000..6ace9de
--- /dev/null
+++ b/test cases/frameworks/21 libwmf/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c
new file mode 100644
index 0000000..fae9c38
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c
@@ -0,0 +1,6 @@
+#include "fake-gthread.h"
+
+int fake_gthread_fake_function (void)
+{
+ return 7;
+}
diff --git a/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h
new file mode 100644
index 0000000..52b5472
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h
@@ -0,0 +1,6 @@
+#ifndef FAKE_GTHREAD_H
+#define FAKE_GTHREAD_H
+
+int fake_gthread_fake_function (void);
+
+#endif /* FAKE_GTHREAD_H */
diff --git a/test cases/frameworks/22 gir link order/fake-gthread/meson.build b/test cases/frameworks/22 gir link order/fake-gthread/meson.build
new file mode 100644
index 0000000..693e8e0
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/fake-gthread/meson.build
@@ -0,0 +1,12 @@
+fake_gthread_sources = ['fake-gthread.c', 'fake-gthread.h']
+fake_gthread_lib = shared_library(
+ 'gthread-2.0',
+ sources : fake_gthread_sources,
+ install : false,
+)
+
+fake_gthread_includes = include_directories('.')
+fake_gthread = declare_dependency(
+ include_directories : fake_gthread_includes,
+ link_with : fake_gthread_lib,
+)
diff --git a/test cases/frameworks/22 gir link order/get-prgname/get-prgname.c b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.c
new file mode 100644
index 0000000..356b45e
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.c
@@ -0,0 +1,8 @@
+#include "get-prgname.h"
+
+#include <glib.h>
+
+const char *get_prgname_get_name (void)
+{
+ return g_get_prgname ();
+}
diff --git a/test cases/frameworks/22 gir link order/get-prgname/get-prgname.h b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.h
new file mode 100644
index 0000000..cb5118e
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.h
@@ -0,0 +1,6 @@
+#ifndef GET_PRGNAME_H
+#define GET_PRGNAME_H
+
+const char *get_prgname_get_name (void);
+
+#endif /* GET_PRGNAME_H */
diff --git a/test cases/frameworks/22 gir link order/get-prgname/meson.build b/test cases/frameworks/22 gir link order/get-prgname/meson.build
new file mode 100644
index 0000000..6a7489d
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/get-prgname/meson.build
@@ -0,0 +1,13 @@
+get_prgname_sources = ['get-prgname.c', 'get-prgname.h']
+get_prgname_lib = shared_library(
+ 'get-prgname',
+ sources : get_prgname_sources,
+ dependencies : [glib],
+ install : false,
+)
+
+get_prgname_includes = include_directories('.')
+get_prgname = declare_dependency(
+ include_directories : get_prgname_includes,
+ link_with : get_prgname_lib,
+)
diff --git a/test cases/frameworks/22 gir link order/meson-sample.c b/test cases/frameworks/22 gir link order/meson-sample.c
new file mode 100644
index 0000000..7c6442a
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/meson-sample.c
@@ -0,0 +1,48 @@
+#include "meson-sample.h"
+
+#include "get-prgname.h"
+#include "fake-gthread.h"
+
+struct _MesonSample {
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (MesonSample, meson_sample, G_TYPE_OBJECT)
+
+/**
+ * meson_sample_new:
+ *
+ * Allocates a new #MesonSample.
+ *
+ * Returns: (transfer full): a #MesonSample.
+ */
+MesonSample *
+meson_sample_new (void)
+{
+ return g_object_new (MESON_TYPE_SAMPLE, NULL);
+}
+
+static void
+meson_sample_class_init (MesonSampleClass *klass)
+{
+}
+
+static void
+meson_sample_init (MesonSample *self)
+{
+}
+
+/**
+ * meson_sample_print_message:
+ * @self: a #MesonSample.
+ *
+ * Prints a message.
+ */
+void
+meson_sample_print_message (MesonSample *self)
+{
+ g_return_if_fail (MESON_IS_SAMPLE (self));
+
+ g_print ("Message: %s\n", get_prgname_get_name ());
+ g_print ("Message: %d\n", fake_gthread_fake_function ());
+}
diff --git a/test cases/frameworks/22 gir link order/meson-sample.h b/test cases/frameworks/22 gir link order/meson-sample.h
new file mode 100644
index 0000000..2c28401
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/meson-sample.h
@@ -0,0 +1,17 @@
+#ifndef MESON_SAMPLE_H
+#define MESON_SAMPLE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SAMPLE (meson_sample_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject)
+
+MesonSample *meson_sample_new (void);
+void meson_sample_print_message (MesonSample *self);
+
+G_END_DECLS
+
+#endif /* MESON_SAMPLE_H */
diff --git a/test cases/frameworks/22 gir link order/meson.build b/test cases/frameworks/22 gir link order/meson.build
new file mode 100644
index 0000000..8a714b5
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/meson.build
@@ -0,0 +1,41 @@
+project('gir link order', 'c')
+
+if not dependency('glib-2.0', required : false).found() or not find_program('g-ir-scanner', required: false).found()
+ error('MESON_SKIP_TEST glib not found.')
+endif
+
+gnome = import('gnome')
+glib = dependency('glib-2.0')
+gobject = dependency('gobject-2.0')
+
+# get-prgname is a shared library which uses a function from glib-2.0. It is
+# used to introduce external -L flags which may cause -L order problems.
+subdir('get-prgname')
+
+# fake-gthread is a shared library which has the same name as gthread-2.0 from
+# GLib. This is used to simulate the case where an older or unrelated version
+# of a library is already installed on the system. Our meson sample library
+# defined below uses a function from fake-gthread. If meson messes up -L order,
+# the linker will find libgthread-2.0.so installed on the system and fail to
+# find the symbol our meson sample library uses.
+subdir('fake-gthread')
+
+meson_sample_sources = ['meson-sample.c', 'meson-sample.h']
+meson_sample_lib = shared_library(
+ 'sample',
+ sources : meson_sample_sources,
+ dependencies : [gobject, get_prgname, fake_gthread],
+ install : false,
+)
+
+gnome.generate_gir(
+ meson_sample_lib,
+ sources : meson_sample_sources,
+ nsversion : '1.0',
+ namespace : 'Meson',
+ symbol_prefix : 'meson',
+ identifier_prefix : 'Meson',
+ includes : ['GObject-2.0'],
+ install : false,
+ build_by_default: true,
+)
diff --git a/test cases/frameworks/22 gir link order/test.json b/test cases/frameworks/22 gir link order/test.json
new file mode 100644
index 0000000..a9d74fb
--- /dev/null
+++ b/test cases/frameworks/22 gir link order/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/23 hotdoc/doc/index.md b/test cases/frameworks/23 hotdoc/doc/index.md
new file mode 100644
index 0000000..ea5eeb1
--- /dev/null
+++ b/test cases/frameworks/23 hotdoc/doc/index.md
@@ -0,0 +1 @@
+# Hello world!
diff --git a/test cases/frameworks/23 hotdoc/doc/meson.build b/test cases/frameworks/23 hotdoc/doc/meson.build
new file mode 100644
index 0000000..a09bff0
--- /dev/null
+++ b/test cases/frameworks/23 hotdoc/doc/meson.build
@@ -0,0 +1,19 @@
+hotdoc = import('hotdoc')
+
+target = hotdoc.generate_doc(
+ 'foobar',
+ c_smart_index: true,
+ project_version: '0.1',
+ sitemap: 'sitemap.txt',
+ index: 'index.md',
+ c_sources: files('../../10 gtk-doc/include/foo.h'),
+ languages: ['c'],
+ install: true,
+)
+
+assert(target.config_path() == target.full_path() + '.json',
+ 'Hotdoc config paths do not match.'
+)
+
+assert(hotdoc.has_extensions('search') == true,
+ 'Extension "search" provided by hotdoc core should always be found')
diff --git a/test cases/frameworks/23 hotdoc/doc/sitemap.txt b/test cases/frameworks/23 hotdoc/doc/sitemap.txt
new file mode 100644
index 0000000..ba96be1
--- /dev/null
+++ b/test cases/frameworks/23 hotdoc/doc/sitemap.txt
@@ -0,0 +1,2 @@
+index.md
+ c-index
diff --git a/test cases/frameworks/23 hotdoc/meson.build b/test cases/frameworks/23 hotdoc/meson.build
new file mode 100644
index 0000000..64cd6da
--- /dev/null
+++ b/test cases/frameworks/23 hotdoc/meson.build
@@ -0,0 +1,14 @@
+project('hotdoc', 'c')
+
+hotdoc = find_program('hotdoc', required: false)
+if not hotdoc.found()
+ error('MESON_SKIP_TEST hotdoc not found.')
+endif
+
+subdir('doc')
+
+assert(hotdoc.has_extensions(['gi-extension']) == true,
+ 'GI extension should always be found.')
+
+assert(hotdoc.has_extensions(['gi-extension', 'no-way-you-exist-extension']) == false,
+ 'A hotdoc extension called "no-way-you-exist-extension" should never be found.')
diff --git a/test cases/frameworks/23 hotdoc/test.json b/test cases/frameworks/23 hotdoc/test.json
new file mode 100644
index 0000000..e13971e
--- /dev/null
+++ b/test cases/frameworks/23 hotdoc/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "dir", "file": "usr/share/doc/foobar/html"}
+ ],
+ "tools": {
+ "hotdoc": ">=0.1.0"
+ },
+ "skip_on_jobname": ["msys2"]
+}
diff --git a/test cases/frameworks/24 libgcrypt/libgcrypt_prog.c b/test cases/frameworks/24 libgcrypt/libgcrypt_prog.c
new file mode 100644
index 0000000..f131359
--- /dev/null
+++ b/test cases/frameworks/24 libgcrypt/libgcrypt_prog.c
@@ -0,0 +1,8 @@
+#include <gcrypt.h>
+
+int
+main()
+{
+ gcry_check_version(NULL);
+ return 0;
+}
diff --git a/test cases/frameworks/24 libgcrypt/meson.build b/test cases/frameworks/24 libgcrypt/meson.build
new file mode 100644
index 0000000..5aadb13
--- /dev/null
+++ b/test cases/frameworks/24 libgcrypt/meson.build
@@ -0,0 +1,23 @@
+project('libgcrypt test', 'c')
+
+wm = find_program('libgcrypt-config', required : false)
+if not wm.found()
+ error('MESON_SKIP_TEST: libgcrypt-config not installed')
+endif
+
+libgcrypt_dep = dependency('libgcrypt', version : '>= 1.0')
+libgcrypt_ver = libgcrypt_dep.version()
+assert(libgcrypt_ver.split('.').length() > 1, 'libgcrypt version is "@0@"'.format(libgcrypt_ver))
+message('libgcrypt version is "@0@"'.format(libgcrypt_ver))
+e = executable('libgcrypt_prog', 'libgcrypt_prog.c', dependencies : libgcrypt_dep)
+
+test('libgcrypttest', e)
+
+# Test using the method keyword:
+
+dependency('libgcrypt', method : 'config-tool')
+dependency('libgcrypt', method : 'pkg-config', required: false)
+
+# Check we can apply a version constraint
+dependency('libgcrypt', version: '>=@0@'.format(libgcrypt_dep.version()), method: 'pkg-config', required: false)
+dependency('libgcrypt', version: '>=@0@'.format(libgcrypt_dep.version()), method: 'config-tool')
diff --git a/test cases/frameworks/24 libgcrypt/test.json b/test cases/frameworks/24 libgcrypt/test.json
new file mode 100644
index 0000000..77b68c0
--- /dev/null
+++ b/test cases/frameworks/24 libgcrypt/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "msys2"]
+}
diff --git a/test cases/frameworks/25 hdf5/main.c b/test cases/frameworks/25 hdf5/main.c
new file mode 100644
index 0000000..4c46310
--- /dev/null
+++ b/test cases/frameworks/25 hdf5/main.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "hdf5.h"
+
+int main(void)
+{
+herr_t ier;
+unsigned maj, min, rel;
+
+ier = H5open();
+if (ier) {
+ fprintf(stderr,"Unable to initialize HDF5: %d\n", ier);
+ return EXIT_FAILURE;
+}
+
+ier = H5get_libversion(&maj, &min, &rel);
+if (ier) {
+ fprintf(stderr,"HDF5 did not initialize!\n");
+ return EXIT_FAILURE;
+}
+printf("C HDF5 version %d.%d.%d\n", maj, min, rel);
+
+ier = H5close();
+if (ier) {
+ fprintf(stderr,"Unable to close HDF5: %d\n", ier);
+ return EXIT_FAILURE;
+}
+return EXIT_SUCCESS;
+}
diff --git a/test cases/frameworks/25 hdf5/main.cpp b/test cases/frameworks/25 hdf5/main.cpp
new file mode 100644
index 0000000..477e76b
--- /dev/null
+++ b/test cases/frameworks/25 hdf5/main.cpp
@@ -0,0 +1,29 @@
+#include <iostream>
+#include "hdf5.h"
+
+
+int main(void)
+{
+herr_t ier;
+unsigned maj, min, rel;
+
+ier = H5open();
+if (ier) {
+ std::cerr << "Unable to initialize HDF5: " << ier << std::endl;
+ return EXIT_FAILURE;
+}
+
+ier = H5get_libversion(&maj, &min, &rel);
+if (ier) {
+ std::cerr << "HDF5 did not initialize!" << std::endl;
+ return EXIT_FAILURE;
+}
+std::cout << "C++ HDF5 version " << maj << "." << min << "." << rel << std::endl;
+
+ier = H5close();
+if (ier) {
+ std::cerr << "Unable to close HDF5: " << ier << std::endl;
+ return EXIT_FAILURE;
+}
+return EXIT_SUCCESS;
+}
diff --git a/test cases/frameworks/25 hdf5/main.f90 b/test cases/frameworks/25 hdf5/main.f90
new file mode 100644
index 0000000..45be146
--- /dev/null
+++ b/test cases/frameworks/25 hdf5/main.f90
@@ -0,0 +1,17 @@
+use hdf5
+
+implicit none
+
+integer :: ier, major, minor, rel
+
+call h5open_f(ier)
+if (ier /= 0) error stop 'Unable to initialize HDF5'
+
+call h5get_libversion_f(major, minor, rel, ier)
+if (ier /= 0) error stop 'Unable to check HDF5 version'
+print '(A,I1,A1,I0.2,A1,I1)','Fortran HDF5 version ',major,'.',minor,'.',rel
+
+call h5close_f(ier)
+if (ier /= 0) error stop 'Unable to close HDF5 library'
+
+end program
diff --git a/test cases/frameworks/25 hdf5/meson.build b/test cases/frameworks/25 hdf5/meson.build
new file mode 100644
index 0000000..0df2ffd
--- /dev/null
+++ b/test cases/frameworks/25 hdf5/meson.build
@@ -0,0 +1,47 @@
+project('hdf5_framework', 'c')
+
+# NOTE: all HDF5 languages must have HDF5 C library working.
+
+method = get_option('method')
+
+# --- C tests
+h5c = dependency('hdf5', language : 'c', required : false, method : method)
+if not h5c.found()
+ error('MESON_SKIP_TEST: HDF5 C library not found.')
+endif
+exec = executable('exec', 'main.c', dependencies : h5c)
+test('HDF5 C', exec, timeout: 30)
+
+# --- C++ tests
+if add_languages('cpp', required: false)
+ h5cpp = dependency('hdf5', language : 'cpp', required : false, disabler: true, method : method)
+ execpp = executable('execpp', 'main.cpp', dependencies : h5cpp)
+ test('HDF5 C++', execpp, timeout: 30)
+endif
+
+test_fortran = add_languages('fortran', required: false)
+
+if test_fortran
+ cpp = meson.get_compiler('cpp')
+ fc = meson.get_compiler('fortran')
+
+ if host_machine.system() == 'darwin' and cpp.get_id() == 'clang' and fc.get_id() == 'gcc'
+ # Search paths don't work correctly here and -lgfortran doesn't work
+ test_fortran = false
+ elif host_machine.system() == 'windows' and cpp.get_id() != 'gcc' and fc.get_id() == 'gcc'
+ # mixing gfotran with non-gcc doesn't work on windows
+ test_fortran = false
+ endif
+
+ # --- Fortran tests
+ if test_fortran
+ h5f = dependency('hdf5', language : 'fortran', required : false, disabler: true, method : method)
+ exef = executable('exef', 'main.f90', dependencies : h5f)
+ test('HDF5 Fortran', exef, timeout: 30)
+ endif
+endif
+
+# Check we can apply a version constraint
+if h5c.version() != 'unknown'
+ dependency('hdf5', version: '>=@0@'.format(h5c.version()))
+endif
diff --git a/test cases/frameworks/25 hdf5/meson_options.txt b/test cases/frameworks/25 hdf5/meson_options.txt
new file mode 100644
index 0000000..741f58e
--- /dev/null
+++ b/test cases/frameworks/25 hdf5/meson_options.txt
@@ -0,0 +1,6 @@
+option(
+ 'method',
+ type : 'combo',
+ choices : ['pkg-config', 'config-tool'],
+ value : 'pkg-config'
+)
diff --git a/test cases/frameworks/25 hdf5/test.json b/test cases/frameworks/25 hdf5/test.json
new file mode 100644
index 0000000..dd073ec
--- /dev/null
+++ b/test cases/frameworks/25 hdf5/test.json
@@ -0,0 +1,11 @@
+{
+ "matrix": {
+ "options": {
+ "method": [
+ { "val": "pkg-config", "skip_on_jobname": ["macos"] },
+ { "val": "config-tool" }
+ ]
+ }
+ },
+ "skip_on_jobname": ["azure", "cygwin", "fedora", "msys2", "opensuse"]
+}
diff --git a/test cases/frameworks/26 netcdf/main.c b/test cases/frameworks/26 netcdf/main.c
new file mode 100644
index 0000000..e592585
--- /dev/null
+++ b/test cases/frameworks/26 netcdf/main.c
@@ -0,0 +1,14 @@
+#include "netcdf.h"
+
+int main(void)
+{
+int ret, ncid;
+
+if ((ret = nc_create("foo.nc", NC_CLOBBER, &ncid)))
+ return ret;
+
+if ((ret = nc_close(ncid)))
+ return ret;
+
+return 0;
+}
diff --git a/test cases/frameworks/26 netcdf/main.cpp b/test cases/frameworks/26 netcdf/main.cpp
new file mode 100644
index 0000000..a3c98ef
--- /dev/null
+++ b/test cases/frameworks/26 netcdf/main.cpp
@@ -0,0 +1,15 @@
+#include <iostream>
+#include "netcdf.h"
+
+int main(void)
+{
+int ret, ncid;
+
+if ((ret = nc_create("foo.nc", NC_CLOBBER, &ncid)))
+ return ret;
+
+if ((ret = nc_close(ncid)))
+ return ret;
+
+return EXIT_SUCCESS;
+}
diff --git a/test cases/frameworks/26 netcdf/main.f90 b/test cases/frameworks/26 netcdf/main.f90
new file mode 100644
index 0000000..3872298
--- /dev/null
+++ b/test cases/frameworks/26 netcdf/main.f90
@@ -0,0 +1,19 @@
+use netcdf
+
+implicit none
+
+integer :: ncid
+
+call check( nf90_create("foo.nc", NF90_CLOBBER, ncid) )
+
+call check( nf90_close(ncid) )
+
+contains
+
+ subroutine check(status)
+ integer, intent (in) :: status
+
+ if(status /= nf90_noerr) error stop trim(nf90_strerror(status))
+end subroutine check
+
+end program
diff --git a/test cases/frameworks/26 netcdf/meson.build b/test cases/frameworks/26 netcdf/meson.build
new file mode 100644
index 0000000..0adc5e9
--- /dev/null
+++ b/test cases/frameworks/26 netcdf/meson.build
@@ -0,0 +1,36 @@
+project('netcdf_test', 'c')
+
+cc = meson.get_compiler('c')
+c_code = '''#include <netcdf.h>
+int main(void) { return 0; }'''
+# --- C
+nc_c = dependency('netcdf', language : 'c', required : false, disabler: true)
+if not cc.links(c_code, dependencies: nc_c, name: 'NetCDF C')
+ nc_c = disabler()
+endif
+if not nc_c.found()
+ error('MESON_SKIP_TEST: NetCDF C library not found, skipping NetCDF framework tests.')
+endif
+exec = executable('exec', 'main.c', dependencies : nc_c)
+test('NetCDF C', exec, timeout: 15)
+
+# --- C++
+if add_languages('cpp', required: false)
+ nc_cpp = dependency('netcdf', language : 'cpp', required : false, disabler: true)
+ execpp = executable('execpp', 'main.cpp', dependencies : nc_cpp)
+ test('NetCDF C++', execpp, timeout: 15)
+endif
+
+# --- Fortran
+if build_machine.system() != 'windows' and build_machine.system() != 'darwin'
+ if add_languages('fortran', required: false)
+ nc_f = dependency('netcdf', language : 'fortran', required : false, disabler: true)
+ exef = executable('exef', 'main.f90', dependencies : nc_f)
+ test('NetCDF Fortran', exef, timeout: 15)
+ endif
+endif
+
+# Check we can apply a version constraint
+if nc_c.version() != 'unknown'
+ dependency('netcdf', version: '>=@0@'.format(nc_c.version()))
+endif
diff --git a/test cases/frameworks/26 netcdf/test.json b/test cases/frameworks/26 netcdf/test.json
new file mode 100644
index 0000000..83c6291
--- /dev/null
+++ b/test cases/frameworks/26 netcdf/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "bionic", "cygwin", "fedora", "macos", "msys2", "opensuse", "ubuntu"]
+}
diff --git a/test cases/frameworks/27 gpgme/gpgme_prog.c b/test cases/frameworks/27 gpgme/gpgme_prog.c
new file mode 100644
index 0000000..594f685
--- /dev/null
+++ b/test cases/frameworks/27 gpgme/gpgme_prog.c
@@ -0,0 +1,8 @@
+#include <gpgme.h>
+
+int
+main()
+{
+ printf("gpgme-v%s", gpgme_check_version(NULL));
+ return 0;
+}
diff --git a/test cases/frameworks/27 gpgme/meson.build b/test cases/frameworks/27 gpgme/meson.build
new file mode 100644
index 0000000..91b1aaa
--- /dev/null
+++ b/test cases/frameworks/27 gpgme/meson.build
@@ -0,0 +1,27 @@
+project('gpgme test', 'c')
+
+wm = find_program('gpgme-config', required: false)
+if not wm.found()
+ error('MESON_SKIP_TEST: gpgme-config not installed')
+endif
+
+gpgme_dep = dependency('gpgme', version: '>= 1.0')
+gpgme_ver = gpgme_dep.version()
+assert(gpgme_ver.split('.').length() > 1, 'gpgme version is "@0@"'.format(gpgme_ver))
+message('gpgme version is "@0@"'.format(gpgme_ver))
+e = executable('gpgme_prog', 'gpgme_prog.c', dependencies: gpgme_dep)
+
+test('gpgmetest', e)
+
+# Test using the method keyword:
+
+dependency('gpgme', method: 'config-tool')
+
+# Check we can apply a version constraint
+dependency('gpgme', version: '>=@0@'.format(gpgme_dep.version()), method: 'config-tool')
+
+# If gpgme is new enough, make sure it picks up pkg-config by default:
+
+if gpgme_ver.version_compare('>=1.13.0')
+ assert(gpgme_dep.type_name() == 'pkgconfig', 'dependency found via pkg-config')
+endif
diff --git a/test cases/frameworks/27 gpgme/test.json b/test cases/frameworks/27 gpgme/test.json
new file mode 100644
index 0000000..aa7d932
--- /dev/null
+++ b/test cases/frameworks/27 gpgme/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2", "linux-arch"]
+}
diff --git a/test cases/frameworks/28 gir link order 2/meson-sample.c b/test cases/frameworks/28 gir link order 2/meson-sample.c
new file mode 100644
index 0000000..d743b2d
--- /dev/null
+++ b/test cases/frameworks/28 gir link order 2/meson-sample.c
@@ -0,0 +1,42 @@
+#include "meson-sample.h"
+
+struct _MesonSample {
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (MesonSample, meson_sample, G_TYPE_OBJECT)
+
+/**
+ * meson_sample_new:
+ *
+ * Allocates a new #MesonSample.
+ *
+ * Returns: (transfer full): a #MesonSample.
+ */
+MesonSample *
+meson_sample_new (void)
+{
+ return g_object_new (MESON_TYPE_SAMPLE, NULL);
+}
+
+static void
+meson_sample_class_init (MesonSampleClass *klass)
+{
+}
+
+static void
+meson_sample_init (MesonSample *self)
+{
+}
+
+/**
+ * meson_sample_print_message:
+ * @self: a #MesonSample.
+ *
+ * Prints a message.
+ */
+void
+meson_sample_print_message (MesonSample *self)
+{
+ g_return_if_fail (MESON_IS_SAMPLE (self));
+}
diff --git a/test cases/frameworks/28 gir link order 2/meson-sample.h b/test cases/frameworks/28 gir link order 2/meson-sample.h
new file mode 100644
index 0000000..2c28401
--- /dev/null
+++ b/test cases/frameworks/28 gir link order 2/meson-sample.h
@@ -0,0 +1,17 @@
+#ifndef MESON_SAMPLE_H
+#define MESON_SAMPLE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SAMPLE (meson_sample_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject)
+
+MesonSample *meson_sample_new (void);
+void meson_sample_print_message (MesonSample *self);
+
+G_END_DECLS
+
+#endif /* MESON_SAMPLE_H */
diff --git a/test cases/frameworks/28 gir link order 2/meson.build b/test cases/frameworks/28 gir link order 2/meson.build
new file mode 100644
index 0000000..a26531b
--- /dev/null
+++ b/test cases/frameworks/28 gir link order 2/meson.build
@@ -0,0 +1,35 @@
+project('gir link order 2', 'c')
+
+if not dependency('gobject-2.0', required : false).found() or not find_program('g-ir-scanner', required: false).found()
+ error('MESON_SKIP_TEST gobject not found.')
+endif
+
+gnome = import('gnome')
+gobject = dependency('gobject-2.0')
+
+# This builds a dummy libsample under samelibname that's not really used
+subdir('samelibname')
+
+# This builds the real libsample
+meson_sample_sources = ['meson-sample.c', 'meson-sample.h']
+meson_sample_lib = shared_library(
+ 'sample',
+ sources : meson_sample_sources,
+ dependencies : [gobject],
+ link_with: [samelibname],
+ install : false,
+)
+
+# g-ir-scanner should get the linker paths in the right order so it links first
+# against the target libsample and not the dummy one that's just a dependency
+# https://github.com/mesonbuild/meson/pull/5423
+gnome.generate_gir(
+ meson_sample_lib,
+ sources : meson_sample_sources,
+ nsversion : '1.0',
+ namespace : 'Meson',
+ symbol_prefix : 'meson',
+ identifier_prefix : 'Meson',
+ install : false,
+ build_by_default: true,
+)
diff --git a/test cases/frameworks/28 gir link order 2/samelibname/dummy.c b/test cases/frameworks/28 gir link order 2/samelibname/dummy.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/28 gir link order 2/samelibname/dummy.c
diff --git a/test cases/frameworks/28 gir link order 2/samelibname/meson.build b/test cases/frameworks/28 gir link order 2/samelibname/meson.build
new file mode 100644
index 0000000..dd923d7
--- /dev/null
+++ b/test cases/frameworks/28 gir link order 2/samelibname/meson.build
@@ -0,0 +1,5 @@
+samelibname = shared_library(
+ 'sample',
+ sources : 'dummy.c',
+ install : false,
+)
diff --git a/test cases/frameworks/28 gir link order 2/test.json b/test cases/frameworks/28 gir link order 2/test.json
new file mode 100644
index 0000000..a9d74fb
--- /dev/null
+++ b/test cases/frameworks/28 gir link order 2/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/29 blocks/main.c b/test cases/frameworks/29 blocks/main.c
new file mode 100644
index 0000000..e5ae589
--- /dev/null
+++ b/test cases/frameworks/29 blocks/main.c
@@ -0,0 +1,6 @@
+int main(int argc, char **argv)
+{
+ int (^callback)(void) = ^ int (void) { return 0; };
+
+ return callback();
+}
diff --git a/test cases/frameworks/29 blocks/meson.build b/test cases/frameworks/29 blocks/meson.build
new file mode 100644
index 0000000..398c92c
--- /dev/null
+++ b/test cases/frameworks/29 blocks/meson.build
@@ -0,0 +1,12 @@
+project('blocks-dependency', 'c')
+
+id = meson.get_compiler('c').get_id()
+if id != 'clang' or build_machine.system() == 'windows'
+ error('MESON_SKIP_TEST: Only clang on unix-like systems supports the blocks extension.')
+endif
+
+exe = executable('main', 'main.c',
+ dependencies: dependency('blocks')
+)
+
+test('test-blocks', exe)
diff --git a/test cases/frameworks/29 blocks/test.json b/test cases/frameworks/29 blocks/test.json
new file mode 100644
index 0000000..34a8c41
--- /dev/null
+++ b/test cases/frameworks/29 blocks/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "gcc", "msys2"]
+}
diff --git a/test cases/frameworks/3 gmock/gmocktest.cc b/test cases/frameworks/3 gmock/gmocktest.cc
new file mode 100644
index 0000000..a8bd2d3
--- /dev/null
+++ b/test cases/frameworks/3 gmock/gmocktest.cc
@@ -0,0 +1,27 @@
+#include<gtest/gtest.h>
+#include<gmock/gmock.h>
+
+using ::testing::Return;
+
+class Foo {
+public:
+ Foo() { x = 42; }
+ virtual ~Foo() {};
+
+ virtual int getValue() const { return x; }
+
+private:
+ int x;
+};
+
+class MockFoo : public Foo {
+public:
+ MOCK_CONST_METHOD0(getValue, int());
+};
+
+TEST(counttest, once) {
+ MockFoo f;
+ EXPECT_CALL(f, getValue()).Times(1).WillOnce(Return(42));
+
+ EXPECT_EQ(f.getValue(), 42) << "Got wrong value";
+}
diff --git a/test cases/frameworks/3 gmock/meson.build b/test cases/frameworks/3 gmock/meson.build
new file mode 100644
index 0000000..58591ae
--- /dev/null
+++ b/test cases/frameworks/3 gmock/meson.build
@@ -0,0 +1,16 @@
+project('gmock test', 'cpp')
+
+# Using gmock without gtest is a pain so just
+# don't support that then.
+
+gtest = dependency('gtest', main : true, required : false, method : 'system')
+if not gtest.found()
+ error('MESON_SKIP_TEST: gtest not installed.')
+endif
+gmock = dependency('gmock', required : false)
+if not gmock.found()
+ error('MESON_SKIP_TEST: gmock not installed.')
+endif
+
+e = executable('gmocktest', 'gmocktest.cc', dependencies : [gtest, gmock])
+test('gmock test', e)
diff --git a/test cases/frameworks/3 gmock/test.json b/test cases/frameworks/3 gmock/test.json
new file mode 100644
index 0000000..6ace9de
--- /dev/null
+++ b/test cases/frameworks/3 gmock/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake b/test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake
new file mode 100644
index 0000000..17f4b3b
--- /dev/null
+++ b/test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake
@@ -0,0 +1,220 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+
+FindSCALAPACK
+-------------
+
+* Michael Hirsch, Ph.D. www.scivision.dev
+
+Let Michael know if there are more MKL / Lapack / compiler combination you want.
+Refer to https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor
+
+Finds SCALAPACK libraries for MKL, OpenMPI and MPICH.
+Intel MKL relies on having environment variable MKLROOT set, typically by sourcing
+mklvars.sh beforehand.
+
+Parameters
+^^^^^^^^^^
+
+``MKL``
+ Intel MKL for MSVC, ICL, ICC, GCC and PGCC. Working with IntelMPI (default Window, Linux), MPICH (default Mac) or OpenMPI (Linux only).
+
+``IntelMPI``
+ MKL BLACS IntelMPI
+
+``MKL64``
+ MKL only: 64-bit integers (default is 32-bit integers)
+
+``OpenMPI``
+ SCALAPACK + OpenMPI
+
+``MPICH``
+ SCALAPACK + MPICH
+
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``SCALAPACK_FOUND``
+ SCALapack libraries were found
+``SCALAPACK_<component>_FOUND``
+ SCALAPACK <component> specified was found
+``SCALAPACK_LIBRARIES``
+ SCALapack library files
+``SCALAPACK_INCLUDE_DIRS``
+ SCALapack include directories
+
+
+References
+^^^^^^^^^^
+
+* Pkg-Config and MKL: https://software.intel.com/en-us/articles/intel-math-kernel-library-intel-mkl-and-pkg-config-tool
+* MKL for Windows: https://software.intel.com/en-us/mkl-windows-developer-guide-static-libraries-in-the-lib-intel64-win-directory
+* MKL Windows directories: https://software.intel.com/en-us/mkl-windows-developer-guide-high-level-directory-structure
+#]=======================================================================]
+
+#===== functions
+function(mkl_scala)
+
+set(_mkl_libs ${ARGV})
+
+foreach(s ${_mkl_libs})
+ find_library(SCALAPACK_${s}_LIBRARY
+ NAMES ${s}
+ PATHS ENV MKLROOT ENV I_MPI_ROOT ENV TBBROOT
+ PATH_SUFFIXES
+ lib/intel64 lib/intel64_win
+ intel64/lib/release
+ lib/intel64/gcc4.7 ../tbb/lib/intel64/gcc4.7
+ lib/intel64/vc_mt ../tbb/lib/intel64/vc_mt
+ ../compiler/lib/intel64
+ HINTS ${MKL_LIBRARY_DIRS} ${MKL_LIBDIR}
+ NO_DEFAULT_PATH)
+ if(NOT SCALAPACK_${s}_LIBRARY)
+ message(WARNING "MKL component not found: " ${s})
+ return()
+ endif()
+
+ list(APPEND SCALAPACK_LIB ${SCALAPACK_${s}_LIBRARY})
+endforeach()
+
+
+find_path(SCALAPACK_INCLUDE_DIR
+ NAMES mkl_scalapack.h
+ PATHS ENV MKLROOT ENV I_MPI_ROOT ENV TBBROOT
+ PATH_SUFFIXES
+ include
+ include/intel64/${_mkl_bitflag}lp64
+ HINTS ${MKL_INCLUDE_DIRS})
+
+if(NOT SCALAPACK_INCLUDE_DIR)
+ message(WARNING "MKL Include Dir not found")
+ return()
+endif()
+
+list(APPEND SCALAPACK_INCLUDE_DIR
+ ${MKL_INCLUDE_DIRS})
+
+set(SCALAPACK_LIBRARY ${SCALAPACK_LIB} PARENT_SCOPE)
+set(SCALAPACK_INCLUDE_DIR ${SCALAPACK_INCLUDE_DIR} PARENT_SCOPE)
+
+endfunction(mkl_scala)
+
+#==== main program
+
+cmake_policy(VERSION 3.11)
+
+if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
+ cmake_policy(SET CMP0074 NEW)
+ cmake_policy(SET CMP0075 NEW)
+endif()
+
+if(NOT (OpenMPI IN_LIST SCALAPACK_FIND_COMPONENTS
+ OR MPICH IN_LIST SCALAPACK_FIND_COMPONENTS
+ OR MKL IN_LIST SCALAPACK_FIND_COMPONENTS))
+ if(DEFINED ENV{MKLROOT})
+ if(APPLE)
+ list(APPEND SCALAPACK_FIND_COMPONENTS MKL MPICH)
+ else()
+ list(APPEND SCALAPACK_FIND_COMPONENTS MKL IntelMPI)
+ endif()
+ else()
+ list(APPEND SCALAPACK_FIND_COMPONENTS OpenMPI)
+ endif()
+endif()
+
+find_package(PkgConfig)
+
+if(NOT WIN32)
+ find_package(Threads) # not required--for example Flang
+endif()
+
+if(MKL IN_LIST SCALAPACK_FIND_COMPONENTS)
+
+ if(BUILD_SHARED_LIBS)
+ set(_mkltype dynamic)
+ else()
+ set(_mkltype static)
+ endif()
+
+ if(MKL64 IN_LIST SCALAPACK_FIND_COMPONENTS)
+ set(_mkl_bitflag i)
+ else()
+ set(_mkl_bitflag)
+ endif()
+
+
+ if(WIN32)
+ set(_impi impi)
+ else()
+ unset(_impi)
+ endif()
+
+
+ pkg_check_modules(MKL mkl-${_mkltype}-${_mkl_bitflag}lp64-iomp)
+
+ if(OpenMPI IN_LIST SCALAPACK_FIND_COMPONENTS)
+ mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_openmpi_${_mkl_bitflag}lp64)
+ if(SCALAPACK_LIBRARY)
+ set(SCALAPACK_OpenMPI_FOUND true)
+ endif()
+ elseif(MPICH IN_LIST SCALAPACK_FIND_COMPONENTS)
+ if(APPLE)
+ mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_mpich_${_mkl_bitflag}lp64)
+ elseif(WIN32)
+ mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_mpich2_${_mkl_bitflag}lp64.lib mpi.lib fmpich2.lib)
+ else() # linux, yes it's just like IntelMPI
+ mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_intelmpi_${_mkl_bitflag}lp64)
+ endif()
+ if(SCALAPACK_LIBRARY)
+ set(SCALAPACK_MPICH_FOUND true)
+ endif()
+ else() # IntelMPI
+ mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_intelmpi_${_mkl_bitflag}lp64 ${_impi})
+ if(SCALAPACK_LIBRARY)
+ set(SCALAPACK_IntelMPI_FOUND true)
+ endif()
+ endif()
+
+ if(SCALAPACK_LIBRARY)
+ set(SCALAPACK_MKL_FOUND true)
+ endif()
+
+elseif(OpenMPI IN_LIST SCALAPACK_FIND_COMPONENTS)
+
+ pkg_check_modules(SCALAPACK scalapack-openmpi)
+
+ find_library(SCALAPACK_LIBRARY
+ NAMES scalapack scalapack-openmpi
+ HINTS ${SCALAPACK_LIBRARY_DIRS} ${SCALAPACK_LIBDIR})
+
+ if(SCALAPACK_LIBRARY)
+ set(SCALAPACK_OpenMPI_FOUND true)
+ endif()
+
+elseif(MPICH IN_LIST SCALAPACK_FIND_COMPONENTS)
+ find_library(SCALAPACK_LIBRARY
+ NAMES scalapack-mpich scalapack-mpich2)
+
+ if(SCALAPACK_LIBRARY)
+ set(SCALAPACK_MPICH_FOUND true)
+ endif()
+
+endif()
+
+# Finalize
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ SCALAPACK
+ REQUIRED_VARS SCALAPACK_LIBRARY
+ HANDLE_COMPONENTS)
+
+if(SCALAPACK_FOUND)
+ set(SCALAPACK_LIBRARIES ${SCALAPACK_LIBRARY})
+ set(SCALAPACK_INCLUDE_DIRS ${SCALAPACK_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(SCALAPACK_LIBRARY SCALAPACK_INCLUDE_DIR)
diff --git a/test cases/frameworks/30 scalapack/main.c b/test cases/frameworks/30 scalapack/main.c
new file mode 100644
index 0000000..ca01977
--- /dev/null
+++ b/test cases/frameworks/30 scalapack/main.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+// #include <mkl.h>
+// #include <mkl_scalapack.h>
+// #include <mkl_blacs.h>
+
+extern float pslamch_(const int *, const char *);
+extern void blacs_pinfo_(int *, int *);
+extern void blacs_get_(const int *, const int *, int *);
+extern void blacs_gridinit_(int *, const char *, const int *, const int *);
+extern void blacs_gridinfo_(const int *, int *, int *, int *, int *);
+extern void blacs_gridexit_(const int *);
+extern void blacs_exit_(const int *);
+
+int main(void){
+
+int myid, nprocs, ictxt, mycol, myrow, npcol=2, nprow=2;
+const int i0=0, i1=1, in1=-1;
+
+blacs_pinfo_(&myid, &nprocs);
+blacs_get_(&in1, &i0, &ictxt);
+blacs_gridinit_(&ictxt, "C", &nprocs, &i1);
+
+blacs_gridinfo_(&ictxt, &nprow, &npcol, &myrow, &mycol);
+
+float eps = pslamch_(&ictxt, "E");
+
+if (myrow == mycol) printf("OK: Scalapack C: eps= %f\n", eps);
+
+blacs_gridexit_(&ictxt);
+blacs_exit_(&i0);
+
+return 0;
+} \ No newline at end of file
diff --git a/test cases/frameworks/30 scalapack/main.f90 b/test cases/frameworks/30 scalapack/main.f90
new file mode 100644
index 0000000..53b5fb9
--- /dev/null
+++ b/test cases/frameworks/30 scalapack/main.f90
@@ -0,0 +1,25 @@
+! minimal Scalapack demo
+implicit none
+
+integer :: ictxt, myid, nprocs, mycol, myrow, npcol, nprow
+real :: eps
+real, external :: pslamch
+
+! arbitrary test parameters
+npcol = 2
+nprow = 2
+
+call blacs_pinfo(myid, nprocs)
+call blacs_get(-1, 0, ictxt)
+call blacs_gridinit(ictxt, "C", nprocs, 1)
+
+call blacs_gridinfo(ictxt, nprow, npcol, myrow, mycol)
+
+eps = pslamch(ictxt, 'E')
+
+if(myrow == mycol) print '(A, F10.6)', "OK: Scalapack Fortran eps=", eps
+
+call blacs_gridexit(ictxt)
+call blacs_exit(0)
+
+end program
diff --git a/test cases/frameworks/30 scalapack/meson.build b/test cases/frameworks/30 scalapack/meson.build
new file mode 100644
index 0000000..165cb30
--- /dev/null
+++ b/test cases/frameworks/30 scalapack/meson.build
@@ -0,0 +1,26 @@
+project('test scalapack', 'c')
+
+mpi_c = dependency('mpi', language: 'c', required: false)
+if not mpi_c.found()
+ error('MESON_SKIP_TEST: MPI library not available')
+endif
+
+scalapack = dependency('scalapack', required: false)
+if not scalapack.found()
+ error('MESON_SKIP_TEST: scalapack library not available')
+endif
+
+c_exe = executable('scalapack_c', 'main.c',
+ dependencies: [scalapack, mpi_c])
+test('scalapack_c', c_exe, timeout: 30)
+
+if add_languages('fortran', required: false)
+ mpi_f = dependency('mpi', language: 'fortran', required: false)
+ if not mpi_f.found()
+ error('MESON_SKIP_TEST: MPI Fortran library not available')
+ endif
+
+ f_exe = executable('scalapack_fortran', 'main.f90',
+ dependencies: [scalapack, mpi_f])
+ test('scalapack_fortran', f_exe, timeout: 30)
+endif
diff --git a/test cases/frameworks/30 scalapack/test.json b/test cases/frameworks/30 scalapack/test.json
new file mode 100644
index 0000000..0c40573
--- /dev/null
+++ b/test cases/frameworks/30 scalapack/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "bionic", "cygwin", "fedora", "msys2", "opensuse"]
+}
diff --git a/test cases/frameworks/31 curses/main.c b/test cases/frameworks/31 curses/main.c
new file mode 100644
index 0000000..07d73f5
--- /dev/null
+++ b/test cases/frameworks/31 curses/main.c
@@ -0,0 +1,7 @@
+#include "curses.h"
+
+int main(void) {
+initscr();
+endwin();
+return 0;
+} \ No newline at end of file
diff --git a/test cases/frameworks/31 curses/meson.build b/test cases/frameworks/31 curses/meson.build
new file mode 100644
index 0000000..796a0d8
--- /dev/null
+++ b/test cases/frameworks/31 curses/meson.build
@@ -0,0 +1,13 @@
+project('curses', 'c')
+
+curses = dependency('curses', required: false, method : get_option('method'), version : '>= 0')
+if not curses.found()
+ error('MESON_SKIP_TEST: Curses library not found')
+endif
+
+exec = executable('basic', 'main.c', dependencies: curses)
+# didn't run the test because in general graphics fail on CI
+
+# this should fail
+not_found = dependency('curses', required: false, method : get_option('method'), version : '> 1000000')
+assert(not_found.found() == false)
diff --git a/test cases/frameworks/31 curses/meson_options.txt b/test cases/frameworks/31 curses/meson_options.txt
new file mode 100644
index 0000000..e294e83
--- /dev/null
+++ b/test cases/frameworks/31 curses/meson_options.txt
@@ -0,0 +1,6 @@
+option(
+ 'method',
+ type : 'combo',
+ choices : ['pkg-config', 'config-tool', 'system'],
+ value : 'pkg-config',
+)
diff --git a/test cases/frameworks/31 curses/test.json b/test cases/frameworks/31 curses/test.json
new file mode 100644
index 0000000..03ed3a2
--- /dev/null
+++ b/test cases/frameworks/31 curses/test.json
@@ -0,0 +1,12 @@
+{
+ "matrix": {
+ "options": {
+ "method": [
+ { "val": "pkg-config" },
+ { "val": "config-tool", "skip_on_jobname": ["msys2"] },
+ { "val": "system", "skip_on_os": ["windows"] }
+ ]
+ }
+ },
+ "skip_on_jobname": ["azure", "cygwin"]
+}
diff --git a/test cases/frameworks/32 boost root/boost/include/boost/version.hpp b/test cases/frameworks/32 boost root/boost/include/boost/version.hpp
new file mode 100644
index 0000000..65e4fab
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/include/boost/version.hpp
@@ -0,0 +1,3 @@
+#define BOOST_VERSION 100
+
+#error This is not a real version of boost
diff --git a/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x32-0_1.lib
diff --git a/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/lib/boost_regex-vc142-mt-gd-x64-0_1.lib
diff --git a/test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.0 b/test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/32 boost root/boost/lib/libboost_regex.so.0.1.0
diff --git a/test cases/frameworks/32 boost root/meson.build b/test cases/frameworks/32 boost root/meson.build
new file mode 100644
index 0000000..50d2f0d
--- /dev/null
+++ b/test cases/frameworks/32 boost root/meson.build
@@ -0,0 +1,6 @@
+project('boosttest', 'cpp')
+
+dep = dependency('boost', modules : 'regex', required: false)
+
+assert(dep.found(), 'expected to find a fake version of boost')
+assert(dep.version() == '0.1.0', 'expected to find version 0.1.0')
diff --git a/test cases/frameworks/32 boost root/nativefile.ini.in b/test cases/frameworks/32 boost root/nativefile.ini.in
new file mode 100644
index 0000000..54510d7
--- /dev/null
+++ b/test cases/frameworks/32 boost root/nativefile.ini.in
@@ -0,0 +1,2 @@
+[properties]
+boost_root = '@MESON_TEST_ROOT@/boost'
diff --git a/test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp b/test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp
new file mode 100644
index 0000000..3ba19ee
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/extra-dir/include/boost/version.hpp
@@ -0,0 +1,3 @@
+#define BOOST_VERSION 200
+
+#error This is not a real version of boost
diff --git a/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x32-0_2.lib
diff --git a/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/lib/boost_regex-vc142-mt-gd-x64-0_2.lib
diff --git a/test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.0 b/test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/boost/lib/libboost_regex.so.0.2.0
diff --git a/test cases/frameworks/33 boost split root/meson.build b/test cases/frameworks/33 boost split root/meson.build
new file mode 100644
index 0000000..a2353bb
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/meson.build
@@ -0,0 +1,6 @@
+project('boosttest', 'cpp')
+
+dep = dependency('boost', modules : 'regex', required: false)
+
+assert(dep.found(), 'expected to find a fake version of boost')
+assert(dep.version() == '0.2.0', 'expected to find version 0.2.0')
diff --git a/test cases/frameworks/33 boost split root/nativefile.ini.in b/test cases/frameworks/33 boost split root/nativefile.ini.in
new file mode 100644
index 0000000..7bd5ac2
--- /dev/null
+++ b/test cases/frameworks/33 boost split root/nativefile.ini.in
@@ -0,0 +1,3 @@
+[properties]
+boost_includedir = '@MESON_TEST_ROOT@/boost/extra-dir/include'
+boost_librarydir = '@MESON_TEST_ROOT@/boost/lib'
diff --git a/test cases/frameworks/34 gir static lib/meson.build b/test cases/frameworks/34 gir static lib/meson.build
new file mode 100644
index 0000000..d7ab9bf
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/meson.build
@@ -0,0 +1,18 @@
+project('gobject-introspection-static-helper', 'c')
+
+gir = find_program('g-ir-scanner', required: false)
+if not gir.found()
+ error('MESON_SKIP_TEST g-ir-scanner not found.')
+endif
+
+gobject_introspection = dependency('gobject-introspection-1.0')
+# This won't work without https://gitlab.gnome.org/GNOME/gobject-introspection/merge_requests/72
+if gobject_introspection.version().version_compare('< 1.58.1')
+ error('MESON_SKIP_TEST gobject-introspection is too old to support static libraries')
+endif
+
+gnome = import('gnome')
+gobj = dependency('gobject-2.0')
+
+subdir('statichelper')
+subdir('subdir/gir')
diff --git a/test cases/frameworks/34 gir static lib/statichelper/meson-sample.c b/test cases/frameworks/34 gir static lib/statichelper/meson-sample.c
new file mode 100644
index 0000000..2ed9cdf
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/statichelper/meson-sample.c
@@ -0,0 +1,126 @@
+#include "meson-sample.h"
+
+typedef struct _MesonSamplePrivate
+{
+ gchar *msg;
+} MesonSamplePrivate;
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (MesonSample, meson_sample, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_sample_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonSample.
+ *
+ * Returns: (transfer full): a #MesonSample.
+ */
+MesonSample *
+meson_sample_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_SAMPLE,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_sample_finalize (GObject *object)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ g_clear_pointer (&priv->msg, g_free);
+
+ G_OBJECT_CLASS (meson_sample_parent_class)->finalize (object);
+}
+
+static void
+meson_sample_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, priv->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ priv->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_class_init (MesonSampleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_sample_finalize;
+ object_class->get_property = meson_sample_get_property;
+ object_class->set_property = meson_sample_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_sample_init (MesonSample *self)
+{
+}
+
+/**
+ * meson_sample_print_message:
+ * @self: a #MesonSample.
+ *
+ * Prints the message.
+ *
+ */
+void
+meson_sample_print_message (MesonSample *self)
+{
+ MesonSamplePrivate *priv;
+
+ g_return_if_fail (MESON_IS_SAMPLE (self));
+
+ priv = meson_sample_get_instance_private (self);
+
+ g_print ("Message: %s\n", priv->msg);
+}
diff --git a/test cases/frameworks/34 gir static lib/statichelper/meson-sample.h.in b/test cases/frameworks/34 gir static lib/statichelper/meson-sample.h.in
new file mode 100644
index 0000000..d0ab29e
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/statichelper/meson-sample.h.in
@@ -0,0 +1,22 @@
+#ifndef MESON_SAMPLE_H
+#define MESON_SAMPLE_H
+
+#include <@HEADER@>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SAMPLE (meson_sample_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject)
+
+struct _MesonSampleClass {
+ GObjectClass parent_class;
+};
+
+
+MesonSample *meson_sample_new (const gchar *msg);
+void meson_sample_print_message (MesonSample *self);
+
+G_END_DECLS
+
+#endif /* MESON_SAMPLE_H */
diff --git a/test cases/frameworks/34 gir static lib/statichelper/meson.build b/test cases/frameworks/34 gir static lib/statichelper/meson.build
new file mode 100644
index 0000000..a815372
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/statichelper/meson.build
@@ -0,0 +1,22 @@
+conf = configuration_data()
+conf.set('HEADER', 'glib-object.h')
+
+meson_sample_header = configure_file(
+ input : 'meson-sample.h.in',
+ output : 'meson-sample.h',
+ configuration : conf)
+
+statichelper_sources = files('meson-sample.c') + [meson_sample_header]
+
+statichelper_lib = static_library(
+ 'statichelper',
+ sources : statichelper_sources,
+ dependencies : gobj,
+)
+
+statichelper_inc = include_directories('.')
+statichelper_dep = declare_dependency(
+ link_with: statichelper_lib,
+ dependencies : gobj,
+ include_directories : [statichelper_inc],
+)
diff --git a/test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.c b/test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.c
new file mode 100644
index 0000000..2d58a10
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.c
@@ -0,0 +1,124 @@
+#include "meson-subsample.h"
+
+struct _MesonSubSample
+{
+ MesonSample parent_instance;
+
+ gchar *msg;
+};
+
+G_DEFINE_TYPE (MesonSubSample, meson_sub_sample, MESON_TYPE_SAMPLE)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_sub_sample_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonSubSample.
+ *
+ * Returns: (transfer full): a #MesonSubSample.
+ */
+MesonSubSample *
+meson_sub_sample_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_SUB_SAMPLE,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_sub_sample_finalize (GObject *object)
+{
+ MesonSubSample *self = (MesonSubSample *)object;
+
+ g_clear_pointer (&self->msg, g_free);
+
+ G_OBJECT_CLASS (meson_sub_sample_parent_class)->finalize (object);
+}
+
+static void
+meson_sub_sample_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSubSample *self = MESON_SUB_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, self->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sub_sample_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSubSample *self = MESON_SUB_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ self->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sub_sample_class_init (MesonSubSampleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_sub_sample_finalize;
+ object_class->get_property = meson_sub_sample_get_property;
+ object_class->set_property = meson_sub_sample_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_sub_sample_init (MesonSubSample *self)
+{
+}
+
+/**
+ * meson_sub_sample_print_message:
+ * @self: a #MesonSubSample.
+ *
+ * Prints the message.
+ *
+ * Returns: Nothing.
+ */
+void
+meson_sub_sample_print_message (MesonSubSample *self)
+{
+ g_return_if_fail (MESON_IS_SUB_SAMPLE (self));
+
+ g_print ("Message: %s\n", self->msg);
+}
diff --git a/test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.h b/test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.h
new file mode 100644
index 0000000..9d34a08
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/subdir/gir/meson-subsample.h
@@ -0,0 +1,17 @@
+#ifndef MESON_SUB_SAMPLE_H
+#define MESON_SUB_SAMPLE_H
+
+#include <glib-object.h>
+#include <meson-sample.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SUB_SAMPLE (meson_sub_sample_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonSubSample, meson_sub_sample, MESON, SUB_SAMPLE, MesonSample)
+
+MesonSubSample *meson_sub_sample_new (const gchar *msg);
+
+G_END_DECLS
+
+#endif /* MESON_SUB_SAMPLE_H */
diff --git a/test cases/frameworks/34 gir static lib/subdir/gir/meson.build b/test cases/frameworks/34 gir static lib/subdir/gir/meson.build
new file mode 100644
index 0000000..b26f04e
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/subdir/gir/meson.build
@@ -0,0 +1,28 @@
+libsources = ['meson-subsample.c', 'meson-subsample.h']
+
+girlib = shared_library(
+ 'girlib',
+ sources : libsources,
+ dependencies : [gobj, statichelper_dep],
+ install : true
+)
+
+girexe = executable(
+ 'girprog',
+ sources : 'prog.c',
+ dependencies : [gobj, statichelper_dep],
+ link_with : girlib
+)
+
+gnome.generate_gir(
+ girlib, statichelper_lib,
+ sources : [ libsources, statichelper_sources ],
+ nsversion : '1.0',
+ namespace : 'Meson',
+ symbol_prefix : 'meson_',
+ identifier_prefix : 'Meson',
+ includes : ['GObject-2.0'],
+ install : true
+)
+
+test('gobject introspection/subproject/c', girexe)
diff --git a/test cases/frameworks/34 gir static lib/subdir/gir/prog.c b/test cases/frameworks/34 gir static lib/subdir/gir/prog.c
new file mode 100644
index 0000000..f25c9d8
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/subdir/gir/prog.c
@@ -0,0 +1,12 @@
+#include "meson-subsample.h"
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ MesonSample * i = (MesonSample*) meson_sub_sample_new ("Hello, sub/meson/c!");
+ meson_sample_print_message (i);
+ g_object_unref (i);
+
+ return 0;
+}
diff --git a/test cases/frameworks/34 gir static lib/test.json b/test cases/frameworks/34 gir static lib/test.json
new file mode 100644
index 0000000..8d7f707
--- /dev/null
+++ b/test cases/frameworks/34 gir static lib/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"},
+ {"type": "expr", "file": "usr/lib/?libgirlib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirlib.dll.a"},
+ {"type": "file", "file": "usr/share/gir-1.0/Meson-1.0.gir"}
+ ],
+ "skip_on_jobname": ["azure", "bionic", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x32-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x32-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x32-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x64-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x64-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/boost_python-vc142-mt-gd-x64-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/libboost_python.so.0.3.0 b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/libboost_python.so.0.3.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost-python/0.3.0/lib/libboost_python.so.0.3.0
diff --git a/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/include/boost/version.hpp b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/include/boost/version.hpp
new file mode 100644
index 0000000..77d9948
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/include/boost/version.hpp
@@ -0,0 +1,3 @@
+#define BOOST_VERSION 300
+
+#error This is not a real version of boost
diff --git a/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x32-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x32-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x32-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x64-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x64-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/boost_regex-vc142-mt-gd-x64-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/libboost_regex.so.0.3.0 b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/libboost_regex.so.0.3.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/Cellar/boost/0.3.0/lib/libboost_regex.so.0.3.0
diff --git a/test cases/frameworks/35 boost symlinks/boost/include/boost/version.hpp b/test cases/frameworks/35 boost symlinks/boost/include/boost/version.hpp
new file mode 100644
index 0000000..77d9948
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/include/boost/version.hpp
@@ -0,0 +1,3 @@
+#define BOOST_VERSION 300
+
+#error This is not a real version of boost
diff --git a/test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x32-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x32-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x32-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x64-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x64-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/lib/boost_python-vc142-mt-gd-x64-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x32-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x32-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x32-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x64-0_3.lib b/test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x64-0_3.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/lib/boost_regex-vc142-mt-gd-x64-0_3.lib
diff --git a/test cases/frameworks/35 boost symlinks/boost/lib/libboost_python.so.0.3.0 b/test cases/frameworks/35 boost symlinks/boost/lib/libboost_python.so.0.3.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/lib/libboost_python.so.0.3.0
diff --git a/test cases/frameworks/35 boost symlinks/boost/lib/libboost_regex.so.0.3.0 b/test cases/frameworks/35 boost symlinks/boost/lib/libboost_regex.so.0.3.0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/boost/lib/libboost_regex.so.0.3.0
diff --git a/test cases/frameworks/35 boost symlinks/meson.build b/test cases/frameworks/35 boost symlinks/meson.build
new file mode 100644
index 0000000..b49a143
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/meson.build
@@ -0,0 +1,6 @@
+project('boosttestsymlinks', 'cpp')
+
+dep = dependency('boost', modules : ['regex', 'python'], required: false)
+
+assert(dep.found(), 'expected to find a fake version of boost')
+assert(dep.version() == '0.3.0', 'expected to find version 0.3.0')
diff --git a/test cases/frameworks/35 boost symlinks/nativefile.ini.in b/test cases/frameworks/35 boost symlinks/nativefile.ini.in
new file mode 100644
index 0000000..54510d7
--- /dev/null
+++ b/test cases/frameworks/35 boost symlinks/nativefile.ini.in
@@ -0,0 +1,2 @@
+[properties]
+boost_root = '@MESON_TEST_ROOT@/boost'
diff --git a/test cases/frameworks/4 qt/main.cpp b/test cases/frameworks/4 qt/main.cpp
new file mode 100644
index 0000000..3c141b9
--- /dev/null
+++ b/test cases/frameworks/4 qt/main.cpp
@@ -0,0 +1,55 @@
+#include <QApplication>
+#include <QTranslator>
+#include <QDebug>
+#include "mainWindow.h"
+
+#if QT_VERSION > 0x050000
+// include some random private headers
+// As you're not supposed to use it, your system may miss
+// qobject_p.h. To locate it try one of these commands:
+// - dnf provides */private/qobject_p.h
+// - apt-file search qobject_p.h
+ #include <private/qobject_p.h>
+#endif
+
+int main(int argc, char **argv) {
+ #ifndef UNITY_BUILD
+ Q_INIT_RESOURCE(stuff);
+ Q_INIT_RESOURCE(stuff2);
+ #endif
+ QApplication app(argc, argv);
+
+ auto *translator = new QTranslator;
+ if (translator->load(QLocale(), QT "embedded", "_", ":/lang"))
+ qApp->installTranslator(translator);
+
+ qDebug() << QObject::tr("Translate me!");
+
+ MainWindow *win = new MainWindow();
+ QImage qi(":/thing.png");
+ if(qi.width() != 640) {
+ return 1;
+ }
+ QImage qi2(":/thing2.png");
+ if(qi2.width() != 640) {
+ return 1;
+ }
+ win->setWindowTitle("Meson Qt5 build test");
+ QLabel *label_stuff = win->findChild<QLabel *>("label_stuff");
+ if(label_stuff == nullptr) {
+ return 1;
+ }
+ int w = label_stuff->width();
+ int h = label_stuff->height();
+ label_stuff->setPixmap(QPixmap::fromImage(qi).scaled(w,h,Qt::KeepAspectRatio));
+ QLabel *label_stuff2 = win->findChild<QLabel *>("label_stuff2");
+ if(label_stuff2 == nullptr) {
+ return 1;
+ }
+ w = label_stuff2->width();
+ h = label_stuff2->height();
+ label_stuff2->setPixmap(QPixmap::fromImage(qi2).scaled(w,h,Qt::KeepAspectRatio));
+ win->show();
+ return app.exec();
+ return 0;
+}
diff --git a/test cases/frameworks/4 qt/mainWindow.cpp b/test cases/frameworks/4 qt/mainWindow.cpp
new file mode 100644
index 0000000..cc82c4f
--- /dev/null
+++ b/test cases/frameworks/4 qt/mainWindow.cpp
@@ -0,0 +1,8 @@
+#include "mainWindow.h"
+
+MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
+ setupUi(this);
+}
+
+MainWindow::~MainWindow() {
+}
diff --git a/test cases/frameworks/4 qt/mainWindow.h b/test cases/frameworks/4 qt/mainWindow.h
new file mode 100644
index 0000000..7f6d906
--- /dev/null
+++ b/test cases/frameworks/4 qt/mainWindow.h
@@ -0,0 +1,20 @@
+#ifndef MES_MAINWINDOW
+#define MES_MAINWINDOW
+
+#include <QObject>
+#include <QMainWindow>
+#include "ui_mainWindow.h"
+
+class NotificationModel;
+
+class MainWindow : public QMainWindow, private Ui_MainWindow {
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent=0);
+ ~MainWindow();
+
+private:
+};
+
+#endif
diff --git a/test cases/frameworks/4 qt/mainWindow.ui b/test cases/frameworks/4 qt/mainWindow.ui
new file mode 100644
index 0000000..c01b8bf
--- /dev/null
+++ b/test cases/frameworks/4 qt/mainWindow.ui
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>260</width>
+ <height>313</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>241</width>
+ <height>91</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>I am a button</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_stuff">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>112</y>
+ <width>241</width>
+ <height>91</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_stuff2">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>212</y>
+ <width>241</width>
+ <height>91</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/test cases/frameworks/4 qt/manualinclude.cpp b/test cases/frameworks/4 qt/manualinclude.cpp
new file mode 100644
index 0000000..60b94e5
--- /dev/null
+++ b/test cases/frameworks/4 qt/manualinclude.cpp
@@ -0,0 +1,26 @@
+#include"manualinclude.h"
+#include<QCoreApplication>
+
+#include<QObject>
+
+ManualInclude::ManualInclude() {
+}
+
+void ManualInclude::myslot(void) {
+ ;
+}
+
+class MocClass : public QObject {
+ Q_OBJECT
+};
+
+int main(int argc, char **argv) {
+ ManualInclude mi;
+ MocClass mc;
+ QObject::connect(&mi, SIGNAL(mysignal(void)),
+ &mi, SLOT(myslot(void)));
+ emit mi.mysignal();
+ return 0;
+}
+
+#include"manualinclude.moc"
diff --git a/test cases/frameworks/4 qt/manualinclude.h b/test cases/frameworks/4 qt/manualinclude.h
new file mode 100644
index 0000000..44bb7a7
--- /dev/null
+++ b/test cases/frameworks/4 qt/manualinclude.h
@@ -0,0 +1,22 @@
+#ifndef MANUALINCLUDE_H_
+#define MANUALINCLUDE_H_
+
+#include<QObject>
+
+class ManualInclude : public QObject {
+ Q_OBJECT
+
+public:
+ ManualInclude();
+#if defined(MOC_EXTRA_FLAG)
+public slots:
+#endif
+ void myslot(void);
+
+#if defined(MOC_EXTRA_FLAG)
+signals:
+#endif
+ int mysignal();
+};
+
+#endif
diff --git a/test cases/frameworks/4 qt/meson.build b/test cases/frameworks/4 qt/meson.build
new file mode 100644
index 0000000..735b3f9
--- /dev/null
+++ b/test cases/frameworks/4 qt/meson.build
@@ -0,0 +1,158 @@
+project('qt4, qt5, and qt6 build test', 'cpp',
+ # Qt6 requires C++ 17 support
+ default_options : ['cpp_std=c++17'])
+
+qt5_modules = ['Widgets']
+qt6_modules = ['Widgets']
+foreach qt : ['qt4', 'qt5', 'qt6']
+ qt_modules = ['Core', 'Gui']
+ if qt == 'qt5'
+ qt_modules += qt5_modules
+ elif qt == 'qt6'
+ qt_modules += qt6_modules
+ endif
+
+ # Test that invalid modules are indeed not found
+ fakeqtdep = dependency(qt, modules : ['DefinitelyNotFound'], required : false, method : get_option('method'))
+ if fakeqtdep.found()
+ error('Invalid qt dep incorrectly found!')
+ endif
+
+ # Test that partially-invalid modules are indeed not found
+ fakeqtdep = dependency(qt, modules : ['Core', 'DefinitelyNotFound'], required : false, method : get_option('method'))
+ if fakeqtdep.found()
+ error('Invalid qt dep incorrectly found!')
+ endif
+
+ # This test should be skipped if the required version of Qt isn't found
+ #
+ # (In the CI environment, the specified version of Qt is definitely present.
+ # An unexpected skip here is treated as a failure, so we are testing that the
+ # detection mechanism is able to find Qt.)
+ needed_qt = get_option('required').to_lower()
+ required = (qt == needed_qt)
+ if required
+ dep = dependency(qt, modules : ['Core'], required : false, method : get_option('method'))
+ if not dep.found()
+ error('MESON_SKIP_TEST @0@ not found.'.format(needed_qt))
+ endif
+ endif
+
+ # Ensure that the "no-Core-module-specified" code branch is hit
+ nocoredep = dependency(qt, modules : ['Gui'], required : required, method : get_option('method'))
+
+ # If 'qt' modules are found, test that.
+ qtdep = dependency(qt, modules : qt_modules, main : true, private_headers: true, required : required, method : get_option('method'))
+ if qtdep.found()
+ qtmodule = import(qt)
+ assert(qtmodule.has_tools())
+
+ # The following has two resource files because having two in one target
+ # requires you to do it properly or you get linker symbol clashes.
+
+ prep = qtmodule.preprocess(
+ moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use.
+ method : get_option('method')
+ )
+ # XML files that need to be compiled with the uic tol.
+ prep += qtmodule.compile_ui(sources : 'mainWindow.ui', method: get_option('method'))
+
+ qtmodule.preprocess(
+ ui_files : 'mainWindow.ui',
+ method: get_option('method'))
+
+ # Resource file(s) for rcc compiler
+ extra_cpp_args = []
+ if meson.is_unity()
+ extra_cpp_args += '-DUNITY_BUILD'
+ prep_rcc = qtmodule.preprocess(qt + '_unity_ressource', qresources : ['stuff.qrc', 'stuff2.qrc'], method : get_option('method'))
+ else
+ prep_rcc = qtmodule.preprocess(qresources : ['stuff.qrc', 'stuff2.qrc'], method : get_option('method'))
+ endif
+
+ # Test that setting a unique name with a positional argument works
+ qtmodule.compile_resources(
+ name : qt + 'teststuff',
+ sources : files(['stuff.qrc', 'stuff2.qrc']),
+ method : get_option('method')
+ )
+
+ # Test that passing extra arguments to rcc works
+ # qt4-rcc and qt5-rcc take different arguments, for example qt4: ['-compress', '3']; qt5: '--compress=3'
+ qtmodule.preprocess(qt + 'testrccarg', qresources : files(['stuff.qrc', 'stuff2.qrc']), rcc_extra_arguments : '--compress=3', method : get_option('method'))
+
+ translations_cpp = qtmodule.compile_translations(qresource: qt+'_lang.qrc')
+ # unity builds suck and definitely cannot handle two qrc embeds in one compilation unit
+ unityproof_translations = static_library(qt+'unityproof_translations', translations_cpp, dependencies: qtdep)
+
+ extra_cpp_args += '-DQT="@0@"'.format(qt)
+ qexe = executable(qt + 'app',
+ sources : ['main.cpp', 'mainWindow.cpp', # Sources that don't need preprocessing.
+ prep, prep_rcc],
+ dependencies : qtdep,
+ link_with: unityproof_translations,
+ cpp_args: extra_cpp_args,
+ gui_app : true)
+
+ # We need a console test application because some test environments
+ # do not have an X server.
+
+ translations = qtmodule.compile_translations(ts_files : qt+'core_fr.ts', build_by_default : true)
+
+ qtcore = dependency(qt, modules : 'Core', method : get_option('method'))
+
+ qtcoreapp = executable(qt + 'core', 'q5core.cpp',
+ cpp_args: '-DQT="@0@"'.format(qt),
+ dependencies : qtcore)
+
+ test(qt + 'test', qtcoreapp)
+
+ # The build system needs to include the cpp files from
+ # headers but the user must manually include moc
+ # files from sources.
+ qtmodule.preprocess(
+ moc_extra_arguments : ['-DMOC_EXTRA_FLAG'], # This is just a random macro to test `extra_arguments`
+ moc_sources : 'manualinclude.cpp',
+ moc_headers : 'manualinclude.h',
+ method : get_option('method'))
+
+ manpreprocessed = qtmodule.compile_moc(
+ extra_args : ['-DMOC_EXTRA_FLAG'], # This is just a random macro to test `extra_arguments`
+ sources : 'manualinclude.cpp',
+ headers : 'manualinclude.h',
+ method : get_option('method'))
+
+ qtmaninclude = executable(qt + 'maninclude',
+ sources : ['manualinclude.cpp', manpreprocessed],
+ dependencies : qtcore)
+
+ test(qt + 'maninclude', qtmaninclude)
+
+ # building Qt plugins implies to give include path to moc
+ plugin_includes = include_directories('pluginInterface', 'plugin')
+ pluginpreprocess = qtmodule.preprocess(
+ moc_headers : 'plugin/plugin.h',
+ include_directories : plugin_includes
+ )
+ plugin = library(qt + 'plugin', 'plugin/plugin.cpp', pluginpreprocess,
+ include_directories : plugin_includes,
+ dependencies : qtcore)
+
+ # implementing Qt interfaces requires passing Qt include paths to moc
+ qtinterfacepreprocess = qtmodule.preprocess(
+ moc_sources : 'qtinterface.cpp',
+ dependencies : qtdep
+ )
+ qtinterface = library(qt + 'qtinterface',
+ sources : ['qtinterface.cpp', qtinterfacepreprocess],
+ dependencies : qtdep)
+
+ if qt == 'qt5'
+ subdir('subfolder')
+ endif
+
+ # Check we can apply a version constraint
+ dependency(qt, modules: qt_modules, version: '>=@0@'.format(qtdep.version()), method : get_option('method'))
+
+ endif
+endforeach
diff --git a/test cases/frameworks/4 qt/meson_options.txt b/test cases/frameworks/4 qt/meson_options.txt
new file mode 100644
index 0000000..223f4fb
--- /dev/null
+++ b/test cases/frameworks/4 qt/meson_options.txt
@@ -0,0 +1,2 @@
+option('method', type : 'string', value : 'auto', description : 'The method to use to find Qt')
+option('required', type : 'string', value : 'qt5', description : 'The version of Qt which is required to be present')
diff --git a/test cases/frameworks/4 qt/plugin/plugin.cpp b/test cases/frameworks/4 qt/plugin/plugin.cpp
new file mode 100644
index 0000000..2c013fe
--- /dev/null
+++ b/test cases/frameworks/4 qt/plugin/plugin.cpp
@@ -0,0 +1,12 @@
+#include "plugin.h"
+#include <QFile>
+
+QString plugin1::getResource()
+{
+ return "hello world";
+}
+
+
+#if QT_VERSION < 0x050000
+ Q_EXPORT_PLUGIN2(Plugin1, plugin1)
+#endif \ No newline at end of file
diff --git a/test cases/frameworks/4 qt/plugin/plugin.h b/test cases/frameworks/4 qt/plugin/plugin.h
new file mode 100644
index 0000000..c8e14e4
--- /dev/null
+++ b/test cases/frameworks/4 qt/plugin/plugin.h
@@ -0,0 +1,14 @@
+#pragma once
+#include <plugin_if.h>
+
+class plugin1:public QObject,public PluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(PluginInterface)
+#if QT_VERSION >= 0x050000
+ Q_PLUGIN_METADATA(IID "demo.PluginInterface" FILE "plugin.json")
+#endif
+
+public:
+ QString getResource() override;
+};
diff --git a/test cases/frameworks/4 qt/plugin/plugin.json b/test cases/frameworks/4 qt/plugin/plugin.json
new file mode 100644
index 0000000..6c6a011
--- /dev/null
+++ b/test cases/frameworks/4 qt/plugin/plugin.json
@@ -0,0 +1,3 @@
+{
+ "name" : "Plugin1"
+}
diff --git a/test cases/frameworks/4 qt/pluginInterface/plugin_if.h b/test cases/frameworks/4 qt/pluginInterface/plugin_if.h
new file mode 100644
index 0000000..97d2800
--- /dev/null
+++ b/test cases/frameworks/4 qt/pluginInterface/plugin_if.h
@@ -0,0 +1,21 @@
+#ifndef PLUGIN_IF_H
+#define PLUGIN_IF_H
+
+#include <QString>
+#include <QtPlugin>
+
+/**
+ * @brief Interface for a plugin
+ */
+class PluginInterface
+{
+public:
+ virtual ~PluginInterface() = default;
+
+ /// Initializes the plugin
+ virtual QString getResource() = 0;
+};
+
+Q_DECLARE_INTERFACE(PluginInterface, "demo.PluginInterface")
+
+#endif
diff --git a/test cases/frameworks/4 qt/q5core.cpp b/test cases/frameworks/4 qt/q5core.cpp
new file mode 100644
index 0000000..44581a6
--- /dev/null
+++ b/test cases/frameworks/4 qt/q5core.cpp
@@ -0,0 +1,28 @@
+#include <QCoreApplication>
+#include <QtGlobal>
+#include <QString>
+#include <QTranslator>
+#include <QLocale>
+#include <QLibraryInfo>
+#include <QDebug>
+
+int main(int argc, char **argv) {
+ QCoreApplication app(argc, argv);
+
+ QTranslator qtTranslator;
+ qtTranslator.load("qt_" + QLocale::system().name(),
+ QLibraryInfo::location(QLibraryInfo::TranslationsPath));
+ app.installTranslator(&qtTranslator);
+
+ QTranslator myappTranslator;
+ if(!myappTranslator.load(QT "core_fr") )
+ return 1;
+
+ app.installTranslator(&myappTranslator);
+
+ qDebug() << QObject::tr("Translate me!");
+ // Don't actually start the main loop so this
+ // can be run as a unit test.
+ //return app.exec();
+ return 0;
+}
diff --git a/test cases/frameworks/4 qt/qt4_lang.qrc b/test cases/frameworks/4 qt/qt4_lang.qrc
new file mode 100644
index 0000000..a6d2b54
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt4_lang.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/lang">
+ <file>qt4embedded_fr.qm</file>
+ </qresource>
+</RCC>
+
diff --git a/test cases/frameworks/4 qt/qt4core_fr.ts b/test cases/frameworks/4 qt/qt4core_fr.ts
new file mode 100644
index 0000000..0638bd5
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt4core_fr.ts
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="q5core.cpp" line="23"/>
+ <source>Translate me!</source>
+ <translation>Traduisez moi!</translation>
+ </message>
+</context>
+</TS>
diff --git a/test cases/frameworks/4 qt/qt4embedded_fr.ts b/test cases/frameworks/4 qt/qt4embedded_fr.ts
new file mode 100644
index 0000000..0638bd5
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt4embedded_fr.ts
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="q5core.cpp" line="23"/>
+ <source>Translate me!</source>
+ <translation>Traduisez moi!</translation>
+ </message>
+</context>
+</TS>
diff --git a/test cases/frameworks/4 qt/qt5_lang.qrc b/test cases/frameworks/4 qt/qt5_lang.qrc
new file mode 100644
index 0000000..cf4ddc6
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt5_lang.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/lang">
+ <file>qt5embedded_fr.qm</file>
+ </qresource>
+</RCC>
+
diff --git a/test cases/frameworks/4 qt/qt5core_fr.ts b/test cases/frameworks/4 qt/qt5core_fr.ts
new file mode 100644
index 0000000..4e3116b
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt5core_fr.ts
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="q5core.cpp" line="23"/>
+ <source>Translate me!</source>
+ <translation>Traduisez moi!</translation>
+ </message>
+</context>
+</TS>
diff --git a/test cases/frameworks/4 qt/qt5embedded_fr.ts b/test cases/frameworks/4 qt/qt5embedded_fr.ts
new file mode 100644
index 0000000..4e3116b
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt5embedded_fr.ts
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="q5core.cpp" line="23"/>
+ <source>Translate me!</source>
+ <translation>Traduisez moi!</translation>
+ </message>
+</context>
+</TS>
diff --git a/test cases/frameworks/4 qt/qt6_lang.qrc b/test cases/frameworks/4 qt/qt6_lang.qrc
new file mode 100644
index 0000000..12cc25a
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt6_lang.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/lang">
+ <file>qt6embedded_fr.qm</file>
+ </qresource>
+</RCC>
+
diff --git a/test cases/frameworks/4 qt/qt6core_fr.ts b/test cases/frameworks/4 qt/qt6core_fr.ts
new file mode 100644
index 0000000..4e3116b
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt6core_fr.ts
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="q5core.cpp" line="23"/>
+ <source>Translate me!</source>
+ <translation>Traduisez moi!</translation>
+ </message>
+</context>
+</TS>
diff --git a/test cases/frameworks/4 qt/qt6embedded_fr.ts b/test cases/frameworks/4 qt/qt6embedded_fr.ts
new file mode 100644
index 0000000..4e3116b
--- /dev/null
+++ b/test cases/frameworks/4 qt/qt6embedded_fr.ts
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="q5core.cpp" line="23"/>
+ <source>Translate me!</source>
+ <translation>Traduisez moi!</translation>
+ </message>
+</context>
+</TS>
diff --git a/test cases/frameworks/4 qt/qtinterface.cpp b/test cases/frameworks/4 qt/qtinterface.cpp
new file mode 100644
index 0000000..b2da99f
--- /dev/null
+++ b/test cases/frameworks/4 qt/qtinterface.cpp
@@ -0,0 +1,8 @@
+#include <QGraphicsLayout>
+
+class Foo : public QGraphicsLayout
+{
+ Q_INTERFACES(QGraphicsLayout)
+};
+
+#include "qtinterface.moc"
diff --git a/test cases/frameworks/4 qt/stuff.qrc b/test cases/frameworks/4 qt/stuff.qrc
new file mode 100644
index 0000000..fdfb58e
--- /dev/null
+++ b/test cases/frameworks/4 qt/stuff.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>thing.png</file>
+ </qresource>
+</RCC>
diff --git a/test cases/frameworks/4 qt/stuff2.qrc b/test cases/frameworks/4 qt/stuff2.qrc
new file mode 100644
index 0000000..910e2fb
--- /dev/null
+++ b/test cases/frameworks/4 qt/stuff2.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>thing2.png</file>
+ </qresource>
+</RCC>
diff --git a/test cases/frameworks/4 qt/subfolder/generator.py b/test cases/frameworks/4 qt/subfolder/generator.py
new file mode 100644
index 0000000..045d99a
--- /dev/null
+++ b/test cases/frameworks/4 qt/subfolder/generator.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+import sys
+
+if len(sys.argv) > 1:
+ with open(sys.argv[1], "w") as output:
+ output.write("Hello World")
diff --git a/test cases/frameworks/4 qt/subfolder/main.cpp b/test cases/frameworks/4 qt/subfolder/main.cpp
new file mode 100644
index 0000000..9661811
--- /dev/null
+++ b/test cases/frameworks/4 qt/subfolder/main.cpp
@@ -0,0 +1,29 @@
+#include <QImage>
+#include <QFile>
+#include <QString>
+
+int main(int argc, char **argv) {
+ #ifndef UNITY_BUILD
+ Q_INIT_RESOURCE(stuff3);
+ Q_INIT_RESOURCE(stuff4);
+ #endif
+
+ for(auto fname:{":/thing.png", ":/thing4.png"})
+ {
+ QImage img1(fname);
+ if(img1.width() != 640) {
+ return 1;
+ }
+ }
+
+ for(auto fname:{":/txt_resource.txt",":/txt_resource2.txt"})
+ {
+ QFile file(fname);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ return 1;
+ QString line = file.readLine();
+ if(line.compare("Hello World"))
+ return 1;
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/test cases/frameworks/4 qt/subfolder/meson.build b/test cases/frameworks/4 qt/subfolder/meson.build
new file mode 100644
index 0000000..f1b84e6
--- /dev/null
+++ b/test cases/frameworks/4 qt/subfolder/meson.build
@@ -0,0 +1,32 @@
+
+simple_gen = find_program('generator.py', required : true)
+
+txt_resource = custom_target('txt_resource',
+ output : 'txt_resource.txt',
+ command : [simple_gen, '@OUTPUT@'],
+)
+
+cfg = configuration_data()
+
+cfg.set('filepath', meson.current_source_dir()+'/../thing2.png')
+cfg.set('txt_resource', txt_resource.full_path())
+# here we abuse the system by guessing build dir layout
+cfg.set('txt_resource2', 'txt_resource.txt')
+
+
+rc_file = configure_file(
+ configuration : cfg,
+ input : 'resources/stuff4.qrc.in',
+ output : 'stuff4.qrc',
+)
+
+extra_cpp_args = []
+if meson.is_unity()
+ extra_cpp_args += '-DUNITY_BUILD'
+ qresources = qtmodule.preprocess(qt + '_subfolder_unity_ressource',qresources : ['resources/stuff3.qrc', rc_file])
+else
+ qresources = qtmodule.preprocess(qresources : ['resources/stuff3.qrc', rc_file])
+endif
+
+app = executable('subfolder', 'main.cpp', qresources, dependencies : qtdep, cpp_args: extra_cpp_args)
+test(qt + 'subfolder', app)
diff --git a/test cases/frameworks/4 qt/subfolder/resources/stuff3.qrc b/test cases/frameworks/4 qt/subfolder/resources/stuff3.qrc
new file mode 100644
index 0000000..fdfb58e
--- /dev/null
+++ b/test cases/frameworks/4 qt/subfolder/resources/stuff3.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>thing.png</file>
+ </qresource>
+</RCC>
diff --git a/test cases/frameworks/4 qt/subfolder/resources/stuff4.qrc.in b/test cases/frameworks/4 qt/subfolder/resources/stuff4.qrc.in
new file mode 100644
index 0000000..c30a358
--- /dev/null
+++ b/test cases/frameworks/4 qt/subfolder/resources/stuff4.qrc.in
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file alias="thing4.png">@filepath@</file>
+ <file alias="txt_resource.txt">@txt_resource@</file>
+ <file alias="txt_resource2.txt">@txt_resource2@</file>
+ </qresource>
+</RCC>
diff --git a/test cases/frameworks/4 qt/subfolder/resources/thing.png b/test cases/frameworks/4 qt/subfolder/resources/thing.png
new file mode 100644
index 0000000..4b001bd
--- /dev/null
+++ b/test cases/frameworks/4 qt/subfolder/resources/thing.png
Binary files differ
diff --git a/test cases/frameworks/4 qt/test.json b/test cases/frameworks/4 qt/test.json
new file mode 100644
index 0000000..4df0b49
--- /dev/null
+++ b/test cases/frameworks/4 qt/test.json
@@ -0,0 +1,12 @@
+{
+ "matrix": {
+ "options": {
+ "method": [
+ { "val": "config-tool" },
+ { "val": "qmake" },
+ { "val": "pkg-config" }
+ ]
+ }
+ },
+ "skip_on_jobname": ["cygwin", "msys2", "azure"]
+}
diff --git a/test cases/frameworks/4 qt/thing.png b/test cases/frameworks/4 qt/thing.png
new file mode 100644
index 0000000..4b001bd
--- /dev/null
+++ b/test cases/frameworks/4 qt/thing.png
Binary files differ
diff --git a/test cases/frameworks/4 qt/thing2.png b/test cases/frameworks/4 qt/thing2.png
new file mode 100644
index 0000000..4b001bd
--- /dev/null
+++ b/test cases/frameworks/4 qt/thing2.png
Binary files differ
diff --git a/test cases/frameworks/5 protocol buffers/asubdir/defs.proto b/test cases/frameworks/5 protocol buffers/asubdir/defs.proto
new file mode 100644
index 0000000..dad5754
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/asubdir/defs.proto
@@ -0,0 +1,5 @@
+syntax = "proto3";
+
+message Dummy {
+ string text = 1;
+}
diff --git a/test cases/frameworks/5 protocol buffers/asubdir/main.cpp b/test cases/frameworks/5 protocol buffers/asubdir/main.cpp
new file mode 100644
index 0000000..f6566d5
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/asubdir/main.cpp
@@ -0,0 +1,9 @@
+#include "defs.pb.h"
+
+int main(int argc, char **argv) {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ Dummy *d = new Dummy;
+ delete d;
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
diff --git a/test cases/frameworks/5 protocol buffers/asubdir/meson.build b/test cases/frameworks/5 protocol buffers/asubdir/meson.build
new file mode 100644
index 0000000..9727165
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/asubdir/meson.build
@@ -0,0 +1,8 @@
+subdirgen = generator(protoc, \
+ output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'],
+ arguments : ['--proto_path=@CURRENT_SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@'])
+
+generated = subdirgen.process('defs.proto')
+e = executable('subdir-prog', 'main.cpp', generated,
+ dependencies : dep)
+test('subdir-prototest', e)
diff --git a/test cases/frameworks/5 protocol buffers/defs.proto b/test cases/frameworks/5 protocol buffers/defs.proto
new file mode 100644
index 0000000..dad5754
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/defs.proto
@@ -0,0 +1,5 @@
+syntax = "proto3";
+
+message Dummy {
+ string text = 1;
+}
diff --git a/test cases/frameworks/5 protocol buffers/main.cpp b/test cases/frameworks/5 protocol buffers/main.cpp
new file mode 100644
index 0000000..f6566d5
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/main.cpp
@@ -0,0 +1,9 @@
+#include "defs.pb.h"
+
+int main(int argc, char **argv) {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ Dummy *d = new Dummy;
+ delete d;
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
diff --git a/test cases/frameworks/5 protocol buffers/meson.build b/test cases/frameworks/5 protocol buffers/meson.build
new file mode 100644
index 0000000..046847a
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/meson.build
@@ -0,0 +1,22 @@
+project('protocol buffer test', 'cpp', default_options: ['cpp_std=c++11'])
+
+protoc = find_program('protoc', required : false)
+dep = dependency('protobuf', required : false)
+
+if not protoc.found() or not dep.found()
+ error('MESON_SKIP_TEST: protoc tool and/or protobuf pkg-config dependency not found')
+endif
+
+
+gen = generator(protoc, \
+ output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'],
+ arguments : ['--proto_path=@CURRENT_SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@'])
+
+generated = gen.process('defs.proto')
+e = executable('prog', 'main.cpp', generated,
+ dependencies : dep)
+test('prototest', e)
+
+subdir('asubdir')
+subdir('withpath')
+subdir('sidedir')
diff --git a/test cases/frameworks/5 protocol buffers/sidedir/meson.build b/test cases/frameworks/5 protocol buffers/sidedir/meson.build
new file mode 100644
index 0000000..ce9b7be
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/sidedir/meson.build
@@ -0,0 +1,7 @@
+# Generated source defined in one directory but
+# used in another.
+
+e = executable('sideprog', 'sideprog.cpp', generated,
+ override_options : ['unity=off'],
+ dependencies : dep)
+test('sideprog', e)
diff --git a/test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp b/test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp
new file mode 100644
index 0000000..83af4b2
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/sidedir/sideprog.cpp
@@ -0,0 +1,16 @@
+#include"com/mesonbuild/simple.pb.h"
+#include"com/mesonbuild/subsite/complex.pb.h"
+
+#include<memory>
+
+int main(int argc, char **argv) {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ {
+ subdirectorial::SimpleMessage *s = new subdirectorial::SimpleMessage();
+ s->set_the_integer(3);
+ subdirectorial::ComplexMessage c;
+ c.set_allocated_sm(s);
+ }
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
diff --git a/test cases/frameworks/5 protocol buffers/test.json b/test cases/frameworks/5 protocol buffers/test.json
new file mode 100644
index 0000000..6ace9de
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2"]
+}
diff --git a/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto
new file mode 100644
index 0000000..336779f
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/simple.proto
@@ -0,0 +1,7 @@
+syntax = "proto3";
+
+package subdirectorial;
+
+message SimpleMessage {
+ int32 the_integer = 1;
+}
diff --git a/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto
new file mode 100644
index 0000000..8dc32c2
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/com/mesonbuild/subsite/complex.proto
@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+package subdirectorial;
+
+import "com/mesonbuild/simple.proto";
+
+message ComplexMessage {
+ string a_message = 1;
+ SimpleMessage sm = 2;
+}
diff --git a/test cases/frameworks/5 protocol buffers/withpath/meson.build b/test cases/frameworks/5 protocol buffers/withpath/meson.build
new file mode 100644
index 0000000..68a7381
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/meson.build
@@ -0,0 +1,13 @@
+# Testing protobuf files that are deeply hierarchical
+# and must preserve their path segments in output files
+# because protoc will always put it in there.
+
+generated = gen.process('com/mesonbuild/simple.proto',
+ 'com/mesonbuild/subsite/complex.proto',
+ preserve_path_from : meson.current_source_dir(),
+ )
+
+e = executable('pathprog', 'pathprog.cpp', generated,
+ override_options : ['unity=off'],
+ dependencies : dep)
+test('pathprog', e)
diff --git a/test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp b/test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp
new file mode 100644
index 0000000..83af4b2
--- /dev/null
+++ b/test cases/frameworks/5 protocol buffers/withpath/pathprog.cpp
@@ -0,0 +1,16 @@
+#include"com/mesonbuild/simple.pb.h"
+#include"com/mesonbuild/subsite/complex.pb.h"
+
+#include<memory>
+
+int main(int argc, char **argv) {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ {
+ subdirectorial::SimpleMessage *s = new subdirectorial::SimpleMessage();
+ s->set_the_integer(3);
+ subdirectorial::ComplexMessage c;
+ c.set_allocated_sm(s);
+ }
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
diff --git a/test cases/frameworks/6 gettext/data/data3/meson.build b/test cases/frameworks/6 gettext/data/data3/meson.build
new file mode 100644
index 0000000..044b498
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data/data3/meson.build
@@ -0,0 +1,9 @@
+# Target name will contain a path separator
+i18n.merge_file(
+ input: 'test.desktop.in',
+ output: 'test4.desktop',
+ type: 'desktop',
+ po_dir: '../../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications')
+)
diff --git a/test cases/frameworks/6 gettext/data/data3/test.desktop.in b/test cases/frameworks/6 gettext/data/data3/test.desktop.in
new file mode 100644
index 0000000..35edf07
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data/data3/test.desktop.in
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Test
+GenericName=Application
+Comment=Test Application
+Type=Application
diff --git a/test cases/frameworks/6 gettext/data/meson.build b/test cases/frameworks/6 gettext/data/meson.build
new file mode 100644
index 0000000..698eeec
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data/meson.build
@@ -0,0 +1,59 @@
+# Use filename substitution
+i18n.merge_file(
+ input: 'test.desktop.in',
+ output: '@BASENAME@',
+ type: 'desktop',
+ po_dir: '../po',
+ data_dirs: '../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications')
+)
+
+# Use filename substitution for another file
+i18n.merge_file(
+ input: files('test2.desktop.in'),
+ output: '@BASENAME@',
+ type: 'desktop',
+ po_dir: '../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications')
+)
+
+i18n.merge_file(
+ input: 'test.desktop.in',
+ output: 'test3.desktop',
+ type: 'desktop',
+ po_dir: '../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications')
+)
+
+# Regression test when passing File object as input and '@BASENAME@' as output
+# in multiple i18n.merge_file() calls. It used to make target name collision.
+# https://github.com/mesonbuild/meson/issues/9022
+i18n.merge_file(
+ input: configure_file(
+ input: 'test5.desktop.in.in',
+ output: '@BASENAME@',
+ configuration: { 'NAME': 'Application' },
+ ),
+ output: '@BASENAME@',
+ type: 'desktop',
+ po_dir: '../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications')
+)
+i18n.merge_file(
+ input: configure_file(
+ input: 'test6.desktop.in.in',
+ output: '@BASENAME@',
+ configuration: { 'NAME': 'Application' },
+ ),
+ output: '@BASENAME@',
+ type: 'desktop',
+ po_dir: '../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications')
+)
+
+subdir('data3')
diff --git a/test cases/frameworks/6 gettext/data/test.desktop.in b/test cases/frameworks/6 gettext/data/test.desktop.in
new file mode 100644
index 0000000..35edf07
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data/test.desktop.in
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Test
+GenericName=Application
+Comment=Test Application
+Type=Application
diff --git a/test cases/frameworks/6 gettext/data/test2.desktop.in b/test cases/frameworks/6 gettext/data/test2.desktop.in
new file mode 100644
index 0000000..23be0a4
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data/test2.desktop.in
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Test 2
+GenericName=Application
+Comment=Test Application
+Type=Application
diff --git a/test cases/frameworks/6 gettext/data/test5.desktop.in.in b/test cases/frameworks/6 gettext/data/test5.desktop.in.in
new file mode 100644
index 0000000..a401e36
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data/test5.desktop.in.in
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Test 2
+GenericName=@NAME@
+Comment=Test Application
+Type=Application
diff --git a/test cases/frameworks/6 gettext/data/test6.desktop.in.in b/test cases/frameworks/6 gettext/data/test6.desktop.in.in
new file mode 100644
index 0000000..a401e36
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data/test6.desktop.in.in
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Test 2
+GenericName=@NAME@
+Comment=Test Application
+Type=Application
diff --git a/test cases/frameworks/6 gettext/data2/meson.build b/test cases/frameworks/6 gettext/data2/meson.build
new file mode 100644
index 0000000..9a992c9
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data2/meson.build
@@ -0,0 +1,10 @@
+i18n.merge_file(
+ input: 'test.desktop.in',
+ output: 'test.plugin',
+ type: 'desktop',
+ po_dir: '../po',
+ data_dirs: '../po',
+ args: ['--keyword=Description'],
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications')
+)
diff --git a/test cases/frameworks/6 gettext/data2/test.desktop.in b/test cases/frameworks/6 gettext/data2/test.desktop.in
new file mode 100644
index 0000000..b57ba21
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data2/test.desktop.in
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=Test
+GenericName=Application
+Description=Test Application
+Type=Application
diff --git a/test cases/frameworks/6 gettext/data3/com.mesonbuild.test.intlprog.metainfo.xml b/test cases/frameworks/6 gettext/data3/com.mesonbuild.test.intlprog.metainfo.xml
new file mode 100644
index 0000000..7fb4d1f
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data3/com.mesonbuild.test.intlprog.metainfo.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="console-application">
+ <id>com.mesonbuild.test.intlprog</id>
+
+ <name>Test</name>
+ <summary>Application</summary>
+
+ <metadata_license>FSFAP</metadata_license>
+ <project_license>FSFAP</project_license>
+
+ <description>
+ <p>
+ Test Application
+ </p>
+ <p>
+ International greeting.
+ </p>
+ <p>
+ This is <code>text</code> with <em>embedded XML tags</em>. Nice!
+ </p>
+ </description>
+
+ <icon type="stock">meson-unittest-intlprog</icon>
+
+ <categories>
+ <category>Development</category>
+ <category>Building</category>
+ </categories>
+
+ <provides>
+ <binary>intlprog</binary>
+ </provides>
+</component>
diff --git a/test cases/frameworks/6 gettext/data3/meson.build b/test cases/frameworks/6 gettext/data3/meson.build
new file mode 100644
index 0000000..2be2e89
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data3/meson.build
@@ -0,0 +1,33 @@
+
+if itstool.found()
+
+ mi_translated = i18n.itstool_join(
+ input: 'com.mesonbuild.test.intlprog.metainfo.xml',
+ output: 'com.mesonbuild.test.intlprog.metainfo.xml',
+ mo_targets: mo_targets,
+ its_files: ['metainfo.its'],
+ install: true,
+ install_dir: get_option('datadir') / 'metainfo',
+ )
+
+ # older versions of itstool have a bug where ITS rules specified on the command-line
+ # are not read when joining files. Since we don't install appstream in the Meson CI
+ # environment, the to-be-tested entry will be untranslated and the test would fail, so
+ # we just skip verification if the installed itstool is too old.
+ r = run_command(itstool, '-v', check: true)
+ itstool_v = r.stdout().strip().split()
+ if itstool_v[1].version_compare('>=2.0.6')
+ verify_exe = find_program('verify.py')
+ test('test xml translation',
+ verify_exe,
+ args: [mi_translated,
+ '<p xml:lang="de">Dies ist <code>Text</code> mit <em>eingebetteten XML Tags</em>. Toll!</p>']
+ )
+ else
+ message('Skipping translation verification: Itstool too old.')
+ endif
+
+else
+ install_data('com.mesonbuild.test.intlprog.metainfo.xml',
+ install_dir: get_option('datadir') / 'metainfo')
+endif
diff --git a/test cases/frameworks/6 gettext/data3/metainfo.its b/test cases/frameworks/6 gettext/data3/metainfo.its
new file mode 100644
index 0000000..0852a0f
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data3/metainfo.its
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) 2015-2021 Matthias Klumpp <matthias@tenstral.net>
+ Copyright (C) 2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ SPDX-License-Identifier: FSFAP
+-->
+<its:rules xmlns:its="http://www.w3.org/2005/11/its"
+ version="2.0">
+
+ <its:withinTextRule withinText="yes" selector="/component//description//em |
+ /component//description//code"/>
+
+ <its:translateRule selector="/component" translate="no"/>
+ <its:translateRule selector="/component/name |
+ /component/summary |
+ /component/description |
+ /component/developer_name |
+ /component/name_variant_suffix |
+ /component/screenshots/screenshot/caption |
+ /component/releases/release/description |
+ /component/agreement/agreement_section/name |
+ /component/agreement/agreement_section/description"
+ translate="yes"/>
+
+ <its:translateRule selector="/component/name[@translatable = 'no']"
+ translate="no"/>
+ <its:translateRule selector="/component/developer_name[@translatable = 'no']"
+ translate="no"/>
+ <its:translateRule selector="/component/name_variant_suffix[@translatable = 'no']"
+ translate="no"/>
+ <its:translateRule selector="/component/releases/release/description[@translatable = 'no']"
+ translate="no"/>
+</its:rules>
diff --git a/test cases/frameworks/6 gettext/data3/verify.py b/test cases/frameworks/6 gettext/data3/verify.py
new file mode 100755
index 0000000..aff2f2e
--- /dev/null
+++ b/test cases/frameworks/6 gettext/data3/verify.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+assert len(sys.argv) == 3
+
+fname = sys.argv[1]
+check_str = sys.argv[2]
+
+assert os.path.isfile(fname)
+with open(fname, 'r', encoding='utf-8') as f:
+ assert check_str in f.read()
diff --git a/test cases/frameworks/6 gettext/generated/desktopgenerator.py b/test cases/frameworks/6 gettext/generated/desktopgenerator.py
new file mode 100644
index 0000000..e49c2d6
--- /dev/null
+++ b/test cases/frameworks/6 gettext/generated/desktopgenerator.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import os, sys, shutil
+
+ifile = sys.argv[1]
+ofile = sys.argv[2]
+
+try:
+ os.unlink(ofile)
+except FileNotFoundError:
+ pass
+
+shutil.copy(ifile, ofile)
diff --git a/test cases/frameworks/6 gettext/generated/meson.build b/test cases/frameworks/6 gettext/generated/meson.build
new file mode 100644
index 0000000..5ed9205
--- /dev/null
+++ b/test cases/frameworks/6 gettext/generated/meson.build
@@ -0,0 +1,16 @@
+dgen = find_program('desktopgenerator.py')
+
+desktop_in_file = custom_target('something.desktop.in',
+ input : ['something.desktop.in.in'],
+ output : 'something.desktop.in',
+ command : [dgen, '@INPUT@', '@OUTPUT@'],
+)
+
+i18n.merge_file(
+ input : desktop_in_file,
+ output : 'something.desktop',
+ type : 'desktop',
+ po_dir : '../po',
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'applications'),
+)
diff --git a/test cases/frameworks/6 gettext/generated/something.desktop.in.in b/test cases/frameworks/6 gettext/generated/something.desktop.in.in
new file mode 100644
index 0000000..e2094fd
--- /dev/null
+++ b/test cases/frameworks/6 gettext/generated/something.desktop.in.in
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Name=Something doer
+Comment=Do something
+# Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
+Keywords=zip;tar;extract;unpack;
+TryExec=file-roller
+Exec=file-roller %U
+StartupNotify=true
+Terminal=false
+Type=Application
+# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
+Icon=something
+Categories=GTK;GNOME;Utility
+X-GNOME-DocPath=file-roller/file-roller.xml
+X-GNOME-UsesNotifications=true
diff --git a/test cases/frameworks/6 gettext/meson.build b/test cases/frameworks/6 gettext/meson.build
new file mode 100644
index 0000000..ce99242
--- /dev/null
+++ b/test cases/frameworks/6 gettext/meson.build
@@ -0,0 +1,27 @@
+project('gettext example', 'c')
+
+gettext = find_program('gettext', required: false)
+if not gettext.found()
+ error('MESON_SKIP_TEST gettext not found.')
+endif
+
+xgettext = find_program('xgettext', required: false)
+if not xgettext.found()
+ error('MESON_SKIP_TEST xgettext not found.')
+endif
+
+intl = dependency('intl', required: false, static: get_option('static'))
+if not intl.found()
+ error('MESON_SKIP_TEST libintl/gettext functions not found.')
+endif
+
+itstool = find_program('itstool', required: false)
+
+i18n = import('i18n')
+
+subdir('po')
+subdir('src')
+subdir('data')
+subdir('data2')
+subdir('data3')
+subdir('generated')
diff --git a/test cases/frameworks/6 gettext/meson_options.txt b/test cases/frameworks/6 gettext/meson_options.txt
new file mode 100644
index 0000000..f41ed25
--- /dev/null
+++ b/test cases/frameworks/6 gettext/meson_options.txt
@@ -0,0 +1 @@
+option('static', type : 'boolean', value : false, description : 'build statically linked binaries')
diff --git a/test cases/frameworks/6 gettext/po/LINGUAS b/test cases/frameworks/6 gettext/po/LINGUAS
new file mode 100644
index 0000000..4cde210
--- /dev/null
+++ b/test cases/frameworks/6 gettext/po/LINGUAS
@@ -0,0 +1,3 @@
+de
+fi
+ru
diff --git a/test cases/frameworks/6 gettext/po/POTFILES b/test cases/frameworks/6 gettext/po/POTFILES
new file mode 100644
index 0000000..8ac0de5
--- /dev/null
+++ b/test cases/frameworks/6 gettext/po/POTFILES
@@ -0,0 +1,2 @@
+src/intlmain.c
+data/test.desktop.in
diff --git a/test cases/frameworks/6 gettext/po/de.po b/test cases/frameworks/6 gettext/po/de.po
new file mode 100644
index 0000000..1e4693b
--- /dev/null
+++ b/test cases/frameworks/6 gettext/po/de.po
@@ -0,0 +1,26 @@
+# German translations for PACKAGE package.
+# Copyright (C) 2013 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Jussi Pakkanen <jpakkane@brash>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-09-12 18:53+0300\n"
+"PO-Revision-Date: 2013-09-12 18:57+0300\n"
+"Last-Translator: Jussi Pakkanen <jpakkane@brash>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ASCII\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/intlmain.c:15
+msgid "International greeting."
+msgstr "Internationale Gruss."
+
+#: data/com.mesonbuild.test.dummy.metainfo.xml:19
+msgid "This is <code>text</code> with <em>embedded XML tags</em>. Nice!"
+msgstr "Dies ist <code>Text</code> mit <em>eingebetteten XML Tags</em>. Toll!"
diff --git a/test cases/frameworks/6 gettext/po/fi.po b/test cases/frameworks/6 gettext/po/fi.po
new file mode 100644
index 0000000..114cb10
--- /dev/null
+++ b/test cases/frameworks/6 gettext/po/fi.po
@@ -0,0 +1,22 @@
+# Finnish translations for PACKAGE package.
+# Copyright (C) 2013 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Jussi Pakkanen <jpakkane@brash>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-09-12 18:53+0300\n"
+"PO-Revision-Date: 2013-09-12 18:57+0300\n"
+"Last-Translator: Jussi Pakkanen <jpakkane@brash>\n"
+"Language-Team: Finnish\n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ASCII\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/intlmain.c:15
+msgid "International greeting."
+msgstr "Maailman tervehdys."
diff --git a/test cases/frameworks/6 gettext/po/intltest.pot b/test cases/frameworks/6 gettext/po/intltest.pot
new file mode 100644
index 0000000..c34e7f9
--- /dev/null
+++ b/test cases/frameworks/6 gettext/po/intltest.pot
@@ -0,0 +1,38 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the intltest package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: intltest\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-05-31 05:16-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/intlmain.c:15
+msgid "International greeting."
+msgstr ""
+
+#: data/test.desktop.in:3
+msgid "Test"
+msgstr ""
+
+#: data/test.desktop.in:4
+msgid "Application"
+msgstr ""
+
+#: data/test.desktop.in:5
+msgid "Test Application"
+msgstr ""
+
+#: data/com.mesonbuild.test.dummy.metainfo.xml:19
+msgid "This is <code>text</code> with <em>embedded XML tags</em>. Nice!"
+msgstr ""
diff --git a/test cases/frameworks/6 gettext/po/meson.build b/test cases/frameworks/6 gettext/po/meson.build
new file mode 100644
index 0000000..5510e42
--- /dev/null
+++ b/test cases/frameworks/6 gettext/po/meson.build
@@ -0,0 +1,4 @@
+langs = ['fi', 'de', 'ru']
+
+gettext_targets = i18n.gettext('intltest', languages : langs)
+mo_targets = gettext_targets[0]
diff --git a/test cases/frameworks/6 gettext/po/ru.po b/test cases/frameworks/6 gettext/po/ru.po
new file mode 100644
index 0000000..e5867c8
--- /dev/null
+++ b/test cases/frameworks/6 gettext/po/ru.po
@@ -0,0 +1,34 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the intltest package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: intltest\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-05-31 05:16-0500\n"
+"PO-Revision-Date: 2019-04-22 02:38+0300\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"X-Generator: Poedit 2.2.1\n"
+
+#: src/intlmain.c:15
+msgid "International greeting."
+msgstr "Межнациональное приветÑтвие."
+
+#: data/test.desktop.in:3
+msgid "Test"
+msgstr "ТеÑÑ‚"
+
+#: data/test.desktop.in:4
+msgid "Application"
+msgstr "Приложение"
+
+#: data/test.desktop.in:5
+msgid "Test Application"
+msgstr "ТеÑтовое приложение"
diff --git a/test cases/frameworks/6 gettext/src/intlmain.c b/test cases/frameworks/6 gettext/src/intlmain.c
new file mode 100644
index 0000000..bd7af6f
--- /dev/null
+++ b/test cases/frameworks/6 gettext/src/intlmain.c
@@ -0,0 +1,17 @@
+#include<libintl.h>
+#include<locale.h>
+#include<stdio.h>
+
+#define _(String) gettext (String)
+
+#define PACKAGE "intltest"
+// WRONG, but enough for this test.
+#define LOCALEDIR "/usr/share/locale"
+
+int main(int argc, char **argv) {
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ printf("%s\n", _("International greeting."));
+ return 0;
+}
diff --git a/test cases/frameworks/6 gettext/src/meson.build b/test cases/frameworks/6 gettext/src/meson.build
new file mode 100644
index 0000000..cda3ea4
--- /dev/null
+++ b/test cases/frameworks/6 gettext/src/meson.build
@@ -0,0 +1,2 @@
+executable('intlprog', 'intlmain.c', install : true,
+ dependencies : intl)
diff --git a/test cases/frameworks/6 gettext/test.json b/test cases/frameworks/6 gettext/test.json
new file mode 100644
index 0000000..910fc1c
--- /dev/null
+++ b/test cases/frameworks/6 gettext/test.json
@@ -0,0 +1,26 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/intlprog"},
+ {"type": "file", "file": "usr/share/locale/de/LC_MESSAGES/intltest.mo"},
+ {"type": "file", "file": "usr/share/locale/fi/LC_MESSAGES/intltest.mo"},
+ {"type": "file", "file": "usr/share/locale/ru/LC_MESSAGES/intltest.mo"},
+ {"type": "file", "file": "usr/share/applications/something.desktop"},
+ {"type": "file", "file": "usr/share/applications/test.desktop"},
+ {"type": "file", "file": "usr/share/applications/test.plugin"},
+ {"type": "file", "file": "usr/share/applications/test2.desktop"},
+ {"type": "file", "file": "usr/share/applications/test3.desktop"},
+ {"type": "file", "file": "usr/share/applications/test4.desktop"},
+ {"type": "file", "file": "usr/share/applications/test5.desktop"},
+ {"type": "file", "file": "usr/share/applications/test6.desktop"},
+ {"type": "file", "file": "usr/share/metainfo/com.mesonbuild.test.intlprog.metainfo.xml"}
+ ],
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": "true" },
+ { "val": "false" }
+ ]
+ }
+ },
+ "skip_on_jobname": ["azure", "cygwin"]
+}
diff --git a/test cases/frameworks/7 gnome/copyfile.py b/test cases/frameworks/7 gnome/copyfile.py
new file mode 100644
index 0000000..7e44c48
--- /dev/null
+++ b/test cases/frameworks/7 gnome/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copy(sys.argv[1], sys.argv[2])
diff --git a/test cases/frameworks/7 gnome/gdbus/data/com.example.Sample.xml b/test cases/frameworks/7 gnome/gdbus/data/com.example.Sample.xml
new file mode 100644
index 0000000..d7adc30
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gdbus/data/com.example.Sample.xml
@@ -0,0 +1,14 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="com.example">
+ <method name="Hello">
+ <arg direction="in" type="s" name="name"/>
+ <arg direction="out" type="s" name="greeting"/>
+ </method>
+ <method name="Bye">
+ <arg direction="in" type="s" name="name"/>
+ <arg direction="out" type="s" name="greeting"/>
+ </method>
+ </interface>
+</node>
diff --git a/test cases/frameworks/7 gnome/gdbus/gdbusprog.c b/test cases/frameworks/7 gnome/gdbus/gdbusprog.c
new file mode 100644
index 0000000..b42b6fe
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gdbus/gdbusprog.c
@@ -0,0 +1,8 @@
+#include"generated-gdbus.h"
+
+int main(int argc, char **argv) {
+ SampleComExample *s;
+ s = sample_com_example_skeleton_new();
+ g_object_unref(s);
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/gdbus/meson.build b/test cases/frameworks/7 gnome/gdbus/meson.build
new file mode 100644
index 0000000..fdb3896
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gdbus/meson.build
@@ -0,0 +1,95 @@
+gdbus_src = gnome.gdbus_codegen('generated-gdbus-no-docbook',
+ 'data/com.example.Sample.xml',
+ interface_prefix : 'com.example.',
+ namespace : 'Sample',
+ annotations : [
+ ['com.example.Hello()', 'org.freedesktop.DBus.Deprecated', 'true']
+ ],
+)
+
+# check that empty annotations work
+gdbus_src2 = gnome.gdbus_codegen(
+ 'generated-gdbus-no-docbook2',
+ 'data/com.example.Sample.xml',
+ interface_prefix : 'com.example.',
+ namespace : 'Sample',
+ annotations : [],
+)
+
+assert(gdbus_src.length() == 2, 'expected 2 targets')
+assert(gdbus_src[0].full_path().endswith('.c'), 'expected 1 c source file')
+assert(gdbus_src[1].full_path().endswith('.h'), 'expected 1 c header file')
+
+sample_xml = configure_file(input: 'data/com.example.Sample.xml',
+ output: 'com.example.Sample.xml',
+ copy: true)
+
+gdbus_src = gnome.gdbus_codegen('generated-gdbus-no-docbook-files-posarg',
+ sample_xml,
+ interface_prefix : 'com.example.',
+ namespace : 'Sample',
+ annotations : [
+ ['com.example.Hello()', 'org.freedesktop.DBus.Deprecated', 'true']
+ ],
+)
+assert(gdbus_src.length() == 2, 'expected 2 targets')
+assert(gdbus_src[0].full_path().endswith('.c'), 'expected 1 c source file')
+assert(gdbus_src[1].full_path().endswith('.h'), 'expected 1 c header file')
+
+gdbus_src = gnome.gdbus_codegen('generated-gdbus',
+ sources : files('data/com.example.Sample.xml'),
+ interface_prefix : 'com.example.',
+ namespace : 'Sample',
+ annotations : [
+ ['com.example.Hello()', 'org.freedesktop.DBus.Deprecated', 'true'],
+ ['com.example.Bye()', 'org.freedesktop.DBus.Deprecated', 'true'],
+ ],
+ docbook : 'generated-gdbus-doc',
+ install_header : true,
+ install_dir : get_option('includedir')
+)
+assert(gdbus_src.length() == 3, 'expected 3 targets')
+assert(gdbus_src[0].full_path().endswith('.c'), 'expected 1 c source file')
+assert(gdbus_src[1].full_path().endswith('.h'), 'expected 1 c header file')
+
+if not pretend_glib_old and glib.version().version_compare('>=2.51.3')
+ includes = []
+else
+ includes = include_directories('..')
+endif
+
+# check that custom targets work
+gdbus_xml_ct = custom_target('built xml sources for gdbus',
+ output: 'com.example.SampleCustomTarget.xml',
+ input: 'data/com.example.Sample.xml',
+ command : [copyfile, '@INPUT@', '@OUTPUT@'])
+
+gdbus_src_ct = gnome.gdbus_codegen(
+ 'generated-gdbus-customtarget-src',
+ gdbus_xml_ct,
+ interface_prefix : 'com.example.',
+ namespace : 'Sample',
+ annotations : [],
+)
+gdbus_src_cti = gnome.gdbus_codegen(
+ 'generated-gdbus-customtargetindex-src',
+ gdbus_xml_ct[0],
+ interface_prefix : 'com.example.',
+ namespace : 'Sample',
+ annotations : [],
+)
+
+gdbus_src_gen = gnome.gdbus_codegen(
+ 'generated-gdbus-generator-src',
+ copyfile_gen.process('data/com.example.Sample.xml'),
+ interface_prefix : 'com.example.',
+ namespace : 'Sample',
+ annotations : [],
+)
+
+gdbus_exe = executable('gdbus-test', 'gdbusprog.c',
+ gdbus_src,
+ include_directories : includes,
+ dependencies : giounix)
+
+test('gdbus', gdbus_exe)
diff --git a/test cases/frameworks/7 gnome/genmarshal/main.c.in b/test cases/frameworks/7 gnome/genmarshal/main.c.in
new file mode 100644
index 0000000..8e3ca7a
--- /dev/null
+++ b/test cases/frameworks/7 gnome/genmarshal/main.c.in
@@ -0,0 +1,102 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib-object.h>
+#include @MARSHALLER_HEADER@
+
+static int singleton = 42;
+
+void foo(gpointer user_data, gpointer data) {
+ if (user_data != &singleton) {
+ fprintf(stderr, "Invoked foo function was passed incorrect user data.\n");
+ exit(1);
+ }
+}
+
+void bar(gpointer user_data, gint param1, gpointer data) {
+ if (param1 != singleton) {
+ fprintf(stderr, "Invoked bar function was passed incorrect param1, but %d.\n", param1);
+ exit(2);
+ }
+ if (user_data != &singleton) {
+ fprintf(stderr, "Invoked bar function was passed incorrect user data.\n");
+ exit(3);
+ }
+}
+
+gfloat baz(gpointer user_data, gboolean param1, guchar param2, gpointer data) {
+ if (param1 != TRUE) {
+ fprintf(stderr, "Invoked baz function was passed incorrect param1.\n");
+ exit(4);
+ }
+ if (param2 != singleton) {
+ fprintf(stderr, "Invoked baz function was passed incorrect param2.\n");
+ exit(5);
+ }
+ if (user_data != &singleton) {
+ fprintf(stderr, "Invoked baz function was passed incorrect user data.\n");
+ exit(6);
+ }
+ return (gfloat)param2;
+}
+
+int main(int argc, char **argv) {
+ GClosure *cc_foo, *cc_bar, *cc_baz;
+ GValue return_value = G_VALUE_INIT;
+ GValue param_values[3] = {G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT};
+
+ fprintf(stderr, "Invoking foo function.\n");
+ cc_foo = g_cclosure_new(G_CALLBACK(foo), NULL, NULL);
+ g_closure_set_marshal(cc_foo, g_cclosure_user_marshal_VOID__VOID);
+ g_value_init(&param_values[0], G_TYPE_POINTER);
+ g_value_set_pointer(&param_values[0], &singleton);
+ g_closure_invoke(cc_foo, &return_value, 1, param_values, NULL);
+ if (G_VALUE_TYPE(&return_value) != G_TYPE_INVALID) {
+ fprintf(stderr, "Invoked foo function did not return empty value, but %s.\n",
+ G_VALUE_TYPE_NAME(&return_value));
+ return 7;
+ }
+ g_value_unset(&param_values[0]);
+ g_value_unset(&return_value);
+ g_closure_unref(cc_foo);
+
+ fprintf(stderr, "Invoking bar function.\n");
+ cc_bar = g_cclosure_new(G_CALLBACK(bar), NULL, NULL);
+ g_closure_set_marshal(cc_bar, g_cclosure_user_marshal_VOID__INT);
+ g_value_init(&param_values[0], G_TYPE_POINTER);
+ g_value_set_pointer(&param_values[0], &singleton);
+ g_value_init(&param_values[1], G_TYPE_INT);
+ g_value_set_int(&param_values[1], 42);
+ g_closure_invoke(cc_bar, &return_value, 2, param_values, NULL);
+ if (G_VALUE_TYPE(&return_value) != G_TYPE_INVALID) {
+ fprintf(stderr, "Invoked bar function did not return empty value.\n");
+ return 8;
+ }
+ g_value_unset(&param_values[0]);
+ g_value_unset(&param_values[1]);
+ g_value_unset(&return_value);
+ g_closure_unref(cc_bar);
+
+ fprintf(stderr, "Invoking baz function.\n");
+ cc_baz = g_cclosure_new(G_CALLBACK(baz), NULL, NULL);
+ g_closure_set_marshal(cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR);
+ g_value_init(&param_values[0], G_TYPE_POINTER);
+ g_value_set_pointer(&param_values[0], &singleton);
+ g_value_init(&param_values[1], G_TYPE_BOOLEAN);
+ g_value_set_boolean(&param_values[1], TRUE);
+ g_value_init(&param_values[2], G_TYPE_UCHAR);
+ g_value_set_uchar(&param_values[2], 42);
+ g_value_init(&return_value, G_TYPE_FLOAT);
+ g_closure_invoke(cc_baz, &return_value, 3, param_values, NULL);
+ if (g_value_get_float(&return_value) != 42.0f) {
+ fprintf(stderr, "Invoked baz function did not return expected value.\n");
+ return 9;
+ }
+ g_value_unset(&param_values[0]);
+ g_value_unset(&param_values[1]);
+ g_value_unset(&param_values[2]);
+ g_value_unset(&return_value);
+ g_closure_unref(cc_baz);
+
+ fprintf(stderr, "All ok.\n");
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/genmarshal/marshaller.list b/test cases/frameworks/7 gnome/genmarshal/marshaller.list
new file mode 100644
index 0000000..a29f6c9
--- /dev/null
+++ b/test cases/frameworks/7 gnome/genmarshal/marshaller.list
@@ -0,0 +1,3 @@
+VOID:VOID
+VOID:INT
+FLOAT:BOOLEAN,UCHAR
diff --git a/test cases/frameworks/7 gnome/genmarshal/meson.build b/test cases/frameworks/7 gnome/genmarshal/meson.build
new file mode 100644
index 0000000..9a2cd7a
--- /dev/null
+++ b/test cases/frameworks/7 gnome/genmarshal/meson.build
@@ -0,0 +1,54 @@
+m_list = configure_file(input: 'marshaller.list',
+ output: 'm.list',
+ copy: true)
+
+idx = 0
+mlists = ['marshaller.list', files('marshaller.list'), m_list]
+
+foreach mlist : mlists
+ marshallers = gnome.genmarshal('marshaller-@0@'.format(idx),
+ sources : mlist,
+ install_header : true,
+ install_dir : get_option('includedir') / 'subdir-@0@'.format(idx),
+ extra_args : ['-UG_ENABLE_DEBUG', '--prototypes'])
+
+ marshaller_c = marshallers[0]
+ marshaller_h = marshallers[1]
+
+ cdata = configuration_data()
+ cdata.set_quoted('MARSHALLER_HEADER', 'marshaller-@0@.h'.format(idx))
+
+ main_c = configure_file(input: 'main.c.in',
+ output: 'main-@0@.c'.format(idx),
+ configuration: cdata)
+
+ genmarshalexe = executable('genmarshalprog-@0@'.format(idx),
+ main_c, marshaller_c, marshaller_h,
+ dependencies : gobj)
+ test('genmarshal test @0@'.format(idx), genmarshalexe)
+ idx += 1
+endforeach
+
+foreach mlist : mlists
+ marshallers = gnome.genmarshal('marshaller-@0@'.format(idx),
+ sources : [mlist],
+ install_header : true,
+ install_dir : get_option('includedir') / 'subdir-@0@'.format(idx),
+ extra_args : ['-UG_ENABLE_DEBUG', '--prototypes'])
+
+ marshaller_c = marshallers[0]
+ marshaller_h = marshallers[1]
+
+ cdata = configuration_data()
+ cdata.set_quoted('MARSHALLER_HEADER', 'marshaller-@0@.h'.format(idx))
+
+ main_c = configure_file(input: 'main.c.in',
+ output: 'main-@0@.c'.format(idx),
+ configuration: cdata)
+
+ genmarshalexe = executable('genmarshalprog-@0@'.format(idx),
+ main_c, marshaller_c, marshaller_h,
+ dependencies : gobj)
+ test('genmarshal test @0@'.format(idx), genmarshalexe)
+ idx += 1
+endforeach
diff --git a/test cases/frameworks/7 gnome/gir/copy.py b/test cases/frameworks/7 gnome/gir/copy.py
new file mode 100755
index 0000000..fa70145
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/copy.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
+# Copyright © 2021 Intel Corproation
+
+import argparse
+import shutil
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('src')
+ parser.add_argument('dest')
+ args = parser.parse_args()
+
+ shutil.copy(args.src, args.dest)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep1.c b/test cases/frameworks/7 gnome/gir/dep1/dep1.c
new file mode 100644
index 0000000..8d4ca4b
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep1.c
@@ -0,0 +1,56 @@
+#include "dep1.h"
+
+struct _MesonDep1
+{
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (MesonDep1, meson_dep1, G_TYPE_OBJECT)
+
+/**
+ * meson_dep1_new:
+ *
+ * Allocates a new #MesonDep1.
+ *
+ * Returns: (transfer full): a #MesonDep1.
+ */
+MesonDep1 *
+meson_dep1_new (void)
+{
+ return g_object_new (MESON_TYPE_DEP1, NULL);
+}
+
+static void
+meson_dep1_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (meson_dep1_parent_class)->finalize (object);
+}
+
+static void
+meson_dep1_class_init (MesonDep1Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_dep1_finalize;
+}
+
+static void
+meson_dep1_init (MesonDep1 *self)
+{
+}
+
+/**
+ * meson_dep1_just_return_it:
+ * @dep: a #MesonDep2.
+ *
+ * Returns the #MesonDep2 that is passed in
+ *
+ * Returns: (transfer none): a #MesonDep2
+ */
+MesonDep2*
+meson_dep1_just_return_it (MesonDep1 *self, MesonDep2 *dep)
+{
+ g_return_val_if_fail (MESON_IS_DEP1 (self), NULL);
+
+ return dep;
+}
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep1.h b/test cases/frameworks/7 gnome/gir/dep1/dep1.h
new file mode 100644
index 0000000..92fc44c
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep1.h
@@ -0,0 +1,23 @@
+#ifndef MESON_DEP1_H
+#define MESON_DEP1_H
+
+#if !defined (MESON_TEST)
+#error "MESON_TEST not defined."
+#endif
+
+#include <glib-object.h>
+#include "dep2/dep2.h"
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_DEP1 (meson_dep1_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonDep1, meson_dep1, MESON, DEP1, GObject)
+
+MesonDep1 *meson_dep1_new (void);
+MesonDep2 *meson_dep1_just_return_it (MesonDep1 *self,
+ MesonDep2 *dep);
+
+G_END_DECLS
+
+#endif /* MESON_DEP1_H */
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c
new file mode 100644
index 0000000..754c6d7
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c
@@ -0,0 +1,124 @@
+#include "dep2.h"
+
+struct _MesonDep2
+{
+ GObject parent_instance;
+
+ gchar *msg;
+};
+
+G_DEFINE_TYPE (MesonDep2, meson_dep2, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_dep2_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonDep2.
+ *
+ * Returns: (transfer full): a #MesonDep2.
+ */
+MesonDep2 *
+meson_dep2_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_DEP2,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_dep2_finalize (GObject *object)
+{
+ MesonDep2 *self = (MesonDep2 *)object;
+
+ g_clear_pointer (&self->msg, g_free);
+
+ G_OBJECT_CLASS (meson_dep2_parent_class)->finalize (object);
+}
+
+static void
+meson_dep2_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonDep2 *self = MESON_DEP2 (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, self->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_dep2_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonDep2 *self = MESON_DEP2 (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ self->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_dep2_class_init (MesonDep2Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_dep2_finalize;
+ object_class->get_property = meson_dep2_get_property;
+ object_class->set_property = meson_dep2_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_dep2_init (MesonDep2 *self)
+{
+}
+
+/**
+ * meson_dep2_return_message:
+ * @self: a #MesonDep2.
+ *
+ * Returns the message.
+ *
+ * Returns: (transfer none): a const gchar*
+ */
+const gchar*
+meson_dep2_return_message (MesonDep2 *self)
+{
+ g_return_val_if_fail (MESON_IS_DEP2 (self), NULL);
+
+ return (const gchar*) self->msg;
+}
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h
new file mode 100644
index 0000000..0afea90
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h
@@ -0,0 +1,21 @@
+#ifndef MESON_DEP2_H
+#define MESON_DEP2_H
+
+#if !defined (MESON_TEST)
+#error "MESON_TEST not defined."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_DEP2 (meson_dep2_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonDep2, meson_dep2, MESON, DEP2, GObject)
+
+MesonDep2 *meson_dep2_new (const gchar *msg);
+const gchar *meson_dep2_return_message (MesonDep2 *self);
+
+G_END_DECLS
+
+#endif /* MESON_DEP2_H */
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build b/test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build
new file mode 100644
index 0000000..4004f22
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build
@@ -0,0 +1,22 @@
+dep2sources = ['dep2.c', 'dep2.h']
+
+dep2lib = shared_library(
+ 'dep2lib',
+ sources : dep2sources,
+ dependencies : gobj,
+ install : true
+)
+
+dep2gir = gnome.generate_gir(
+ dep2lib,
+ sources : dep2sources,
+ nsversion : '1.0',
+ namespace : 'MesonDep2',
+ symbol_prefix : 'meson',
+ identifier_prefix : 'Meson',
+ includes : ['GObject-2.0'],
+ install : true
+)
+
+dep2_dep = declare_dependency(link_with : dep2lib,
+ sources : [dep2gir])
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.c b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.c
new file mode 100644
index 0000000..ee5c5e1
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.c
@@ -0,0 +1,124 @@
+#include "dep3.h"
+
+struct _MesonDep3
+{
+ GObject parent_instance;
+
+ gchar *msg;
+};
+
+G_DEFINE_TYPE (MesonDep3, meson_dep3, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_dep3_new:
+ * @msg: The message to set.
+ *
+ * Allocates a new #MesonDep3.
+ *
+ * Returns: (transfer full): a #MesonDep3.
+ */
+MesonDep3 *
+meson_dep3_new (const gchar *msg)
+{
+ g_return_val_if_fail (msg != NULL, NULL);
+
+ return g_object_new (MESON_TYPE_DEP3,
+ "message", msg,
+ NULL);
+}
+
+static void
+meson_dep3_finalize (GObject *object)
+{
+ MesonDep3 *self = (MesonDep3 *)object;
+
+ g_clear_pointer (&self->msg, g_free);
+
+ G_OBJECT_CLASS (meson_dep3_parent_class)->finalize (object);
+}
+
+static void
+meson_dep3_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonDep3 *self = MESON_DEP3 (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, self->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_dep3_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonDep3 *self = MESON_DEP3 (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ self->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_dep3_class_init (MesonDep3Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_dep3_finalize;
+ object_class->get_property = meson_dep3_get_property;
+ object_class->set_property = meson_dep3_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_dep3_init (MesonDep3 *self)
+{
+}
+
+/**
+ * meson_dep3_return_message:
+ * @self: a #MesonDep3.
+ *
+ * Returns the message.
+ *
+ * Returns: (transfer none): a const gchar*
+ */
+const gchar*
+meson_dep3_return_message (MesonDep3 *self)
+{
+ g_return_val_if_fail (MESON_IS_DEP3 (self), NULL);
+
+ return (const gchar*) self->msg;
+}
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.h b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.h
new file mode 100644
index 0000000..9883d76
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep3/dep3.h
@@ -0,0 +1,21 @@
+#ifndef MESON_DEP3_H
+#define MESON_DEP3_H
+
+#if !defined (MESON_TEST)
+#error "MESON_TEST not defined."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_DEP3 (meson_dep3_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonDep3, meson_dep3, MESON, DEP3, GObject)
+
+MesonDep3 *meson_dep3_new (const gchar *msg);
+const gchar *meson_dep3_return_message (MesonDep3 *self);
+
+G_END_DECLS
+
+#endif /* MESON_DEP3_H */
diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build b/test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build
new file mode 100644
index 0000000..1ef7765
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/dep3/meson.build
@@ -0,0 +1,22 @@
+dep3sources = ['dep3.c', 'dep3.h']
+
+dep3lib = shared_library(
+ 'dep3lib',
+ sources : dep3sources,
+ dependencies : gobj,
+ install : true
+)
+
+dep3gir = gnome.generate_gir(
+ dep3lib,
+ sources : dep3sources,
+ nsversion : '1.0',
+ namespace : 'MesonDep3',
+ symbol_prefix : 'meson',
+ identifier_prefix : 'Meson',
+ includes : ['GObject-2.0'],
+ install : true
+)
+
+dep3_dep = declare_dependency(link_with : dep3lib,
+ sources : [dep3gir])
diff --git a/test cases/frameworks/7 gnome/gir/dep1/meson.build b/test cases/frameworks/7 gnome/gir/dep1/meson.build
new file mode 100644
index 0000000..2f03ede
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/dep1/meson.build
@@ -0,0 +1,31 @@
+subdir('dep2')
+subdir('dep3')
+
+dep1sources = ['dep1.c', 'dep1.h']
+
+# Do not need to link to dep2lib because we don't use any symbols from it
+dep1lib = shared_library(
+ 'dep1lib',
+ sources : dep1sources,
+ dependencies : gobj,
+ install : true
+)
+
+# But the gir does need it because it we use the MesonDep2* structure defined
+# in the header
+dep1gir = gnome.generate_gir(
+ dep1lib,
+ sources : dep1sources,
+ nsversion : '1.0',
+ namespace : 'MesonDep1',
+ symbol_prefix : 'meson',
+ identifier_prefix : 'Meson',
+ header: 'dep1.h',
+ includes : ['GObject-2.0', 'MesonDep2-1.0', dep3gir[0]],
+ dependencies : [dep2_dep],
+ install : true
+)
+
+dep1_dep = declare_dependency(link_with : dep1lib,
+ dependencies : [dep2_dep, dep3_dep],
+ sources : [dep1gir])
diff --git a/test cases/frameworks/7 gnome/gir/meson-sample.c b/test cases/frameworks/7 gnome/gir/meson-sample.c
new file mode 100644
index 0000000..850b850
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/meson-sample.c
@@ -0,0 +1,121 @@
+#include "meson-sample.h"
+
+struct _MesonSample
+{
+ GObject parent_instance;
+
+ gchar *msg;
+};
+
+G_DEFINE_TYPE (MesonSample, meson_sample, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_MSG,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * meson_sample_new:
+ *
+ * Allocates a new #MesonSample.
+ *
+ * Returns: (transfer full): a #MesonSample.
+ */
+MesonSample *
+meson_sample_new (void)
+{
+ return g_object_new (MESON_TYPE_SAMPLE, NULL);
+}
+
+static void
+meson_sample_finalize (GObject *object)
+{
+ MesonSample *self = (MesonSample *)object;
+
+ g_clear_pointer (&self->msg, g_free);
+
+ G_OBJECT_CLASS (meson_sample_parent_class)->finalize (object);
+}
+
+static void
+meson_sample_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSample *self = MESON_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ g_value_set_string (value, self->msg);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MesonSample *self = MESON_SAMPLE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MSG:
+ self->msg = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meson_sample_class_init (MesonSampleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meson_sample_finalize;
+ object_class->get_property = meson_sample_get_property;
+ object_class->set_property = meson_sample_set_property;
+
+ gParamSpecs [PROP_MSG] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message to print.",
+ NULL,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+}
+
+static void
+meson_sample_init (MesonSample *self)
+{
+}
+
+/**
+ * meson_sample_print_message:
+ * @self: a #MesonSample.
+ *
+ * Prints the message.
+ *
+ * Returns: Nothing.
+ */
+void
+meson_sample_print_message (MesonSample *self, MesonDep1 *dep1, MesonDep2 *dep2)
+{
+ MesonDep2 *samedep;
+ g_return_if_fail (MESON_IS_SAMPLE (self));
+
+ samedep = meson_dep1_just_return_it (dep1, dep2);
+ g_print ("Message: %s\n", meson_dep2_return_message (samedep));
+}
diff --git a/test cases/frameworks/7 gnome/gir/meson-sample.h b/test cases/frameworks/7 gnome/gir/meson-sample.h
new file mode 100644
index 0000000..04e79b8
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/meson-sample.h
@@ -0,0 +1,24 @@
+#ifndef MESON_SAMPLE_H
+#define MESON_SAMPLE_H
+
+#if !defined (MESON_TEST)
+#error "MESON_TEST not defined."
+#endif
+
+#include <glib-object.h>
+#include "dep1/dep1.h"
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SAMPLE (meson_sample_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject)
+
+MesonSample *meson_sample_new (void);
+void meson_sample_print_message (MesonSample *self,
+ MesonDep1 *dep1,
+ MesonDep2 *dep2);
+
+G_END_DECLS
+
+#endif /* MESON_SAMPLE_H */
diff --git a/test cases/frameworks/7 gnome/gir/meson-sample2.c b/test cases/frameworks/7 gnome/gir/meson-sample2.c
new file mode 100644
index 0000000..f76bc16
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/meson-sample2.c
@@ -0,0 +1,45 @@
+#include "meson-sample2.h"
+
+struct _MesonSample2
+{
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (MesonSample2, meson_sample2, G_TYPE_OBJECT)
+
+/**
+ * meson_sample2_new:
+ *
+ * Allocates a new #MesonSample2.
+ *
+ * Returns: (transfer full): a #MesonSample2.
+ */
+MesonSample2 *
+meson_sample2_new (void)
+{
+ return g_object_new (MESON_TYPE_SAMPLE2, NULL);
+}
+
+static void
+meson_sample2_class_init (MesonSample2Class *klass)
+{
+}
+
+static void
+meson_sample2_init (MesonSample2 *self)
+{
+}
+
+/**
+ * meson_sample2_print_message:
+ * @self: a #MesonSample2.
+ *
+ * Prints Hello.
+ *
+ * Returns: Nothing.
+ */
+void
+meson_sample2_print_message (MesonSample2 *self)
+{
+ g_print ("Message: Hello\n");
+}
diff --git a/test cases/frameworks/7 gnome/gir/meson-sample2.h b/test cases/frameworks/7 gnome/gir/meson-sample2.h
new file mode 100644
index 0000000..d39084e
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/meson-sample2.h
@@ -0,0 +1,21 @@
+#ifndef MESON_SAMPLE2_H
+#define MESON_SAMPLE2_H
+
+#if !defined (MESON_TEST)
+#error "MESON_TEST not defined."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MESON_TYPE_SAMPLE2 (meson_sample2_get_type())
+
+G_DECLARE_FINAL_TYPE (MesonSample2, meson_sample2, MESON, SAMPLE2, GObject)
+
+MesonSample2 *meson_sample2_new (void);
+void meson_sample2_print_message (MesonSample2 *self);
+
+G_END_DECLS
+
+#endif /* MESON_SAMPLE2_H */
diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build
new file mode 100644
index 0000000..fbff206
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/meson.build
@@ -0,0 +1,60 @@
+subdir('dep1')
+
+libsources = ['meson-sample.c', 'meson-sample.h']
+lib2sources = ['meson-sample2.c', 'meson-sample2.h']
+
+gen_source = custom_target(
+ 'meson_smaple3.h',
+ input : 'meson-sample.h',
+ output : 'meson-sample3.h',
+ command : [find_program('copy.py'), '@INPUT@', '@OUTPUT@'],
+ build_by_default : false, # this will force a race condition if one exists
+)
+
+girlib = shared_library(
+ 'gir_lib',
+ sources : libsources,
+ dependencies : [gobj, dep1_dep],
+ install : true
+)
+
+girlib2 = shared_library(
+ 'gir_lib2',
+ sources : lib2sources,
+ dependencies : [gobj],
+ install : true
+)
+
+girexe = executable(
+ 'girprog',
+ sources : 'prog.c',
+ dependencies : [glib, gobj, gir, dep1_dep],
+ link_with : girlib
+)
+
+fake_dep = dependency('no-way-this-exists', required: false)
+
+gnome.generate_gir(
+ girlib, girlib2,
+ sources : [libsources, lib2sources, gen_source],
+ nsversion : '1.0',
+ namespace : 'Meson',
+ symbol_prefix : 'meson',
+ identifier_prefix : 'Meson',
+ includes : ['GObject-2.0', 'MesonDep1-1.0'],
+ # dep1_dep pulls in dep2_dep for us
+ dependencies : [[fake_dep, dep1_dep]],
+ install : true,
+ build_by_default : true,
+)
+
+test('gobject introspection/c', girexe)
+gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir(), dep3lib.outdir()])
+envdata = environment()
+envdata.append('GI_TYPELIB_PATH', gir_paths, separator : ':')
+envdata.append('LD_LIBRARY_PATH', gir_paths)
+if ['windows', 'cygwin'].contains(host_machine.system())
+ envdata.append('PATH', gir_paths)
+endif
+test('gobject introspection/py', find_program('prog.py'),
+ env : envdata)
diff --git a/test cases/frameworks/7 gnome/gir/prog.c b/test cases/frameworks/7 gnome/gir/prog.c
new file mode 100644
index 0000000..001f6d0
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/prog.c
@@ -0,0 +1,35 @@
+#include <girepository.h>
+
+#include "meson-sample.h"
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ GError * error = NULL;
+
+ GOptionContext * ctx = g_option_context_new (NULL);
+ g_option_context_add_group (ctx, g_irepository_get_option_group ());
+
+ if (!g_option_context_parse (ctx, &argc, &argv, &error)) {
+ g_print ("sample: %s\n", error->message);
+ g_option_context_free (ctx);
+ if (error) {
+ g_error_free (error);
+ }
+
+ return 1;
+ }
+
+ MesonSample * i = meson_sample_new ();
+ MesonDep1 * dep1 = meson_dep1_new ();
+ MesonDep2 * dep2 = meson_dep2_new ("Hello, meson/c!");
+ meson_sample_print_message (i, dep1, dep2);
+
+ g_object_unref (i);
+ g_object_unref (dep1);
+ g_object_unref (dep2);
+ g_option_context_free (ctx);
+
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/gir/prog.py b/test cases/frameworks/7 gnome/gir/prog.py
new file mode 100755
index 0000000..aa1f9a7
--- /dev/null
+++ b/test cases/frameworks/7 gnome/gir/prog.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+from gi.repository import Meson, MesonDep1, MesonDep2
+
+if __name__ == "__main__":
+ s = Meson.Sample.new()
+ dep1 = MesonDep1.Dep1.new()
+ dep2 = MesonDep2.Dep2.new("Hello, meson/py!")
+ s.print_message(dep1, dep2)
+
+ s2 = Meson.Sample2.new()
+ s2.print_message()
diff --git a/test cases/frameworks/7 gnome/meson.build b/test cases/frameworks/7 gnome/meson.build
new file mode 100644
index 0000000..5f438cb
--- /dev/null
+++ b/test cases/frameworks/7 gnome/meson.build
@@ -0,0 +1,63 @@
+project('gobject-introspection', 'c')
+
+copyfile = find_program('copyfile.py')
+copyfile_gen = generator(copyfile,
+ output: '@BASENAME@Gen.xml',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+glib = dependency('glib-2.0', required: false)
+if not glib.found()
+ error('MESON_SKIP_TEST glib not found.')
+endif
+
+gir = dependency('gobject-introspection-1.0', required: false)
+if not gir.found()
+ error('MESON_SKIP_TEST gobject-introspection not found.')
+endif
+
+python3 = import('python3')
+py3 = python3.find_python()
+if run_command(py3, '-c', 'import gi;', check: false).returncode() != 0
+ error('MESON_SKIP_TEST python3-gi not found')
+endif
+
+cc = meson.get_compiler('c')
+
+add_global_arguments('-DMESON_TEST', language : 'c')
+if cc.get_id() == 'intel'
+ # Ignore invalid GCC pragma warnings from glib
+ # https://bugzilla.gnome.org/show_bug.cgi?id=776562
+ add_global_arguments('-wd2282', language : 'c')
+endif
+
+py3 = import('python3').find_python()
+pycode = '''import os, sys
+if "MESON_UNIT_TEST_PRETEND_GLIB_OLD" in os.environ:
+ sys.exit(0)
+sys.exit(1)
+'''
+
+pretend_glib_old = false
+res = run_command(py3, '-c', pycode, check: false)
+if res.returncode() == 0
+ pretend_glib_old = true
+endif
+
+gnome = import('gnome')
+gio = dependency('gio-2.0')
+giounix = dependency('gio-unix-2.0')
+glib = dependency('glib-2.0')
+gobj = dependency('gobject-2.0')
+gir = dependency('gobject-introspection-1.0')
+gmod = dependency('gmodule-2.0')
+
+# Test that static deps don't error out when static libraries aren't found
+glib_static = dependency('glib-2.0', static : true)
+
+subdir('resources-data')
+subdir('resources')
+subdir('gir')
+subdir('schemas')
+subdir('gdbus')
+subdir('mkenums')
+subdir('genmarshal')
diff --git a/test cases/frameworks/7 gnome/mkenums/enums.c.in b/test cases/frameworks/7 gnome/mkenums/enums.c.in
new file mode 100644
index 0000000..1c19d8f
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/enums.c.in
@@ -0,0 +1,41 @@
+/*** BEGIN file-header ***/
+
+#include "enums.h"
+
+/*** END file-header ***/
+/*** BEGIN file-production ***/
+
+/* enumerations from "@basename@" */
+#include "@basename@"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type(void) {
+ static gsize static_g_define_type_id = 0;
+
+ if(g_once_init_enter(&static_g_define_type_id)) {
+ static const G@Type@Value values [] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+
+ GType g_define_type_id =
+ g_@type@_register_static(g_intern_static_string("@EnumName@"), values);
+ g_once_init_leave(&static_g_define_type_id, g_define_type_id);
+ }
+
+ return static_g_define_type_id;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/test cases/frameworks/7 gnome/mkenums/enums.h.in b/test cases/frameworks/7 gnome/mkenums/enums.h.in
new file mode 100644
index 0000000..479867f
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/enums.h.in
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef MESON_ENUMS_H
+#define MESON_ENUMS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@basename@" */
+/*** END file-production ***/
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type(void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+
+G_END_DECLS
+
+#endif /* MESON_ENUMS_H */
+/*** END file-tail ***/
diff --git a/test cases/frameworks/7 gnome/mkenums/enums2.c.in b/test cases/frameworks/7 gnome/mkenums/enums2.c.in
new file mode 100644
index 0000000..1c19d8f
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/enums2.c.in
@@ -0,0 +1,41 @@
+/*** BEGIN file-header ***/
+
+#include "enums.h"
+
+/*** END file-header ***/
+/*** BEGIN file-production ***/
+
+/* enumerations from "@basename@" */
+#include "@basename@"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type(void) {
+ static gsize static_g_define_type_id = 0;
+
+ if(g_once_init_enter(&static_g_define_type_id)) {
+ static const G@Type@Value values [] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+
+ GType g_define_type_id =
+ g_@type@_register_static(g_intern_static_string("@EnumName@"), values);
+ g_once_init_leave(&static_g_define_type_id, g_define_type_id);
+ }
+
+ return static_g_define_type_id;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/test cases/frameworks/7 gnome/mkenums/enums2.h.in b/test cases/frameworks/7 gnome/mkenums/enums2.h.in
new file mode 100644
index 0000000..479867f
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/enums2.h.in
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef MESON_ENUMS_H
+#define MESON_ENUMS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@basename@" */
+/*** END file-production ***/
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type(void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+
+G_END_DECLS
+
+#endif /* MESON_ENUMS_H */
+/*** END file-tail ***/
diff --git a/test cases/frameworks/7 gnome/mkenums/main.c b/test cases/frameworks/7 gnome/mkenums/main.c
new file mode 100644
index 0000000..d257185
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/main.c
@@ -0,0 +1,30 @@
+#include<stdio.h>
+#include<string.h>
+#include<glib-object.h>
+#include"meson-sample.h"
+#include"@ENUM_FILE@"
+
+int main(int argc, char **argv) {
+ GEnumClass *xenum = g_type_class_ref(MESON_TYPE_THE_XENUM);
+ GFlagsClass *flags_enum = g_type_class_ref(MESON_TYPE_THE_FLAGS_ENUM);
+ if (g_enum_get_value_by_name(xenum, "MESON_THE_XVALUE")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by name failed.\n");
+ return 1;
+ }
+ if (g_enum_get_value_by_nick(xenum, "the-xvalue")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by nick failed.\n");
+ return 2;
+ }
+ if (g_flags_get_value_by_name(flags_enum, "MESON_THE_FIRST_VALUE")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by name failed.\n");
+ return 3;
+ }
+ if (g_flags_get_value_by_nick(flags_enum, "the-first-value")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by nick failed.\n");
+ return 4;
+ }
+ g_type_class_unref(xenum);
+ g_type_class_unref(flags_enum);
+ fprintf(stderr, "All ok.\n");
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/mkenums/main4.c b/test cases/frameworks/7 gnome/mkenums/main4.c
new file mode 100644
index 0000000..3df4dd8
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/main4.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <string.h>
+#include <glib-object.h>
+#include "enums4.h"
+#include "meson-sample.h"
+
+int main(int argc, char **argv) {
+ GEnumClass *xenum = g_type_class_ref(MESON_TYPE_THE_XENUM);
+ GFlagsClass *flags_enum = g_type_class_ref(MESON_TYPE_THE_FLAGS_ENUM);
+ if (g_enum_get_value_by_name(xenum, "MESON_THE_XVALUE")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by name failed.\n");
+ return 1;
+ }
+ if (g_enum_get_value_by_nick(xenum, "the-xvalue")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by nick failed.\n");
+ return 2;
+ }
+ if (g_flags_get_value_by_name(flags_enum, "MESON_THE_FIRST_VALUE")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by name failed.\n");
+ return 3;
+ }
+ if (g_flags_get_value_by_nick(flags_enum, "the-first-value")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by nick failed.\n");
+ return 4;
+ }
+
+ /* Make sure that funcs are generated with leading underscore as requested */
+ if (!_meson_the_xenum_get_type())
+ g_error ("Bad!");
+
+ g_type_class_unref(xenum);
+ g_type_class_unref(flags_enum);
+ fprintf(stderr, "All ok.\n");
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/mkenums/main5.c b/test cases/frameworks/7 gnome/mkenums/main5.c
new file mode 100644
index 0000000..ed1ccfd
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/main5.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <string.h>
+#include <glib-object.h>
+#include "enums5.h"
+#include "meson-sample.h"
+
+int main(int argc, char **argv) {
+ GEnumClass *xenum = g_type_class_ref(MESON_TYPE_THE_XENUM);
+ GFlagsClass *flags_enum = g_type_class_ref(MESON_TYPE_THE_FLAGS_ENUM);
+ if (g_enum_get_value_by_name(xenum, "MESON_THE_XVALUE")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by name failed.\n");
+ return 1;
+ }
+ if (g_enum_get_value_by_nick(xenum, "the-xvalue")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by nick failed.\n");
+ return 2;
+ }
+ if (g_flags_get_value_by_name(flags_enum, "MESON_THE_FIRST_VALUE")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by name failed.\n");
+ return 3;
+ }
+ if (g_flags_get_value_by_nick(flags_enum, "the-first-value")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by nick failed.\n");
+ return 4;
+ }
+
+ /* Make sure that funcs do not have any extra prefix */
+ if (!meson_the_xenum_get_type())
+ g_error ("Bad!");
+
+ g_type_class_unref(xenum);
+ g_type_class_unref(flags_enum);
+ fprintf(stderr, "All ok.\n");
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/mkenums/meson-decls.h b/test cases/frameworks/7 gnome/mkenums/meson-decls.h
new file mode 100644
index 0000000..ba94eb9
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/meson-decls.h
@@ -0,0 +1,2 @@
+#pragma once
+#define MESON_EXPORT extern
diff --git a/test cases/frameworks/7 gnome/mkenums/meson-sample.h b/test cases/frameworks/7 gnome/mkenums/meson-sample.h
new file mode 100644
index 0000000..ee7b5cb
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/meson-sample.h
@@ -0,0 +1,20 @@
+#pragma once
+
+typedef enum
+{
+ MESON_THE_XVALUE,
+ MESON_ANOTHER_VALUE
+} MesonTheXEnum;
+
+typedef enum /*< skip >*/
+{
+ MESON_FOO
+} MesonThisEnumWillBeSkipped;
+
+typedef enum /*< flags,prefix=MESON >*/
+{
+ MESON_THE_ZEROTH_VALUE, /*< skip >*/
+ MESON_THE_FIRST_VALUE,
+ MESON_THE_SECOND_VALUE,
+ MESON_THE_THIRD_VALUE, /*< nick=the-last-value >*/
+} MesonTheFlagsEnum;
diff --git a/test cases/frameworks/7 gnome/mkenums/meson.build b/test cases/frameworks/7 gnome/mkenums/meson.build
new file mode 100644
index 0000000..4cf4dcf
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/meson.build
@@ -0,0 +1,164 @@
+# Generate both header and source via template together.
+
+myenums = gnome.mkenums('abc1',
+ sources : 'meson-sample.h',
+ h_template : 'enums.h.in',
+ c_template : 'enums.c.in',
+ install_header : true,
+ install_dir : get_option('includedir'))
+
+enums_c1 = myenums[0]
+enums_h1 = myenums[1]
+
+conf = configuration_data()
+conf.set('ENUM_FILE', 'enums.h')
+main = configure_file(
+ input : 'main.c',
+ output : 'main1.c',
+ configuration : conf)
+
+enumexe1 = executable('enumprog1', main, enums_c1, enums_h1,
+dependencies : gobj)
+test('enum test 1', enumexe1)
+
+# Generate both header and source via template individually and overriding.
+
+enums_h2 = gnome.mkenums('abc2',
+ sources : 'meson-sample.h',
+ h_template : 'enums2.h.in',
+ ftail : '/* trailing header file info */',
+ install_header : true,
+ install_dir : get_option('includedir'))
+
+enums_c2 = gnome.mkenums('abc2',
+ sources : 'meson-sample.h',
+ depends : [enums_h1, enums_h2],
+ c_template : 'enums2.c.in',
+ ftail : '/* trailing source file info */')
+# explicitly don't set install_dir here, for bug testing
+# See https://github.com/mesonbuild/meson/issues/9472
+
+conf = configuration_data()
+conf.set('ENUM_FILE', 'enums2.h')
+main = configure_file(
+ input : 'main.c',
+ output : 'main2.c',
+ configuration : conf)
+
+enumexe2 = executable('enumprog2', main, enums_c2, enums_h2,
+dependencies : gobj)
+test('enum test 2', enumexe2)
+
+# Generate both header and source by options only.
+# These are specified in a way that should produce the same result as above
+# (modulo any filename changes.)
+
+enums_h3 = gnome.mkenums('enums3.h',
+ sources : 'meson-sample.h',
+ fhead : '''#ifndef MESON_ENUMS_H
+#define MESON_ENUMS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+''',
+ fprod : '''
+/* enumerations from "@basename@" */
+''',
+ vhead : '''GType @enum_name@_get_type(void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+''',
+ ftail : '''
+G_END_DECLS
+
+#endif /* MESON_ENUMS_H */
+''',
+ install_header : true,
+ install_dir : get_option('includedir'))
+
+enums_c3 = gnome.mkenums('enums3.c',
+ sources : 'meson-sample.h',
+ depends : enums_h3,
+ fhead : '''#include "enums3.h"
+''',
+ fprod : '''
+
+/* enumerations from "@basename@" */
+#include "@basename@"
+''',
+ vhead : '''
+GType
+@enum_name@_get_type(void) {
+ static gsize static_g_define_type_id = 0;
+
+ if(g_once_init_enter(&static_g_define_type_id)) {
+ static const G@Type@Value values [] = {
+''',
+ vprod : ''' { @VALUENAME@, "@VALUENAME@", "@valuenick@" },''',
+ vtail : ''' { 0, NULL, NULL }
+ };
+
+ GType g_define_type_id =
+ g_@type@_register_static(g_intern_static_string("@EnumName@"), values);
+ g_once_init_leave(&static_g_define_type_id, g_define_type_id);
+ }
+
+ return static_g_define_type_id;
+}
+''')
+
+conf = configuration_data()
+conf.set('ENUM_FILE', 'enums3.h')
+main = configure_file(
+ input : 'main.c',
+ output : 'main3.c',
+ configuration : conf)
+
+enumexe3 = executable('enumprog3', main, enums_c3, enums_h3,
+dependencies : gobj)
+test('enum test 3', enumexe3)
+
+enums4 = gnome.mkenums_simple('enums4', sources : files('meson-sample.h'),
+ function_prefix : '_')
+enumexe4 = executable('enumprog4', 'main4.c', enums4, dependencies : gobj)
+
+enums5 = gnome.mkenums_simple('enums5', sources : 'meson-sample.h',
+ install_header : true,
+ decorator : 'MESON_EXPORT',
+ header_prefix : '#include "meson-decls.h"')
+
+conf = configuration_data()
+conf.set('ENUM_FILE', 'enums5.h')
+main = configure_file(
+ input : 'main.c',
+ output : 'main5.c',
+ configuration : conf)
+
+enumexe5 = executable('enumprog5', main, enums5, dependencies : gobj)
+
+# Generate template then use as input to mkenums
+
+# Simple trick to copy the file without substitutions, can be
+# removed when https://github.com/mesonbuild/meson/pull/3383 is fixed
+gen_h_template = configure_file(input: 'enums.h.in',
+ output: 'enums6.h.in',
+ configuration: configuration_data(),
+ format: 'cmake')
+
+enums_h6 = gnome.mkenums('enums6',
+ sources : 'meson-sample.h',
+ h_template : gen_h_template,
+ ftail : '/* trailing header file info */',
+ install_header : true,
+ install_dir : get_option('includedir'))
+
+conf = configuration_data()
+conf.set('ENUM_FILE', 'enums6.h')
+main = configure_file(
+ input : 'main.c',
+ output : 'main6.c',
+ configuration : conf)
+
+enumexe6 = executable('enumprog6', main, enums_c2, enums_h6,
+dependencies : gobj)
+test('enum test 4', enumexe6)
diff --git a/test cases/frameworks/7 gnome/resources-data/meson.build b/test cases/frameworks/7 gnome/resources-data/meson.build
new file mode 100644
index 0000000..31a577b
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources-data/meson.build
@@ -0,0 +1,18 @@
+subdir('subdir')
+
+python3 = import('python3').find_python()
+
+fake_generator_script = '''
+import os, sys
+assert os.path.exists(sys.argv[1]), "File %s not found" % sys.argv[1]
+print("This is a generated resource.")
+'''
+
+# Generate file res3.txt from file res3.txt.in. This is then included
+# in a GResource file, driven by resources/meson.build.
+res3_txt = custom_target('res3',
+ input: 'res3.txt.in',
+ output: 'res3.txt',
+ command: [python3, '-c', fake_generator_script, '@INPUT@'],
+ capture: true,
+)
diff --git a/test cases/frameworks/7 gnome/resources-data/res1.txt b/test cases/frameworks/7 gnome/resources-data/res1.txt
new file mode 100644
index 0000000..e10afea
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources-data/res1.txt
@@ -0,0 +1 @@
+This is a resource.
diff --git a/test cases/frameworks/7 gnome/resources-data/res3.txt.in b/test cases/frameworks/7 gnome/resources-data/res3.txt.in
new file mode 100644
index 0000000..077a8e3
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources-data/res3.txt.in
@@ -0,0 +1 @@
+This content is ignored, but Meson doesn't need to know that.
diff --git a/test cases/frameworks/7 gnome/resources-data/subdir/meson.build b/test cases/frameworks/7 gnome/resources-data/subdir/meson.build
new file mode 100644
index 0000000..b41300f
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources-data/subdir/meson.build
@@ -0,0 +1,8 @@
+cdata = configuration_data()
+cdata.set('NOISE', 'BARK')
+
+res4_txt = configure_file(
+ input: 'res4.txt.in',
+ output: 'res4.txt',
+ configuration: cdata
+)
diff --git a/test cases/frameworks/7 gnome/resources-data/subdir/res2.txt b/test cases/frameworks/7 gnome/resources-data/subdir/res2.txt
new file mode 100644
index 0000000..d297899
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources-data/subdir/res2.txt
@@ -0,0 +1 @@
+This is a resource in a subdirectory.
diff --git a/test cases/frameworks/7 gnome/resources-data/subdir/res4.txt.in b/test cases/frameworks/7 gnome/resources-data/subdir/res4.txt.in
new file mode 100644
index 0000000..c0ec6f2
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources-data/subdir/res4.txt.in
@@ -0,0 +1 @@
+@NOISE@ @NOISE@ @NOISE@
diff --git a/test cases/frameworks/7 gnome/resources/generated-main.c b/test cases/frameworks/7 gnome/resources/generated-main.c
new file mode 100644
index 0000000..d102604
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/generated-main.c
@@ -0,0 +1,26 @@
+#include<stdio.h>
+#include<string.h>
+#include<gio/gio.h>
+#include"generated-resources.h"
+
+#define EXPECTED "This is a generated resource.\n"
+
+int main(int argc, char **argv) {
+ generated_resources_get_resource();
+ GError *err = NULL;
+ GBytes *data = g_resources_lookup_data("/com/example/myprog/res3.txt",
+ G_RESOURCE_LOOKUP_FLAGS_NONE, &err);
+
+ if(data == NULL) {
+ fprintf(stderr, "Data lookup failed: %s\n", err->message);
+ return 1;
+ }
+ if(strcmp(g_bytes_get_data(data, NULL), EXPECTED) != 0) {
+ fprintf(stderr, "Resource contents are wrong:\n %s\n",
+ (const char*)g_bytes_get_data(data, NULL));
+ return 1;
+ }
+ fprintf(stdout, "All ok.\n");
+ g_bytes_unref(data);
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/resources/generated.gresource.xml b/test cases/frameworks/7 gnome/resources/generated.gresource.xml
new file mode 100644
index 0000000..7a242d7
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/generated.gresource.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/com/example/myprog">
+ <file>res1.txt</file>
+ <file>subdir/res2.txt</file>
+ <file>res3.txt</file>
+ <file>subdir/res4.txt</file>
+ </gresource>
+</gresources>
diff --git a/test cases/frameworks/7 gnome/resources/generated/meson.build b/test cases/frameworks/7 gnome/resources/generated/meson.build
new file mode 100644
index 0000000..9805c66
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/generated/meson.build
@@ -0,0 +1,4 @@
+ct_simple_gresource = custom_target(
+ input : '../simple.gresource.xml',
+ output : 'simple-ct.gresource.xml',
+ command : [copyfile, '@INPUT@', '@OUTPUT@'])
diff --git a/test cases/frameworks/7 gnome/resources/meson.build b/test cases/frameworks/7 gnome/resources/meson.build
new file mode 100644
index 0000000..60fc848
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/meson.build
@@ -0,0 +1,72 @@
+# There are two tests here, because the 2nd one depends on a version of
+# GLib (2.51.1) that is very recent at the time of writing.
+
+simple_gresource = configure_file(
+ input : 'simple.gresource.xml',
+ output : 'simple-gen.gresource.xml',
+ command : [copyfile, '@INPUT@', '@OUTPUT@'])
+
+simple_resources = gnome.compile_resources('simple-resources',
+ simple_gresource,
+ install_header : true,
+ export : true,
+ source_dir : '../resources-data',
+ c_name : 'simple_resources')
+
+simple_res_exe = executable('simple-resources-test',
+ 'simple-main.c', simple_resources,
+ dependencies: gio)
+test('simple resource test', simple_res_exe)
+
+gnome.compile_resources('simple-resources',
+ 'simple.gresource.xml',
+ gresource_bundle: true,
+ install: true,
+ install_dir: get_option('datadir'),
+ source_dir : '../resources-data',
+)
+test('simple resource test (gresource)', find_program('resources.py'))
+
+if not pretend_glib_old and glib.version() >= '2.52.0'
+ # This test cannot pass if GLib version is too old. Generated resource
+ # dependencies do not work correctly and Meson will raise an error if the
+ # user tries to use either the 'dependencies' kwarg or a gresource file that
+ # is itself generated.
+ generated_resources = gnome.compile_resources('generated-resources',
+ 'generated.gresource.xml',
+ source_dir : '../resources-data',
+ c_name : 'generated_resources',
+ dependencies : [res3_txt, res4_txt])
+
+ generated_res_exe = executable('generated-resources-test',
+ 'generated-main.c', generated_resources,
+ dependencies: gio)
+ test('generated resource test', generated_res_exe)
+
+ # Test with a CustomTarget
+ subdir('generated')
+
+ ct_resources = gnome.compile_resources(
+ 'ct-resources',
+ ct_simple_gresource,
+ install_header : true,
+ export : true,
+ source_dir : '../resources-data',
+ c_name : 'simple_resources')
+
+ cti_resources = gnome.compile_resources(
+ 'cti-resources',
+ ct_simple_gresource[0],
+ install_header : true,
+ export : true,
+ source_dir : '../resources-data',
+ c_name : 'simple_resources')
+endif
+
+# Test build_by_default
+gnome.compile_resources('build-resources',
+ 'simple.gresource.xml',
+ gresource_bundle : true,
+ build_by_default : true,
+ source_dir : '../resources-data',
+)
diff --git a/test cases/frameworks/7 gnome/resources/myresource.gresource.xml b/test cases/frameworks/7 gnome/resources/myresource.gresource.xml
new file mode 100644
index 0000000..7a242d7
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/myresource.gresource.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/com/example/myprog">
+ <file>res1.txt</file>
+ <file>subdir/res2.txt</file>
+ <file>res3.txt</file>
+ <file>subdir/res4.txt</file>
+ </gresource>
+</gresources>
diff --git a/test cases/frameworks/7 gnome/resources/res3.txt b/test cases/frameworks/7 gnome/resources/res3.txt
new file mode 100644
index 0000000..aeed4a5
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/res3.txt
@@ -0,0 +1 @@
+This file is from the wrong directory.
diff --git a/test cases/frameworks/7 gnome/resources/resources.py b/test cases/frameworks/7 gnome/resources/resources.py
new file mode 100644
index 0000000..0855ef7
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/resources.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+import os
+from gi.repository import Gio
+
+if __name__ == '__main__':
+ res = Gio.resource_load(os.path.join('resources', 'simple-resources.gresource'))
+ Gio.Resource._register(res)
+
+ data = Gio.resources_lookup_data('/com/example/myprog/res1.txt', Gio.ResourceLookupFlags.NONE)
+ assert data.get_data() == b'This is a resource.\n'
diff --git a/test cases/frameworks/7 gnome/resources/simple-main.c b/test cases/frameworks/7 gnome/resources/simple-main.c
new file mode 100644
index 0000000..c021a54
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/simple-main.c
@@ -0,0 +1,27 @@
+#include<stdio.h>
+#include<string.h>
+#include<gio/gio.h>
+#include"simple-resources.h"
+
+#define EXPECTED "This is a resource.\n"
+
+int main(int argc, char **argv) {
+ simple_resources_get_resource();
+
+ GError *err = NULL;
+ GBytes *data = g_resources_lookup_data("/com/example/myprog/res1.txt",
+ G_RESOURCE_LOOKUP_FLAGS_NONE, &err);
+
+ if(data == NULL) {
+ fprintf(stderr, "Data lookup failed: %s\n", err->message);
+ return 1;
+ }
+ if(strcmp(g_bytes_get_data(data, NULL), EXPECTED) != 0) {
+ fprintf(stderr, "Resource contents are wrong:\n %s\n",
+ (const char*)g_bytes_get_data(data, NULL));
+ return 1;
+ }
+ fprintf(stdout, "All ok.\n");
+ g_bytes_unref(data);
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/resources/simple.gresource.xml b/test cases/frameworks/7 gnome/resources/simple.gresource.xml
new file mode 100644
index 0000000..6e55910
--- /dev/null
+++ b/test cases/frameworks/7 gnome/resources/simple.gresource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/com/example/myprog">
+ <file>res1.txt</file>
+ <file>subdir/res2.txt</file>
+ </gresource>
+</gresources>
diff --git a/test cases/frameworks/7 gnome/schemas/com.github.meson.gschema.xml b/test cases/frameworks/7 gnome/schemas/com.github.meson.gschema.xml
new file mode 100644
index 0000000..741518d
--- /dev/null
+++ b/test cases/frameworks/7 gnome/schemas/com.github.meson.gschema.xml
@@ -0,0 +1,12 @@
+<schemalist>
+ <schema id="com.github.meson" path="/com/github/meson/" gettext-domain="test">
+
+ <key name="greeting" type="s">
+ <default l10n="messages">"Hello"</default>
+ <summary>A greeting</summary>
+ <description>
+ Sample text to test schema compilation
+ </description>
+ </key>
+ </schema>
+</schemalist> \ No newline at end of file
diff --git a/test cases/frameworks/7 gnome/schemas/meson.build b/test cases/frameworks/7 gnome/schemas/meson.build
new file mode 100644
index 0000000..9544a57
--- /dev/null
+++ b/test cases/frameworks/7 gnome/schemas/meson.build
@@ -0,0 +1,7 @@
+
+compiled = gnome.compile_schemas(build_by_default: true)
+install_data('com.github.meson.gschema.xml',
+install_dir : 'share/glib-2.0/schemas')
+
+schemaexe = executable('schemaprog', 'schemaprog.c', dependencies : gio)
+test('schema test', schemaexe)
diff --git a/test cases/frameworks/7 gnome/schemas/schemaprog.c b/test cases/frameworks/7 gnome/schemas/schemaprog.c
new file mode 100644
index 0000000..17dab65
--- /dev/null
+++ b/test cases/frameworks/7 gnome/schemas/schemaprog.c
@@ -0,0 +1,47 @@
+#include<gio/gio.h>
+#include<stdio.h>
+#include<string.h>
+
+int main(int argc, char **argv) {
+ GSettingsSchemaSource *src;
+ GSettingsSchema *schema;
+ GSettings *settings;
+ GVariant *value;
+
+ GError *error = NULL;
+ src = g_settings_schema_source_new_from_directory("schemas",
+ g_settings_schema_source_get_default(), TRUE, &error);
+ if(error) {
+ fprintf(stderr, "Fail: %s\n", error->message);
+ g_error_free(error);
+ return 1;
+ }
+
+ schema = g_settings_schema_source_lookup(src, "com.github.meson", FALSE);
+ if(!schema) {
+ fprintf(stderr, "Could not get schema from source.\n");
+ return 2;
+ }
+
+ settings = g_settings_new_full(schema, NULL, NULL);
+ if(!settings) {
+ fprintf(stderr, "Could not get settings object.\n");
+ return 3;
+ }
+
+ value = g_settings_get_value(settings, "greeting");
+ if(!value) {
+ fprintf(stderr, "Could not get value from settings.\n");
+ return 4;
+ }
+
+ if(strcmp("Hello", g_variant_get_string(value, NULL)) != 0) {
+ fprintf(stderr, "Value of setting is incorrect.\n");
+ return 5;
+ }
+ g_variant_unref(value);
+ g_object_unref(settings);
+ g_settings_schema_unref(schema);
+ g_settings_schema_source_unref(src);
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/test.json b/test cases/frameworks/7 gnome/test.json
new file mode 100644
index 0000000..f75ba13
--- /dev/null
+++ b/test cases/frameworks/7 gnome/test.json
@@ -0,0 +1,40 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/ct-resources.h"},
+ {"type": "file", "file": "usr/include/cti-resources.h"},
+ {"type": "file", "file": "usr/include/enums.h"},
+ {"type": "file", "file": "usr/include/enums2.h"},
+ {"type": "file", "file": "usr/include/enums3.h"},
+ {"type": "file", "file": "usr/include/enums5.h"},
+ {"type": "file", "file": "usr/include/subdir-0/marshaller-0.h"},
+ {"type": "file", "file": "usr/include/subdir-1/marshaller-1.h"},
+ {"type": "file", "file": "usr/include/subdir-2/marshaller-2.h"},
+ {"type": "file", "file": "usr/include/subdir-3/marshaller-3.h"},
+ {"type": "file", "file": "usr/include/subdir-4/marshaller-4.h"},
+ {"type": "file", "file": "usr/include/subdir-5/marshaller-5.h"},
+ {"type": "expr", "file": "usr/lib/?libgir_lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgir_lib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libgir_lib2.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgir_lib2.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libdep1lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep1lib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libdep2lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep2lib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libdep3lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep3lib.dll.a"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep1-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep2-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep3-1.0.typelib"},
+ {"type": "file", "file": "usr/share/gir-1.0/Meson-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonDep1-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonDep2-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonDep3-1.0.gir"},
+ {"type": "file", "file": "usr/share/glib-2.0/schemas/com.github.meson.gschema.xml"},
+ {"type": "file", "file": "usr/share/simple-resources.gresource"},
+ {"type": "file", "file": "usr/include/enums6.h"},
+ {"type": "file", "file": "usr/include/simple-resources.h"},
+ {"type": "file", "file": "usr/include/generated-gdbus.h"}
+ ],
+ "skip_on_jobname": ["azure", "cygwin", "macos", "msys2", "pypy"]
+}
diff --git a/test cases/frameworks/8 flex/lexer.l b/test cases/frameworks/8 flex/lexer.l
new file mode 100644
index 0000000..ca6513c
--- /dev/null
+++ b/test cases/frameworks/8 flex/lexer.l
@@ -0,0 +1,13 @@
+%{
+#include <stdlib.h>
+#include "parser.tab.h"
+
+extern int yylex(void);
+extern int yyerror();
+%}
+
+%option noyywrap nounput noinput
+
+%%
+("true"|"false") {return BOOLEAN;}
+. { yyerror(); }
diff --git a/test cases/frameworks/8 flex/meson.build b/test cases/frameworks/8 flex/meson.build
new file mode 100644
index 0000000..55b96dd
--- /dev/null
+++ b/test cases/frameworks/8 flex/meson.build
@@ -0,0 +1,36 @@
+project('flex and bison', 'c')
+
+# The point of this test is that one generator
+# may output headers that are necessary to build
+# the sources of a different generator.
+
+flex = find_program('flex', required: false)
+bison = find_program('bison', required: false)
+
+if not flex.found()
+ error('MESON_SKIP_TEST flex not found.')
+endif
+
+if not bison.found()
+ error('MESON_SKIP_TEST bison not found.')
+endif
+
+lgen = generator(flex,
+output : '@PLAINNAME@.yy.c',
+arguments : ['-o', '@OUTPUT@', '@INPUT@'])
+
+lfiles = lgen.process('lexer.l')
+
+pgen = generator(bison,
+output : ['@BASENAME@.tab.c', '@BASENAME@.tab.h'],
+arguments : ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@'])
+
+pfiles = pgen.process('parser.y')
+
+e = executable('pgen', 'prog.c',
+ lfiles,
+ pfiles,
+ override_options: 'unity=off')
+
+test('parsertest', e,
+ args: [meson.current_source_dir() / 'testfile'])
diff --git a/test cases/frameworks/8 flex/parser.y b/test cases/frameworks/8 flex/parser.y
new file mode 100644
index 0000000..663f2f3
--- /dev/null
+++ b/test cases/frameworks/8 flex/parser.y
@@ -0,0 +1,11 @@
+%{
+extern int yylex(void);
+extern int yyerror();
+%}
+
+%token BOOLEAN
+
+%%
+input:
+ BOOLEAN { $$ = $1;}
+;
diff --git a/test cases/frameworks/8 flex/prog.c b/test cases/frameworks/8 flex/prog.c
new file mode 100644
index 0000000..ae481d0
--- /dev/null
+++ b/test cases/frameworks/8 flex/prog.c
@@ -0,0 +1,30 @@
+#include"parser.tab.h"
+#include<unistd.h>
+#include<sys/types.h>
+#include<sys/stat.h>
+#include<fcntl.h>
+#include<stdio.h>
+#include<stdlib.h>
+
+extern int yyparse();
+
+int main(int argc, char **argv) {
+ int input;
+ if(argc != 2) {
+ printf("%s <input file>\n", argv[0]);
+ return 1;
+ }
+ input = open(argv[1], O_RDONLY);
+ dup2(input, STDIN_FILENO);
+ close(input);
+ return yyparse();
+}
+
+int yywrap(void) {
+ return 0;
+}
+
+int yyerror(void) {
+ printf("Parse error\n");
+ exit(1);
+}
diff --git a/test cases/frameworks/8 flex/test.json b/test cases/frameworks/8 flex/test.json
new file mode 100644
index 0000000..613cfe5
--- /dev/null
+++ b/test cases/frameworks/8 flex/test.json
@@ -0,0 +1,3 @@
+{
+ "skip_on_jobname": ["azure", "cygwin"]
+}
diff --git a/test cases/frameworks/8 flex/test.txt b/test cases/frameworks/8 flex/test.txt
new file mode 100644
index 0000000..27ba77d
--- /dev/null
+++ b/test cases/frameworks/8 flex/test.txt
@@ -0,0 +1 @@
+true
diff --git a/test cases/frameworks/8 flex/testfile b/test cases/frameworks/8 flex/testfile
new file mode 100644
index 0000000..27ba77d
--- /dev/null
+++ b/test cases/frameworks/8 flex/testfile
@@ -0,0 +1 @@
+true
diff --git a/test cases/frameworks/9 wxwidgets/mainwin.h b/test cases/frameworks/9 wxwidgets/mainwin.h
new file mode 100644
index 0000000..b5ca18d
--- /dev/null
+++ b/test cases/frameworks/9 wxwidgets/mainwin.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <wx/wx.h>
+
+class MyApp: public wxApp
+{
+public:
+ virtual bool OnInit();
+};
+class MyFrame: public wxFrame
+{
+public:
+ MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
+private:
+ void OnHello(wxCommandEvent& event);
+ void OnExit(wxCommandEvent& event);
+ void OnAbout(wxCommandEvent& event);
+ wxDECLARE_EVENT_TABLE();
+};
+
+enum {
+ ID_Hello = 1
+};
diff --git a/test cases/frameworks/9 wxwidgets/meson.build b/test cases/frameworks/9 wxwidgets/meson.build
new file mode 100644
index 0000000..0c7ecaa
--- /dev/null
+++ b/test cases/frameworks/9 wxwidgets/meson.build
@@ -0,0 +1,19 @@
+project('wxwidgets test', 'cpp', default_options : ['cpp_std=c++11'])
+
+wxd = dependency('wxwidgets', version : '>=5', required : false)
+wxd = dependency('wxwidgets', version : '>=3.0.0', required : false)
+
+if wxd.found()
+ wp = executable('wxprog', 'wxprog.cpp', dependencies : wxd)
+
+ test('wxtest', wp)
+
+ # WxWidgets framework is available, we can use required here
+ wx_stc = dependency('wxwidgets', version : '>=3.0.0', modules : ['std', 'stc'])
+ stc_exe = executable('wxstc', 'wxstc.cpp', dependencies : wx_stc)
+ test('wxstctest', stc_exe)
+
+ # Check we can apply a version constraint
+ dependency('wxwidgets', version: '>=@0@'.format(wxd.version()))
+
+endif
diff --git a/test cases/frameworks/9 wxwidgets/wxprog.cpp b/test cases/frameworks/9 wxwidgets/wxprog.cpp
new file mode 100644
index 0000000..2be5512
--- /dev/null
+++ b/test cases/frameworks/9 wxwidgets/wxprog.cpp
@@ -0,0 +1,56 @@
+#include"mainwin.h"
+
+wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
+EVT_MENU(ID_Hello, MyFrame::OnHello)
+EVT_MENU(wxID_EXIT, MyFrame::OnExit)
+EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
+wxEND_EVENT_TABLE()
+
+bool MyApp::OnInit() {
+ MyFrame *frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340));
+ frame->Show( true );
+ return true;
+}
+
+MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
+ : wxFrame(NULL, wxID_ANY, title, pos, size) {
+ wxMenu *menuFile = new wxMenu;
+ menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
+ "Help string shown in status bar for this menu item");
+ menuFile->AppendSeparator();
+ menuFile->Append(wxID_EXIT);
+ wxMenu *menuHelp = new wxMenu;
+ menuHelp->Append(wxID_ABOUT);
+ wxMenuBar *menuBar = new wxMenuBar;
+ menuBar->Append(menuFile, "&File");
+ menuBar->Append(menuHelp, "&Help");
+ SetMenuBar(menuBar);
+ CreateStatusBar();
+ SetStatusText("This is status." );
+}
+
+void MyFrame::OnExit(wxCommandEvent& event) {
+ Close( true );
+}
+
+void MyFrame::OnAbout(wxCommandEvent& event) {
+ //wxMessageBox("Some text", wxOK | wxICON_INFORMATION);
+}
+
+void MyFrame::OnHello(wxCommandEvent& event) {
+ wxLogMessage("Some more text.");
+}
+
+#if 0
+wxIMPLEMENT_APP(MyApp);
+#else
+// Don't open a window because this is an unit test and needs to
+// run headless.
+int main(int, char **) {
+ wxString name("Some app");
+ wxPoint p(0, 0);
+ wxSize s(100, 100);
+ return 0;
+}
+
+#endif
diff --git a/test cases/frameworks/9 wxwidgets/wxstc.cpp b/test cases/frameworks/9 wxwidgets/wxstc.cpp
new file mode 100644
index 0000000..c0c7043
--- /dev/null
+++ b/test cases/frameworks/9 wxwidgets/wxstc.cpp
@@ -0,0 +1,6 @@
+#include <wx/stc/stc.h>
+
+int main(void) {
+ wxStyledTextCtrl *canvas = new wxStyledTextCtrl();
+ delete canvas;
+}
diff --git a/test cases/java/1 basic/com/mesonbuild/Simple.java b/test cases/java/1 basic/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..325a49a
--- /dev/null
+++ b/test cases/java/1 basic/com/mesonbuild/Simple.java
@@ -0,0 +1,7 @@
+package com.mesonbuild;
+
+class Simple {
+ public static void main(String [] args) {
+ System.out.println("Java is working.\n");
+ }
+}
diff --git a/test cases/java/1 basic/meson.build b/test cases/java/1 basic/meson.build
new file mode 100644
index 0000000..ef1a4b7
--- /dev/null
+++ b/test cases/java/1 basic/meson.build
@@ -0,0 +1,11 @@
+project('simplejava', 'java')
+
+javaprog = jar('myprog', 'com/mesonbuild/Simple.java',
+ main_class : 'com.mesonbuild.Simple',
+ install : true,
+ install_dir : get_option('bindir'))
+test('mytest', javaprog)
+
+jc = meson.get_compiler('java')
+message(jc.get_id())
+message(jc.get_linker_id())
diff --git a/test cases/java/1 basic/test.json b/test cases/java/1 basic/test.json
new file mode 100644
index 0000000..b5b1539
--- /dev/null
+++ b/test cases/java/1 basic/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/myprog.jar"}
+ ]
+}
diff --git a/test cases/java/10 resources/meson.build b/test cases/java/10 resources/meson.build
new file mode 100644
index 0000000..3b87219
--- /dev/null
+++ b/test cases/java/10 resources/meson.build
@@ -0,0 +1,7 @@
+project('resources', ['java'])
+
+if meson.backend() != 'ninja'
+ error('MESON_SKIP_TEST: only valid on backends which support jar()')
+endif
+
+subdir('src')
diff --git a/test cases/java/10 resources/src/com/mesonbuild/Resources.java b/test cases/java/10 resources/src/com/mesonbuild/Resources.java
new file mode 100644
index 0000000..de1b7d6
--- /dev/null
+++ b/test cases/java/10 resources/src/com/mesonbuild/Resources.java
@@ -0,0 +1,26 @@
+package com.mesonbuild;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+public class Resources {
+ public static void main(String[] args) throws IOException {
+ try (InputStreamReader reader = new InputStreamReader(
+ Resources.class.getResourceAsStream("/resource1.txt"),
+ StandardCharsets.UTF_8)) {
+ final BufferedReader buffered = new BufferedReader(reader);
+
+ assert buffered.readLine() == "1";
+ }
+
+ try (InputStreamReader reader = new InputStreamReader(
+ Resources.class.getResourceAsStream("/subdir/resource2.txt"),
+ StandardCharsets.UTF_8)) {
+ final BufferedReader buffered = new BufferedReader(reader);
+
+ assert buffered.readLine() == "2";
+ }
+ }
+}
diff --git a/test cases/java/10 resources/src/meson.build b/test cases/java/10 resources/src/meson.build
new file mode 100644
index 0000000..51f7d75
--- /dev/null
+++ b/test cases/java/10 resources/src/meson.build
@@ -0,0 +1,13 @@
+sources = files('com/mesonbuild/Resources.java')
+
+resources = jar(
+ meson.project_name(),
+ sources,
+ main_class: 'com.mesonbuild.Resources',
+ java_resources: structured_sources(
+ files('resources/resource1.txt'),
+ {
+ 'subdir': files('resources/subdir/resource2.txt'),
+ }
+ )
+)
diff --git a/test cases/java/10 resources/src/resources/resource1.txt b/test cases/java/10 resources/src/resources/resource1.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/test cases/java/10 resources/src/resources/resource1.txt
@@ -0,0 +1 @@
+1
diff --git a/test cases/java/10 resources/src/resources/subdir/resource2.txt b/test cases/java/10 resources/src/resources/subdir/resource2.txt
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/test cases/java/10 resources/src/resources/subdir/resource2.txt
@@ -0,0 +1 @@
+2
diff --git a/test cases/java/2 subdir/meson.build b/test cases/java/2 subdir/meson.build
new file mode 100644
index 0000000..5aaa028
--- /dev/null
+++ b/test cases/java/2 subdir/meson.build
@@ -0,0 +1,3 @@
+project('subdirjava', 'java')
+
+subdir('sub')
diff --git a/test cases/java/2 subdir/sub/com/mesonbuild/Simple.java b/test cases/java/2 subdir/sub/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..05a73ac
--- /dev/null
+++ b/test cases/java/2 subdir/sub/com/mesonbuild/Simple.java
@@ -0,0 +1,8 @@
+package com.mesonbuild;
+
+class Simple {
+ public static void main(String [] args) {
+ TextPrinter t = new TextPrinter("Printing from Java.");
+ t.print();
+ }
+}
diff --git a/test cases/java/2 subdir/sub/com/mesonbuild/TextPrinter.java b/test cases/java/2 subdir/sub/com/mesonbuild/TextPrinter.java
new file mode 100644
index 0000000..dc2771c
--- /dev/null
+++ b/test cases/java/2 subdir/sub/com/mesonbuild/TextPrinter.java
@@ -0,0 +1,14 @@
+package com.mesonbuild;
+
+class TextPrinter {
+
+ private String msg;
+
+ TextPrinter(String s) {
+ msg = s;
+ }
+
+ public void print() {
+ System.out.println(msg);
+ }
+}
diff --git a/test cases/java/2 subdir/sub/meson.build b/test cases/java/2 subdir/sub/meson.build
new file mode 100644
index 0000000..2111c06
--- /dev/null
+++ b/test cases/java/2 subdir/sub/meson.build
@@ -0,0 +1,5 @@
+javaprog = jar('myprog',
+ 'com/mesonbuild/Simple.java',
+ 'com/mesonbuild/TextPrinter.java',
+ main_class : 'com.mesonbuild.Simple')
+test('subdirtest', javaprog)
diff --git a/test cases/java/3 args/com/mesonbuild/Simple.java b/test cases/java/3 args/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..325a49a
--- /dev/null
+++ b/test cases/java/3 args/com/mesonbuild/Simple.java
@@ -0,0 +1,7 @@
+package com.mesonbuild;
+
+class Simple {
+ public static void main(String [] args) {
+ System.out.println("Java is working.\n");
+ }
+}
diff --git a/test cases/java/3 args/meson.build b/test cases/java/3 args/meson.build
new file mode 100644
index 0000000..d13573f
--- /dev/null
+++ b/test cases/java/3 args/meson.build
@@ -0,0 +1,8 @@
+project('simplejava', 'java')
+
+add_project_arguments('-target', '1.7', language : 'java')
+
+javaprog = jar('myprog', 'com/mesonbuild/Simple.java',
+ main_class : 'com.mesonbuild.Simple',
+ java_args : ['-source', '1.7'])
+test('mytest', javaprog)
diff --git a/test cases/java/4 inner class/com/mesonbuild/Simple.java b/test cases/java/4 inner class/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..fd0e0bf
--- /dev/null
+++ b/test cases/java/4 inner class/com/mesonbuild/Simple.java
@@ -0,0 +1,15 @@
+package com.mesonbuild;
+
+class Simple {
+ class Inner {
+ public String getString() {
+ return "Inner class is working.\n";
+ }
+ }
+
+ public static void main(String [] args) {
+ Simple s = new Simple();
+ Simple.Inner ic = s.new Inner();
+ System.out.println(ic.getString());
+ }
+}
diff --git a/test cases/java/4 inner class/meson.build b/test cases/java/4 inner class/meson.build
new file mode 100644
index 0000000..bed5c0f
--- /dev/null
+++ b/test cases/java/4 inner class/meson.build
@@ -0,0 +1,5 @@
+project('simplejava', 'java')
+
+javaprog = jar('myprog', 'com/mesonbuild/Simple.java',
+ main_class : 'com.mesonbuild.Simple')
+test('mytest', javaprog)
diff --git a/test cases/java/5 includedirs/com/mesonbuild/Simple.java b/test cases/java/5 includedirs/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..05a73ac
--- /dev/null
+++ b/test cases/java/5 includedirs/com/mesonbuild/Simple.java
@@ -0,0 +1,8 @@
+package com.mesonbuild;
+
+class Simple {
+ public static void main(String [] args) {
+ TextPrinter t = new TextPrinter("Printing from Java.");
+ t.print();
+ }
+}
diff --git a/test cases/java/5 includedirs/com/mesonbuild/TextPrinter.java b/test cases/java/5 includedirs/com/mesonbuild/TextPrinter.java
new file mode 100644
index 0000000..dc2771c
--- /dev/null
+++ b/test cases/java/5 includedirs/com/mesonbuild/TextPrinter.java
@@ -0,0 +1,14 @@
+package com.mesonbuild;
+
+class TextPrinter {
+
+ private String msg;
+
+ TextPrinter(String s) {
+ msg = s;
+ }
+
+ public void print() {
+ System.out.println(msg);
+ }
+}
diff --git a/test cases/java/5 includedirs/meson.build b/test cases/java/5 includedirs/meson.build
new file mode 100644
index 0000000..cf0b565
--- /dev/null
+++ b/test cases/java/5 includedirs/meson.build
@@ -0,0 +1,14 @@
+# The Ninja backend used to try and pass -sourcepath repeatedly for
+# multiple includes which would discard prior includes. Since this
+# won't compile without the '.' include, this ensures that multiple
+# paths are passed in a [semi-]colon separated list instead...
+
+project('includedirsjava', 'java')
+
+javaprog = jar('myprog',
+ 'com/mesonbuild/Simple.java',
+ 'com/mesonbuild/TextPrinter.java',
+ main_class : 'com.mesonbuild.Simple',
+ include_directories : [ include_directories('com'),
+ include_directories('com/mesonbuild') ])
+test('subdirtest', javaprog)
diff --git a/test cases/java/6 codegen/com/mesonbuild/Config.java.in b/test cases/java/6 codegen/com/mesonbuild/Config.java.in
new file mode 100644
index 0000000..fcc8811
--- /dev/null
+++ b/test cases/java/6 codegen/com/mesonbuild/Config.java.in
@@ -0,0 +1,5 @@
+package com.mesonbuild;
+
+public class Config {
+ public static final boolean FOOBAR = @foobar@;
+}
diff --git a/test cases/java/6 codegen/com/mesonbuild/Simple.java b/test cases/java/6 codegen/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..df3c53d
--- /dev/null
+++ b/test cases/java/6 codegen/com/mesonbuild/Simple.java
@@ -0,0 +1,12 @@
+package com.mesonbuild;
+
+import com.mesonbuild.Config;
+
+class Simple {
+ public static void main(String [] args) {
+ if (Config.FOOBAR) {
+ TextPrinter t = new TextPrinter("Printing from Java.");
+ t.print();
+ }
+ }
+}
diff --git a/test cases/java/6 codegen/com/mesonbuild/TextPrinter.java b/test cases/java/6 codegen/com/mesonbuild/TextPrinter.java
new file mode 100644
index 0000000..dc2771c
--- /dev/null
+++ b/test cases/java/6 codegen/com/mesonbuild/TextPrinter.java
@@ -0,0 +1,14 @@
+package com.mesonbuild;
+
+class TextPrinter {
+
+ private String msg;
+
+ TextPrinter(String s) {
+ msg = s;
+ }
+
+ public void print() {
+ System.out.println(msg);
+ }
+}
diff --git a/test cases/java/6 codegen/com/mesonbuild/meson.build b/test cases/java/6 codegen/com/mesonbuild/meson.build
new file mode 100644
index 0000000..188bedf
--- /dev/null
+++ b/test cases/java/6 codegen/com/mesonbuild/meson.build
@@ -0,0 +1,6 @@
+
+conf_data = configuration_data()
+conf_data.set('foobar', 'true')
+config_file = configure_file(input : 'Config.java.in',
+ output : 'Config.java',
+ configuration : conf_data)
diff --git a/test cases/java/6 codegen/meson.build b/test cases/java/6 codegen/meson.build
new file mode 100644
index 0000000..f85d45a
--- /dev/null
+++ b/test cases/java/6 codegen/meson.build
@@ -0,0 +1,15 @@
+# If we generate code under the build directory then the backend needs to add
+# the build directory to the -sourcepath passed to javac otherwise the compiler
+# won't be able to handle the -implicit:class behaviour of automatically
+# compiling dependency classes.
+
+project('codegenjava', 'java')
+
+subdir('com/mesonbuild')
+
+javaprog = jar('myprog',
+ config_file,
+ 'com/mesonbuild/Simple.java',
+ 'com/mesonbuild/TextPrinter.java',
+ main_class : 'com.mesonbuild.Simple')
+test('subdirtest', javaprog)
diff --git a/test cases/java/7 linking/com/mesonbuild/Linking.java b/test cases/java/7 linking/com/mesonbuild/Linking.java
new file mode 100644
index 0000000..170e2aa
--- /dev/null
+++ b/test cases/java/7 linking/com/mesonbuild/Linking.java
@@ -0,0 +1,9 @@
+package com.mesonbuild;
+
+import com.mesonbuild.SimpleLib;
+
+class Linking {
+ public static void main(String [] args) {
+ SimpleLib.func();
+ }
+}
diff --git a/test cases/java/7 linking/meson.build b/test cases/java/7 linking/meson.build
new file mode 100644
index 0000000..0ae0db3
--- /dev/null
+++ b/test cases/java/7 linking/meson.build
@@ -0,0 +1,8 @@
+project('linkingjava', 'java')
+
+subdir('sub')
+
+javaprog = jar('myprog', 'com/mesonbuild/Linking.java',
+ main_class : 'com.mesonbuild.Linking',
+ link_with : simplelib)
+test('mytest', javaprog) \ No newline at end of file
diff --git a/test cases/java/7 linking/sub/com/mesonbuild/SimpleLib.java b/test cases/java/7 linking/sub/com/mesonbuild/SimpleLib.java
new file mode 100644
index 0000000..835b2e4
--- /dev/null
+++ b/test cases/java/7 linking/sub/com/mesonbuild/SimpleLib.java
@@ -0,0 +1,7 @@
+package com.mesonbuild;
+
+public class SimpleLib {
+ public static void func() {
+ System.out.println("Java linking is working.\n");
+ }
+}
diff --git a/test cases/java/7 linking/sub/meson.build b/test cases/java/7 linking/sub/meson.build
new file mode 100644
index 0000000..13fd202
--- /dev/null
+++ b/test cases/java/7 linking/sub/meson.build
@@ -0,0 +1,2 @@
+simplelib = jar('simplelib',
+ 'com/mesonbuild/SimpleLib.java')
diff --git a/test cases/java/8 codegen custom target/com/mesonbuild/Config.java.in b/test cases/java/8 codegen custom target/com/mesonbuild/Config.java.in
new file mode 100644
index 0000000..8845985
--- /dev/null
+++ b/test cases/java/8 codegen custom target/com/mesonbuild/Config.java.in
@@ -0,0 +1,5 @@
+package com.mesonbuild;
+
+public class Config {
+ public static final boolean FOOBAR = true;
+}
diff --git a/test cases/java/8 codegen custom target/com/mesonbuild/Simple.java b/test cases/java/8 codegen custom target/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..df3c53d
--- /dev/null
+++ b/test cases/java/8 codegen custom target/com/mesonbuild/Simple.java
@@ -0,0 +1,12 @@
+package com.mesonbuild;
+
+import com.mesonbuild.Config;
+
+class Simple {
+ public static void main(String [] args) {
+ if (Config.FOOBAR) {
+ TextPrinter t = new TextPrinter("Printing from Java.");
+ t.print();
+ }
+ }
+}
diff --git a/test cases/java/8 codegen custom target/com/mesonbuild/TextPrinter.java b/test cases/java/8 codegen custom target/com/mesonbuild/TextPrinter.java
new file mode 100644
index 0000000..dc2771c
--- /dev/null
+++ b/test cases/java/8 codegen custom target/com/mesonbuild/TextPrinter.java
@@ -0,0 +1,14 @@
+package com.mesonbuild;
+
+class TextPrinter {
+
+ private String msg;
+
+ TextPrinter(String s) {
+ msg = s;
+ }
+
+ public void print() {
+ System.out.println(msg);
+ }
+}
diff --git a/test cases/java/8 codegen custom target/com/mesonbuild/meson.build b/test cases/java/8 codegen custom target/com/mesonbuild/meson.build
new file mode 100644
index 0000000..0309941
--- /dev/null
+++ b/test cases/java/8 codegen custom target/com/mesonbuild/meson.build
@@ -0,0 +1,8 @@
+python = import('python').find_installation('python3')
+
+config_file = custom_target('confgen',
+ input : 'Config.java.in',
+ output : 'Config.java',
+ command : [python, '-c',
+ 'import shutil, sys, time; time.sleep(1); shutil.copy(sys.argv[1], sys.argv[2])',
+ '@INPUT@', '@OUTPUT@'])
diff --git a/test cases/java/8 codegen custom target/meson.build b/test cases/java/8 codegen custom target/meson.build
new file mode 100644
index 0000000..ab441a6
--- /dev/null
+++ b/test cases/java/8 codegen custom target/meson.build
@@ -0,0 +1,15 @@
+# If we generate code under the build directory then the backend needs to add
+# the build directory to the -sourcepath passed to javac otherwise the compiler
+# won't be able to handle the -implicit:class behaviour of automatically
+# compiling dependency classes.
+
+project('codegenjava', 'java')
+
+subdir('com/mesonbuild')
+
+javaprog = jar('myprog',
+ config_file[0],
+ 'com/mesonbuild/Simple.java',
+ 'com/mesonbuild/TextPrinter.java',
+ main_class : 'com.mesonbuild.Simple')
+test('subdirtest', javaprog)
diff --git a/test cases/java/9 jni/lib/com_mesonbuild_JniTest.c b/test cases/java/9 jni/lib/com_mesonbuild_JniTest.c
new file mode 100644
index 0000000..5deca03
--- /dev/null
+++ b/test cases/java/9 jni/lib/com_mesonbuild_JniTest.c
@@ -0,0 +1,9 @@
+#include <jni.h>
+
+#include "com_mesonbuild_JniTest.h"
+
+JNIEXPORT jint JNICALL Java_com_mesonbuild_JniTest_jni_1test
+ (JNIEnv *env, jclass clazz)
+{
+ return (jint)0xdeadbeef;
+}
diff --git a/test cases/java/9 jni/lib/meson.build b/test cases/java/9 jni/lib/meson.build
new file mode 100644
index 0000000..c2ddc7a
--- /dev/null
+++ b/test cases/java/9 jni/lib/meson.build
@@ -0,0 +1,18 @@
+sources = [
+ files(
+ 'native.c',
+ 'com_mesonbuild_JniTest.c',
+ ),
+ native_headers
+]
+
+jnijava = shared_module(
+ 'jnijava',
+ sources,
+ dependencies : [jni_dep],
+ include_directories : [native_header_includes]
+)
+
+jnijava_dep = declare_dependency(
+ link_with : jnijava
+)
diff --git a/test cases/java/9 jni/lib/native.c b/test cases/java/9 jni/lib/native.c
new file mode 100644
index 0000000..0b5e718
--- /dev/null
+++ b/test cases/java/9 jni/lib/native.c
@@ -0,0 +1,11 @@
+#include <jni.h>
+
+JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ return JNI_VERSION_1_8;
+}
+
+JNIEXPORT void JNICALL
+JNI_OnUnload(JavaVM *vm, void *reserved)
+{}
diff --git a/test cases/java/9 jni/meson.build b/test cases/java/9 jni/meson.build
new file mode 100644
index 0000000..7a68165
--- /dev/null
+++ b/test cases/java/9 jni/meson.build
@@ -0,0 +1,38 @@
+project('jnijava', ['c', 'java'])
+
+if build_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST: cygwin test failures')
+endif
+
+if build_machine.system() == 'windows' and build_machine.cpu_family() == 'x86'
+ error('MESON_SKIP_TEST: failing builds on 32bit Windows because a 32bit JDK is not available in the Azure Pipelines Windows images')
+endif
+
+fs = import('fs')
+javamod = import('java')
+
+cc = meson.get_compiler('c')
+java = find_program('java')
+
+jni_dep = dependency('jni', version : '>=1.8', modules: ['jvm', 'awt'])
+
+# Assert that the header can actually be found with the dependency.
+cc.has_header('jni.h', dependencies: [jni_dep])
+# Assert that the platform-specific include directory is included in the compiler arguments.
+cc.has_header('jni_md.h', dependencies: [jni_dep])
+
+# generate native headers
+subdir('src')
+subdir('lib')
+
+test(
+ 'jnitest',
+ java,
+ args: [
+ '-Djava.library.path=@0@'.format(fs.parent(jnijava.full_path())),
+ '-jar',
+ jnijar,
+ ],
+ protocol : 'exitcode',
+ depends : [jnijava],
+)
diff --git a/test cases/java/9 jni/src/com/mesonbuild/Configured.java.in b/test cases/java/9 jni/src/com/mesonbuild/Configured.java.in
new file mode 100644
index 0000000..fac6e05
--- /dev/null
+++ b/test cases/java/9 jni/src/com/mesonbuild/Configured.java.in
@@ -0,0 +1,5 @@
+package com.mesonbuild;
+
+public final class Configured {
+ public static final int FINGERPRINT = @fingerprint@;
+}
diff --git a/test cases/java/9 jni/src/com/mesonbuild/JniTest.java b/test cases/java/9 jni/src/com/mesonbuild/JniTest.java
new file mode 100644
index 0000000..4bfffe9
--- /dev/null
+++ b/test cases/java/9 jni/src/com/mesonbuild/JniTest.java
@@ -0,0 +1,15 @@
+package com.mesonbuild;
+
+public final class JniTest {
+ private static native int jni_test();
+
+ public static void main(String[] args) {
+ if (jni_test() != Configured.FINGERPRINT) {
+ throw new RuntimeException("jdk_test() did not return 0");
+ }
+ }
+
+ static {
+ System.loadLibrary("jnijava");
+ }
+}
diff --git a/test cases/java/9 jni/src/com/mesonbuild/meson.build b/test cases/java/9 jni/src/com/mesonbuild/meson.build
new file mode 100644
index 0000000..a505b1a
--- /dev/null
+++ b/test cases/java/9 jni/src/com/mesonbuild/meson.build
@@ -0,0 +1,11 @@
+configured = configure_file(
+ input: files('Configured.java.in'),
+ output: 'Configured.java',
+ configuration: configuration_data({'fingerprint': '0xdeadbeef'})
+)
+
+sources += configured
+
+native_headers = javamod.native_headers(
+ sources, package: 'com.mesonbuild', classes: ['JniTest'])
+native_header_includes = include_directories('.')
diff --git a/test cases/java/9 jni/src/meson.build b/test cases/java/9 jni/src/meson.build
new file mode 100644
index 0000000..af443b5
--- /dev/null
+++ b/test cases/java/9 jni/src/meson.build
@@ -0,0 +1,9 @@
+sources = [files('com/mesonbuild/JniTest.java')]
+
+subdir('com/mesonbuild')
+
+jnijar = jar(
+ 'jnijar',
+ sources,
+ main_class : 'com.mesonbuild.JniTest',
+)
diff --git a/test cases/keyval/1 basic/.config b/test cases/keyval/1 basic/.config
new file mode 100644
index 0000000..071d185
--- /dev/null
+++ b/test cases/keyval/1 basic/.config
@@ -0,0 +1,3 @@
+CONFIG_VAL1=y
+# CONFIG_VAL2 is not set
+CONFIG_VAL_VAL=4
diff --git a/test cases/keyval/1 basic/meson.build b/test cases/keyval/1 basic/meson.build
new file mode 100644
index 0000000..a6e023e
--- /dev/null
+++ b/test cases/keyval/1 basic/meson.build
@@ -0,0 +1,18 @@
+project('keyval basic test', meson_version : '>= 0.55')
+
+k = import('keyval')
+conf = k.load('.config')
+
+if not conf.has_key('CONFIG_VAL1')
+ error('Expected CONFIG_VAL1 to be set, but it wasn\'t')
+endif
+
+if conf.has_key('CONFIG_VAL2')
+ error('Expected CONFIG_VAL2 not be set, but it was')
+endif
+
+if conf.get('CONFIG_VAL_VAL').to_int() != 4
+ error('Expected CONFIG_VAL_VAL to be 4')
+endif
+
+k = import('unstable-keyval')
diff --git a/test cases/keyval/1 basic/test.json b/test cases/keyval/1 basic/test.json
new file mode 100644
index 0000000..1f8fd9b
--- /dev/null
+++ b/test cases/keyval/1 basic/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/keyval/1 basic/meson.build:3: WARNING: Project targets '>= 0.55' but uses feature introduced in '0.56.0': module keyval as stable module. Consider either adding \"unstable-\" to the module name, or updating the meson required version to \">= 0.56.0\""
+ }
+ ]
+}
diff --git a/test cases/keyval/2 subdir/.config b/test cases/keyval/2 subdir/.config
new file mode 100644
index 0000000..0599d46
--- /dev/null
+++ b/test cases/keyval/2 subdir/.config
@@ -0,0 +1,2 @@
+CONFIG_IS_SET=y
+# CONFIG_NOT_IS_SET is not set
diff --git a/test cases/keyval/2 subdir/dir/meson.build b/test cases/keyval/2 subdir/dir/meson.build
new file mode 100644
index 0000000..3db80ad
--- /dev/null
+++ b/test cases/keyval/2 subdir/dir/meson.build
@@ -0,0 +1,12 @@
+
+k = import('keyval')
+
+conf = k.load(meson.source_root() / '.config')
+
+if not conf.has_key('CONFIG_IS_SET')
+ error('Expected CONFIG_IS_SET to be set, but it wasn\'t')
+endif
+
+if conf.has_key('CONFIG_NOT_IS_SET')
+ error('Expected CONFIG_NOT_IS_SET not be set, but it was')
+endif
diff --git a/test cases/keyval/2 subdir/meson.build b/test cases/keyval/2 subdir/meson.build
new file mode 100644
index 0000000..0651acf
--- /dev/null
+++ b/test cases/keyval/2 subdir/meson.build
@@ -0,0 +1,4 @@
+project('keyval subdir test')
+
+# Test into sub directory
+subdir('dir')
diff --git a/test cases/keyval/3 load_config files/dir/config b/test cases/keyval/3 load_config files/dir/config
new file mode 100644
index 0000000..0599d46
--- /dev/null
+++ b/test cases/keyval/3 load_config files/dir/config
@@ -0,0 +1,2 @@
+CONFIG_IS_SET=y
+# CONFIG_NOT_IS_SET is not set
diff --git a/test cases/keyval/3 load_config files/dir/meson.build b/test cases/keyval/3 load_config files/dir/meson.build
new file mode 100644
index 0000000..d8826ec
--- /dev/null
+++ b/test cases/keyval/3 load_config files/dir/meson.build
@@ -0,0 +1,12 @@
+
+k = import('keyval')
+
+conf = k.load(files('config'))
+
+if not conf.has_key('CONFIG_IS_SET')
+ error('Expected CONFIG_IS_SET to be set, but it wasn\'t')
+endif
+
+if conf.has_key('CONFIG_NOT_IS_SET')
+ error('Expected CONFIG_NOT_IS_SET not be set, but it was')
+endif
diff --git a/test cases/keyval/3 load_config files/meson.build b/test cases/keyval/3 load_config files/meson.build
new file mode 100644
index 0000000..0651acf
--- /dev/null
+++ b/test cases/keyval/3 load_config files/meson.build
@@ -0,0 +1,4 @@
+project('keyval subdir test')
+
+# Test into sub directory
+subdir('dir')
diff --git a/test cases/keyval/4 load_config builddir/config b/test cases/keyval/4 load_config builddir/config
new file mode 100644
index 0000000..0599d46
--- /dev/null
+++ b/test cases/keyval/4 load_config builddir/config
@@ -0,0 +1,2 @@
+CONFIG_IS_SET=y
+# CONFIG_NOT_IS_SET is not set
diff --git a/test cases/keyval/4 load_config builddir/meson.build b/test cases/keyval/4 load_config builddir/meson.build
new file mode 100644
index 0000000..6bd83db
--- /dev/null
+++ b/test cases/keyval/4 load_config builddir/meson.build
@@ -0,0 +1,14 @@
+project('keyval builddir test')
+
+k = import('keyval')
+
+out_conf = configure_file(input: 'config', output: 'out-config', copy: true)
+conf = k.load(out_conf)
+
+if not conf.has_key('CONFIG_IS_SET')
+ error('Expected CONFIG_IS_SET to be set, but it wasn\'t')
+endif
+
+if conf.has_key('CONFIG_NOT_IS_SET')
+ error('Expected CONFIG_NOT_IS_SET not be set, but it was')
+endif
diff --git a/test cases/linuxlike/1 pkg-config/incdir/myinc.h b/test cases/linuxlike/1 pkg-config/incdir/myinc.h
new file mode 100644
index 0000000..4b66a6c
--- /dev/null
+++ b/test cases/linuxlike/1 pkg-config/incdir/myinc.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include<zlib.h>
diff --git a/test cases/linuxlike/1 pkg-config/meson.build b/test cases/linuxlike/1 pkg-config/meson.build
new file mode 100644
index 0000000..ca48e9b
--- /dev/null
+++ b/test cases/linuxlike/1 pkg-config/meson.build
@@ -0,0 +1,53 @@
+project('external dependency', 'c')
+
+# Zlib is probably on all dev machines.
+
+dep = dependency('zlib', version : '>=1.2',
+ not_found_message: 'DANGER! DANGER! THIS MUST NEVER BE SEEN!')
+exe = executable('zlibprog', 'prog-checkver.c',
+ dependencies : dep,
+ c_args : '-DFOUND_ZLIB="' + dep.version() + '"')
+
+assert(dep.version().version_compare('>=1.2'), 'Pkg-config version numbers exposed incorrectly.')
+
+# Check that the version exposed by zlib internally is the same as the one we
+# retrieve from the pkg-config file. This assumes that the packager didn't mess
+# up, but we can be reasonably sure of that.
+test('zlibtest', exe)
+
+zprefix = dep.get_pkgconfig_variable('prefix') # Always set but we can't be sure what the value is.
+# pkg-config returns empty string for not defined variables
+assert(dep.get_pkgconfig_variable('nonexisting') == '', 'Value of unknown variable is not empty.')
+# ... unless default: is used
+assert(dep.get_pkgconfig_variable('nonexisting', default: 'foo') == 'foo', 'Value of unknown variable is not defaulted.')
+# pkg-config is able to replace variables
+assert(dep.get_pkgconfig_variable('prefix', define_variable: ['prefix', '/tmp']) == '/tmp', 'prefix variable has not been replaced.')
+
+# Test that dependencies of dependencies work.
+dep2 = declare_dependency(dependencies : dep)
+exe2 = executable('zlibprog2', 'prog.c', dependencies : dep2)
+test('zlibtest2', exe2)
+
+# Try to find a nonexistent library to ensure requires:false works.
+
+dep = dependency('nvakuhrabnsdfasdf', required : false,
+ not_found_message : 'This dependency was not found as was expected.')
+
+# Try to compile a test that takes a dep and an include_directories
+
+cc = meson.get_compiler('c')
+zlibdep = cc.find_library('z')
+code = '''#include<myinc.h>
+
+int main(void) {
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return 1;
+}
+'''
+
+inc = include_directories('incdir')
+
+r = cc.run(code, include_directories : inc, dependencies : zlibdep)
+assert(r.returncode() == 0, 'Running manual zlib test failed.')
diff --git a/test cases/linuxlike/1 pkg-config/prog-checkver.c b/test cases/linuxlike/1 pkg-config/prog-checkver.c
new file mode 100644
index 0000000..ea1ed32
--- /dev/null
+++ b/test cases/linuxlike/1 pkg-config/prog-checkver.c
@@ -0,0 +1,15 @@
+#include <zlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(void) {
+ void * something = deflate;
+ if(strcmp(ZLIB_VERSION, FOUND_ZLIB) != 0) {
+ printf("Meson found '%s' but zlib is '%s'\n", FOUND_ZLIB, ZLIB_VERSION);
+ return 2;
+ }
+ if(something != 0)
+ return 0;
+ printf("Couldn't find 'deflate'\n");
+ return 1;
+}
diff --git a/test cases/linuxlike/1 pkg-config/prog.c b/test cases/linuxlike/1 pkg-config/prog.c
new file mode 100644
index 0000000..eccc477
--- /dev/null
+++ b/test cases/linuxlike/1 pkg-config/prog.c
@@ -0,0 +1,8 @@
+#include<zlib.h>
+
+int main(void) {
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return 1;
+}
diff --git a/test cases/linuxlike/10 large file support/meson.build b/test cases/linuxlike/10 large file support/meson.build
new file mode 100644
index 0000000..6683345
--- /dev/null
+++ b/test cases/linuxlike/10 large file support/meson.build
@@ -0,0 +1,16 @@
+project('trivial test', 'c')
+
+if host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST _FILE_OFFSET_BITS not yet supported on Cygwin.')
+endif
+
+cc = meson.get_compiler('c')
+
+size = cc.sizeof('off_t')
+assert(size == 8, 'off_t size is @0@ bytes instead of 8'.format(size))
+
+code = '''#if !defined(_FILE_OFFSET_BITS) || (_FILE_OFFSET_BITS != 64)
+#error "Large-file support was not enabled"
+#endif'''
+
+assert(cc.compiles(code, name : 'checking for LFS'), 'Large file support was not enabled')
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c
new file mode 100644
index 0000000..2784e01
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c
@@ -0,0 +1,3 @@
+int some_symbol (void) {
+ return RET_VALUE;
+}
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build
new file mode 100644
index 0000000..cbc75bd
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build
@@ -0,0 +1,2 @@
+lib1 = shared_library('testeh', libsrc,
+ c_args : '-DRET_VALUE=1')
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build
new file mode 100644
index 0000000..f2c6dcc
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build
@@ -0,0 +1,3 @@
+lib2 = shared_library('esteh', libsrc,
+ name_prefix : 'libt',
+ c_args : '-DRET_VALUE=2')
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c b/test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c
new file mode 100644
index 0000000..5009531
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int some_symbol (void);
+
+int main () {
+ int ret = some_symbol ();
+ if (ret == 1)
+ return 0;
+ fprintf (stderr, "ret was %i instead of 1\n", ret);
+ return -1;
+}
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build b/test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build
new file mode 100644
index 0000000..a3103ac
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build
@@ -0,0 +1,16 @@
+project('runpath rpath ldlibrarypath', 'c')
+
+error('MESON_SKIP_TEST test disabled due to bug #1635.')
+
+libsrc = files('lib.c')
+
+subdir('lib1')
+subdir('lib2')
+
+lib2dir = meson.current_build_dir() + '/lib2'
+
+e = executable('testexe', 'main.c',
+ link_with : lib1)
+
+test('ld-library-path-test', e,
+ env : ['LD_LIBRARY_PATH=' + lib2dir])
diff --git a/test cases/linuxlike/12 subprojects in subprojects/main.c b/test cases/linuxlike/12 subprojects in subprojects/main.c
new file mode 100644
index 0000000..7452317
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/main.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "a.h"
+#include "b.h"
+
+int main(void) {
+ int life = a_fun() + b_fun();
+ printf("%d\n", life);
+ return 0;
+}
diff --git a/test cases/linuxlike/12 subprojects in subprojects/meson.build b/test cases/linuxlike/12 subprojects in subprojects/meson.build
new file mode 100644
index 0000000..4014149
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/meson.build
@@ -0,0 +1,9 @@
+project('super', 'c')
+
+# A will use version 1 of C
+a_dep = dependency('a', fallback: ['a', 'a_dep'])
+
+# B has an optional dependency on C version 2 and will therefore work
+b_dep = dependency('b', fallback: ['b', 'b_dep'])
+
+main = executable('main', files('main.c'), dependencies: [a_dep, b_dep])
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.c b/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.c
new file mode 100644
index 0000000..f7dd126
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.c
@@ -0,0 +1,5 @@
+#include "c.h"
+
+int a_fun(void) {
+ return c_fun();
+}
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.h b/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.h
new file mode 100644
index 0000000..9de0deb
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/a.h
@@ -0,0 +1 @@
+int a_fun(void);
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/meson.build b/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/meson.build
new file mode 100644
index 0000000..5f579a3
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/a/meson.build
@@ -0,0 +1,11 @@
+project('a', 'c', version:'1.0')
+
+c_dep = dependency('c', version:'1', fallback: ['c', 'c_dep'])
+
+alib = library('a', 'a.c',
+ dependencies: c_dep)
+
+a_dep = declare_dependency(
+ link_with: alib,
+ include_directories: include_directories('.'),
+)
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.c b/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.c
new file mode 100644
index 0000000..45c9348
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.c
@@ -0,0 +1,11 @@
+#if defined(WITH_C)
+#include "c.h"
+#endif
+
+int b_fun(void){
+#if defined(WITH_C)
+return c_fun();
+#else
+return 0;
+#endif
+}
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.h b/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.h
new file mode 100644
index 0000000..47b84d4
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/b.h
@@ -0,0 +1 @@
+int b_fun(void);
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/meson.build b/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/meson.build
new file mode 100644
index 0000000..80903f3
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/b/meson.build
@@ -0,0 +1,17 @@
+project('b', 'c')
+
+c_dep = dependency('c', version:'2', fallback: ['c', 'c_dep'], required: false)
+
+assert(c_dep.found() == false, 'C project has the wrong version and should not be found')
+
+if c_dep.found()
+ add_global_arguments('-DWITH_C', language: 'c')
+endif
+
+blib = library('b', 'b.c',
+ dependencies: c_dep)
+
+b_dep = declare_dependency(
+ link_with: blib,
+ include_directories: include_directories('.'),
+)
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/c/c.h b/test cases/linuxlike/12 subprojects in subprojects/subprojects/c/c.h
new file mode 100644
index 0000000..b2e3f9b
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/c/c.h
@@ -0,0 +1,3 @@
+static int c_fun(void){
+ return 3;
+}
diff --git a/test cases/linuxlike/12 subprojects in subprojects/subprojects/c/meson.build b/test cases/linuxlike/12 subprojects in subprojects/subprojects/c/meson.build
new file mode 100644
index 0000000..7184933
--- /dev/null
+++ b/test cases/linuxlike/12 subprojects in subprojects/subprojects/c/meson.build
@@ -0,0 +1,5 @@
+project('c', 'c', version:'1')
+
+c_dep = declare_dependency(
+ include_directories: include_directories('.')
+)
diff --git a/test cases/linuxlike/13 cmake dependency/cmake/FindImportedOldStyle.cmake b/test cases/linuxlike/13 cmake dependency/cmake/FindImportedOldStyle.cmake
new file mode 100644
index 0000000..595b887
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake/FindImportedOldStyle.cmake
@@ -0,0 +1,5 @@
+find_package(ZLIB)
+
+set(IMPORTEDOLDSTYLE_LIBRARIES ZLIB::ZLIB)
+set(IMPORTEDOLDSTYLE_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR})
+set(IMPORTEDOLDSTYLE_FOUND ON)
diff --git a/test cases/linuxlike/13 cmake dependency/cmake/FindImportedTarget.cmake b/test cases/linuxlike/13 cmake dependency/cmake/FindImportedTarget.cmake
new file mode 100644
index 0000000..1dd1657
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake/FindImportedTarget.cmake
@@ -0,0 +1,15 @@
+find_package(ZLIB)
+
+if(ZLIB_FOUND OR ZLIB_Found)
+ set(ImportedTarget_FOUND ON)
+ add_library(mesonTestLibDefs SHARED IMPORTED)
+ set_property(TARGET mesonTestLibDefs PROPERTY IMPORTED_LOCATION ${ZLIB_LIBRARY})
+ set_property(TARGET mesonTestLibDefs PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${ZLIB_INCLUDE_DIR})
+ set_property(TARGET mesonTestLibDefs APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS REQUIRED_MESON_FLAG1)
+ set_property(TARGET mesonTestLibDefs APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$<NOT:$<CONFIG:Debug>>:;QT_NO_DEBUG;>) # Error empty string
+ set_property(TARGET mesonTestLibDefs APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS REQUIRED_MESON_FLAG2)
+ set_target_properties(mesonTestLibDefs PROPERTIES IMPORTED_GLOBAL TRUE)
+ add_library(MesonTest::TestLibDefs ALIAS mesonTestLibDefs)
+else()
+ set(ImportedTarget_FOUND OFF)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake b/test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake
new file mode 100644
index 0000000..483926c
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake
@@ -0,0 +1,56 @@
+find_package(ZLIB)
+
+include(CMakeFindDependencyMacro)
+include(CheckCXXSourceRuns)
+include(CheckCSourceRuns)
+
+# Do something stupid (see https://github.com/mesonbuild/meson/issues/7501)
+set("")
+
+check_cxx_source_runs(
+"
+#include <iostream>
+
+using namespace std;
+
+int main(void) {
+ cout << \"Hello World\" << endl;
+ return 0;
+}
+"
+CXX_CODE_RAN
+)
+
+check_c_source_runs(
+"
+#include <stdio.h>
+
+int main(void) {
+ printf(\"Hello World\");
+ return 0;
+}
+"
+C_CODE_RAN
+)
+
+if(NOT CXX_CODE_RAN)
+ message(FATAL_ERROR "Running CXX source code failed")
+endif()
+
+if(NOT C_CODE_RAN)
+ message(FATAL_ERROR "Running C source code failed")
+endif()
+
+if(NOT SomethingLikeZLIB_FIND_COMPONENTS STREQUAL "required_comp")
+ message(FATAL_ERROR "Component 'required_comp' was not specified")
+endif()
+
+find_dependency(Threads)
+
+if(ZLIB_FOUND OR ZLIB_Found)
+ set(SomethingLikeZLIB_FOUND ON)
+ set(SomethingLikeZLIB_LIBRARIES ${ZLIB_LIBRARY})
+ set(SomethingLikeZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+else()
+ set(SomethingLikeZLIB_FOUND OFF)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/cmake_fake1/cmMesonTestF1Config.cmake b/test cases/linuxlike/13 cmake dependency/cmake_fake1/cmMesonTestF1Config.cmake
new file mode 100644
index 0000000..4b3f814
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake_fake1/cmMesonTestF1Config.cmake
@@ -0,0 +1,11 @@
+find_package(ZLIB)
+
+if(ZLIB_FOUND OR ZLIB_Found)
+ set(cmMesonTestF1_FOUND ON)
+ set(cmMesonTestF1_LIBRARIES general ${ZLIB_LIBRARY})
+ set(cmMesonTestF1_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+
+ add_library(CMMesonTESTf1::evil_non_standard_trget UNKNOWN IMPORTED)
+else()
+ set(cmMesonTestF1_FOUND OFF)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/cmake_fake2/cmMesonTestF2Config.cmake b/test cases/linuxlike/13 cmake dependency/cmake_fake2/cmMesonTestF2Config.cmake
new file mode 100644
index 0000000..a7a55d8
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake_fake2/cmMesonTestF2Config.cmake
@@ -0,0 +1,9 @@
+find_package(ZLIB)
+
+if(ZLIB_FOUND OR ZLIB_Found)
+ set(cmMesonTestF2_FOUND ON)
+ set(cmMesonTestF2_LIBRARIES ${ZLIB_LIBRARY})
+ set(cmMesonTestF2_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+else()
+ set(cmMesonTestF2_FOUND OFF)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/cmake_fake3/bin/.gitkeep b/test cases/linuxlike/13 cmake dependency/cmake_fake3/bin/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake_fake3/bin/.gitkeep
diff --git a/test cases/linuxlike/13 cmake dependency/cmake_fake3/lib/cmake/cmMesonTestF3/cmMesonTestF3Config.cmake b/test cases/linuxlike/13 cmake dependency/cmake_fake3/lib/cmake/cmMesonTestF3/cmMesonTestF3Config.cmake
new file mode 100644
index 0000000..2fab395
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake_fake3/lib/cmake/cmMesonTestF3/cmMesonTestF3Config.cmake
@@ -0,0 +1,9 @@
+find_package(ZLIB)
+
+if(ZLIB_FOUND OR ZLIB_Found)
+ set(cmMesonTestF3_FOUND ON)
+ set(cmMesonTestF3_LIBRARIES ${ZLIB_LIBRARY})
+ set(cmMesonTestF3_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+else()
+ set(cmMesonTestF3_FOUND OFF)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonTestDep/cmMesonTestDepConfig.cmake b/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonTestDep/cmMesonTestDepConfig.cmake
new file mode 100644
index 0000000..06a2060
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonTestDep/cmMesonTestDepConfig.cmake
@@ -0,0 +1,9 @@
+find_package(ZLIB)
+
+if(ZLIB_FOUND OR ZLIB_Found)
+ set(cmMesonTestDep_FOUND ON)
+ set(cmMesonTestDep_LIBRARIES ${ZLIB_LIBRARY})
+ set(cmMesonTestDep_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+else()
+ set(cmMesonTestDep_FOUND OFF)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfig.cmake b/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfig.cmake
new file mode 100644
index 0000000..d3adcb7
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfig.cmake
@@ -0,0 +1,9 @@
+find_package(ZLIB)
+
+if(ZLIB_FOUND OR ZLIB_Found)
+ set(cmMesonVersionedTestDep_FOUND ON)
+ set(cmMesonVersionedTestDep_LIBRARIES ${ZLIB_LIBRARY})
+ set(cmMesonVersionedTestDep_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+else()
+ set(cmMesonVersionedTestDep_FOUND OFF)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfigVersion.cmake b/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfigVersion.cmake
new file mode 100644
index 0000000..5b9905d
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/cmake_pref_env/lib/cmake/cmMesonVersionedTestDep/cmMesonVersionedTestDepConfigVersion.cmake
@@ -0,0 +1,12 @@
+set(PACKAGE_VERSION 3.1.4)
+
+if (${PACKAGE_FIND_VERSION_MAJOR} EQUAL 3)
+ if (${PACKAGE_FIND_VERSION} VERSION_LESS 3.1.4)
+ set(PACKAGE_VERSION_COMPATIBLE 1)
+ endif()
+ if (${PACKAGE_FIND_VERSION} VERSION_EQUAL 3.1.4)
+ set(PACKAGE_VERSION_EXACT 1)
+ endif()
+else()
+ set(PACKAGE_VERSION_UNSUITABLE 1)
+endif()
diff --git a/test cases/linuxlike/13 cmake dependency/incdir/myinc.h b/test cases/linuxlike/13 cmake dependency/incdir/myinc.h
new file mode 100644
index 0000000..4b66a6c
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/incdir/myinc.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include<zlib.h>
diff --git a/test cases/linuxlike/13 cmake dependency/meson.build b/test cases/linuxlike/13 cmake dependency/meson.build
new file mode 100644
index 0000000..193ad18
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/meson.build
@@ -0,0 +1,101 @@
+# this test can ONLY be run successfully from run_project_test.py
+# due to use of setup_env.json
+project('external CMake dependency', ['c', 'cpp'])
+
+if not find_program('cmake', required: false).found()
+ error('MESON_SKIP_TEST cmake binary not available.')
+endif
+
+# Zlib is probably on all dev machines.
+
+dep = dependency('ZLIB', version : '>=1.2', method : 'cmake')
+exe = executable('zlibprog', 'prog-checkver.c',
+ dependencies : dep,
+ c_args : '-DFOUND_ZLIB="' + dep.version() + '"')
+
+assert(dep.version().version_compare('>=1.2'), 'CMake version numbers exposed incorrectly.')
+
+# Check that CMake targets are extracted
+dept = dependency('ZLIB', version : '>=1.2', method : 'cmake', modules : 'ZLIB::ZLIB')
+exet = executable('zlibprog_target', 'prog-checkver.c',
+ dependencies : dep,
+ c_args : '-DFOUND_ZLIB="' + dep.version() + '"')
+
+# Check that the version exposed by zlib internally is the same as the one we
+# retrieve from the pkg-config file. This assumes that the packager didn't mess
+# up, but we can be reasonably sure of that.
+test('zlibtest', exe)
+
+# Test that dependencies of dependencies work.
+dep2 = declare_dependency(dependencies : dep)
+exe2 = executable('zlibprog2', 'prog.c', dependencies : dep2)
+test('zlibtest2', exe2)
+
+# Try to find a nonexistent library to ensure requires:false works.
+
+depf1 = dependency('nvakuhrabnsdfasdf', required : false, method : 'cmake')
+depf2 = dependency('ZLIB', required : false, method : 'cmake', modules : 'dfggh::hgfgag')
+
+assert(depf2.found() == false, 'Invalid CMake targets should fail')
+
+# Try to find cmMesonTestDep in a custom prefix
+# setup_env.json is used by run_project_tests.py:_run_test to point to ./cmake_pref_env/
+depPrefEnv = dependency('cmMesonTestDep', required : true, method : 'cmake')
+depPrefEnv1 = dependency('cmMesonTestF1', required : true, method : 'cmake')
+depPrefEnv2 = dependency('cmMesonTestF2', required : true, method : 'cmake')
+depPrefEnv3 = dependency('cmMesonTestF3', required : true, method : 'cmake')
+
+# Try to actually link with depPrefEnv1, since we are doing "fun" stuff there
+exe3 = executable('zlibprog3', 'prog.c', dependencies : depPrefEnv1)
+test('zlibtest3', exe3)
+
+# Try to find a dependency with a custom CMake module
+
+depm1 = dependency('SomethingLikeZLIB', required : true, components : 'required_comp', method : 'cmake', cmake_module_path : 'cmake')
+depm2 = dependency('SomethingLikeZLIB', required : true, components : 'required_comp', method : 'cmake', cmake_module_path : ['cmake'])
+depm3 = dependency('SomethingLikeZLIB', required : true, components : ['required_comp'], cmake_module_path : 'cmake')
+
+
+# Mix of imported targets and old style variables
+
+depio1 = dependency('ImportedOldStyle', required : true, cmake_module_path : 'cmake')
+
+# Try to actually link with depio1, since we are doing even more "fun" stuff there
+exe4 = executable('zlibprog4', 'prog.c', dependencies : depio1)
+test('zlibtest4', exe4)
+
+# Test some edge cases with spaces, etc. (but only for CMake >= 3.15)
+
+if find_program('cmake', required: false, version: '>=3.15').found()
+ testDep1 = dependency('ImportedTarget', required : true, method : 'cmake', cmake_module_path : 'cmake', modules: 'mesonTestLibDefs')
+ testDep2 = dependency('ImportedTarget', required : true, method : 'cmake', cmake_module_path : 'cmake', modules : ['MesonTest::TestLibDefs'])
+ testFlagSet1 = executable('testFlagSet1', ['testFlagSet.c'], dependencies: [testDep1])
+ testFlagSet2 = executable('testFlagSet2', ['testFlagSet.c'], dependencies: [testDep2])
+ test('testFlagSetTest1', testFlagSet1)
+ test('testFlagSetTest2', testFlagSet2)
+endif
+
+# Try to find a dependency with a cmake module which requires a package version
+# test.json sets CMAKE_PREFIX_PATH to include ./cmake_pref_env/
+verdep1 = dependency('cmMesonVersionedTestDep', required : true, method : 'cmake', cmake_package_version : '3.0')
+verdep2 = dependency('cmMesonVersionedTestDep', required : false, method : 'cmake', cmake_package_version : '200.0')
+assert(not verdep2.found(), 'found a version dep we shouldn\'t have')
+
+# Try to compile a test that takes a dep and an include_directories
+
+cc = meson.get_compiler('c')
+zlibdep = cc.find_library('z')
+code = '''#include<myinc.h>
+
+int main(void) {
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return 1;
+}
+'''
+
+inc = include_directories('incdir')
+
+r = cc.run(code, include_directories : inc, dependencies : zlibdep)
+assert(r.returncode() == 0, 'Running manual zlib test failed.')
diff --git a/test cases/linuxlike/13 cmake dependency/prog-checkver.c b/test cases/linuxlike/13 cmake dependency/prog-checkver.c
new file mode 100644
index 0000000..ea1ed32
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/prog-checkver.c
@@ -0,0 +1,15 @@
+#include <zlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(void) {
+ void * something = deflate;
+ if(strcmp(ZLIB_VERSION, FOUND_ZLIB) != 0) {
+ printf("Meson found '%s' but zlib is '%s'\n", FOUND_ZLIB, ZLIB_VERSION);
+ return 2;
+ }
+ if(something != 0)
+ return 0;
+ printf("Couldn't find 'deflate'\n");
+ return 1;
+}
diff --git a/test cases/linuxlike/13 cmake dependency/prog.c b/test cases/linuxlike/13 cmake dependency/prog.c
new file mode 100644
index 0000000..eccc477
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/prog.c
@@ -0,0 +1,8 @@
+#include<zlib.h>
+
+int main(void) {
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return 1;
+}
diff --git a/test cases/linuxlike/13 cmake dependency/test.json b/test cases/linuxlike/13 cmake dependency/test.json
new file mode 100644
index 0000000..1505986
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/test.json
@@ -0,0 +1,14 @@
+{
+ "env": {
+ "CMAKE_PREFIX_PATH": "@ROOT@/cmake_fake1;@ROOT@/cmake_fake2:@ROOT@/cmake_pref_env",
+ "PATH": "@ROOT@/cmake_fake3/bin:@PATH@"
+ },
+ "stdout": [
+ {
+ "line": "WARNING: Could not find and exact match for the CMake dependency cmMesonTestF1."
+ },
+ {
+ "line": " ['CMMesonTESTf1::evil_non_standard_trget']"
+ }
+ ]
+}
diff --git a/test cases/linuxlike/13 cmake dependency/testFlagSet.c b/test cases/linuxlike/13 cmake dependency/testFlagSet.c
new file mode 100644
index 0000000..1f93ea3
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/testFlagSet.c
@@ -0,0 +1,18 @@
+#include<stdio.h>
+#include<zlib.h>
+
+#ifndef REQUIRED_MESON_FLAG1
+#error "REQUIRED_MESON_FLAG1 not set"
+#endif
+
+#ifndef REQUIRED_MESON_FLAG2
+#error "REQUIRED_MESON_FLAG2 not set"
+#endif
+
+int main(void) {
+ printf("Hello World\n");
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return 1;
+}
diff --git a/test cases/linuxlike/14 static dynamic linkage/main.c b/test cases/linuxlike/14 static dynamic linkage/main.c
new file mode 100644
index 0000000..09d1509
--- /dev/null
+++ b/test cases/linuxlike/14 static dynamic linkage/main.c
@@ -0,0 +1,7 @@
+#include "stdio.h"
+#include "zlib.h"
+
+int main(void) {
+ printf("%s\n", zlibVersion());
+ return 0;
+}
diff --git a/test cases/linuxlike/14 static dynamic linkage/meson.build b/test cases/linuxlike/14 static dynamic linkage/meson.build
new file mode 100644
index 0000000..fb0e353
--- /dev/null
+++ b/test cases/linuxlike/14 static dynamic linkage/meson.build
@@ -0,0 +1,36 @@
+project('static dynamic', 'c')
+
+# Solaris does not ship static libraries
+if host_machine.system() == 'sunos'
+ has_static = false
+else
+ has_static = true
+endif
+
+cc = meson.get_compiler('c')
+
+z_default = cc.find_library('z')
+if has_static
+ z_static = cc.find_library('z', static: true)
+endif
+z_dynamic = cc.find_library('z', static: false)
+
+exe_default = executable('main_default', 'main.c', dependencies: [z_default])
+if has_static
+ exe_static = executable('main_static', 'main.c', dependencies: [z_static])
+endif
+exe_dynamic = executable('main_dynamic', 'main.c', dependencies: [z_dynamic])
+
+test('test default', exe_default)
+if has_static
+ test('test static', exe_static)
+endif
+test('test dynamic', exe_dynamic)
+
+if has_static
+ test('verify static linking', find_program('verify_static.py'),
+ args: ['--platform=' + host_machine.system(), exe_static.full_path()])
+endif
+test('verify dynamic linking', find_program('verify_static.py'),
+ args: ['--platform=' + host_machine.system(), exe_dynamic.full_path()],
+ should_fail: true)
diff --git a/test cases/linuxlike/14 static dynamic linkage/verify_static.py b/test cases/linuxlike/14 static dynamic linkage/verify_static.py
new file mode 100755
index 0000000..8d16d48
--- /dev/null
+++ b/test cases/linuxlike/14 static dynamic linkage/verify_static.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+"""Test script that checks if zlib was statically linked to executable"""
+import subprocess
+import sys
+
+def handle_common(path):
+ """Handle the common case."""
+ output = subprocess.check_output(['nm', path]).decode('utf-8')
+ if 'T zlibVersion' in output:
+ return 0
+ return 1
+
+def handle_cygwin(path):
+ """Handle the Cygwin case."""
+ output = subprocess.check_output(['nm', path]).decode('utf-8')
+ if (('I __imp_zlibVersion' in output) or ('D __imp_zlibVersion' in output)):
+ return 1
+ return 0
+
+def main():
+ """Main function"""
+ if len(sys.argv) > 2 and sys.argv[1] == '--platform=cygwin':
+ return handle_cygwin(sys.argv[2])
+ else:
+ return handle_common(sys.argv[2])
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/test cases/linuxlike/15 ld binary/meson.build b/test cases/linuxlike/15 ld binary/meson.build
new file mode 100644
index 0000000..6452813
--- /dev/null
+++ b/test cases/linuxlike/15 ld binary/meson.build
@@ -0,0 +1,4 @@
+project('ld binary')
+
+ld = find_program('ld')
+assert(run_command(ld, '--version', check: false).returncode() == 0)
diff --git a/test cases/linuxlike/2 external library/meson.build b/test cases/linuxlike/2 external library/meson.build
new file mode 100644
index 0000000..3188ebf
--- /dev/null
+++ b/test cases/linuxlike/2 external library/meson.build
@@ -0,0 +1,43 @@
+project('external library', 'c')
+
+cc = meson.get_compiler('c')
+zlib = cc.find_library('z')
+
+# Verify that link testing works.
+linkcode = '''#include<zlib.h>
+int main(void) {
+ void *ptr = (void*)(deflate);
+ return ptr == 0;
+}
+'''
+
+nolinkcode='''int nonexisting();
+int main(void) {
+ return nonexisting();
+}
+'''
+
+assert(cc.links(linkcode, args : '-lz', name : 'Test link against zlib'), 'Linking test failed.')
+d1 = declare_dependency(compile_args: '-DSOMETHING', link_args: '-lz')
+assert(cc.links(linkcode, dependencies : d1,
+ name : 'Test link against zlib via declare_dependency'), 'Linking test failed.')
+d2 = declare_dependency(dependencies: d1)
+assert(cc.links(linkcode, dependencies : d2,
+ name : 'Test link against zlib via indirect declare_dependency'), 'Linking test failed.')
+assert(not cc.links(nolinkcode, name : 'Failing link'), 'Linking succeeded when it should have failed.')
+
+e = executable('zprog', 'prog.c', dependencies : zlib)
+test('libtest', e)
+
+e2 = executable('zprog_alt', 'prog.c', dependencies : zlib)
+test('libtest_alt', e2)
+
+# Test that ext deps work via an internal dep.
+intdep = declare_dependency(dependencies : zlib)
+exe2 = executable('zprog2', 'prog.c', dependencies : intdep)
+test('libtest2', exe2)
+
+# Test that deps that use find_library deps work.
+depdep = declare_dependency(dependencies : intdep)
+exe3 = executable('zprog3', 'prog.c', dependencies : depdep)
+test('libtest3', exe3)
diff --git a/test cases/linuxlike/2 external library/prog.c b/test cases/linuxlike/2 external library/prog.c
new file mode 100644
index 0000000..eccc477
--- /dev/null
+++ b/test cases/linuxlike/2 external library/prog.c
@@ -0,0 +1,8 @@
+#include<zlib.h>
+
+int main(void) {
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return 1;
+}
diff --git a/test cases/linuxlike/3 linker script/bob.c b/test cases/linuxlike/3 linker script/bob.c
new file mode 100644
index 0000000..50e29c7
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/bob.c
@@ -0,0 +1,9 @@
+#include"bob.h"
+
+int hiddenFunction(void) {
+ return 42;
+}
+
+int bobMcBob(void) {
+ return hiddenFunction();
+}
diff --git a/test cases/linuxlike/3 linker script/bob.h b/test cases/linuxlike/3 linker script/bob.h
new file mode 100644
index 0000000..351e2fc
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/bob.h
@@ -0,0 +1,6 @@
+#ifndef BOB_H_
+#define BOB_H_
+
+int bobMcBob(void);
+
+#endif
diff --git a/test cases/linuxlike/3 linker script/bob.map b/test cases/linuxlike/3 linker script/bob.map
new file mode 100644
index 0000000..e07a780
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/bob.map
@@ -0,0 +1,6 @@
+V1_0_0 {
+ global:
+ "bobMcBob";
+ local:
+ *;
+};
diff --git a/test cases/linuxlike/3 linker script/bob.map.in b/test cases/linuxlike/3 linker script/bob.map.in
new file mode 100644
index 0000000..f695e4a
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/bob.map.in
@@ -0,0 +1,6 @@
+V1_0_0 {
+ global:
+ "@in@";
+ local:
+ *;
+};
diff --git a/test cases/linuxlike/3 linker script/copy.py b/test cases/linuxlike/3 linker script/copy.py
new file mode 100644
index 0000000..49e7a85
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/copy.py
@@ -0,0 +1,5 @@
+import shutil
+import sys
+
+if __name__ == '__main__':
+ shutil.copy(sys.argv[1], sys.argv[2])
diff --git a/test cases/linuxlike/3 linker script/meson.build b/test cases/linuxlike/3 linker script/meson.build
new file mode 100644
index 0000000..5901bf7
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/meson.build
@@ -0,0 +1,62 @@
+project('linker script', 'c')
+
+# Solaris 11.4 ld supports --version-script only when you also specify
+# -z gnu-version-script-compat
+if meson.get_compiler('c').get_linker_id() == 'ld.solaris'
+ add_project_link_arguments('-Wl,-z,gnu-version-script-compat', language: 'C')
+endif
+
+# Static map file
+mapfile = 'bob.map'
+vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
+
+l = shared_library('bob', 'bob.c', link_args : vflag, link_depends : mapfile)
+e = executable('prog', 'prog.c', link_with : l)
+test('core', e)
+
+# configure_file
+conf = configuration_data()
+conf.set('in', 'bobMcBob')
+m = configure_file(
+ input : 'bob.map.in',
+ output : 'bob-conf.map',
+ configuration : conf,
+)
+vflag = '-Wl,--version-script,@0@'.format(m)
+
+l = shared_library('bob-conf', 'bob.c', link_args : vflag, link_depends : m)
+e = executable('prog-conf', 'prog.c', link_with : l)
+test('core', e)
+
+# custom_target
+python = find_program('python3')
+m = custom_target(
+ 'bob-ct.map',
+ command : [python, '@INPUT0@', '@INPUT1@', 'bob-ct.map'],
+ input : ['copy.py', 'bob.map'],
+ output : 'bob-ct.map',
+ depend_files : 'bob.map',
+)
+vflag = '-Wl,--version-script,@0@'.format(m.full_path())
+
+l = shared_library('bob-ct', ['bob.c', m], link_args : vflag, link_depends : m)
+e = executable('prog-ct', 'prog.c', link_with : l)
+test('core', e)
+
+# File
+mapfile = files('bob.map')
+vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile[0])
+
+l = shared_library('bob-files', 'bob.c', link_args : vflag, link_depends : mapfile)
+e = executable('prog-files', 'prog.c', link_with : l)
+test('core', e)
+
+subdir('sub')
+
+# With map file in subdir
+mapfile = 'sub/foo.map'
+vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
+
+l = shared_library('bar', 'bob.c', link_args : vflag, link_depends : mapfile)
+e = executable('prog-bar', 'prog.c', link_with : l)
+test('core', e)
diff --git a/test cases/linuxlike/3 linker script/prog.c b/test cases/linuxlike/3 linker script/prog.c
new file mode 100644
index 0000000..b010b15
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/prog.c
@@ -0,0 +1,5 @@
+#include"bob.h"
+
+int main(void) {
+ return bobMcBob() != 42;
+}
diff --git a/test cases/linuxlike/3 linker script/sub/foo.map b/test cases/linuxlike/3 linker script/sub/foo.map
new file mode 100644
index 0000000..e07a780
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/sub/foo.map
@@ -0,0 +1,6 @@
+V1_0_0 {
+ global:
+ "bobMcBob";
+ local:
+ *;
+};
diff --git a/test cases/linuxlike/3 linker script/sub/meson.build b/test cases/linuxlike/3 linker script/sub/meson.build
new file mode 100644
index 0000000..93199f3
--- /dev/null
+++ b/test cases/linuxlike/3 linker script/sub/meson.build
@@ -0,0 +1,6 @@
+mapfile = 'foo.map'
+vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
+
+l = shared_library('foo', '../bob.c', link_args : vflag, link_depends : mapfile)
+e = executable('prog-foo', '../prog.c', link_with : l)
+test('core', e)
diff --git a/test cases/linuxlike/4 extdep static lib/lib.c b/test cases/linuxlike/4 extdep static lib/lib.c
new file mode 100644
index 0000000..bbda9aa
--- /dev/null
+++ b/test cases/linuxlike/4 extdep static lib/lib.c
@@ -0,0 +1,8 @@
+#include<zlib.h>
+
+int statlibfunc(void) {
+ void * something = deflate;
+ if(something != 0)
+ return 0;
+ return 1;
+}
diff --git a/test cases/linuxlike/4 extdep static lib/meson.build b/test cases/linuxlike/4 extdep static lib/meson.build
new file mode 100644
index 0000000..1a73e49
--- /dev/null
+++ b/test cases/linuxlike/4 extdep static lib/meson.build
@@ -0,0 +1,10 @@
+project('external dependency with static', 'c')
+
+# Zlib is probably on all dev machines.
+
+dep = dependency('zlib')
+statlib = static_library('statlib', 'lib.c', dependencies : dep)
+exe = executable('prog', 'prog.c', link_with : statlib)
+
+
+test('zlibtest', exe)
diff --git a/test cases/linuxlike/4 extdep static lib/prog.c b/test cases/linuxlike/4 extdep static lib/prog.c
new file mode 100644
index 0000000..0aeb827
--- /dev/null
+++ b/test cases/linuxlike/4 extdep static lib/prog.c
@@ -0,0 +1,5 @@
+int statlibfunc(void);
+
+int main(void) {
+ return statlibfunc();
+}
diff --git a/test cases/linuxlike/5 dependency versions/meson.build b/test cases/linuxlike/5 dependency versions/meson.build
new file mode 100644
index 0000000..164e679
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/meson.build
@@ -0,0 +1,122 @@
+project('dep versions', 'c', 'cpp')
+
+# Find external dependency without version
+zlib = dependency('zlib')
+# Find external dependency with version
+zlibver = dependency('zlib', version : '>1.0')
+assert(zlib.version() == zlibver.version(), 'zlib versions did not match!')
+# Find external dependency with conflicting version
+assert(zlib.type_name() == 'pkgconfig', 'zlib should be of type "pkgconfig" not ' + zlib.type_name())
+zlibver = dependency('zlib', version : '<1.0', required : false)
+assert(zlibver.found() == false, 'zlib <1.0 should not be found!')
+
+# Find external dependencies with various version restrictions
+dependency('zlib', version : '>=1.0')
+dependency('zlib', version : '<=9999')
+dependency('zlib', version : '=' + zlib.version())
+
+# Find external dependencies with multiple version restrictions
+dependency('zlib', version : ['>=1.0', '<=9999'])
+if dependency('zlib', version : ['<=1.0', '>=9999', '=' + zlib.version()], required : false).found()
+ error('zlib <=1.0 >=9999 should not have been found')
+endif
+
+# Test that a versionless zlib is found after not finding an optional zlib dep with version reqs
+zlibopt = dependency('zlib', required : false)
+assert(zlibopt.found() == true, 'zlib not found')
+
+# Test https://github.com/mesonbuild/meson/pull/610
+dependency('somebrokenlib', version : '>=2.0', required : false)
+dependency('somebrokenlib', version : '>=1.0', required : false)
+
+# Search for an external dependency that won't be found, but must later be
+# found via fallbacks
+somelibnotfound = dependency('somelib1', required : false)
+assert(somelibnotfound.found() == false, 'somelibnotfound was found?')
+# Find internal dependency without version
+somelibver = dependency('somelib1',
+ fallback : ['somelibnover', 'some_dep'])
+assert(somelibver.type_name() == 'internal', 'somelibver should be of type "internal", not ' + somelibver.type_name())
+# Find an internal dependency again with the same name and a specific version
+somelib = dependency('somelib2',
+ version : '== 0.1',
+ fallback : ['somelib', 'some_dep'])
+# Find an internal dependency again even if required = false
+somelib_reqfalse = dependency('somelib3',
+ required: false,
+ fallback : ['somelib', 'some_dep'])
+assert(somelib_reqfalse.found(), 'somelib should have been found')
+# Find an internal dependency again with the same name and incompatible version
+somelibver = dependency('somelib4',
+ version : '>= 0.3',
+ fallback : ['somelibver', 'some_dep'])
+# Find an internal dependency again with impossible multi-version
+somelibver = dependency('somelib5',
+ version : ['>= 0.3', '<0.3'],
+ required : false,
+ fallback : ['somelibver', 'some_dep'])
+assert(not somelibver.found(), 'Dependency should not be found')
+# Find somelib again, but with a fallback that will fail because subproject does not exist
+somelibfail = dependency('somelib6',
+ version : '>= 0.2',
+ required : false,
+ fallback : ['somelibfail', 'some_dep'])
+assert(somelibfail.found() == false, 'somelibfail found via wrong fallback')
+# Find somelib again, but with a fallback that will fail because dependency does not exist
+somefail_dep = dependency('somelib7',
+ version : '>= 0.2',
+ required : false,
+ fallback : ['somelib', 'somefail_dep'])
+assert(somefail_dep.found() == false, 'somefail_dep found via wrong fallback')
+
+# Fallback should only be used if the primary was not found
+fallbackzlib_dep = dependency('zlib',
+ fallback : ['fakezlib', 'fakezlib_dep'])
+assert(fallbackzlib_dep.type_name() == 'pkgconfig', 'fallbackzlib_dep should be of type "pkgconfig", not ' + fallbackzlib_dep.type_name())
+# Check that the above dependency was pkgconfig because the fallback wasn't
+# checked, not because the fallback didn't work
+fakezlib_dep = dependency('fakezlib',
+ fallback : ['fakezlib', 'fakezlib_dep'])
+assert(fakezlib_dep.type_name() == 'internal', 'fakezlib_dep should be of type "internal", not ' + fakezlib_dep.type_name())
+
+# Verify that once we got a system dependency, we won't fallback if a newer
+# version is requested.
+d = dependency('zlib', version: '>= 999',
+ fallback : ['donotexist', 'fakezlib_dep'],
+ required: false)
+assert(not d.found(), 'version should not match and it should not fallback')
+
+# Check that you can find a dependency by not specifying a version after not
+# finding it by specifying a version. We add `static: true` here so that the
+# previously cached zlib dependencies don't get checked.
+dependency('zlib', static : true, version : '>=8000', required : false)
+dependency('zlib', static : true)
+
+# Check that you can find a dependency by specifying a correct version after
+# not finding it by specifying a wrong one. We add `method: pkg-config` here so that
+# the previously cached zlib dependencies don't get checked.
+bzip2 = dependency('zlib', method : 'pkg-config', version : '>=9000', required : false)
+bzip2 = dependency('zlib', method : 'pkg-config', version : '>=1.0')
+
+if meson.is_cross_build()
+ # Test caching of native and cross dependencies
+ # https://github.com/mesonbuild/meson/issues/1736
+ cross_prefix = dependency('zlib').get_pkgconfig_variable('prefix')
+ native_prefix = dependency('zlib', native : true).get_pkgconfig_variable('prefix')
+ assert(cross_prefix != '', 'cross zlib prefix is not defined')
+ assert(native_prefix != '', 'native zlib prefix is not defined')
+ assert(native_prefix != cross_prefix, 'native prefix == cross_prefix == ' + native_prefix)
+endif
+
+objc_found = add_languages('objc', required : false)
+
+foreach d : ['sdl2', 'gnustep', 'wxwidgets', 'gl', 'python3', 'boost', 'gtest', 'gmock', 'valgrind']
+ if d == 'gnustep' and not objc_found
+ message('Skipping gnustep because no ObjC compiler found')
+ else
+ dep = dependency(d, required : false)
+ if dep.found()
+ dep.version()
+ endif
+ endif
+endforeach
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/fakezlib/meson.build b/test cases/linuxlike/5 dependency versions/subprojects/fakezlib/meson.build
new file mode 100644
index 0000000..5a07763
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/fakezlib/meson.build
@@ -0,0 +1,3 @@
+project('some', 'c', version : '0.1')
+
+fakezlib_dep = declare_dependency()
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c b/test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build b/test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build
new file mode 100644
index 0000000..670b10f
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build
@@ -0,0 +1,11 @@
+# Define version only in project, should get inherited by declare_dependency
+project('some', 'c', version : '0.1')
+
+somelib = library('some', 'lib.c')
+someinc = include_directories('.')
+
+some_dep = declare_dependency(link_with : somelib,
+ include_directories : someinc)
+
+fakezlib_dep = declare_dependency(link_with : somelib,
+ include_directories : someinc)
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build
new file mode 100644
index 0000000..aa7e554
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build
@@ -0,0 +1,8 @@
+project('some', 'c')
+
+somelib = library('some', 'lib.c')
+someinc = include_directories('.')
+
+# Define version only in declare_dependency
+some_dep = declare_dependency(link_with : somelib,
+ include_directories : someinc)
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build
new file mode 100644
index 0000000..c773814
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build
@@ -0,0 +1,9 @@
+project('some', 'c')
+
+somelib = library('some', 'lib.c')
+someinc = include_directories('.')
+
+# Define version only in declare_dependency
+some_dep = declare_dependency(link_with : somelib,
+ include_directories : someinc,
+ version : '0.3')
diff --git a/test cases/linuxlike/6 subdir include order/meson.build b/test cases/linuxlike/6 subdir include order/meson.build
new file mode 100644
index 0000000..fea3984
--- /dev/null
+++ b/test cases/linuxlike/6 subdir include order/meson.build
@@ -0,0 +1,12 @@
+project('subdir include order', 'c')
+
+# Ensure that headers in subdirs override external dependencies
+cc = meson.get_compiler('c')
+
+glib = dependency('glib-2.0')
+
+# This will fail to compile if it picks up the system-installed glib instead of
+# the glib in the subdir
+executable('prog', 'prog.c',
+ include_directories : include_directories('subdir'),
+ dependencies : glib)
diff --git a/test cases/linuxlike/6 subdir include order/prog.c b/test cases/linuxlike/6 subdir include order/prog.c
new file mode 100644
index 0000000..2d47a93
--- /dev/null
+++ b/test cases/linuxlike/6 subdir include order/prog.c
@@ -0,0 +1,7 @@
+#include <glib.h>
+
+#ifndef MESON_OUR_GLIB
+#error "Failed"
+#endif
+
+int main(void) { return 0; }
diff --git a/test cases/linuxlike/6 subdir include order/subdir/glib.h b/test cases/linuxlike/6 subdir include order/subdir/glib.h
new file mode 100644
index 0000000..444b2d0
--- /dev/null
+++ b/test cases/linuxlike/6 subdir include order/subdir/glib.h
@@ -0,0 +1 @@
+#define MESON_OUR_GLIB 1
diff --git a/test cases/linuxlike/7 library versions/exe.orig.c b/test cases/linuxlike/7 library versions/exe.orig.c
new file mode 100644
index 0000000..1e8e90e
--- /dev/null
+++ b/test cases/linuxlike/7 library versions/exe.orig.c
@@ -0,0 +1,8 @@
+int myFunc (void);
+
+int main(void)
+{
+ if (myFunc() == 55)
+ return 0;
+ return 1;
+}
diff --git a/test cases/linuxlike/7 library versions/lib.c b/test cases/linuxlike/7 library versions/lib.c
new file mode 100644
index 0000000..bd251d7
--- /dev/null
+++ b/test cases/linuxlike/7 library versions/lib.c
@@ -0,0 +1,3 @@
+int myFunc(void) {
+ return 55;
+}
diff --git a/test cases/linuxlike/7 library versions/meson.build b/test cases/linuxlike/7 library versions/meson.build
new file mode 100644
index 0000000..5160947
--- /dev/null
+++ b/test cases/linuxlike/7 library versions/meson.build
@@ -0,0 +1,55 @@
+project('library versions', 'c')
+
+if host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST linuxlike soversions not supported on Cygwin.')
+endif
+
+some = shared_library('some', 'lib.c',
+ version : '1.2.3',
+ soversion : '0',
+ install : true)
+
+noversion = shared_library('noversion', 'lib.c',
+ install : true)
+
+onlyversion = shared_library('onlyversion', 'lib.c',
+ version : '1.4.5',
+ install : true)
+
+onlysoversion = shared_library('onlysoversion', 'lib.c',
+ # Also test that int soversion is acceptable
+ soversion : 5,
+ install : true)
+
+# Hack to make the executables below depend on the shared libraries above
+# without actually adding them as `link_with` dependencies since we want to try
+# linking to them with -lfoo linker arguments.
+out = custom_target('library-dependency-hack',
+ input : 'exe.orig.c',
+ output : 'exe.c',
+ depends : [some, noversion, onlyversion, onlysoversion],
+ command : ['cp', '@INPUT@', '@OUTPUT@'])
+
+# Need to add this manually because Meson can't add it automatically because
+# it doesn't know that we are linking to libraries in the build directory.
+rpath_dir = meson.current_build_dir()
+
+# Manually test if the linker can find the above libraries
+# i.e., whether they were generated with the right naming scheme
+test('manually linked 1', executable('manuallink1', out,
+ link_args : ['-L.', '-lsome'],
+ build_rpath : rpath_dir))
+
+test('manually linked 2', executable('manuallink2', out,
+ link_args : ['-L.', '-lnoversion'],
+ build_rpath : rpath_dir))
+
+test('manually linked 3', executable('manuallink3', out,
+ link_args : ['-L.', '-lonlyversion'],
+ build_rpath : rpath_dir))
+
+test('manually linked 4', executable('manuallink4', out,
+ link_args : ['-L.', '-lonlysoversion'],
+ build_rpath : rpath_dir))
+
+shared_module('module', 'lib.c', install : true)
diff --git a/test cases/linuxlike/7 library versions/test.json b/test cases/linuxlike/7 library versions/test.json
new file mode 100644
index 0000000..0da9277
--- /dev/null
+++ b/test cases/linuxlike/7 library versions/test.json
@@ -0,0 +1,14 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libsome.so"},
+ {"type": "file", "file": "usr/lib/libsome.so.0"},
+ {"type": "file", "file": "usr/lib/libsome.so.1.2.3"},
+ {"type": "file", "file": "usr/lib/libnoversion.so"},
+ {"type": "file", "file": "usr/lib/libonlyversion.so"},
+ {"type": "file", "file": "usr/lib/libonlyversion.so.1"},
+ {"type": "file", "file": "usr/lib/libonlyversion.so.1.4.5"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.so"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.so.5"},
+ {"type": "file", "file": "usr/lib/libmodule.so"}
+ ]
+}
diff --git a/test cases/linuxlike/8 subproject library install/meson.build b/test cases/linuxlike/8 subproject library install/meson.build
new file mode 100644
index 0000000..ff55799
--- /dev/null
+++ b/test cases/linuxlike/8 subproject library install/meson.build
@@ -0,0 +1,10 @@
+project('subproj lib install', 'c',
+ version : '2.3.4',
+ license : 'mylicense')
+
+if host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST linuxlike soversions not supported on Cygwin.')
+endif
+
+# Test that the subproject library gets installed
+subproject('sublib', version : '1.0.0')
diff --git a/test cases/linuxlike/8 subproject library install/subprojects/sublib/include/subdefs.h b/test cases/linuxlike/8 subproject library install/subprojects/sublib/include/subdefs.h
new file mode 100644
index 0000000..6ae8462
--- /dev/null
+++ b/test cases/linuxlike/8 subproject library install/subprojects/sublib/include/subdefs.h
@@ -0,0 +1,21 @@
+#ifndef SUBDEFS_H_
+#define SUBDEFS_H_
+
+#if defined _WIN32 || defined __CYGWIN__
+#if defined BUILDING_SUB
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #define DLL_PUBLIC __declspec(dllimport)
+#endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC subfunc(void);
+
+#endif
diff --git a/test cases/linuxlike/8 subproject library install/subprojects/sublib/meson.build b/test cases/linuxlike/8 subproject library install/subprojects/sublib/meson.build
new file mode 100644
index 0000000..97658fa
--- /dev/null
+++ b/test cases/linuxlike/8 subproject library install/subprojects/sublib/meson.build
@@ -0,0 +1,10 @@
+project('subproject', 'c',
+ version : '1.0.0',
+ license : ['sublicense1', 'sublicense2'])
+
+i = include_directories('include')
+shared_library('sublib', 'sublib.c',
+ version : '2.1.0',
+ soversion : 5,
+ include_directories : i, install : true,
+ c_args : '-DBUILDING_SUB=2')
diff --git a/test cases/linuxlike/8 subproject library install/subprojects/sublib/sublib.c b/test cases/linuxlike/8 subproject library install/subprojects/sublib/sublib.c
new file mode 100644
index 0000000..f71564f
--- /dev/null
+++ b/test cases/linuxlike/8 subproject library install/subprojects/sublib/sublib.c
@@ -0,0 +1,5 @@
+#include<subdefs.h>
+
+int DLL_PUBLIC subfunc(void) {
+ return 42;
+}
diff --git a/test cases/linuxlike/8 subproject library install/test.json b/test cases/linuxlike/8 subproject library install/test.json
new file mode 100644
index 0000000..5a2bf04
--- /dev/null
+++ b/test cases/linuxlike/8 subproject library install/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libsublib.so"},
+ {"type": "file", "file": "usr/lib/libsublib.so.5"},
+ {"type": "file", "file": "usr/lib/libsublib.so.2.1.0"}
+ ]
+}
diff --git a/test cases/linuxlike/9 compiler checks with dependencies/meson.build b/test cases/linuxlike/9 compiler checks with dependencies/meson.build
new file mode 100644
index 0000000..24a9ac0
--- /dev/null
+++ b/test cases/linuxlike/9 compiler checks with dependencies/meson.build
@@ -0,0 +1,36 @@
+project('compiler checks with dependencies', 'c')
+
+cc = meson.get_compiler('c')
+
+glib = dependency ('glib-2.0')
+if glib.found()
+ assert (cc.has_header('glib.h', dependencies : glib), 'glib.h not found')
+ assert (cc.has_type('gint32', prefix : '#include <glib.h>', dependencies : glib), 'gint32 not found')
+ assert (cc.has_function('g_print', dependencies : glib), 'g_print not found')
+ assert (cc.has_member('GError', 'message', prefix : '#include <glib.h>', dependencies : glib), 'GError::message not found')
+ assert (cc.has_header_symbol('glib.h', 'gint32', dependencies : glib), 'gint32 symbol not found')
+ linkcode = '''#include <glib.h>
+int main (void) {
+ GError *error = g_error_new_literal (0, 0, NULL);
+ return error == NULL;
+}
+ '''
+ assert (cc.links(linkcode, dependencies : glib, name : 'Test link against glib'), 'Linking test against glib failed')
+endif
+
+zlib = cc.find_library ('z')
+if zlib.found()
+ linkcode = '''#include<zlib.h>
+int main(void) {
+ void *ptr = (void*)(deflate);
+ return ptr == 0;
+}
+'''
+ assert (cc.has_function('deflate', prefix : '#include<zlib.h>', dependencies : zlib), 'has_function test failed.')
+ assert (cc.links(linkcode, dependencies : zlib, name : 'Test link against zlib'), 'Linking test failed against zlib.')
+endif
+
+assert(cc.has_function('pthread_create',
+ dependencies : dependency('threads'),
+ prefix : '#include <pthread.h>'),
+ 'Could not detect pthread_create with a thread dependency.')
diff --git a/test cases/nasm/1 configure file/hello.asm b/test cases/nasm/1 configure file/hello.asm
new file mode 100644
index 0000000..bf4bf96
--- /dev/null
+++ b/test cases/nasm/1 configure file/hello.asm
@@ -0,0 +1,27 @@
+; hello.asm a first program for nasm for Linux, Intel, gcc
+;
+; assemble: nasm -f elf -l hello.lst hello.asm
+; link: gcc -o hello hello.o
+; run: hello
+; output is: Hello World
+
+%include "config.asm"
+
+ SECTION .data ; data section
+msg: db "Hello World",10 ; the string to print, 10=cr
+len: equ $-msg ; "$" means "here"
+ ; len is a value, not an address
+
+ SECTION .text ; code section
+ global main ; make label available to linker
+main: ; standard gcc entry point
+
+ mov edx,len ; arg3, length of string to print
+ mov ecx,msg ; arg2, pointer to string
+ mov ebx,1 ; arg1, where to write, screen
+ mov eax,4 ; write sysout command to int 80 hex
+ int 0x80 ; interrupt 80 hex, call kernel
+
+ mov ebx,HELLO ; exit code, 0=normal
+ mov eax,1 ; exit command to kernel
+ int 0x80 ; interrupt 80 hex, call kernel
diff --git a/test cases/nasm/1 configure file/meson.build b/test cases/nasm/1 configure file/meson.build
new file mode 100644
index 0000000..85ecaf1
--- /dev/null
+++ b/test cases/nasm/1 configure file/meson.build
@@ -0,0 +1,55 @@
+project('nasm config file', 'c')
+
+if host_machine.cpu_family() == 'x86' and host_machine.system() == 'windows'
+ asm_format = 'win32'
+elif host_machine.cpu_family() == 'x86_64' and host_machine.system() == 'windows'
+ asm_format = 'win64'
+elif host_machine.cpu_family() == 'x86' and host_machine.system() == 'linux'
+ asm_format = 'elf32'
+elif host_machine.cpu_family() == 'x86_64' and host_machine.system() == 'linux'
+ asm_format = 'elf64'
+else
+ error('MESON_SKIP_TEST: skipping test on this platform')
+endif
+
+nasm = find_program('nasm', required: false)
+
+if not nasm.found()
+ error('MESON_SKIP_TEST: nasm not available')
+endif
+
+conf = configuration_data()
+
+conf.set('HELLO', 0)
+
+asm_gen = generator(nasm,
+ output : '@BASENAME@.o',
+ arguments : [
+ '-f', asm_format,
+ '-i', meson.current_source_dir() + '/',
+ '-i', join_paths(meson.current_source_dir(), ''),
+ '-P', join_paths(meson.current_build_dir(), 'config.asm'),
+ '@INPUT@',
+ '-o', '@OUTPUT@'])
+
+
+config_file = configure_file(
+ output: 'config.asm',
+ configuration: conf,
+ output_format: 'nasm',
+)
+
+cc = meson.get_compiler('c')
+link_args = cc.get_supported_link_arguments(['-no-pie'])
+
+exe = executable('hello', asm_gen.process('hello.asm'),
+ link_args: link_args,
+)
+
+test('test-nasm-configure-file', exe)
+
+exe2 = executable('hello2', objects : exe.extract_all_objects(),
+ link_args: link_args,
+)
+
+test('test-nasm-extract-all-objects', exe2)
diff --git a/test cases/nasm/2 asm language/hello.asm b/test cases/nasm/2 asm language/hello.asm
new file mode 100644
index 0000000..1e3e8fd
--- /dev/null
+++ b/test cases/nasm/2 asm language/hello.asm
@@ -0,0 +1,31 @@
+; hello.asm a first program for nasm for Linux, Intel, gcc
+;
+; assemble: nasm -f elf -l hello.lst hello.asm
+; link: gcc -o hello hello.o
+; run: hello
+; output is: Hello World
+
+%include "config.asm"
+
+%ifdef FOO
+%define RETVAL HELLO
+%endif
+
+ SECTION .data ; data section
+msg: db "Hello World",10 ; the string to print, 10=cr
+len: equ $-msg ; "$" means "here"
+ ; len is a value, not an address
+
+ SECTION .text ; code section
+ global main ; make label available to linker
+main: ; standard gcc entry point
+
+ mov edx,len ; arg3, length of string to print
+ mov ecx,msg ; arg2, pointer to string
+ mov ebx,1 ; arg1, where to write, screen
+ mov eax,4 ; write sysout command to int 80 hex
+ int 0x80 ; interrupt 80 hex, call kernel
+
+ mov ebx,RETVAL ; exit code, 0=normal
+ mov eax,1 ; exit command to kernel
+ int 0x80 ; interrupt 80 hex, call kernel
diff --git a/test cases/nasm/2 asm language/meson.build b/test cases/nasm/2 asm language/meson.build
new file mode 100644
index 0000000..390ffed
--- /dev/null
+++ b/test cases/nasm/2 asm language/meson.build
@@ -0,0 +1,57 @@
+project('test', 'c')
+
+if not host_machine.cpu_family().startswith('x86')
+ assert(not add_languages('nasm', required: false))
+ error('MESON_SKIP_TEST: nasm only supported for x86 and x86_64')
+endif
+
+if not add_languages('nasm', required: false)
+ nasm = find_program('nasm', 'yasm', required: false)
+ assert(not nasm.found())
+ error('MESON_SKIP_TEST: nasm not found')
+endif
+
+nasm = meson.get_compiler('nasm')
+
+code = '''
+SECTION .text
+global main
+main:
+ mov foo,bar ; error: symbol `foo' not defined
+'''
+assert(not nasm.compiles(code, name: 'Invalid NASM code'))
+
+code = '''
+SECTION .text
+global main
+main:
+ mov eax,1
+'''
+assert(nasm.compiles(code, name: 'Valid NASM code'))
+
+config_file = configure_file(
+ output: 'config.asm',
+ configuration: {'HELLO': 0},
+ output_format: 'nasm',
+)
+
+cc = meson.get_compiler('c')
+link_args = cc.get_supported_link_arguments(['-no-pie'])
+
+exe = executable('hello', 'hello.asm',
+ nasm_args: '-DFOO',
+ link_args: link_args,
+)
+test('hello', exe)
+
+#Test whether pthread dependency gets filtered out
+threads = dependency('threads')
+
+exe2 = executable('hello_w_threads', 'hello.asm',
+ config_file,
+ nasm_args: '-DFOO',
+ link_args: link_args,
+ dependencies: [threads]
+)
+
+test('hello_w_threads', exe2)
diff --git a/test cases/native/1 trivial/meson.build b/test cases/native/1 trivial/meson.build
new file mode 100644
index 0000000..f6c5d4d
--- /dev/null
+++ b/test cases/native/1 trivial/meson.build
@@ -0,0 +1,9 @@
+project('trivial native test', 'c')
+
+sources = 'trivial.c'
+cc = meson.get_compiler('c', native: true)
+
+if meson.is_cross_build()
+ native_exe = executable('native-trivialprog', sources : sources, native : true)
+ test('native exe in cross build', native_exe)
+endif
diff --git a/test cases/native/1 trivial/trivial.c b/test cases/native/1 trivial/trivial.c
new file mode 100644
index 0000000..96612d4
--- /dev/null
+++ b/test cases/native/1 trivial/trivial.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Trivial test is working.\n");
+ return 0;
+}
diff --git a/test cases/native/2 global arg/meson.build b/test cases/native/2 global arg/meson.build
new file mode 100644
index 0000000..c303a02
--- /dev/null
+++ b/test cases/native/2 global arg/meson.build
@@ -0,0 +1,14 @@
+project('global arg test', 'cpp', 'c')
+
+add_global_arguments('-DMYTHING', language : 'c', native : true)
+add_global_arguments('-DMYCPPTHING', language : 'cpp', native : true)
+add_global_arguments('-DGLOBAL_BUILD', language : 'c', native : true)
+
+build_c_args = ['-DARG_BUILD']
+c_args = ['-DARG_HOST']
+
+add_global_arguments('-DMYCANDCPPTHING', language: ['c', 'cpp'], native: true)
+
+exe1 = executable('prog1', 'prog.c', c_args : build_c_args, native : true)
+
+test('prog1', exe1)
diff --git a/test cases/native/2 global arg/prog.c b/test cases/native/2 global arg/prog.c
new file mode 100644
index 0000000..2a71236
--- /dev/null
+++ b/test cases/native/2 global arg/prog.c
@@ -0,0 +1,43 @@
+#ifndef MYTHING
+ #error "Global argument not set"
+#endif
+
+#ifdef MYCPPTHING
+ #error "Wrong global argument set"
+#endif
+
+#ifndef MYCANDCPPTHING
+ #error "Global argument not set"
+#endif
+
+#if !defined(GLOBAL_HOST) && !defined(GLOBAL_BUILD)
+ #error "Neither global_host nor glogal_build is set."
+#endif
+
+#if defined(GLOBAL_HOST) && defined(GLOBAL_BUILD)
+ #error "Both global build and global host set."
+#endif
+
+#ifdef GLOBAL_BUILD
+ #ifndef ARG_BUILD
+ #error "Global is build but arg_build is not set."
+ #endif
+
+ #ifdef ARG_HOST
+ #error "Global is build but arg host is set."
+ #endif
+#endif
+
+#ifdef GLOBAL_HOST
+ #ifndef ARG_HOST
+ #error "Global is host but arg_host is not set."
+ #endif
+
+ #ifdef ARG_BUILD
+ #error "Global is host but arg_build is set."
+ #endif
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/native/2 global arg/prog.cc b/test cases/native/2 global arg/prog.cc
new file mode 100644
index 0000000..5c32209
--- /dev/null
+++ b/test cases/native/2 global arg/prog.cc
@@ -0,0 +1,15 @@
+#ifdef MYTHING
+#error "Wrong global argument set"
+#endif
+
+#ifndef MYCPPTHING
+#error "Global argument not set"
+#endif
+
+#ifndef MYCANDCPPTHING
+#error "Global argument not set"
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/native/3 pipeline/depends/copyrunner.py b/test cases/native/3 pipeline/depends/copyrunner.py
new file mode 100755
index 0000000..0ef6a6d
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/copyrunner.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys, subprocess
+
+prog, infile, outfile = sys.argv[1:]
+
+subprocess.check_call([prog, infile, outfile])
diff --git a/test cases/native/3 pipeline/depends/filecopier.c b/test cases/native/3 pipeline/depends/filecopier.c
new file mode 100644
index 0000000..e10e4e7
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/filecopier.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+#define BUFSIZE 1024
+
+int main(int argc, char **argv) {
+ char buffer[BUFSIZE];
+ size_t num_read;
+ size_t num_written;
+ FILE *fin = fopen(argv[1], "rb");
+ FILE *fout;
+ assert(argc>0);
+ assert(fin);
+ num_read = fread(buffer, 1, BUFSIZE, fin);
+ assert(num_read > 0);
+ fclose(fin);
+ fout = fopen(argv[2], "wb");
+ assert(fout);
+ num_written = fwrite(buffer, 1, num_read, fout);
+ assert(num_written == num_read);
+ fclose(fout);
+ return 0;
+}
diff --git a/test cases/native/3 pipeline/depends/libsrc.c.in b/test cases/native/3 pipeline/depends/libsrc.c.in
new file mode 100644
index 0000000..8180551
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/libsrc.c.in
@@ -0,0 +1,3 @@
+int func(void) {
+ return 42;
+}
diff --git a/test cases/native/3 pipeline/depends/meson.build b/test cases/native/3 pipeline/depends/meson.build
new file mode 100644
index 0000000..5111fee
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/meson.build
@@ -0,0 +1,11 @@
+runner = find_program('copyrunner.py')
+
+copier = executable('copier', 'filecopier.c', native: true)
+
+cg = generator(runner,
+ output: ['@BASENAME@.c'],
+ arguments: [copier.full_path(), '@INPUT@', '@OUTPUT@'],
+ depends: copier)
+
+test('generatordep',
+ executable('gd', 'prog.c', cg.process('libsrc.c.in')))
diff --git a/test cases/native/3 pipeline/depends/prog.c b/test cases/native/3 pipeline/depends/prog.c
new file mode 100644
index 0000000..54c40e1
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/prog.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func() != 42;
+}
diff --git a/test cases/native/3 pipeline/input_src.dat b/test cases/native/3 pipeline/input_src.dat
new file mode 100644
index 0000000..a324dca
--- /dev/null
+++ b/test cases/native/3 pipeline/input_src.dat
@@ -0,0 +1 @@
+int func(void) { return 0; }
diff --git a/test cases/native/3 pipeline/meson.build b/test cases/native/3 pipeline/meson.build
new file mode 100644
index 0000000..e12cb7b
--- /dev/null
+++ b/test cases/native/3 pipeline/meson.build
@@ -0,0 +1,23 @@
+project('pipeline test', 'c')
+
+# We need to run this executable locally so build it with
+# the host compiler.
+e1 = executable('srcgen', 'srcgen.c', native : true)
+
+# Generate a source file that needs to be included in the build.
+gen = generator(e1, \
+ depfile : '@BASENAME@.d',
+ output : '@BASENAME@.c', # Line continuation inside arguments should work without needing a "\".
+ arguments : ['@INPUT@', '@OUTPUT@', '@DEPFILE@'])
+
+generated = gen.process(['input_src.dat'])
+
+e2 = executable('prog', 'prog.c', generated)
+
+test('pipelined', e2)
+
+# This is in a subdirectory to make sure
+# we write proper subdir paths to output.
+subdir('src')
+
+subdir('depends')
diff --git a/test cases/native/3 pipeline/prog.c b/test cases/native/3 pipeline/prog.c
new file mode 100644
index 0000000..128f2bb
--- /dev/null
+++ b/test cases/native/3 pipeline/prog.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/native/3 pipeline/src/input_src.dat b/test cases/native/3 pipeline/src/input_src.dat
new file mode 100644
index 0000000..354499a
--- /dev/null
+++ b/test cases/native/3 pipeline/src/input_src.dat
@@ -0,0 +1 @@
+#include<stdio.h>
diff --git a/test cases/native/3 pipeline/src/meson.build b/test cases/native/3 pipeline/src/meson.build
new file mode 100644
index 0000000..4e9ac11
--- /dev/null
+++ b/test cases/native/3 pipeline/src/meson.build
@@ -0,0 +1,12 @@
+e1 = executable('srcgen', 'srcgen.c', native : true)
+
+# Generate a header file that needs to be included.
+gen = generator(e1,
+ output : '@BASENAME@.h',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+generated = gen.process('input_src.dat')
+
+e2 = executable('prog', 'prog.c', generated)
+
+test('pipelined', e2)
diff --git a/test cases/native/3 pipeline/src/prog.c b/test cases/native/3 pipeline/src/prog.c
new file mode 100644
index 0000000..83121b5
--- /dev/null
+++ b/test cases/native/3 pipeline/src/prog.c
@@ -0,0 +1,9 @@
+#include"input_src.h"
+
+int main(void) {
+ void *foo = printf;
+ if(foo) {
+ return 0;
+ }
+ return 1;
+}
diff --git a/test cases/native/3 pipeline/src/srcgen.c b/test cases/native/3 pipeline/src/srcgen.c
new file mode 100644
index 0000000..26761d2
--- /dev/null
+++ b/test cases/native/3 pipeline/src/srcgen.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+#define ARRSIZE 80
+
+int main(int argc, char **argv) {
+ char arr[ARRSIZE];
+ char *ifilename;
+ char *ofilename;
+ FILE *ifile;
+ FILE *ofile;
+ size_t bytes;
+
+ if(argc != 3) {
+ fprintf(stderr, "%s <input file> <output file>\n", argv[0]);
+ return 1;
+ }
+ ifilename = argv[1];
+ ofilename = argv[2];
+ printf("%s\n", ifilename);
+ ifile = fopen(ifilename, "r");
+ if(!ifile) {
+ fprintf(stderr, "Could not open source file %s.\n", ifilename);
+ return 1;
+ }
+ ofile = fopen(ofilename, "w");
+ if(!ofile) {
+ fprintf(stderr, "Could not open target file %s\n", ofilename);
+ fclose(ifile);
+ return 1;
+ }
+ bytes = fread(arr, 1, ARRSIZE, ifile);
+ assert(bytes < 80);
+ assert(bytes > 0);
+ fwrite(arr, 1, bytes, ofile);
+
+ fclose(ifile);
+ fclose(ofile);
+ return 0;
+}
diff --git a/test cases/native/3 pipeline/srcgen.c b/test cases/native/3 pipeline/srcgen.c
new file mode 100644
index 0000000..ceb9ecc
--- /dev/null
+++ b/test cases/native/3 pipeline/srcgen.c
@@ -0,0 +1,69 @@
+#include<stdio.h>
+#include<assert.h>
+#include<string.h>
+
+#define ARRSIZE 80
+
+int main(int argc, char **argv) {
+ char arr[ARRSIZE];
+ char *ofilename;
+ char *ifilename;
+ char *dfilename;
+ FILE *ifile;
+ FILE *ofile;
+ FILE *depfile;
+ size_t bytes;
+ int i;
+
+ if(argc != 4) {
+ fprintf(stderr, "%s <input file> <output file> <dependency file>\n", argv[0]);
+ return 1;
+ }
+ ifilename = argv[1];
+ ofilename = argv[2];
+ dfilename = argv[3];
+ ifile = fopen(argv[1], "r");
+ if(!ifile) {
+ fprintf(stderr, "Could not open source file %s.\n", argv[1]);
+ return 1;
+ }
+ ofile = fopen(ofilename, "w");
+ if(!ofile) {
+ fprintf(stderr, "Could not open target file %s\n", ofilename);
+ fclose(ifile);
+ return 1;
+ }
+ bytes = fread(arr, 1, ARRSIZE, ifile);
+ assert(bytes < 80);
+ assert(bytes > 0);
+ fwrite(arr, 1, bytes, ofile);
+
+ depfile = fopen(dfilename, "w");
+ if(!depfile) {
+ fprintf(stderr, "Could not open depfile %s\n", ofilename);
+ fclose(ifile);
+ fclose(ofile);
+ return 1;
+ }
+ for(i=0; i<strlen(ofilename); i++) {
+ if(ofilename[i] == ' ') {
+ fwrite("\\ ", 1, 2, depfile);
+ } else {
+ fwrite(&ofilename[i], 1, 1, depfile);
+ }
+ }
+ fwrite(": ", 1, 2, depfile);
+ for(i=0; i<strlen(ifilename); i++) {
+ if(ifilename[i] == ' ') {
+ fwrite("\\ ", 1, 2, depfile);
+ } else {
+ fwrite(&ifilename[i], 1, 1, depfile);
+ }
+ }
+ fwrite("\n", 1, 1, depfile);
+
+ fclose(ifile);
+ fclose(ofile);
+ fclose(depfile);
+ return 0;
+}
diff --git a/test cases/native/4 tryrun/error.c b/test cases/native/4 tryrun/error.c
new file mode 100644
index 0000000..53ef08e
--- /dev/null
+++ b/test cases/native/4 tryrun/error.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 1;
+}
diff --git a/test cases/native/4 tryrun/meson.build b/test cases/native/4 tryrun/meson.build
new file mode 100644
index 0000000..5580974
--- /dev/null
+++ b/test cases/native/4 tryrun/meson.build
@@ -0,0 +1,78 @@
+project('tryrun', 'c', 'cpp')
+
+# Complex to exercise all code paths.
+if meson.is_cross_build()
+ if meson.can_run_host_binaries()
+ compilers = [meson.get_compiler('c', native : false), meson.get_compiler('cpp', native : false)]
+ else
+ compilers = [meson.get_compiler('c', native : true), meson.get_compiler('cpp', native : true)]
+ endif
+else
+ compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
+endif
+
+ok_code = '''#include<stdio.h>
+int main(void) {
+ printf("%s\n", "stdout");
+ fprintf(stderr, "%s\n", "stderr");
+ return 0;
+}
+'''
+
+error_code = '''int main(void) {
+ return 1;
+}
+'''
+
+no_compile_code = '''int main(void) {
+'''
+
+INPUTS = [
+ ['String', ok_code, error_code, no_compile_code],
+ ['File', files('ok.c'), files('error.c'), files('no_compile.c')],
+]
+
+foreach cc : compilers
+ foreach input : INPUTS
+ type = input[0]
+ ok = cc.run(input[1], name : type + ' should succeed')
+ err = cc.run(input[2], name : type + ' should fail')
+ noc = cc.run(input[3], name : type + ' does not compile')
+
+ if noc.compiled()
+ error(type + ' compilation fail test failed.')
+ else
+ message(type + ' fail detected properly.')
+ endif
+
+ if ok.compiled()
+ message(type + ' compilation worked.')
+ else
+ error(type + ' compilation did not work.')
+ endif
+
+ if ok.returncode() == 0
+ message(type + ' return code ok.')
+ else
+ error(type + ' return code fail')
+ endif
+
+ if err.returncode() == 1
+ message(type + ' bad return code ok.')
+ else
+ error(type + ' bad return code fail.')
+ endif
+
+ if ok.stdout().strip() == 'stdout'
+ message(type + ' stdout ok.')
+ else
+ message(type + ' bad stdout.')
+ endif
+
+ if ok.stderr().strip() == 'stderr'
+ message(type + ' stderr ok.')
+ else
+ message(type + ' bad stderr.')
+ endif
+ endforeach
+endforeach
diff --git a/test cases/native/4 tryrun/no_compile.c b/test cases/native/4 tryrun/no_compile.c
new file mode 100644
index 0000000..496c2e8
--- /dev/null
+++ b/test cases/native/4 tryrun/no_compile.c
@@ -0,0 +1 @@
+int main(void) {
diff --git a/test cases/native/4 tryrun/ok.c b/test cases/native/4 tryrun/ok.c
new file mode 100644
index 0000000..e2a36c8
--- /dev/null
+++ b/test cases/native/4 tryrun/ok.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("%s\n", "stdout");
+ fprintf(stderr, "%s\n", "stderr");
+ return 0;
+}
diff --git a/test cases/native/5 install script/file.txt b/test cases/native/5 install script/file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/native/5 install script/file.txt
diff --git a/test cases/native/5 install script/meson.build b/test cases/native/5 install script/meson.build
new file mode 100644
index 0000000..8a69a0d
--- /dev/null
+++ b/test cases/native/5 install script/meson.build
@@ -0,0 +1,12 @@
+project('custom install script', 'c')
+
+# this is just to ensure that the install directory exists before exe is run
+install_data('file.txt', install_dir: '.')
+
+subdir('src')
+
+meson.add_install_script(exe, 'generated.txt')
+wrap = find_program('wrap.py')
+# Yes, these are getting silly
+meson.add_install_script(wrap, exe, 'wrapped.txt')
+meson.add_install_script(wrap, wrap, exe, 'wrapped2.txt')
diff --git a/test cases/native/5 install script/src/exe.c b/test cases/native/5 install script/src/exe.c
new file mode 100644
index 0000000..2df3ee8
--- /dev/null
+++ b/test cases/native/5 install script/src/exe.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char * argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "Takes exactly 2 arguments\n");
+ return 1;
+ }
+
+ char * dirname = getenv("MESON_INSTALL_DESTDIR_PREFIX");
+ char * fullname = malloc(strlen(dirname) + 1 + strlen(argv[1]) + 1);
+ strcpy(fullname, dirname);
+ strcat(fullname, "/");
+ strcat(fullname, argv[1]);
+
+ FILE * fp = fopen(fullname, "w");
+ if (!fp)
+ return 1;
+
+ fputs("Some text\n", fp);
+ fclose(fp);
+
+ free(fullname);
+
+ return 0;
+}
diff --git a/test cases/native/5 install script/src/meson.build b/test cases/native/5 install script/src/meson.build
new file mode 100644
index 0000000..f60c995
--- /dev/null
+++ b/test cases/native/5 install script/src/meson.build
@@ -0,0 +1 @@
+exe = executable('exe', 'exe.c', install : false, native : true)
diff --git a/test cases/native/5 install script/test.json b/test cases/native/5 install script/test.json
new file mode 100644
index 0000000..c41c27c
--- /dev/null
+++ b/test cases/native/5 install script/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/file.txt"},
+ {"type": "file", "file": "usr/generated.txt"},
+ {"type": "file", "file": "usr/wrapped.txt"},
+ {"type": "file", "file": "usr/wrapped2.txt"}
+ ]
+}
diff --git a/test cases/native/5 install script/wrap.py b/test cases/native/5 install script/wrap.py
new file mode 100755
index 0000000..87508e0
--- /dev/null
+++ b/test cases/native/5 install script/wrap.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import subprocess
+import sys
+
+subprocess.run(sys.argv[1:])
diff --git a/test cases/native/6 add language/meson.build b/test cases/native/6 add language/meson.build
new file mode 100644
index 0000000..a7aad73
--- /dev/null
+++ b/test cases/native/6 add language/meson.build
@@ -0,0 +1,3 @@
+project('add language', 'c')
+assert(add_languages('cpp', native: true), 'Add_languages returned false on success')
+test('C++', executable('cppprog', 'prog.cc', native: true))
diff --git a/test cases/native/6 add language/prog.cc b/test cases/native/6 add language/prog.cc
new file mode 100644
index 0000000..03647dd
--- /dev/null
+++ b/test cases/native/6 add language/prog.cc
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int, char**) {
+ std::cout << "I am C++.\n";
+ return 0;
+}
diff --git a/test cases/native/7 selfbuilt custom/checkarg.cpp b/test cases/native/7 selfbuilt custom/checkarg.cpp
new file mode 100644
index 0000000..99092ee
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/checkarg.cpp
@@ -0,0 +1,6 @@
+#include <cassert>
+
+int main(int argc, char *[]) {
+ assert(argc == 2);
+ return 0;
+}
diff --git a/test cases/native/7 selfbuilt custom/data.dat b/test cases/native/7 selfbuilt custom/data.dat
new file mode 100644
index 0000000..83fd1d9
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/data.dat
@@ -0,0 +1 @@
+generated_function
diff --git a/test cases/native/7 selfbuilt custom/mainprog.cpp b/test cases/native/7 selfbuilt custom/mainprog.cpp
new file mode 100644
index 0000000..bb45dca
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/mainprog.cpp
@@ -0,0 +1,5 @@
+#include"data.h"
+
+int main(void) {
+ return generated_function() != 52;
+}
diff --git a/test cases/native/7 selfbuilt custom/meson.build b/test cases/native/7 selfbuilt custom/meson.build
new file mode 100644
index 0000000..b536352
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/meson.build
@@ -0,0 +1,39 @@
+project('selfbuilt custom', 'cpp')
+
+# Build an exe and use it in a custom target
+# whose output is used to build a different exe.
+
+tool = executable('tool', 'tool.cpp', native : true)
+
+hfile = custom_target('datah',
+ output : 'data.h',
+ input : 'data.dat',
+ command : [tool, '@INPUT@', '@OUTPUT@'],
+)
+
+main = executable('mainprog', 'mainprog.cpp', hfile)
+
+test('maintest', main)
+
+lib = library('libtool', 'tool.cpp')
+
+checkarg = executable('checkarg', 'checkarg.cpp', native : true)
+
+ctlib = custom_target('ctlib',
+ output : 'ctlib.out',
+ capture : true,
+ command : [checkarg, lib],
+ build_by_default : true,
+)
+
+if meson.is_cross_build() and meson.can_run_host_binaries()
+ checkarg_host = executable('checkarg_host', 'checkarg.cpp')
+
+ ctlib_host = custom_target(
+ 'ctlib_host',
+ output : 'ctlib.host.out',
+ capture : true,
+ command : [checkarg_host, lib],
+ build_by_default : true,
+ )
+endif
diff --git a/test cases/native/7 selfbuilt custom/tool.cpp b/test cases/native/7 selfbuilt custom/tool.cpp
new file mode 100644
index 0000000..6a28dd8
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/tool.cpp
@@ -0,0 +1,34 @@
+#include<iostream>
+#include<fstream>
+#include<string>
+
+using namespace std;
+
+const char prefix[] = "int ";
+const char suffix[] = " () {\n return 52;}\n";
+
+int main(int argc, char **argv) {
+ if(argc != 3) {
+ cout << "You is fail.\n";
+ return 1;
+ }
+ ifstream is(argv[1], ifstream::binary);
+ if(!is) {
+ cout << "Opening input file failed.\n";
+ return 1;
+ }
+ string funcname;
+ is >> funcname;
+ ofstream os(argv[2], ofstream::binary);
+ if(!os) {
+ cout << "Opening output file failed.\n";
+ return 1;
+ }
+ os << prefix << funcname << suffix;
+ os.close();
+ if(!os.good()) {
+ cout << "Writing data out failed.\n";
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/native/8 external program shebang parsing/input.txt b/test cases/native/8 external program shebang parsing/input.txt
new file mode 100644
index 0000000..40e30d4
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/input.txt
@@ -0,0 +1 @@
+some stuff here
diff --git a/test cases/native/8 external program shebang parsing/main.c b/test cases/native/8 external program shebang parsing/main.c
new file mode 100644
index 0000000..48b080e
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/main.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#ifdef _WIN32
+ #include <io.h>
+ #include <windows.h>
+#else
+ #include <unistd.h>
+#endif
+
+/* Who cares about stack sizes in test programs anyway */
+#define LINE_LENGTH 4096
+
+static int
+intrp_copyfile (char * src, char * dest)
+{
+#ifdef _WIN32
+ if (!CopyFile (src, dest, FALSE))
+ return 1;
+ return 0;
+#else
+ return execlp ("cp", "cp", src, dest, NULL);
+#endif
+}
+
+static void
+parser_get_line (FILE * f, char line[LINE_LENGTH])
+{
+ if (!fgets (line, LINE_LENGTH, f))
+ fprintf (stderr, "%s\n", strerror (errno));
+}
+
+int
+main (int argc, char * argv[])
+{
+ FILE *f = NULL;
+ char line[LINE_LENGTH];
+
+ if (argc != 4) {
+ fprintf (stderr, "Invalid number of arguments: %i\n", argc);
+ goto err;
+ }
+
+ if ((f = fopen (argv[1], "r")) == NULL) {
+ fprintf (stderr, "%s\n", strerror (errno));
+ goto err;
+ }
+
+ parser_get_line (f, line);
+
+ if (!line || line[0] != '#' || line[1] != '!') {
+ fprintf (stderr, "Invalid script\n");
+ goto err;
+ }
+
+ parser_get_line (f, line);
+
+ if (!line || strncmp (line, "copy", 4) != 0) {
+ fprintf (stderr, "Syntax error: %s\n", line);
+ goto err;
+ }
+
+ return intrp_copyfile (argv[2], argv[3]);
+
+err:
+ fclose (f);
+ return 1;
+}
diff --git a/test cases/native/8 external program shebang parsing/meson.build b/test cases/native/8 external program shebang parsing/meson.build
new file mode 100644
index 0000000..c1cc5af
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/meson.build
@@ -0,0 +1,21 @@
+project('shebang parsing', 'c')
+
+interpreter = executable('aninterp', 'main.c', native : true)
+
+cdata = configuration_data()
+cdata.set('INTRP', interpreter.full_path())
+
+f = configure_file(input : 'script.int.in',
+ output : 'script.int',
+ configuration : cdata)
+
+# Test that parsing a shebang with spaces works properly. See `man execve`,
+# specifically the section on "Interpreter scripts" and the one under "NOTES".
+script = find_program(f)
+
+custom_target('interpthis',
+ input : 'input.txt',
+ output : 'output.txt',
+ depends : interpreter,
+ command : [script, '@INPUT@', '@OUTPUT@'],
+ build_by_default : true)
diff --git a/test cases/native/8 external program shebang parsing/script.int.in b/test cases/native/8 external program shebang parsing/script.int.in
new file mode 100644
index 0000000..77ff909
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/script.int.in
@@ -0,0 +1,2 @@
+#!/usr/bin/env @INTRP@
+copy
diff --git a/test cases/native/9 override with exe/main2.input b/test cases/native/9 override with exe/main2.input
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/native/9 override with exe/main2.input
diff --git a/test cases/native/9 override with exe/meson.build b/test cases/native/9 override with exe/meson.build
new file mode 100644
index 0000000..5275532
--- /dev/null
+++ b/test cases/native/9 override with exe/meson.build
@@ -0,0 +1,21 @@
+project('myexe', 'c', version: '0.1')
+sub = subproject('sub')
+
+prog = find_program('foobar', version : '>= 2.0', required : false)
+assert(not prog.found())
+
+prog = find_program('foobar', version : '>= 1.0')
+custom1 = custom_target('custom1',
+ build_by_default : true,
+ input : [],
+ output : 'main1.c',
+ command : [prog, '@OUTPUT@'])
+gen = generator(prog,
+ output : '@BASENAME@.c',
+ arguments : ['@OUTPUT@'])
+custom2 = gen.process('main2.input')
+
+message(prog.full_path())
+
+executable('e1', custom1)
+executable('e2', custom2)
diff --git a/test cases/native/9 override with exe/subprojects/sub/foobar.c b/test cases/native/9 override with exe/subprojects/sub/foobar.c
new file mode 100644
index 0000000..c21d450
--- /dev/null
+++ b/test cases/native/9 override with exe/subprojects/sub/foobar.c
@@ -0,0 +1,13 @@
+#include <assert.h>
+#include <stdio.h>
+
+int main(int argc, char* argv[]) {
+ assert(argc == 2);
+ FILE *f = fopen(argv[1], "w");
+ const char msg[] = "int main(void) {return 0;}\n";
+ size_t w = fwrite(msg, 1, sizeof(msg) - 1, f);
+ assert(w == sizeof(msg) - 1);
+ int r = fclose(f);
+ assert(r == 0);
+ return 0;
+}
diff --git a/test cases/native/9 override with exe/subprojects/sub/meson.build b/test cases/native/9 override with exe/subprojects/sub/meson.build
new file mode 100644
index 0000000..f0343b2
--- /dev/null
+++ b/test cases/native/9 override with exe/subprojects/sub/meson.build
@@ -0,0 +1,3 @@
+project('sub', 'c', version : '1.0')
+foobar = executable('foobar', 'foobar.c', native : true)
+meson.override_find_program('foobar', foobar)
diff --git a/test cases/objc/1 simple/meson.build b/test cases/objc/1 simple/meson.build
new file mode 100644
index 0000000..f9d5c14
--- /dev/null
+++ b/test cases/objc/1 simple/meson.build
@@ -0,0 +1,4 @@
+project('objective c', 'objc', default_options: ['c_std=c99'])
+
+exe = executable('prog', 'prog.m')
+test('objctest', exe)
diff --git a/test cases/objc/1 simple/prog.m b/test cases/objc/1 simple/prog.m
new file mode 100644
index 0000000..87457bf
--- /dev/null
+++ b/test cases/objc/1 simple/prog.m
@@ -0,0 +1,5 @@
+#import<stdio.h>
+
+int main(void) {
+ return 0;
+} \ No newline at end of file
diff --git a/test cases/objc/2 nsstring/meson.build b/test cases/objc/2 nsstring/meson.build
new file mode 100644
index 0000000..94d2cf1
--- /dev/null
+++ b/test cases/objc/2 nsstring/meson.build
@@ -0,0 +1,20 @@
+project('nsstring', 'objc')
+
+if host_machine.system() == 'darwin'
+ dep = dependency('appleframeworks', modules : 'foundation')
+elif host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST GNUstep is not packaged for Cygwin.')
+else
+ dep = dependency('gnustep', required : false)
+ if not dep.found()
+ error('MESON_SKIP_TEST: GNUstep is not installed')
+ endif
+ if host_machine.system() == 'linux' and meson.get_compiler('objc').get_id() == 'clang'
+ error('MESON_SKIP_TEST: GNUstep is broken on Linux with Clang')
+ endif
+endif
+exe = executable('stringprog', 'stringprog.m', dependencies : dep)
+test('stringtest', exe)
+
+# Ensure that a non-required dep that is not found does not cause an error
+dependency('appleframeworks', modules: 'nonexisting', required: false)
diff --git a/test cases/objc/2 nsstring/stringprog.m b/test cases/objc/2 nsstring/stringprog.m
new file mode 100644
index 0000000..5407538
--- /dev/null
+++ b/test cases/objc/2 nsstring/stringprog.m
@@ -0,0 +1,9 @@
+#import<Foundation/NSString.h>
+
+int main(void) {
+ int result;
+ NSString *str = [NSString new];
+ result = [str length];
+ [str release];
+ return result;
+}
diff --git a/test cases/objc/3 objc args/meson.build b/test cases/objc/3 objc args/meson.build
new file mode 100644
index 0000000..8887d96
--- /dev/null
+++ b/test cases/objc/3 objc args/meson.build
@@ -0,0 +1,4 @@
+project('objective c args', 'objc')
+
+exe = executable('prog', 'prog.m', objc_args : ['-DMESON_TEST'])
+test('objective c args', exe)
diff --git a/test cases/objc/3 objc args/prog.m b/test cases/objc/3 objc args/prog.m
new file mode 100644
index 0000000..003df98
--- /dev/null
+++ b/test cases/objc/3 objc args/prog.m
@@ -0,0 +1,11 @@
+#import<stdio.h>
+
+int main(void)
+{
+#ifdef MESON_TEST
+ int x = 3;
+#endif
+
+ printf("x = %d\n", x);
+ return 0;
+}
diff --git a/test cases/objc/4 c++ project objc subproject/master.cpp b/test cases/objc/4 c++ project objc subproject/master.cpp
new file mode 100644
index 0000000..cd08fb1
--- /dev/null
+++ b/test cases/objc/4 c++ project objc subproject/master.cpp
@@ -0,0 +1,11 @@
+
+#include <iostream>
+
+extern "C"
+int foo();
+
+int main(void) {
+ std::cout << "Starting\n";
+ std::cout << foo() << "\n";
+ return 0;
+}
diff --git a/test cases/objc/4 c++ project objc subproject/meson.build b/test cases/objc/4 c++ project objc subproject/meson.build
new file mode 100644
index 0000000..8a77ded
--- /dev/null
+++ b/test cases/objc/4 c++ project objc subproject/meson.build
@@ -0,0 +1,6 @@
+project('master', ['cpp'])
+
+foo = subproject('foo')
+dep = foo.get_variable('foo_dep')
+
+executable('master', 'master.cpp', dependencies: dep)
diff --git a/test cases/objc/4 c++ project objc subproject/subprojects/foo/foo.m b/test cases/objc/4 c++ project objc subproject/subprojects/foo/foo.m
new file mode 100644
index 0000000..e193b86
--- /dev/null
+++ b/test cases/objc/4 c++ project objc subproject/subprojects/foo/foo.m
@@ -0,0 +1,4 @@
+
+int foo() {
+ return 42;
+}
diff --git a/test cases/objc/4 c++ project objc subproject/subprojects/foo/meson.build b/test cases/objc/4 c++ project objc subproject/subprojects/foo/meson.build
new file mode 100644
index 0000000..2dbf8ab
--- /dev/null
+++ b/test cases/objc/4 c++ project objc subproject/subprojects/foo/meson.build
@@ -0,0 +1,5 @@
+project('foo', ['objc'])
+
+l = static_library('foo', 'foo.m')
+
+foo_dep = declare_dependency(link_with : l)
diff --git a/test cases/objcpp/1 simple/meson.build b/test cases/objcpp/1 simple/meson.build
new file mode 100644
index 0000000..c9a5c84
--- /dev/null
+++ b/test cases/objcpp/1 simple/meson.build
@@ -0,0 +1,4 @@
+project('Objective C++', 'objcpp', default_options: 'cpp_std=c++14')
+
+exe = executable('objcppprog', 'prog.mm')
+test('objcpp', exe)
diff --git a/test cases/objcpp/1 simple/prog.mm b/test cases/objcpp/1 simple/prog.mm
new file mode 100644
index 0000000..b26d5b7
--- /dev/null
+++ b/test cases/objcpp/1 simple/prog.mm
@@ -0,0 +1,8 @@
+#import<stdio.h>
+
+class MyClass {
+};
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/objcpp/2 objc++ args/meson.build b/test cases/objcpp/2 objc++ args/meson.build
new file mode 100644
index 0000000..e0e34b0
--- /dev/null
+++ b/test cases/objcpp/2 objc++ args/meson.build
@@ -0,0 +1,4 @@
+project('objective c++ args', 'objcpp')
+
+exe = executable('prog', 'prog.mm', objcpp_args : ['-DMESON_OBJCPP_TEST'])
+test('objective c++ args', exe)
diff --git a/test cases/objcpp/2 objc++ args/prog.mm b/test cases/objcpp/2 objc++ args/prog.mm
new file mode 100644
index 0000000..2b437ce
--- /dev/null
+++ b/test cases/objcpp/2 objc++ args/prog.mm
@@ -0,0 +1,16 @@
+#import<stdio.h>
+
+class TestClass
+{
+};
+
+int main(void)
+{
+#ifdef MESON_OBJCPP_TEST
+int x = 1;
+#endif
+
+ printf("x = %x\n", x);
+
+ return 0;
+}
diff --git a/test cases/osx/1 basic/main.c b/test cases/osx/1 basic/main.c
new file mode 100644
index 0000000..0a07218
--- /dev/null
+++ b/test cases/osx/1 basic/main.c
@@ -0,0 +1,5 @@
+#include <CoreFoundation/CoreFoundation.h>
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/osx/1 basic/meson.build b/test cases/osx/1 basic/meson.build
new file mode 100644
index 0000000..e0412e1
--- /dev/null
+++ b/test cases/osx/1 basic/meson.build
@@ -0,0 +1,3 @@
+project('osx fundamentals', 'c')
+e = executable('prog', 'main.c')
+test('basic', e)
diff --git a/test cases/osx/2 library versions/CMakeLists.txt b/test cases/osx/2 library versions/CMakeLists.txt
new file mode 100644
index 0000000..2cd03b9
--- /dev/null
+++ b/test cases/osx/2 library versions/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.6.0)
+project(dylibversion C)
+
+# This file is here for debugging purposes to easily compare how
+# CMake does it.
+
+# libnoversion.dylib
+add_library(noversion SHARED lib.c)
+
+# libonlysoversion.dylib -> libonlysoversion.5.dylib
+# libonlyversion.1.4.5.dylib
+# -current_version 1.4.5
+
+add_library(onlyversion SHARED lib.c)
+set_target_properties(onlyversion PROPERTIES VERSION 1.4.5)
+
+# libonlysoversion.6.dylib
+# -compatibility_version 6.0.0
+
+add_library(onlysoversion SHARED lib.c)
+set_target_properties(onlysoversion PROPERTIES SOVERSION 6)
+
+# libsome.1.4.5.dylib
+# libsome.6.dylib -> libsome.1.4.5.dylib
+# libsome.dylib -> libsome.6.dylib
+# -current_version 1.4.5 -compatibility_version 5.0.0
+
+add_library(some SHARED lib.c)
+set_target_properties(some PROPERTIES VERSION 1.4.5 SOVERSION 6)
diff --git a/test cases/osx/2 library versions/exe.orig.c b/test cases/osx/2 library versions/exe.orig.c
new file mode 100644
index 0000000..ad38e6d
--- /dev/null
+++ b/test cases/osx/2 library versions/exe.orig.c
@@ -0,0 +1,7 @@
+int myFunc (void);
+
+int main (void) {
+ if (myFunc() == 55)
+ return 0;
+ return 1;
+}
diff --git a/test cases/osx/2 library versions/lib.c b/test cases/osx/2 library versions/lib.c
new file mode 100644
index 0000000..bd251d7
--- /dev/null
+++ b/test cases/osx/2 library versions/lib.c
@@ -0,0 +1,3 @@
+int myFunc(void) {
+ return 55;
+}
diff --git a/test cases/osx/2 library versions/meson.build b/test cases/osx/2 library versions/meson.build
new file mode 100644
index 0000000..5420133
--- /dev/null
+++ b/test cases/osx/2 library versions/meson.build
@@ -0,0 +1,81 @@
+project('library versions', 'c')
+
+if run_command(find_program('require_pkgconfig.py'), check: true).stdout().strip() == 'yes'
+ required = true
+else
+ required = false
+endif
+
+zlib_dep = dependency('zlib', required: required)
+if zlib_dep.found()
+ build_rpath = zlib_dep.type_name() == 'pkgconfig' ? zlib_dep.get_pkgconfig_variable('libdir') : 'lib'
+ some = shared_library('some', 'lib.c',
+ # duplicate the rpath again, in order
+ # to test Meson's RPATH deduplication
+ build_rpath : build_rpath,
+ dependencies : zlib_dep,
+ version : '1.2.3',
+ soversion : '7',
+ install : true)
+else
+ some = shared_library('some', 'lib.c',
+ version : '1.2.3',
+ soversion : '7',
+ install : true)
+endif
+
+noversion = shared_library('noversion', 'lib.c',
+ install : true)
+
+onlyversion = shared_library('onlyversion', 'lib.c',
+ version : '1.4.5',
+ install : true)
+
+onlysoversion = shared_library('onlysoversion', 'lib.c',
+ # Also test that int soversion is acceptable
+ soversion : 5,
+ install : true)
+
+shared_library('intver', 'lib.c',
+ darwin_versions : 2)
+
+shared_library('stringver', 'lib.c',
+ darwin_versions : '2.3')
+
+shared_library('stringlistver', 'lib.c',
+ darwin_versions : ['2.4'])
+
+shared_library('intstringver', 'lib.c',
+ darwin_versions : [1111, '2.5'])
+
+shared_library('stringlistvers', 'lib.c',
+ darwin_versions : ['2.6', '2.6.1'])
+
+# Hack to make the executables below depend on the shared libraries above
+# without actually adding them as `link_with` dependencies since we want to try
+# linking to them with -lfoo linker arguments.
+out = custom_target('library-dependency-hack',
+ input : 'exe.orig.c',
+ output : 'exe.c',
+ depends : [some, noversion, onlyversion, onlysoversion],
+ command : ['cp', '@INPUT@', '@OUTPUT@'])
+
+# Manually test if the linker can find the above libraries
+# i.e., whether they were generated with the right naming scheme
+test('manually linked 1', executable('manuallink1', out,
+ link_args : ['-L.', '-lsome'],
+ build_rpath : meson.current_build_dir()))
+
+test('manually linked 2', executable('manuallink2', out,
+ link_args : ['-L.', '-lnoversion'],
+ build_rpath : meson.current_build_dir()))
+
+test('manually linked 3', executable('manuallink3', out,
+ link_args : ['-L.', '-lonlyversion'],
+ build_rpath : meson.current_build_dir()))
+
+test('manually linked 4', executable('manuallink4', out,
+ link_args : ['-L.', '-lonlysoversion'],
+ build_rpath : meson.current_build_dir()))
+
+shared_module('module', 'lib.c', install : true)
diff --git a/test cases/osx/2 library versions/require_pkgconfig.py b/test cases/osx/2 library versions/require_pkgconfig.py
new file mode 100644
index 0000000..3d228aa
--- /dev/null
+++ b/test cases/osx/2 library versions/require_pkgconfig.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+
+if 'CI' in os.environ or shutil.which('pkg-config'):
+ print('yes')
+else:
+ print('no')
diff --git a/test cases/osx/2 library versions/test.json b/test cases/osx/2 library versions/test.json
new file mode 100644
index 0000000..3234425
--- /dev/null
+++ b/test cases/osx/2 library versions/test.json
@@ -0,0 +1,12 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libsome.dylib"},
+ {"type": "file", "file": "usr/lib/libsome.7.dylib"},
+ {"type": "file", "file": "usr/lib/libnoversion.dylib"},
+ {"type": "file", "file": "usr/lib/libonlyversion.dylib"},
+ {"type": "file", "file": "usr/lib/libonlyversion.1.dylib"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.dylib"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.5.dylib"},
+ {"type": "file", "file": "usr/lib/libmodule.dylib"}
+ ]
+}
diff --git a/test cases/osx/3 has function xcode8/meson.build b/test cases/osx/3 has function xcode8/meson.build
new file mode 100644
index 0000000..edd3688
--- /dev/null
+++ b/test cases/osx/3 has function xcode8/meson.build
@@ -0,0 +1,30 @@
+project('has function xcode8', 'c')
+
+cc = meson.get_compiler('c')
+
+# XCode 8 location for the macOS 10.12 SDK
+sdk_args = ['-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk']
+args_10_11 = ['-mmacosx-version-min=10.11'] + sdk_args
+args_10_12 = ['-mmacosx-version-min=10.12'] + sdk_args
+
+# XCode 9 location for the macOS 10.13 SDK
+sdk_args = ['-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk']
+args_10_12 = ['-mmacosx-version-min=10.13'] + sdk_args
+
+# Test requires XCode 8 which has the MacOSX 10.12 SDK
+if cc.version().version_compare('>=8.0') and cc.version().version_compare('<8.1')
+ if cc.has_function('clock_gettime', args : args_10_11, prefix : '#include <time.h>')
+ error('Should not have found clock_gettime via <time.h> when targeting Mac OS X 10.11')
+ endif
+ if not cc.has_function('clock_gettime', args : args_10_12, prefix : '#include <time.h>')
+ error('Did NOT find clock_gettime via <time.h> when targeting Mac OS X 10.12')
+ endif
+ if not cc.has_function('clock_gettime', args : args_10_11)
+ error('Did NOT find clock_gettime w/o a prototype when targeting Mac OS X 10.11')
+ endif
+ if not cc.has_function('clock_gettime', args : args_10_12)
+ error('Did NOT find clock_gettime w/o a prototype when targeting Mac OS X 10.12')
+ endif
+else
+ error('MESON_SKIP_TEST Test needs XCode 8.')
+endif
diff --git a/test cases/osx/4 framework/meson.build b/test cases/osx/4 framework/meson.build
new file mode 100644
index 0000000..d1f7036
--- /dev/null
+++ b/test cases/osx/4 framework/meson.build
@@ -0,0 +1,32 @@
+# Primitive test for adding frameworks in XCode
+# When opening the xcodeproj, the Folder "Frameworks" should contain two frameworks (OpenGL.framework and Foundation.framework)
+# "Target Membership" of ...
+# - OpenGL.framework should be only to prog@exe
+# - Foundation.framework should be only to stat@sta
+# "Build Phase" / "Link Binary with Libraries" for the target
+# - "prog@exe" should be only "Foundation.framework"
+# - "stat@sta" should be only "OpenGL.framework"
+# see "xcode-frameworks.png" for an example
+
+project('xcode framework test', 'objc', default_options : ['libdir=libtest'])
+
+dep_main = dependency('appleframeworks', modules : ['Foundation'])
+
+if meson.is_cross_build()
+ # This is only available in iOS, not macOS. Just test finding it.
+ uikit_dep = dependency('appleframeworks', modules: 'UIKit')
+else
+ dep_libs = dependency('appleframeworks', modules : ['OpenGL'], required : false)
+ if not dep_libs.found()
+ error('OpenGL framework not found')
+ endif
+ assert(dep_libs.type_name() == 'appleframeworks', 'type_name is wrong')
+ # Only add the C compiler now, to ensure all lookups above were done with the ObjC one.
+ add_languages('c')
+ stlib = static_library('stat', 'stat.c', install : true, dependencies: dep_libs)
+ exe = executable('prog', 'prog.c', install : true, dependencies: dep_main)
+ uikit_dep = dependency('appleframeworks', modules: 'UIKit', required: false)
+ if uikit_dep.found()
+ error('UIKit found on macOS even though it should not be there.')
+ endif
+endif
diff --git a/test cases/osx/4 framework/prog.c b/test cases/osx/4 framework/prog.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/osx/4 framework/prog.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/osx/4 framework/stat.c b/test cases/osx/4 framework/stat.c
new file mode 100644
index 0000000..4825cef
--- /dev/null
+++ b/test cases/osx/4 framework/stat.c
@@ -0,0 +1 @@
+int func(void) { return 933; }
diff --git a/test cases/osx/4 framework/test.json b/test cases/osx/4 framework/test.json
new file mode 100644
index 0000000..8def69a
--- /dev/null
+++ b/test cases/osx/4 framework/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstat.a"}
+ ]
+}
diff --git a/test cases/osx/4 framework/xcode-frameworks.png b/test cases/osx/4 framework/xcode-frameworks.png
new file mode 100644
index 0000000..673d05a
--- /dev/null
+++ b/test cases/osx/4 framework/xcode-frameworks.png
Binary files differ
diff --git a/test cases/osx/5 extra frameworks/meson.build b/test cases/osx/5 extra frameworks/meson.build
new file mode 100644
index 0000000..0bd2c17
--- /dev/null
+++ b/test cases/osx/5 extra frameworks/meson.build
@@ -0,0 +1,10 @@
+project('xcode extra framework test', 'c')
+
+dep_libs = dependency('OpenGL', method : 'extraframework')
+assert(dep_libs.type_name() == 'extraframeworks', 'type_name is ' + dep_libs.type_name())
+
+dep_main = dependency('Foundation')
+assert(dep_main.type_name() == 'extraframeworks', 'type_name is ' + dep_main.type_name())
+
+stlib = static_library('stat', 'stat.c', install : true, dependencies: dep_libs)
+exe = executable('prog', 'prog.c', install : true, dependencies: dep_main)
diff --git a/test cases/osx/5 extra frameworks/prog.c b/test cases/osx/5 extra frameworks/prog.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/osx/5 extra frameworks/prog.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/osx/5 extra frameworks/stat.c b/test cases/osx/5 extra frameworks/stat.c
new file mode 100644
index 0000000..4825cef
--- /dev/null
+++ b/test cases/osx/5 extra frameworks/stat.c
@@ -0,0 +1 @@
+int func(void) { return 933; }
diff --git a/test cases/osx/5 extra frameworks/test.json b/test cases/osx/5 extra frameworks/test.json
new file mode 100644
index 0000000..8def69a
--- /dev/null
+++ b/test cases/osx/5 extra frameworks/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstat.a"}
+ ]
+}
diff --git a/test cases/osx/6 multiframework/main.m b/test cases/osx/6 multiframework/main.m
new file mode 100644
index 0000000..8a6799b
--- /dev/null
+++ b/test cases/osx/6 multiframework/main.m
@@ -0,0 +1,5 @@
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/test cases/osx/6 multiframework/meson.build b/test cases/osx/6 multiframework/meson.build
new file mode 100644
index 0000000..2884624
--- /dev/null
+++ b/test cases/osx/6 multiframework/meson.build
@@ -0,0 +1,13 @@
+project('multiframework', 'objc')
+
+# In theory only 'AppKit' would be enough but there was a bug
+# that causes a build failure when defining two modules. The
+# arguments for the latter module overwrote the arguments for
+# the first one rather than adding to them.
+cocoa_dep = dependency('appleframeworks', modules : ['AppKit', 'foundation'])
+
+executable('deptester',
+ 'main.m',
+ objc_args : ['-fobjc-arc'],
+ dependencies : [cocoa_dep],
+)
diff --git a/test cases/osx/7 bitcode/libbar.mm b/test cases/osx/7 bitcode/libbar.mm
new file mode 100644
index 0000000..489b1d1
--- /dev/null
+++ b/test cases/osx/7 bitcode/libbar.mm
@@ -0,0 +1,6 @@
+#import <stdio.h>
+#import "vis.h"
+
+int EXPORT_PUBLIC libbar(void) {
+ return 0;
+}
diff --git a/test cases/osx/7 bitcode/libfile.c b/test cases/osx/7 bitcode/libfile.c
new file mode 100644
index 0000000..8edc66b
--- /dev/null
+++ b/test cases/osx/7 bitcode/libfile.c
@@ -0,0 +1,5 @@
+#include "vis.h"
+
+int EXPORT_PUBLIC libfunc(void) {
+ return 3;
+}
diff --git a/test cases/osx/7 bitcode/libfoo.m b/test cases/osx/7 bitcode/libfoo.m
new file mode 100644
index 0000000..c0f4985
--- /dev/null
+++ b/test cases/osx/7 bitcode/libfoo.m
@@ -0,0 +1,6 @@
+#import <stdio.h>
+#import "vis.h"
+
+int EXPORT_PUBLIC libfoo(void) {
+ return 0;
+}
diff --git a/test cases/osx/7 bitcode/meson.build b/test cases/osx/7 bitcode/meson.build
new file mode 100644
index 0000000..50ce3f2
--- /dev/null
+++ b/test cases/osx/7 bitcode/meson.build
@@ -0,0 +1,11 @@
+project('bitcode test', 'c', 'objc', 'objcpp',
+ default_options : ['b_bitcode=true'])
+
+both_libraries('alib', 'libfoo.m')
+shared_module('amodule', 'libfoo.m')
+
+both_libraries('blib', 'libbar.mm')
+shared_module('bmodule', 'libbar.mm')
+
+both_libraries('clib', 'libfile.c')
+shared_module('cmodule', 'libfile.c')
diff --git a/test cases/osx/7 bitcode/vis.h b/test cases/osx/7 bitcode/vis.h
new file mode 100644
index 0000000..fa252b4
--- /dev/null
+++ b/test cases/osx/7 bitcode/vis.h
@@ -0,0 +1,6 @@
+#if defined __GNUC__
+ #define EXPORT_PUBLIC __attribute__ ((visibility("default")))
+#else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define EXPORT_PUBLIC
+#endif
diff --git a/test cases/osx/8 pie/main.c b/test cases/osx/8 pie/main.c
new file mode 100644
index 0000000..0a07218
--- /dev/null
+++ b/test cases/osx/8 pie/main.c
@@ -0,0 +1,5 @@
+#include <CoreFoundation/CoreFoundation.h>
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/osx/8 pie/meson.build b/test cases/osx/8 pie/meson.build
new file mode 100644
index 0000000..e4d66ed
--- /dev/null
+++ b/test cases/osx/8 pie/meson.build
@@ -0,0 +1,3 @@
+project('osx pie', 'c')
+e = executable('prog', 'main.c', pie : true)
+test('pie', e)
diff --git a/test cases/python/1 basic/gluon/__init__.py b/test cases/python/1 basic/gluon/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/1 basic/gluon/__init__.py
diff --git a/test cases/python/1 basic/gluon/gluonator.py b/test cases/python/1 basic/gluon/gluonator.py
new file mode 100644
index 0000000..b53d6de
--- /dev/null
+++ b/test cases/python/1 basic/gluon/gluonator.py
@@ -0,0 +1,2 @@
+def gluoninate():
+ return 42
diff --git a/test cases/python/1 basic/meson.build b/test cases/python/1 basic/meson.build
new file mode 100644
index 0000000..2e543dd
--- /dev/null
+++ b/test cases/python/1 basic/meson.build
@@ -0,0 +1,27 @@
+project('python sample')
+
+py_mod = import('python')
+py = py_mod.find_installation('python3')
+
+py_version = py.language_version()
+if py_version.version_compare('< 3.2')
+ error('MESON_SKIP_TEST python 3 required for tests')
+endif
+
+py_purelib = py.get_path('purelib')
+if not (py_purelib.endswith('site-packages') or py_purelib.endswith('dist-packages'))
+ error('Python3 purelib path seems invalid? ' + py_purelib)
+endif
+message('Python purelib path:', py_purelib)
+
+# could be 'lib64' or 'Lib' on some systems
+py_platlib = py.get_path('platlib')
+if not (py_platlib.endswith('site-packages') or py_platlib.endswith('dist-packages'))
+ error('Python3 platlib path seems invalid? ' + py_platlib)
+endif
+
+main = files('prog.py')
+
+test('toplevel', py, args : main)
+
+subdir('subdir')
diff --git a/test cases/python/1 basic/prog.py b/test cases/python/1 basic/prog.py
new file mode 100755
index 0000000..720fdb1
--- /dev/null
+++ b/test cases/python/1 basic/prog.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+from gluon import gluonator
+
+print('Running mainprog from root dir.')
+
+if gluonator.gluoninate() != 42:
+ raise ValueError("!= 42")
diff --git a/test cases/python/1 basic/subdir/meson.build b/test cases/python/1 basic/subdir/meson.build
new file mode 100644
index 0000000..66957c1
--- /dev/null
+++ b/test cases/python/1 basic/subdir/meson.build
@@ -0,0 +1,4 @@
+test('subdir',
+ py,
+ args : files('subprog.py'),
+ env : 'PYTHONPATH=' + meson.source_root())
diff --git a/test cases/python/1 basic/subdir/subprog.py b/test cases/python/1 basic/subdir/subprog.py
new file mode 100755
index 0000000..54178e5
--- /dev/null
+++ b/test cases/python/1 basic/subdir/subprog.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+
+# In order to run this program, PYTHONPATH must be set to
+# point to source root.
+
+from gluon import gluonator
+
+print('Running mainprog from subdir.')
+
+if gluonator.gluoninate() != 42:
+ raise ValueError("!= 42")
diff --git a/test cases/python/2 extmodule/blaster.py.in b/test cases/python/2 extmodule/blaster.py.in
new file mode 100755
index 0000000..b690b40
--- /dev/null
+++ b/test cases/python/2 extmodule/blaster.py.in
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+
+import @tachyon_module@ as tachyon
+
+result = tachyon.phaserize('shoot')
+
+if not isinstance(result, int):
+ raise SystemExit('Returned result not an integer.')
+
+if result != 1:
+ raise SystemExit(f'Returned result {result} is not 1.')
diff --git a/test cases/python/2 extmodule/ext/meson.build b/test cases/python/2 extmodule/ext/meson.build
new file mode 100644
index 0000000..14fa94a
--- /dev/null
+++ b/test cases/python/2 extmodule/ext/meson.build
@@ -0,0 +1,9 @@
+pylib = py.extension_module('tachyon',
+ 'tachyon_module.c',
+ c_args: '-DMESON_MODULENAME="tachyon"',
+ install: true,
+)
+
+subdir('nested')
+subdir('wrongdir')
+pypathdir = meson.current_build_dir()
diff --git a/test cases/python/2 extmodule/ext/nested/meson.build b/test cases/python/2 extmodule/ext/nested/meson.build
new file mode 100644
index 0000000..34c1192
--- /dev/null
+++ b/test cases/python/2 extmodule/ext/nested/meson.build
@@ -0,0 +1,15 @@
+py.extension_module('tachyon',
+ '../tachyon_module.c',
+ c_args: '-DMESON_MODULENAME="nested.tachyon"',
+ install: true,
+ subdir: 'nested'
+)
+py.install_sources(
+ configure_file(
+ input: '../../blaster.py.in',
+ output: 'blaster.py',
+ configuration: {'tachyon_module': 'nested.tachyon'}
+ ),
+ pure: false,
+ subdir: 'nested',
+)
diff --git a/test cases/python/2 extmodule/ext/tachyon_module.c b/test cases/python/2 extmodule/ext/tachyon_module.c
new file mode 100644
index 0000000..a5d7cdc
--- /dev/null
+++ b/test cases/python/2 extmodule/ext/tachyon_module.c
@@ -0,0 +1,49 @@
+/*
+ Copyright 2016 The Meson development team
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* A very simple Python extension module. */
+
+#include <Python.h>
+#include <string.h>
+
+static PyObject* phaserize(PyObject *self, PyObject *args) {
+ const char *message;
+ int result;
+
+ if(!PyArg_ParseTuple(args, "s", &message))
+ return NULL;
+
+ result = strcmp(message, "shoot") ? 0 : 1;
+ return PyLong_FromLong(result);
+}
+
+static PyMethodDef TachyonMethods[] = {
+ {"phaserize", phaserize, METH_VARARGS,
+ "Shoot tachyon cannons."},
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef tachyonmodule = {
+ PyModuleDef_HEAD_INIT,
+ MESON_MODULENAME,
+ NULL,
+ -1,
+ TachyonMethods
+};
+
+PyMODINIT_FUNC PyInit_tachyon(void) {
+ return PyModule_Create(&tachyonmodule);
+}
diff --git a/test cases/python/2 extmodule/ext/wrongdir/meson.build b/test cases/python/2 extmodule/ext/wrongdir/meson.build
new file mode 100644
index 0000000..5074701
--- /dev/null
+++ b/test cases/python/2 extmodule/ext/wrongdir/meson.build
@@ -0,0 +1,6 @@
+py.extension_module('tachyon',
+ '../tachyon_module.c',
+ c_args: '-DMESON_MODULENAME="tachyon"',
+ install: true,
+ install_dir: get_option('libdir')
+)
diff --git a/test cases/python/2 extmodule/meson.build b/test cases/python/2 extmodule/meson.build
new file mode 100644
index 0000000..239492c
--- /dev/null
+++ b/test cases/python/2 extmodule/meson.build
@@ -0,0 +1,50 @@
+project('Python extension module', 'c',
+ default_options : ['buildtype=release'])
+# Because Windows Python ships only with optimized libs,
+# we must build this project the same way.
+
+if meson.backend() != 'ninja'
+ error('MESON_SKIP_TEST: Ninja backend required')
+endif
+
+
+py_mod = import('python')
+py = py_mod.find_installation()
+py_dep = py.dependency(required: false)
+
+if not py_dep.found()
+ error('MESON_SKIP_TEST: Python libraries not found.')
+endif
+
+subdir('ext')
+
+blaster = configure_file(
+ input: 'blaster.py.in',
+ output: 'blaster.py',
+ configuration: {'tachyon_module': 'tachyon'}
+)
+
+test('extmod',
+ py,
+ args : blaster,
+ env : ['PYTHONPATH=' + pypathdir])
+
+py.install_sources(blaster, pure: false)
+py.install_sources(blaster, subdir: 'pure')
+
+py3_pkg_dep = dependency('python3', method: 'pkg-config', required : false)
+if py3_pkg_dep.found()
+ py3_dep_majver = py3_pkg_dep.version().split('.')
+ py3_dep_majver = py3_dep_majver[0] + '.' + py3_dep_majver[1]
+ message(f'got two pythons: pkg-config is @py3_dep_majver@, and module is', py.language_version())
+ if py3_dep_majver != py.language_version()
+ message('skipped python3 pkg-config test because the default python3 is different from Meson\'s')
+ else
+ python_lib_dir = py3_pkg_dep.get_pkgconfig_variable('libdir')
+
+ # Check we can apply a version constraint
+ dependency('python3', version: '>=@0@'.format(py_dep.version()))
+ endif
+else
+ message('Skipped python3 pkg-config test because it was not found')
+endif
diff --git a/test cases/python/2 extmodule/test.json b/test cases/python/2 extmodule/test.json
new file mode 100644
index 0000000..6bd1195
--- /dev/null
+++ b/test cases/python/2 extmodule/test.json
@@ -0,0 +1,13 @@
+{
+ "installed": [
+ { "type": "python_file", "file": "usr/@PYTHON_PLATLIB@/blaster.py" },
+ { "type": "python_lib", "file": "usr/@PYTHON_PLATLIB@/tachyon" },
+ { "type": "py_implib", "file": "usr/@PYTHON_PLATLIB@/tachyon" },
+ { "type": "python_file", "file": "usr/@PYTHON_PURELIB@/pure/blaster.py" },
+ { "type": "python_file", "file": "usr/@PYTHON_PLATLIB@/nested/blaster.py" },
+ { "type": "python_lib", "file": "usr/@PYTHON_PLATLIB@/nested/tachyon" },
+ { "type": "py_implib", "file": "usr/@PYTHON_PLATLIB@/nested/tachyon" },
+ { "type": "python_lib", "file": "usr/lib/tachyon" },
+ { "type": "py_implib", "file": "usr/lib/tachyon" }
+ ]
+}
diff --git a/test cases/python/3 cython/cytest.py b/test cases/python/3 cython/cytest.py
new file mode 100755
index 0000000..c08ffee
--- /dev/null
+++ b/test cases/python/3 cython/cytest.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+from storer import Storer
+
+s = Storer()
+
+if s.get_value() != 0:
+ raise SystemExit('Initial value incorrect.')
+
+s.set_value(42)
+
+if s.get_value() != 42:
+ raise SystemExit('Setting value failed.')
+
+try:
+ s.set_value('not a number')
+ raise SystemExit('Using wrong argument type did not fail.')
+except TypeError:
+ pass
diff --git a/test cases/python/3 cython/libdir/cstorer.pxd b/test cases/python/3 cython/libdir/cstorer.pxd
new file mode 100644
index 0000000..7b730fc
--- /dev/null
+++ b/test cases/python/3 cython/libdir/cstorer.pxd
@@ -0,0 +1,9 @@
+
+cdef extern from "storer.h":
+ ctypedef struct Storer:
+ pass
+
+ Storer* storer_new();
+ void storer_destroy(Storer *s);
+ int storer_get_value(Storer *s);
+ void storer_set_value(Storer *s, int v);
diff --git a/test cases/python/3 cython/libdir/meson.build b/test cases/python/3 cython/libdir/meson.build
new file mode 100644
index 0000000..2b6ebc7
--- /dev/null
+++ b/test cases/python/3 cython/libdir/meson.build
@@ -0,0 +1,11 @@
+pyx_c = custom_target('storer_pyx',
+ output : 'storer_pyx.c',
+ input : 'storer.pyx',
+ command : [cython, '@INPUT@', '-o', '@OUTPUT@'],
+)
+
+slib = py3.extension_module('storer',
+ 'storer.c', pyx_c,
+ dependencies : py3_dep)
+
+pydir = meson.current_build_dir()
diff --git a/test cases/python/3 cython/libdir/storer.c b/test cases/python/3 cython/libdir/storer.c
new file mode 100644
index 0000000..0199bb8
--- /dev/null
+++ b/test cases/python/3 cython/libdir/storer.c
@@ -0,0 +1,24 @@
+#include"storer.h"
+#include<stdlib.h>
+
+struct _Storer {
+ int value;
+};
+
+Storer* storer_new() {
+ Storer *s = malloc(sizeof(struct _Storer));
+ s->value = 0;
+ return s;
+}
+
+void storer_destroy(Storer *s) {
+ free(s);
+}
+
+int storer_get_value(Storer *s) {
+ return s->value;
+}
+
+void storer_set_value(Storer *s, int v) {
+ s->value = v;
+}
diff --git a/test cases/python/3 cython/libdir/storer.h b/test cases/python/3 cython/libdir/storer.h
new file mode 100644
index 0000000..4f71917
--- /dev/null
+++ b/test cases/python/3 cython/libdir/storer.h
@@ -0,0 +1,8 @@
+#pragma once
+
+typedef struct _Storer Storer;
+
+Storer* storer_new();
+void storer_destroy(Storer *s);
+int storer_get_value(Storer *s);
+void storer_set_value(Storer *s, int v);
diff --git a/test cases/python/3 cython/libdir/storer.pyx b/test cases/python/3 cython/libdir/storer.pyx
new file mode 100644
index 0000000..ed551dc
--- /dev/null
+++ b/test cases/python/3 cython/libdir/storer.pyx
@@ -0,0 +1,16 @@
+cimport cstorer
+
+cdef class Storer:
+ cdef cstorer.Storer* _c_storer
+
+ def __cinit__(self):
+ self._c_storer = cstorer.storer_new()
+
+ def __dealloc__(self):
+ cstorer.storer_destroy(self._c_storer)
+
+ cpdef int get_value(self):
+ return cstorer.storer_get_value(self._c_storer)
+
+ cpdef set_value(self, int value):
+ cstorer.storer_set_value(self._c_storer, value)
diff --git a/test cases/python/3 cython/meson.build b/test cases/python/3 cython/meson.build
new file mode 100644
index 0000000..5fc07a8
--- /dev/null
+++ b/test cases/python/3 cython/meson.build
@@ -0,0 +1,26 @@
+project('cython', 'c',
+ default_options : ['warning_level=3'])
+
+if meson.backend() != 'ninja'
+ error('MESON_SKIP_TEST: Ninja backend required')
+endif
+
+cython = find_program('cython', required : false)
+if not cython.found()
+ error('MESON_SKIP_TEST: Cython3 not found.')
+endif
+
+py_mod = import('python')
+py3 = py_mod.find_installation()
+py3_dep = py3.dependency(required: false)
+if not py3_dep.found()
+ error('MESON_SKIP_TEST: Python library not found.')
+endif
+
+subdir('libdir')
+
+test('cython tester',
+ py3,
+ args : files('cytest.py'),
+ env : ['PYTHONPATH=' + pydir]
+)
diff --git a/test cases/python/4 custom target depends extmodule/blaster.py b/test cases/python/4 custom target depends extmodule/blaster.py
new file mode 100644
index 0000000..61b11f9
--- /dev/null
+++ b/test cases/python/4 custom target depends extmodule/blaster.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import argparse
+
+from pathlib import Path
+
+filedir = Path(os.path.dirname(__file__)).resolve()
+if list(filedir.glob('ext/*tachyon*')):
+ sys.path.insert(0, (filedir / 'ext').as_posix())
+
+import tachyon
+
+parser = argparse.ArgumentParser()
+parser.add_argument('-o', dest='output', default=None)
+
+options = parser.parse_args(sys.argv[1:])
+
+result = tachyon.phaserize('shoot')
+
+if options.output:
+ with open(options.output, 'w') as f:
+ f.write('success')
+
+if not isinstance(result, int):
+ raise SystemExit('Returned result not an integer.')
+
+if result != 1:
+ raise SystemExit(f'Returned result {result} is not 1.')
diff --git a/test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c b/test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c
new file mode 100644
index 0000000..aeff296
--- /dev/null
+++ b/test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c
@@ -0,0 +1,8 @@
+#ifdef _MSC_VER
+__declspec(dllexport)
+#endif
+const char*
+tachyon_phaser_command (void)
+{
+ return "shoot";
+}
diff --git a/test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h b/test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h
new file mode 100644
index 0000000..dca71d3
--- /dev/null
+++ b/test cases/python/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#ifdef _MSC_VER
+__declspec(dllimport)
+#endif
+const char* tachyon_phaser_command (void);
diff --git a/test cases/python/4 custom target depends extmodule/ext/lib/meson.build b/test cases/python/4 custom target depends extmodule/ext/lib/meson.build
new file mode 100644
index 0000000..b1f8938
--- /dev/null
+++ b/test cases/python/4 custom target depends extmodule/ext/lib/meson.build
@@ -0,0 +1,4 @@
+libtachyon = shared_library('tachyonlib', 'meson-tachyonlib.c')
+
+libtachyon_dep = declare_dependency(link_with : libtachyon,
+ include_directories : include_directories('.'))
diff --git a/test cases/python/4 custom target depends extmodule/ext/meson.build b/test cases/python/4 custom target depends extmodule/ext/meson.build
new file mode 100644
index 0000000..1bb275d
--- /dev/null
+++ b/test cases/python/4 custom target depends extmodule/ext/meson.build
@@ -0,0 +1,6 @@
+subdir('lib')
+
+pylib = py3.extension_module('tachyon',
+ 'tachyon_module.c',
+ dependencies : [libtachyon_dep, py3_dep],
+)
diff --git a/test cases/python/4 custom target depends extmodule/ext/tachyon_module.c b/test cases/python/4 custom target depends extmodule/ext/tachyon_module.c
new file mode 100644
index 0000000..b48032b
--- /dev/null
+++ b/test cases/python/4 custom target depends extmodule/ext/tachyon_module.c
@@ -0,0 +1,51 @@
+/*
+ Copyright 2016 The Meson development team
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* A very simple Python extension module. */
+
+#include <Python.h>
+#include <string.h>
+
+#include "meson-tachyonlib.h"
+
+static PyObject* phaserize(PyObject *self, PyObject *args) {
+ const char *message;
+ int result;
+
+ if(!PyArg_ParseTuple(args, "s", &message))
+ return NULL;
+
+ result = strcmp(message, tachyon_phaser_command()) ? 0 : 1;
+ return PyLong_FromLong(result);
+}
+
+static PyMethodDef TachyonMethods[] = {
+ {"phaserize", phaserize, METH_VARARGS,
+ "Shoot tachyon cannons."},
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef tachyonmodule = {
+ PyModuleDef_HEAD_INIT,
+ "tachyon",
+ NULL,
+ -1,
+ TachyonMethods
+};
+
+PyMODINIT_FUNC PyInit_tachyon(void) {
+ return PyModule_Create(&tachyonmodule);
+}
diff --git a/test cases/python/4 custom target depends extmodule/meson.build b/test cases/python/4 custom target depends extmodule/meson.build
new file mode 100644
index 0000000..d8a62ed
--- /dev/null
+++ b/test cases/python/4 custom target depends extmodule/meson.build
@@ -0,0 +1,45 @@
+project('Python extension module', 'c',
+ default_options : ['buildtype=release'])
+# Because Windows Python ships only with optimized libs,
+# we must build this project the same way.
+
+if meson.backend() != 'ninja'
+ error('MESON_SKIP_TEST: Ninja backend required')
+endif
+
+py_mod = import('python')
+py3 = py_mod.find_installation()
+py3_dep = py3.dependency(required : false)
+cc = meson.get_compiler('c')
+
+if not py3_dep.found()
+ error('MESON_SKIP_TEST: Python3 libraries not found, skipping test.')
+endif
+
+# Copy to the builddir so that blaster.py can find the built tachyon module
+# FIXME: We should automatically detect this case and append the correct paths
+# to PYTHONLIBDIR
+blaster_py = configure_file(input : 'blaster.py',
+ output : 'blaster.py',
+ copy : true)
+
+check_exists = '''
+import os, sys
+with open(sys.argv[1], 'rb') as f:
+ assert(f.read() == b'success')
+'''
+
+message('Detected Python version: ' + py3_dep.version())
+if py3_dep.version().version_compare('>=3.8') and cc.get_id() == 'msvc' and cc.version().version_compare('<=19.00.24215.1')
+ error('MESON_SKIP_TEST: Python modules do not work with Python 3.8 and VS2015 or earlier.')
+endif
+subdir('ext')
+
+out_txt = custom_target('tachyon flux',
+ input : blaster_py,
+ output : 'out.txt',
+ command : [py3, '@INPUT@', '-o', '@OUTPUT@'],
+ depends : pylib,
+ build_by_default: true)
+
+test('flux', py3, args : ['-c', check_exists, out_txt])
diff --git a/test cases/python/5 modules kwarg/meson.build b/test cases/python/5 modules kwarg/meson.build
new file mode 100644
index 0000000..9751ada
--- /dev/null
+++ b/test cases/python/5 modules kwarg/meson.build
@@ -0,0 +1,7 @@
+project('python kwarg')
+
+py = import('python')
+prog_python = py.find_installation('python3', modules : ['distutils'])
+assert(prog_python.found() == true, 'python not found when should be')
+prog_python = py.find_installation('python3', modules : ['thisbetternotexistmod'], required : false)
+assert(prog_python.found() == false, 'python not found but reported as found')
diff --git a/test cases/python/6 failing subproject/meson.build b/test cases/python/6 failing subproject/meson.build
new file mode 100644
index 0000000..cc33a1c
--- /dev/null
+++ b/test cases/python/6 failing subproject/meson.build
@@ -0,0 +1,5 @@
+project('foo', 'cpp')
+
+# Regression test for https://github.com/mesonbuild/meson/issues/9038
+dependency('bar', required: false, allow_fallback: true)
+python = import('python').find_installation('python3').dependency()
diff --git a/test cases/python/6 failing subproject/subprojects/bar/meson.build b/test cases/python/6 failing subproject/subprojects/bar/meson.build
new file mode 100644
index 0000000..21431ca
--- /dev/null
+++ b/test cases/python/6 failing subproject/subprojects/bar/meson.build
@@ -0,0 +1,4 @@
+project('bar', 'cpp')
+
+python = import('python').find_installation('python3')
+dependency('nonexistant-dependency')
diff --git a/test cases/python/7 install path/meson.build b/test cases/python/7 install path/meson.build
new file mode 100644
index 0000000..1075c1b
--- /dev/null
+++ b/test cases/python/7 install path/meson.build
@@ -0,0 +1,20 @@
+project('install path',
+ default_options: [
+ 'python.purelibdir=/pure',
+ 'python.platlibdir=/plat'
+ ]
+)
+
+py = import('python').find_installation()
+py.install_sources('test.py')
+py.install_sources('test.py', pure: false)
+install_data('test.py', install_dir: py.get_install_dir() / 'data')
+install_data('test.py', install_dir: py.get_install_dir(pure: false) / 'data')
+
+py_plat = import('python').find_installation(pure: false)
+py_plat.install_sources('test.py', subdir: 'kw')
+py_plat.install_sources('test.py', pure: true, subdir: 'kwrevert')
+install_data('test.py', install_dir: py_plat.get_install_dir() / 'kw/data')
+install_data('test.py', install_dir: py_plat.get_install_dir(pure: true) / 'kwrevert/data')
+
+subdir('structured')
diff --git a/test cases/python/7 install path/structured/alpha/one.py b/test cases/python/7 install path/structured/alpha/one.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/alpha/one.py
diff --git a/test cases/python/7 install path/structured/alpha/three.py b/test cases/python/7 install path/structured/alpha/three.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/alpha/three.py
diff --git a/test cases/python/7 install path/structured/alpha/two.py b/test cases/python/7 install path/structured/alpha/two.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/alpha/two.py
diff --git a/test cases/python/7 install path/structured/beta/one.py b/test cases/python/7 install path/structured/beta/one.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/beta/one.py
diff --git a/test cases/python/7 install path/structured/meson.build b/test cases/python/7 install path/structured/meson.build
new file mode 100644
index 0000000..6c85587
--- /dev/null
+++ b/test cases/python/7 install path/structured/meson.build
@@ -0,0 +1,9 @@
+py.install_sources(
+ 'one.py',
+ 'two.py',
+ 'alpha/one.py',
+ 'alpha/two.py',
+ 'alpha/three.py',
+ 'beta/one.py',
+ preserve_path: true,
+)
diff --git a/test cases/python/7 install path/structured/one.py b/test cases/python/7 install path/structured/one.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/one.py
diff --git a/test cases/python/7 install path/structured/two.py b/test cases/python/7 install path/structured/two.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/structured/two.py
diff --git a/test cases/python/7 install path/test.json b/test cases/python/7 install path/test.json
new file mode 100644
index 0000000..cf8e7a9
--- /dev/null
+++ b/test cases/python/7 install path/test.json
@@ -0,0 +1,18 @@
+{
+ "installed": [
+ {"type": "file", "file": "pure/one.py"},
+ {"type": "file", "file": "pure/two.py"},
+ {"type": "file", "file": "pure/alpha/one.py"},
+ {"type": "file", "file": "pure/alpha/two.py"},
+ {"type": "file", "file": "pure/alpha/three.py"},
+ {"type": "file", "file": "pure/beta/one.py"},
+ {"type": "file", "file": "plat/kw/test.py"},
+ {"type": "file", "file": "pure/kwrevert/test.py"},
+ {"type": "file", "file": "plat/test.py"},
+ {"type": "file", "file": "pure/test.py"},
+ {"type": "file", "file": "plat/data/test.py"},
+ {"type": "file", "file": "pure/data/test.py"},
+ {"type": "file", "file": "plat/kw/data/test.py"},
+ {"type": "file", "file": "pure/kwrevert/data/test.py"}
+ ]
+}
diff --git a/test cases/python/7 install path/test.py b/test cases/python/7 install path/test.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python/7 install path/test.py
diff --git a/test cases/python/8 different python versions/blaster.py b/test cases/python/8 different python versions/blaster.py
new file mode 100755
index 0000000..163b6d4
--- /dev/null
+++ b/test cases/python/8 different python versions/blaster.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+import sys
+import tachyon
+
+result = tachyon.phaserize('shoot')
+
+if not isinstance(result, int):
+ print('Returned result not an integer.')
+ sys.exit(1)
+
+if result != 1:
+ print('Returned result {} is not 1.'.format(result))
+ sys.exit(1)
diff --git a/test cases/python/8 different python versions/ext/meson.build b/test cases/python/8 different python versions/ext/meson.build
new file mode 100644
index 0000000..b13bb32
--- /dev/null
+++ b/test cases/python/8 different python versions/ext/meson.build
@@ -0,0 +1,6 @@
+pylib = py.extension_module('tachyon',
+ 'tachyon_module.c',
+ dependencies : py_dep,
+)
+
+pypathdir = meson.current_build_dir()
diff --git a/test cases/python/8 different python versions/ext/tachyon_module.c b/test cases/python/8 different python versions/ext/tachyon_module.c
new file mode 100644
index 0000000..68eda53
--- /dev/null
+++ b/test cases/python/8 different python versions/ext/tachyon_module.c
@@ -0,0 +1,59 @@
+/*
+ Copyright 2018 The Meson development team
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* A very simple Python extension module. */
+
+#include <Python.h>
+#include <string.h>
+
+static PyObject* phaserize(PyObject *self, PyObject *args) {
+ const char *message;
+ int result;
+
+ if(!PyArg_ParseTuple(args, "s", &message))
+ return NULL;
+
+ result = strcmp(message, "shoot") ? 0 : 1;
+#if PY_VERSION_HEX < 0x03000000
+ return PyInt_FromLong(result);
+#else
+ return PyLong_FromLong(result);
+#endif
+}
+
+static PyMethodDef TachyonMethods[] = {
+ {"phaserize", phaserize, METH_VARARGS,
+ "Shoot tachyon cannons."},
+ {NULL, NULL, 0, NULL}
+};
+
+#if PY_VERSION_HEX < 0x03000000
+PyMODINIT_FUNC inittachyon(void) {
+ Py_InitModule("tachyon", TachyonMethods);
+}
+#else
+static struct PyModuleDef tachyonmodule = {
+ PyModuleDef_HEAD_INIT,
+ "tachyon",
+ NULL,
+ -1,
+ TachyonMethods
+};
+
+PyMODINIT_FUNC PyInit_tachyon(void) {
+ return PyModule_Create(&tachyonmodule);
+}
+#endif
diff --git a/test cases/python/8 different python versions/meson.build b/test cases/python/8 different python versions/meson.build
new file mode 100644
index 0000000..2655b06
--- /dev/null
+++ b/test cases/python/8 different python versions/meson.build
@@ -0,0 +1,34 @@
+project('Python extension module', 'c',
+ default_options : ['buildtype=release'])
+
+py_mod = import('python')
+
+py = py_mod.find_installation(get_option('python'), required : false)
+
+# CI images don't have 32-bit python2 for 32-bit windows,
+# so this actually gets detected then fails
+require = not (
+ get_option('python') == 'python2' and
+ host_machine.system() == 'windows' and
+ host_machine.cpu() == 'x86'
+)
+
+if py.found()
+ py_dep = py.dependency(required: require)
+
+ if py_dep.found()
+ subdir('ext')
+
+ test('extmod',
+ py,
+ args : files('blaster.py'),
+ env : ['PYTHONPATH=' + pypathdir])
+ else
+ error('MESON_SKIP_TEST: Python libraries not found, skipping test.')
+ endif
+else
+ error('MESON_SKIP_TEST: Python not found, skipping test.')
+endif
+
+py = py_mod.find_installation(get_option('python'), required : get_option('disabled_opt'))
+assert(not py.found(), 'find_installation not working with disabled feature')
diff --git a/test cases/python/8 different python versions/meson_options.txt b/test cases/python/8 different python versions/meson_options.txt
new file mode 100644
index 0000000..c85110d
--- /dev/null
+++ b/test cases/python/8 different python versions/meson_options.txt
@@ -0,0 +1,4 @@
+option('python', type: 'string',
+ description: 'Name of or path to the python executable'
+)
+option('disabled_opt', type: 'feature', value: 'disabled')
diff --git a/test cases/python/8 different python versions/test.json b/test cases/python/8 different python versions/test.json
new file mode 100644
index 0000000..fe75a1c
--- /dev/null
+++ b/test cases/python/8 different python versions/test.json
@@ -0,0 +1,13 @@
+{
+ "matrix": {
+ "options": {
+ "python": [
+ { "val": null },
+ { "val": "python2" },
+ { "val": "python3" },
+ { "val": "pypy" },
+ { "val": "pypy3" }
+ ]
+ }
+ }
+}
diff --git a/test cases/python3/1 basic/gluon/__init__.py b/test cases/python3/1 basic/gluon/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/python3/1 basic/gluon/__init__.py
diff --git a/test cases/python3/1 basic/gluon/gluonator.py b/test cases/python3/1 basic/gluon/gluonator.py
new file mode 100644
index 0000000..b53d6de
--- /dev/null
+++ b/test cases/python3/1 basic/gluon/gluonator.py
@@ -0,0 +1,2 @@
+def gluoninate():
+ return 42
diff --git a/test cases/python3/1 basic/meson.build b/test cases/python3/1 basic/meson.build
new file mode 100644
index 0000000..48cfb6d
--- /dev/null
+++ b/test cases/python3/1 basic/meson.build
@@ -0,0 +1,34 @@
+project('python sample', 'c')
+
+py3_mod = import('python3')
+py3 = py3_mod.find_python()
+
+py3_version = py3_mod.language_version()
+if py3_version.version_compare('< 3.2')
+ error('Invalid python version!?')
+endif
+
+py3_purelib = py3_mod.sysconfig_path('purelib')
+message('Python purelib:', py3_purelib)
+if not (py3_purelib.endswith('site-packages') or py3_purelib.endswith('dist-packages'))
+ error('Python3 purelib path seems invalid?')
+endif
+
+# could be 'lib64' or 'Lib' on some systems
+py3_platlib = py3_mod.sysconfig_path('platlib')
+message('Python platlib:', py3_platlib)
+if not (py3_platlib.endswith('site-packages') or py3_platlib.endswith('dist-packages'))
+ error('Python3 platlib path seems invalid?')
+endif
+
+# could be 'Include' on Windows
+py3_include = py3_mod.sysconfig_path('include')
+if not py3_include.to_lower().startswith('include')
+ error('Python3 include path seems invalid?')
+endif
+
+main = files('prog.py')
+
+test('toplevel', py3, args : main)
+
+subdir('subdir')
diff --git a/test cases/python3/1 basic/prog.py b/test cases/python3/1 basic/prog.py
new file mode 100755
index 0000000..9d95aea
--- /dev/null
+++ b/test cases/python3/1 basic/prog.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+from gluon import gluonator
+import sys
+
+print('Running mainprog from root dir.')
+
+if gluonator.gluoninate() != 42:
+ sys.exit(1)
diff --git a/test cases/python3/1 basic/subdir/meson.build b/test cases/python3/1 basic/subdir/meson.build
new file mode 100644
index 0000000..8fe91b9
--- /dev/null
+++ b/test cases/python3/1 basic/subdir/meson.build
@@ -0,0 +1,4 @@
+test('subdir',
+ py3,
+ args : files('subprog.py'),
+ env : 'PYTHONPATH=' + meson.source_root())
diff --git a/test cases/python3/1 basic/subdir/subprog.py b/test cases/python3/1 basic/subdir/subprog.py
new file mode 100755
index 0000000..08652f0
--- /dev/null
+++ b/test cases/python3/1 basic/subdir/subprog.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+# In order to run this program, PYTHONPATH must be set to
+# point to source root.
+
+from gluon import gluonator
+import sys
+
+print('Running mainprog from subdir.')
+
+if gluonator.gluoninate() != 42:
+ sys.exit(1)
diff --git a/test cases/python3/2 extmodule/blaster.py b/test cases/python3/2 extmodule/blaster.py
new file mode 100755
index 0000000..529b028
--- /dev/null
+++ b/test cases/python3/2 extmodule/blaster.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import tachyon
+import sys
+
+result = tachyon.phaserize('shoot')
+
+if not isinstance(result, int):
+ print('Returned result not an integer.')
+ sys.exit(1)
+
+if result != 1:
+ print(f'Returned result {result} is not 1.')
+ sys.exit(1)
diff --git a/test cases/python3/2 extmodule/ext/meson.build b/test cases/python3/2 extmodule/ext/meson.build
new file mode 100644
index 0000000..d5d8849
--- /dev/null
+++ b/test cases/python3/2 extmodule/ext/meson.build
@@ -0,0 +1,6 @@
+pylib = py3_mod.extension_module('tachyon',
+ 'tachyon_module.c',
+ dependencies : py3_dep,
+)
+
+pypathdir = meson.current_build_dir()
diff --git a/test cases/python3/2 extmodule/ext/tachyon_module.c b/test cases/python3/2 extmodule/ext/tachyon_module.c
new file mode 100644
index 0000000..b2592e4
--- /dev/null
+++ b/test cases/python3/2 extmodule/ext/tachyon_module.c
@@ -0,0 +1,49 @@
+/*
+ Copyright 2016 The Meson development team
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* A very simple Python extension module. */
+
+#include <Python.h>
+#include <string.h>
+
+static PyObject* phaserize(PyObject *self, PyObject *args) {
+ const char *message;
+ int result;
+
+ if(!PyArg_ParseTuple(args, "s", &message))
+ return NULL;
+
+ result = strcmp(message, "shoot") ? 0 : 1;
+ return PyLong_FromLong(result);
+}
+
+static PyMethodDef TachyonMethods[] = {
+ {"phaserize", phaserize, METH_VARARGS,
+ "Shoot tachyon cannons."},
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef tachyonmodule = {
+ PyModuleDef_HEAD_INIT,
+ "tachyon",
+ NULL,
+ -1,
+ TachyonMethods
+};
+
+PyMODINIT_FUNC PyInit_tachyon(void) {
+ return PyModule_Create(&tachyonmodule);
+}
diff --git a/test cases/python3/2 extmodule/meson.build b/test cases/python3/2 extmodule/meson.build
new file mode 100644
index 0000000..def21b0
--- /dev/null
+++ b/test cases/python3/2 extmodule/meson.build
@@ -0,0 +1,37 @@
+project('Python extension module', 'c',
+ default_options : ['buildtype=release'])
+# Because Windows Python ships only with optimized libs,
+# we must build this project the same way.
+
+py3_mod = import('python3')
+py3 = py3_mod.find_python()
+py3_dep = dependency('python3', required : false)
+cc = meson.get_compiler('c')
+
+if py3_dep.found()
+ message('Detected Python version: ' + py3_dep.version())
+ # Building extensions for Python 3 using Visual Studio 2015
+ # no longer works (or, rather, they build but don't run).
+ # Disable the tests in this case.
+ if py3_dep.version().version_compare('>=3.8') and cc.get_id() == 'msvc' and cc.version().version_compare('<=19.00.24215.1')
+ error('MESON_SKIP_TEST: Python modules do not work with Python 3.8 and VS2015 or earlier.')
+ endif
+
+ subdir('ext')
+
+ test('extmod',
+ py3,
+ args : files('blaster.py'),
+ env : ['PYTHONPATH=' + pypathdir])
+
+ # Check we can apply a version constraint
+ dependency('python3', version: '>=@0@'.format(py3_dep.version()))
+
+else
+ error('MESON_SKIP_TEST: Python3 libraries not found, skipping test.')
+endif
+
+py3_pkg_dep = dependency('python3', method: 'pkg-config', required : false)
+if py3_pkg_dep.found()
+ python_lib_dir = py3_pkg_dep.get_pkgconfig_variable('libdir')
+endif
diff --git a/test cases/python3/3 cython/cytest.py b/test cases/python3/3 cython/cytest.py
new file mode 100755
index 0000000..43443dc
--- /dev/null
+++ b/test cases/python3/3 cython/cytest.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+
+from storer import Storer
+import sys
+
+s = Storer()
+
+if s.get_value() != 0:
+ print('Initial value incorrect.')
+ sys.exit(1)
+
+s.set_value(42)
+
+if s.get_value() != 42:
+ print('Setting value failed.')
+ sys.exit(1)
+
+try:
+ s.set_value('not a number')
+ print('Using wrong argument type did not fail.')
+ sys.exit(1)
+except TypeError:
+ pass
diff --git a/test cases/python3/3 cython/libdir/cstorer.pxd b/test cases/python3/3 cython/libdir/cstorer.pxd
new file mode 100644
index 0000000..7b730fc
--- /dev/null
+++ b/test cases/python3/3 cython/libdir/cstorer.pxd
@@ -0,0 +1,9 @@
+
+cdef extern from "storer.h":
+ ctypedef struct Storer:
+ pass
+
+ Storer* storer_new();
+ void storer_destroy(Storer *s);
+ int storer_get_value(Storer *s);
+ void storer_set_value(Storer *s, int v);
diff --git a/test cases/python3/3 cython/libdir/meson.build b/test cases/python3/3 cython/libdir/meson.build
new file mode 100644
index 0000000..4aaa041
--- /dev/null
+++ b/test cases/python3/3 cython/libdir/meson.build
@@ -0,0 +1,12 @@
+pyx_c = custom_target('storer_pyx',
+ output : 'storer_pyx.c',
+ input : 'storer.pyx',
+ depend_files : 'cstorer.pxd',
+ command : [cython, '@INPUT@', '-o', '@OUTPUT@'],
+)
+
+slib = py3_mod.extension_module('storer',
+ 'storer.c', pyx_c,
+ dependencies : py3_dep)
+
+pydir = meson.current_build_dir()
diff --git a/test cases/python3/3 cython/libdir/storer.c b/test cases/python3/3 cython/libdir/storer.c
new file mode 100644
index 0000000..0199bb8
--- /dev/null
+++ b/test cases/python3/3 cython/libdir/storer.c
@@ -0,0 +1,24 @@
+#include"storer.h"
+#include<stdlib.h>
+
+struct _Storer {
+ int value;
+};
+
+Storer* storer_new() {
+ Storer *s = malloc(sizeof(struct _Storer));
+ s->value = 0;
+ return s;
+}
+
+void storer_destroy(Storer *s) {
+ free(s);
+}
+
+int storer_get_value(Storer *s) {
+ return s->value;
+}
+
+void storer_set_value(Storer *s, int v) {
+ s->value = v;
+}
diff --git a/test cases/python3/3 cython/libdir/storer.h b/test cases/python3/3 cython/libdir/storer.h
new file mode 100644
index 0000000..4f71917
--- /dev/null
+++ b/test cases/python3/3 cython/libdir/storer.h
@@ -0,0 +1,8 @@
+#pragma once
+
+typedef struct _Storer Storer;
+
+Storer* storer_new();
+void storer_destroy(Storer *s);
+int storer_get_value(Storer *s);
+void storer_set_value(Storer *s, int v);
diff --git a/test cases/python3/3 cython/libdir/storer.pyx b/test cases/python3/3 cython/libdir/storer.pyx
new file mode 100644
index 0000000..ed551dc
--- /dev/null
+++ b/test cases/python3/3 cython/libdir/storer.pyx
@@ -0,0 +1,16 @@
+cimport cstorer
+
+cdef class Storer:
+ cdef cstorer.Storer* _c_storer
+
+ def __cinit__(self):
+ self._c_storer = cstorer.storer_new()
+
+ def __dealloc__(self):
+ cstorer.storer_destroy(self._c_storer)
+
+ cpdef int get_value(self):
+ return cstorer.storer_get_value(self._c_storer)
+
+ cpdef set_value(self, int value):
+ cstorer.storer_set_value(self._c_storer, value)
diff --git a/test cases/python3/3 cython/meson.build b/test cases/python3/3 cython/meson.build
new file mode 100644
index 0000000..d41fc93
--- /dev/null
+++ b/test cases/python3/3 cython/meson.build
@@ -0,0 +1,26 @@
+project('cython', 'c',
+ default_options : ['warning_level=3'])
+
+cython = find_program('cython3', required : false)
+py3_dep = dependency('python3', required : false)
+
+if cython.found() and py3_dep.found()
+ py3_dep = dependency('python3')
+ py3_dep_majver = py3_dep.version().split('.')
+ py3_dep_majver = py3_dep_majver[0] + '.' + py3_dep_majver[1]
+ py3_mod = import('python3')
+ py3 = py3_mod.find_python()
+ if py3_dep_majver != py3_mod.language_version()
+ v = py3_mod.language_version()
+ error('MESON_SKIP_TEST: deprecated python3 module is non-functional when default python3 is different from Meson\'s', v)
+ endif
+ subdir('libdir')
+
+ test('cython tester',
+ py3,
+ args : files('cytest.py'),
+ env : ['PYTHONPATH=' + pydir]
+ )
+else
+ error('MESON_SKIP_TEST: Cython3 or Python3 libraries not found, skipping test.')
+endif
diff --git a/test cases/python3/4 custom target depends extmodule/blaster.py b/test cases/python3/4 custom target depends extmodule/blaster.py
new file mode 100644
index 0000000..d2c93ad
--- /dev/null
+++ b/test cases/python3/4 custom target depends extmodule/blaster.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import argparse
+
+from pathlib import Path
+
+filedir = Path(os.path.dirname(__file__)).resolve()
+if list(filedir.glob('ext/*tachyon.*')):
+ sys.path.insert(0, (filedir / 'ext').as_posix())
+
+import tachyon
+
+parser = argparse.ArgumentParser()
+parser.add_argument('-o', dest='output', default=None)
+
+options = parser.parse_args(sys.argv[1:])
+
+result = tachyon.phaserize('shoot')
+
+if options.output:
+ with open(options.output, 'w') as f:
+ f.write('success')
+
+if not isinstance(result, int):
+ print('Returned result not an integer.')
+ sys.exit(1)
+
+if result != 1:
+ print(f'Returned result {result} is not 1.')
+ sys.exit(1)
diff --git a/test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c b/test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c
new file mode 100644
index 0000000..aeff296
--- /dev/null
+++ b/test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.c
@@ -0,0 +1,8 @@
+#ifdef _MSC_VER
+__declspec(dllexport)
+#endif
+const char*
+tachyon_phaser_command (void)
+{
+ return "shoot";
+}
diff --git a/test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h b/test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h
new file mode 100644
index 0000000..dca71d3
--- /dev/null
+++ b/test cases/python3/4 custom target depends extmodule/ext/lib/meson-tachyonlib.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#ifdef _MSC_VER
+__declspec(dllimport)
+#endif
+const char* tachyon_phaser_command (void);
diff --git a/test cases/python3/4 custom target depends extmodule/ext/lib/meson.build b/test cases/python3/4 custom target depends extmodule/ext/lib/meson.build
new file mode 100644
index 0000000..b1f8938
--- /dev/null
+++ b/test cases/python3/4 custom target depends extmodule/ext/lib/meson.build
@@ -0,0 +1,4 @@
+libtachyon = shared_library('tachyonlib', 'meson-tachyonlib.c')
+
+libtachyon_dep = declare_dependency(link_with : libtachyon,
+ include_directories : include_directories('.'))
diff --git a/test cases/python3/4 custom target depends extmodule/ext/meson.build b/test cases/python3/4 custom target depends extmodule/ext/meson.build
new file mode 100644
index 0000000..5ccbe22
--- /dev/null
+++ b/test cases/python3/4 custom target depends extmodule/ext/meson.build
@@ -0,0 +1,6 @@
+subdir('lib')
+
+pylib = py3_mod.extension_module('tachyon',
+ 'tachyon_module.c',
+ dependencies : [libtachyon_dep, py3_dep],
+)
diff --git a/test cases/python3/4 custom target depends extmodule/ext/tachyon_module.c b/test cases/python3/4 custom target depends extmodule/ext/tachyon_module.c
new file mode 100644
index 0000000..b48032b
--- /dev/null
+++ b/test cases/python3/4 custom target depends extmodule/ext/tachyon_module.c
@@ -0,0 +1,51 @@
+/*
+ Copyright 2016 The Meson development team
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* A very simple Python extension module. */
+
+#include <Python.h>
+#include <string.h>
+
+#include "meson-tachyonlib.h"
+
+static PyObject* phaserize(PyObject *self, PyObject *args) {
+ const char *message;
+ int result;
+
+ if(!PyArg_ParseTuple(args, "s", &message))
+ return NULL;
+
+ result = strcmp(message, tachyon_phaser_command()) ? 0 : 1;
+ return PyLong_FromLong(result);
+}
+
+static PyMethodDef TachyonMethods[] = {
+ {"phaserize", phaserize, METH_VARARGS,
+ "Shoot tachyon cannons."},
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef tachyonmodule = {
+ PyModuleDef_HEAD_INIT,
+ "tachyon",
+ NULL,
+ -1,
+ TachyonMethods
+};
+
+PyMODINIT_FUNC PyInit_tachyon(void) {
+ return PyModule_Create(&tachyonmodule);
+}
diff --git a/test cases/python3/4 custom target depends extmodule/meson.build b/test cases/python3/4 custom target depends extmodule/meson.build
new file mode 100644
index 0000000..d76aa36
--- /dev/null
+++ b/test cases/python3/4 custom target depends extmodule/meson.build
@@ -0,0 +1,41 @@
+project('Python extension module', 'c',
+ default_options : ['buildtype=release'])
+# Because Windows Python ships only with optimized libs,
+# we must build this project the same way.
+
+py3_mod = import('python3')
+py3 = py3_mod.find_python()
+py3_dep = dependency('python3', required : false)
+cc = meson.get_compiler('c')
+
+# Copy to the builddir so that blaster.py can find the built tachyon module
+# FIXME: We should automatically detect this case and append the correct paths
+# to PYTHONLIBDIR
+blaster_py = configure_file(input : 'blaster.py',
+ output : 'blaster.py',
+ configuration : configuration_data())
+
+check_exists = '''
+import os, sys
+with open(sys.argv[1], 'rb') as f:
+ assert(f.read() == b'success')
+'''
+if py3_dep.found()
+ message('Detected Python version: ' + py3_dep.version())
+ if py3_dep.version().version_compare('>=3.8') and cc.get_id() == 'msvc' and cc.version().version_compare('<=19.00.24215.1')
+ error('MESON_SKIP_TEST: Python modules do not work with Python 3.8 and VS2015 or earlier.')
+ endif
+
+ subdir('ext')
+
+ out_txt = custom_target('tachyon flux',
+ input : blaster_py,
+ output : 'out.txt',
+ command : [py3, '@INPUT@', '-o', '@OUTPUT@'],
+ depends : pylib,
+ build_by_default: true)
+
+ test('flux', py3, args : ['-c', check_exists, out_txt])
+else
+ error('MESON_SKIP_TEST: Python3 libraries not found, skipping test.')
+endif
diff --git a/test cases/rewrite/1 basic/addSrc.json b/test cases/rewrite/1 basic/addSrc.json
new file mode 100644
index 0000000..b8bc439
--- /dev/null
+++ b/test cases/rewrite/1 basic/addSrc.json
@@ -0,0 +1,94 @@
+[
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "src_add",
+ "sources": ["a2.cpp", "a1.cpp", "a2.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog2",
+ "operation": "src_add",
+ "sources": ["a7.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "src_add",
+ "sources": ["a5.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "src_add",
+ "sources": ["a5.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "src_add",
+ "sources": ["a3.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog6",
+ "operation": "src_add",
+ "sources": ["a4.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "src_add",
+ "sources": ["a6.cpp", "a1.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog0",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog2",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog6",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog8",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/1 basic/addTgt.json b/test cases/rewrite/1 basic/addTgt.json
new file mode 100644
index 0000000..2f4e7e2
--- /dev/null
+++ b/test cases/rewrite/1 basic/addTgt.json
@@ -0,0 +1,9 @@
+[
+ {
+ "type": "target",
+ "target": "trivialprog10",
+ "operation": "target_add",
+ "sources": ["new1.cpp", "new2.cpp"],
+ "target_type": "shared_library"
+ }
+]
diff --git a/test cases/rewrite/1 basic/info.json b/test cases/rewrite/1 basic/info.json
new file mode 100644
index 0000000..0f1a3bd
--- /dev/null
+++ b/test cases/rewrite/1 basic/info.json
@@ -0,0 +1,57 @@
+[
+ {
+ "type": "target",
+ "target": "trivialprog0",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe2",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe4",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe6",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe8",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog10",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/1 basic/meson.build b/test cases/rewrite/1 basic/meson.build
new file mode 100644
index 0000000..0f87c45
--- /dev/null
+++ b/test cases/rewrite/1 basic/meson.build
@@ -0,0 +1,19 @@
+project('rewritetest', 'cpp')
+
+src1 = ['main.cpp', 'fileA.cpp']
+src2 = files(['fileB.cpp', 'fileC.cpp'])
+src3 = src1
+src4 = [src3]
+
+# Magic comment
+
+exe0 = executable('trivialprog0', src1 + src2)
+exe1 = executable('trivialprog1', src1)
+exe2 = executable('trivialprog2', [src2])
+exe3 = executable('trivialprog3', ['main.cpp', 'fileA.cpp'])
+exe4 = executable('trivialprog4', ['main.cpp', ['fileA.cpp']])
+exe5 = executable('trivialprog5', [src2, 'main.cpp'])
+exe6 = executable('trivialprog6', 'main.cpp', 'fileA.cpp')
+exe7 = executable('trivialprog7', 'fileB.cpp', src1, 'fileC.cpp')
+exe8 = executable('trivialprog8', src3)
+executable('trivialprog9', src4)
diff --git a/test cases/rewrite/1 basic/rmSrc.json b/test cases/rewrite/1 basic/rmSrc.json
new file mode 100644
index 0000000..2e7447c
--- /dev/null
+++ b/test cases/rewrite/1 basic/rmSrc.json
@@ -0,0 +1,88 @@
+[
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "src_rm",
+ "sources": ["fileA.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "src_rm",
+ "sources": ["fileA.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "src_rm",
+ "sources": ["fileA.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "src_rm",
+ "sources": ["fileB.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog6",
+ "operation": "src_rm",
+ "sources": ["fileA.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "src_rm",
+ "sources": ["fileB.cpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog0",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog2",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog6",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog8",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/1 basic/rmTgt.json b/test cases/rewrite/1 basic/rmTgt.json
new file mode 100644
index 0000000..dbaf025
--- /dev/null
+++ b/test cases/rewrite/1 basic/rmTgt.json
@@ -0,0 +1,17 @@
+[
+ {
+ "type": "target",
+ "target": "exe0",
+ "operation": "target_rm"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "target_rm"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "target_rm"
+ }
+]
diff --git a/test cases/rewrite/2 subdirs/addSrc.json b/test cases/rewrite/2 subdirs/addSrc.json
new file mode 100644
index 0000000..1a5c13e
--- /dev/null
+++ b/test cases/rewrite/2 subdirs/addSrc.json
@@ -0,0 +1,13 @@
+[
+ {
+ "type": "target",
+ "target": "something",
+ "operation": "src_add",
+ "sources": ["third.c"]
+ },
+ {
+ "type": "target",
+ "target": "something",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/2 subdirs/addTgt.json b/test cases/rewrite/2 subdirs/addTgt.json
new file mode 100644
index 0000000..2e1e8bc
--- /dev/null
+++ b/test cases/rewrite/2 subdirs/addTgt.json
@@ -0,0 +1,10 @@
+[
+ {
+ "type": "target",
+ "target": "newLib",
+ "operation": "target_add",
+ "sources": ["new1.cpp", "new2.cpp"],
+ "target_type": "shared_library",
+ "subdir": "sub2"
+ }
+]
diff --git a/test cases/rewrite/2 subdirs/info.json b/test cases/rewrite/2 subdirs/info.json
new file mode 100644
index 0000000..dba2cd6
--- /dev/null
+++ b/test cases/rewrite/2 subdirs/info.json
@@ -0,0 +1,12 @@
+[
+ {
+ "type": "target",
+ "target": "something",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "newLib",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/2 subdirs/meson.build b/test cases/rewrite/2 subdirs/meson.build
new file mode 100644
index 0000000..c7f3fec
--- /dev/null
+++ b/test cases/rewrite/2 subdirs/meson.build
@@ -0,0 +1,4 @@
+project('subdir rewrite', 'c')
+
+subdir('sub1')
+subdir('sub2')
diff --git a/test cases/rewrite/2 subdirs/rmTgt.json b/test cases/rewrite/2 subdirs/rmTgt.json
new file mode 100644
index 0000000..9b112f9
--- /dev/null
+++ b/test cases/rewrite/2 subdirs/rmTgt.json
@@ -0,0 +1,7 @@
+[
+ {
+ "type": "target",
+ "target": "something",
+ "operation": "target_rm"
+ }
+]
diff --git a/test cases/rewrite/2 subdirs/sub1/meson.build b/test cases/rewrite/2 subdirs/sub1/meson.build
new file mode 100644
index 0000000..ca42205
--- /dev/null
+++ b/test cases/rewrite/2 subdirs/sub1/meson.build
@@ -0,0 +1 @@
+srcs = ['first.c', 'second.c']
diff --git a/test cases/rewrite/2 subdirs/sub2/meson.build b/test cases/rewrite/2 subdirs/sub2/meson.build
new file mode 100644
index 0000000..44b4075
--- /dev/null
+++ b/test cases/rewrite/2 subdirs/sub2/meson.build
@@ -0,0 +1 @@
+executable('something', srcs)
diff --git a/test cases/rewrite/3 kwargs/add.json b/test cases/rewrite/3 kwargs/add.json
new file mode 100644
index 0000000..5b3ce0b
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/add.json
@@ -0,0 +1,38 @@
+[
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "set",
+ "kwargs": {
+ "license": "GPL"
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "add",
+ "kwargs": {
+ "license": ["MIT"]
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "add",
+ "kwargs": {
+ "license": "BSD"
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "//",
+ "operation": "add",
+ "kwargs": {
+ "license": "Boost"
+ }
+ }
+]
diff --git a/test cases/rewrite/3 kwargs/defopts_delete.json b/test cases/rewrite/3 kwargs/defopts_delete.json
new file mode 100644
index 0000000..4fe39e2
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/defopts_delete.json
@@ -0,0 +1,18 @@
+[
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "set",
+ "kwargs": {
+ "default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"]
+ }
+ },
+ {
+ "type": "default_options",
+ "operation": "delete",
+ "options": {
+ "buildtype": null
+ }
+ }
+]
diff --git a/test cases/rewrite/3 kwargs/defopts_set.json b/test cases/rewrite/3 kwargs/defopts_set.json
new file mode 100644
index 0000000..f8f855f
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/defopts_set.json
@@ -0,0 +1,24 @@
+[
+ {
+ "type": "default_options",
+ "operation": "set",
+ "options": {
+ "cpp_std": "c++14"
+ }
+ },
+ {
+ "type": "default_options",
+ "operation": "set",
+ "options": {
+ "buildtype": "release",
+ "debug": true
+ }
+ },
+ {
+ "type": "default_options",
+ "operation": "set",
+ "options": {
+ "cpp_std": "c++11"
+ }
+ }
+]
diff --git a/test cases/rewrite/3 kwargs/delete.json b/test cases/rewrite/3 kwargs/delete.json
new file mode 100644
index 0000000..7047f4a
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/delete.json
@@ -0,0 +1,20 @@
+[
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "delete",
+ "kwargs": {
+ "version": null
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "target",
+ "id": "helloWorld",
+ "operation": "delete",
+ "kwargs": {
+ "build_by_default": false
+ }
+ }
+]
diff --git a/test cases/rewrite/3 kwargs/info.json b/test cases/rewrite/3 kwargs/info.json
new file mode 100644
index 0000000..0eed404
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/info.json
@@ -0,0 +1,20 @@
+[
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "info"
+ },
+ {
+ "type": "kwargs",
+ "function": "target",
+ "id": "tgt1",
+ "operation": "info"
+ },
+ {
+ "type": "kwargs",
+ "function": "dependency",
+ "id": "dep1",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/3 kwargs/meson.build b/test cases/rewrite/3 kwargs/meson.build
new file mode 100644
index 0000000..13b336c
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/meson.build
@@ -0,0 +1,7 @@
+project('rewritetest', 'cpp', version: '0.0.1')
+
+# Find ZLIB
+dep1 = dependency('zlib', required: false)
+
+# Make a test exe
+tgt1 = executable('helloWorld', 'main.cpp', build_by_default: true)
diff --git a/test cases/rewrite/3 kwargs/remove.json b/test cases/rewrite/3 kwargs/remove.json
new file mode 100644
index 0000000..e33cb66
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/remove.json
@@ -0,0 +1,38 @@
+[
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "set",
+ "kwargs": {
+ "license": ["GPL", "MIT", "BSD", "Boost"]
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "remove",
+ "kwargs": {
+ "license": ["MIT"]
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "remove",
+ "kwargs": {
+ "license": "BSD"
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "//",
+ "operation": "remove",
+ "kwargs": {
+ "license": "Boost"
+ }
+ }
+]
diff --git a/test cases/rewrite/3 kwargs/remove_regex.json b/test cases/rewrite/3 kwargs/remove_regex.json
new file mode 100644
index 0000000..07fa58e
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/remove_regex.json
@@ -0,0 +1,29 @@
+[
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "set",
+ "kwargs": {
+ "default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"]
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "/",
+ "operation": "remove_regex",
+ "kwargs": {
+ "default_options": ["cpp_std=.*"]
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "//",
+ "operation": "remove_regex",
+ "kwargs": {
+ "default_options": ["buildtype=.*"]
+ }
+ }
+]
diff --git a/test cases/rewrite/3 kwargs/set.json b/test cases/rewrite/3 kwargs/set.json
new file mode 100644
index 0000000..6ca2ee4
--- /dev/null
+++ b/test cases/rewrite/3 kwargs/set.json
@@ -0,0 +1,34 @@
+[
+ {
+ "type": "kwargs",
+ "function": "project",
+ "id": "//",
+ "operation": "set",
+ "kwargs": {
+ "version": "0.0.2",
+ "meson_version": "0.50.0",
+ "license": ["GPL", "MIT"]
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "target",
+ "id": "helloWorld",
+ "operation": "set",
+ "kwargs": {
+ "build_by_default": false,
+ "build_rpath": "/usr/local",
+ "dependencies": "dep1"
+ }
+ },
+ {
+ "type": "kwargs",
+ "function": "dependency",
+ "id": "zlib",
+ "operation": "set",
+ "kwargs": {
+ "required": true,
+ "method": "cmake"
+ }
+ }
+]
diff --git a/test cases/rewrite/4 same name targets/addSrc.json b/test cases/rewrite/4 same name targets/addSrc.json
new file mode 100644
index 0000000..98d0d1e
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/addSrc.json
@@ -0,0 +1,8 @@
+[
+ {
+ "type": "target",
+ "target": "myExe",
+ "operation": "src_add",
+ "sources": ["a1.cpp", "a2.cpp"]
+ }
+]
diff --git a/test cases/rewrite/4 same name targets/info.json b/test cases/rewrite/4 same name targets/info.json
new file mode 100644
index 0000000..a9fc2dd
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/info.json
@@ -0,0 +1,12 @@
+[
+ {
+ "type": "target",
+ "target": "exe1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe2",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/4 same name targets/meson.build b/test cases/rewrite/4 same name targets/meson.build
new file mode 100644
index 0000000..384fa2b
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/meson.build
@@ -0,0 +1,6 @@
+project('rewrite same name targets', 'cpp')
+
+src1 = ['main.cpp']
+
+exe1 = executable('myExe', src1)
+subdir('sub1')
diff --git a/test cases/rewrite/4 same name targets/sub1/meson.build b/test cases/rewrite/4 same name targets/sub1/meson.build
new file mode 100644
index 0000000..ac53667
--- /dev/null
+++ b/test cases/rewrite/4 same name targets/sub1/meson.build
@@ -0,0 +1,3 @@
+src2 = ['main.cpp']
+
+exe2 = executable('myExe', src2)
diff --git a/test cases/rewrite/5 sorting/meson.build b/test cases/rewrite/5 sorting/meson.build
new file mode 100644
index 0000000..80934a0
--- /dev/null
+++ b/test cases/rewrite/5 sorting/meson.build
@@ -0,0 +1,33 @@
+project('rewriter source sorting', ['c', 'cpp'])
+
+src1 = files([
+ 'a1.c',
+ 'a10.c',
+ 'a2.c',
+ 'a3.c',
+ 'bbb/a/b1.c',
+ 'bbb/a4.c',
+ 'bbb/b3.c',
+ 'bbb/b4.c',
+ 'bbb/b/b2.c',
+ 'bbb/c1/b5.c',
+ 'bbb/c10/b6.c',
+ 'bbb/c2/b7.c',
+ 'bbb/b5.c',
+ 'a110.c',
+ 'aaa/f1.c',
+ 'aaa/f2.c',
+ 'aaa/f3.c',
+ 'a20.c',
+ 'b1.c',
+ 'aaa/b/b1.c',
+ 'aaa/b/b2.c',
+ 'a30.c',
+ 'a100.c',
+ 'aaa/a/a1.c',
+ 'a101.c',
+ 'a210.c',
+ 'c2.c'
+])
+
+exe1 = executable('exe1', src1)
diff --git a/test cases/rewrite/6 extra_files/addExtraFiles.json b/test cases/rewrite/6 extra_files/addExtraFiles.json
new file mode 100644
index 0000000..421ed92
--- /dev/null
+++ b/test cases/rewrite/6 extra_files/addExtraFiles.json
@@ -0,0 +1,111 @@
+[
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "extra_files_add",
+ "sources": ["a2.hpp", "a1.hpp", "a2.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog2",
+ "operation": "extra_files_add",
+ "sources": ["a7.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "extra_files_add",
+ "sources": ["a5.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "extra_files_add",
+ "sources": ["a5.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "extra_files_add",
+ "sources": ["a3.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "extra_files_add",
+ "sources": ["a6.hpp", "a1.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog8",
+ "operation": "extra_files_add",
+ "sources": ["a2.hpp", "a7.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "extra_files_add",
+ "sources": ["a9.hpp", "a8.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog10",
+ "operation": "extra_files_add",
+ "sources": ["a4.hpp", "a1.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog0",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog2",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog6",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog8",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog10",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/6 extra_files/info.json b/test cases/rewrite/6 extra_files/info.json
new file mode 100644
index 0000000..0f1a3bd
--- /dev/null
+++ b/test cases/rewrite/6 extra_files/info.json
@@ -0,0 +1,57 @@
+[
+ {
+ "type": "target",
+ "target": "trivialprog0",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe2",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe4",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe6",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "exe8",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog10",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rewrite/6 extra_files/meson.build b/test cases/rewrite/6 extra_files/meson.build
new file mode 100644
index 0000000..f9aab46
--- /dev/null
+++ b/test cases/rewrite/6 extra_files/meson.build
@@ -0,0 +1,21 @@
+project('rewritetest', 'cpp')
+
+ef1 = ['main.hpp', 'fileA.hpp']
+ef2 = files(['fileB.hpp', 'fileC.hpp'])
+ef3 = ef1
+ef4 = [ef3]
+ef5 = []
+
+# Magic comment
+
+exe0 = executable('trivialprog0', 'main.cpp', extra_files : ef1 + ef2)
+exe1 = executable('trivialprog1', 'main.cpp', extra_files : ef1)
+exe2 = executable('trivialprog2', 'main.cpp', extra_files : [ef2])
+exe3 = executable('trivialprog3', 'main.cpp', extra_files : ['main.hpp', 'fileA.hpp'])
+exe4 = executable('trivialprog4', 'main.cpp', extra_files : ['main.hpp', ['fileA.hpp']])
+exe5 = executable('trivialprog5', 'main.cpp', extra_files : [ef2, 'main.hpp'])
+exe6 = executable('trivialprog6', 'main.cpp', extra_files : ef3)
+executable('trivialprog7', 'main.cpp', extra_files : ef4)
+exe8 = executable('trivialprog8', 'main.cpp', extra_files : [])
+exe9 = executable('trivialprog9', 'main.cpp')
+exe10 = executable('trivialprog10', 'main.cpp', extra_files : ef5)
diff --git a/test cases/rewrite/6 extra_files/rmExtraFiles.json b/test cases/rewrite/6 extra_files/rmExtraFiles.json
new file mode 100644
index 0000000..bd2855b
--- /dev/null
+++ b/test cases/rewrite/6 extra_files/rmExtraFiles.json
@@ -0,0 +1,93 @@
+[
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "extra_files_rm",
+ "sources": ["fileA.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "extra_files_rm",
+ "sources": ["fileA.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "extra_files_rm",
+ "sources": ["fileA.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "extra_files_rm",
+ "sources": ["fileB.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog6",
+ "operation": "extra_files_rm",
+ "sources": ["fileA.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "extra_files_rm",
+ "sources": ["fileA.hpp"]
+ },
+ {
+ "type": "target",
+ "target": "trivialprog0",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog1",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog2",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog3",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog4",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog5",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog6",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog7",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog8",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog9",
+ "operation": "info"
+ },
+ {
+ "type": "target",
+ "target": "trivialprog10",
+ "operation": "info"
+ }
+]
diff --git a/test cases/rust/1 basic/clippy.toml b/test cases/rust/1 basic/clippy.toml
new file mode 100644
index 0000000..e9ac31b
--- /dev/null
+++ b/test cases/rust/1 basic/clippy.toml
@@ -0,0 +1 @@
+blacklisted-names = ["foo"]
diff --git a/test cases/rust/1 basic/meson.build b/test cases/rust/1 basic/meson.build
new file mode 100644
index 0000000..63ad375
--- /dev/null
+++ b/test cases/rust/1 basic/meson.build
@@ -0,0 +1,9 @@
+project('rustprog', 'rust')
+
+e = executable('rust-program', 'prog.rs',
+ rust_args : ['-C', 'lto'], # Just a test
+ install : true
+)
+test('rusttest', e)
+
+subdir('subdir')
diff --git a/test cases/rust/1 basic/prog.rs b/test cases/rust/1 basic/prog.rs
new file mode 100644
index 0000000..f1b3d30
--- /dev/null
+++ b/test cases/rust/1 basic/prog.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let foo = "rust compiler is working";
+ println!("{}", foo);
+}
diff --git a/test cases/rust/1 basic/subdir/meson.build b/test cases/rust/1 basic/subdir/meson.build
new file mode 100644
index 0000000..36a3d4a
--- /dev/null
+++ b/test cases/rust/1 basic/subdir/meson.build
@@ -0,0 +1,2 @@
+e = executable('rust-program2', 'prog.rs', install : true)
+test('rusttest2', e)
diff --git a/test cases/rust/1 basic/subdir/prog.rs b/test cases/rust/1 basic/subdir/prog.rs
new file mode 100644
index 0000000..b171a80
--- /dev/null
+++ b/test cases/rust/1 basic/subdir/prog.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("rust compiler is working");
+}
diff --git a/test cases/rust/1 basic/test.json b/test cases/rust/1 basic/test.json
new file mode 100644
index 0000000..95e6ced
--- /dev/null
+++ b/test cases/rust/1 basic/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/rust-program"},
+ {"type": "pdb", "file": "usr/bin/rust-program"},
+ {"type": "exe", "file": "usr/bin/rust-program2"},
+ {"type": "pdb", "file": "usr/bin/rust-program2"}
+ ]
+}
diff --git a/test cases/rust/10 language stds/2015.rs b/test cases/rust/10 language stds/2015.rs
new file mode 100644
index 0000000..4d28c57
--- /dev/null
+++ b/test cases/rust/10 language stds/2015.rs
@@ -0,0 +1,3 @@
+trait Foo {
+ fn foo(&self, Box<dyn Foo>);
+}
diff --git a/test cases/rust/10 language stds/2018.rs b/test cases/rust/10 language stds/2018.rs
new file mode 100644
index 0000000..4009154
--- /dev/null
+++ b/test cases/rust/10 language stds/2018.rs
@@ -0,0 +1,9 @@
+const fn foo(x: i32) -> i32 {
+ return x + 1;
+}
+
+const VALUE: i32 = foo(-1);
+
+pub fn main() {
+ std::process::exit(VALUE);
+}
diff --git a/test cases/rust/10 language stds/meson.build b/test cases/rust/10 language stds/meson.build
new file mode 100644
index 0000000..9944339
--- /dev/null
+++ b/test cases/rust/10 language stds/meson.build
@@ -0,0 +1,18 @@
+project('rust std options', 'rust')
+
+# this only works in 2018
+new = executable(
+ 'new',
+ '2018.rs',
+ override_options : ['rust_std=2018'],
+)
+
+# this only works in 2015
+old = static_library(
+ 'old',
+ '2015.rs',
+ override_options : ['rust_std=2015'],
+)
+
+
+test('2018 std', new)
diff --git a/test cases/rust/11 generated main/gen.py b/test cases/rust/11 generated main/gen.py
new file mode 100644
index 0000000..c8cfe76
--- /dev/null
+++ b/test cases/rust/11 generated main/gen.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import argparse
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('out')
+ parser.add_argument('--mode', choices=['main', 'lib'], default='main')
+ args = parser.parse_args()
+
+ with open(args.out, 'w') as f:
+ if args.mode == 'main':
+ f.write('fn main() { println!("I prefer tarnish, actually.") }')
+ elif args.mode == 'lib':
+ f.write('pub fn libfun() { println!("I prefer tarnish, actually.") }')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/11 generated main/generated_lib_main.rs b/test cases/rust/11 generated main/generated_lib_main.rs
new file mode 100644
index 0000000..d9b373e
--- /dev/null
+++ b/test cases/rust/11 generated main/generated_lib_main.rs
@@ -0,0 +1,5 @@
+extern crate static_lib_generated as lib;
+
+fn main() {
+ lib::libfun();
+}
diff --git a/test cases/rust/11 generated main/meson.build b/test cases/rust/11 generated main/meson.build
new file mode 100644
index 0000000..695124c
--- /dev/null
+++ b/test cases/rust/11 generated main/meson.build
@@ -0,0 +1,21 @@
+project('generated rust main', 'rust')
+
+gen = find_program('gen.py')
+
+c = custom_target(
+ 'custom_target',
+ command : [gen, '@OUTPUT@'],
+ output : ['main.rs'],
+)
+
+executable('custom_target_main', c)
+executable('custom_target_index_main', c[0])
+
+gener = generator(gen, arguments : ['@OUTPUT@'], output : '@BASENAME@.rs')
+# Doesn't actually use gen.py as input, just a limitation of generators
+executable('generator_main', gener.process(['gen.py']))
+
+subdir('sub')
+executable('custom_target_subdir_main', s)
+
+executable('link_with_generated_lib', 'generated_lib_main.rs', link_with : lib)
diff --git a/test cases/rust/11 generated main/sub/meson.build b/test cases/rust/11 generated main/sub/meson.build
new file mode 100644
index 0000000..3ce96e5
--- /dev/null
+++ b/test cases/rust/11 generated main/sub/meson.build
@@ -0,0 +1,13 @@
+s = custom_target(
+ 'subdir_target',
+ command : [gen, '@OUTPUT@'],
+ output : ['main.rs'],
+)
+
+l = custom_target(
+ 'lib_target',
+ command : [gen, '@OUTPUT@', '--mode', 'lib'],
+ output : ['lib.rs'],
+)
+
+lib = static_library('static_lib_generated', l)
diff --git a/test cases/rust/12 bindgen/dependencies/clib2.c b/test cases/rust/12 bindgen/dependencies/clib2.c
new file mode 100644
index 0000000..63d3e0a
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/clib2.c
@@ -0,0 +1,5 @@
+#include "internal_dep.h"
+
+int64_t add64(const int64_t first, const int64_t second) {
+ return first + second;
+}
diff --git a/test cases/rust/12 bindgen/dependencies/external_dep.h b/test cases/rust/12 bindgen/dependencies/external_dep.h
new file mode 100644
index 0000000..284661b
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/external_dep.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifer: Apache-2.0 */
+/* Copyright © 2022 Intel Corporation */
+
+#include <zlib.h>
+
+struct External {
+ z_stream * stream;
+};
diff --git a/test cases/rust/12 bindgen/dependencies/internal_dep.h b/test cases/rust/12 bindgen/dependencies/internal_dep.h
new file mode 100644
index 0000000..b0629de
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/internal_dep.h
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright © 2022 Intel Corporation
+
+#include "gen.h"
+
+int64_t add64(const int64_t, const int64_t);
diff --git a/test cases/rust/12 bindgen/dependencies/internal_main.rs b/test cases/rust/12 bindgen/dependencies/internal_main.rs
new file mode 100644
index 0000000..4890b43
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/internal_main.rs
@@ -0,0 +1,16 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!("internal_dep.rs");
+
+use std::convert::TryInto;
+
+fn main() {
+ unsafe {
+ std::process::exit(add64(0, 0).try_into().unwrap_or(5));
+ };
+}
diff --git a/test cases/rust/12 bindgen/dependencies/meson.build b/test cases/rust/12 bindgen/dependencies/meson.build
new file mode 100644
index 0000000..37e5a42
--- /dev/null
+++ b/test cases/rust/12 bindgen/dependencies/meson.build
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright © 2022 Intel Corporation
+
+dep_zlib = dependency('zlib', required : false, disabler : true)
+
+external_dep_rs = rust.bindgen(
+ input : 'external_dep.h',
+ output : 'external_dep.rs',
+ dependencies : dep_zlib
+)
+
+external_dep = static_library(
+ 'external_dep',
+ [external_dep_rs],
+ dependencies : dep_zlib.partial_dependency(links : true),
+)
+
+rust.test('external dep', external_dep)
+
+int_dep = declare_dependency(
+ sources : [gen_h, gen2_h],
+ include_directories : include_directories('..'),
+)
+
+internal_dep_rs = rust.bindgen(
+ input : 'internal_dep.h',
+ output : 'internal_dep.rs',
+ dependencies : int_dep,
+)
+
+c_lib2 = static_library(
+ 'clib2',
+ 'clib2.c',
+ dependencies : int_dep,
+)
+
+rust_bin_int_dep = executable(
+ 'rust_bin_int_dep',
+ structured_sources(['internal_main.rs', internal_dep_rs]),
+ link_with : [c_lib, c_lib2],
+)
+
+test('generated header dependency', rust_bin_int_dep)
diff --git a/test cases/rust/12 bindgen/include/other.h b/test cases/rust/12 bindgen/include/other.h
new file mode 100644
index 0000000..3f715f1
--- /dev/null
+++ b/test cases/rust/12 bindgen/include/other.h
@@ -0,0 +1,6 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+# pragma once
+
+#include <stdint.h>
diff --git a/test cases/rust/12 bindgen/meson.build b/test cases/rust/12 bindgen/meson.build
new file mode 100644
index 0000000..c05cc06
--- /dev/null
+++ b/test cases/rust/12 bindgen/meson.build
@@ -0,0 +1,83 @@
+# SPDX-license-identifer: Apache-2.0
+# Copyright © 2021-2022 Intel Corporation
+
+project('rustmod bindgen', ['c', 'rust'], meson_version : '>= 0.63')
+
+prog_bindgen = find_program('bindgen', required : false)
+if not prog_bindgen.found()
+ error('MESON_SKIP_TEST bindgen not found')
+endif
+
+# This seems to happen on windows when libclang.dll is not in path or is not
+# valid. We must try to process a header file for this to work.
+#
+# See https://github.com/rust-lang/rust-bindgen/issues/1797
+result = run_command(prog_bindgen, 'include/other.h', check: false)
+if result.returncode() != 0
+ error('MESON_SKIP_TEST bindgen does not seem to work')
+endif
+
+# This is to test the include_directories argument to bindgen
+inc = include_directories('include')
+
+c_lib = static_library('clib', 'src/source.c', include_directories : inc)
+
+rust = import('unstable-rust')
+
+gen = rust.bindgen(
+ input : 'src/header.h',
+ output : 'header.rs',
+ include_directories : 'include',
+)
+
+# see: https://github.com/mesonbuild/meson/issues/8160
+f = configure_file(
+ input : 'src/main.rs',
+ output : 'main.rs',
+ copy : true,
+)
+
+rust_bin = executable(
+ 'rust_bin',
+ [f, gen],
+ link_with : c_lib,
+)
+
+test('main', rust_bin)
+
+# Test a generated header
+gen_h = custom_target(
+ 'gen.h',
+ command : [find_program('src/gen_header.py'), '@INPUT@', '@OUTPUT@'],
+ output : 'gen.h',
+ input : 'src/header.h'
+)
+
+gen2_h = custom_target(
+ 'other.h',
+ command : [find_program('src/gen_header.py'), '@INPUT@', '@OUTPUT@'],
+ output : 'other.h',
+ input : 'include/other.h'
+)
+
+gen_rs = rust.bindgen(
+ input : [gen_h, gen2_h],
+ output : 'gen.rs',
+)
+
+f = configure_file(
+ input : 'src/main2.rs',
+ output : 'main2.rs',
+ copy : true,
+)
+
+rust_bin2 = executable(
+ 'rust_bin2',
+ [f, gen_rs],
+ link_with : c_lib,
+)
+
+test('generated header', rust_bin2)
+
+subdir('sub')
+subdir('dependencies')
diff --git a/test cases/rust/12 bindgen/src/gen_header.py b/test cases/rust/12 bindgen/src/gen_header.py
new file mode 100644
index 0000000..099e4ec
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/gen_header.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+# SPDX-license-identifer: Apache-2.0
+# Copyright © 2021 Intel Corporation
+
+import argparse
+import shutil
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('input')
+ parser.add_argument('output')
+ args = parser.parse_args()
+
+ shutil.copy2(args.input, args.output)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/12 bindgen/src/header.h b/test cases/rust/12 bindgen/src/header.h
new file mode 100644
index 0000000..2c03f33
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/header.h
@@ -0,0 +1,8 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#pragma once
+
+#include "other.h"
+
+int32_t add(const int32_t, const int32_t);
diff --git a/test cases/rust/12 bindgen/src/main.rs b/test cases/rust/12 bindgen/src/main.rs
new file mode 100644
index 0000000..3f85e96
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/main.rs
@@ -0,0 +1,14 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!("header.rs");
+
+fn main() {
+ unsafe {
+ std::process::exit(add(0, 0));
+ };
+}
diff --git a/test cases/rust/12 bindgen/src/main2.rs b/test cases/rust/12 bindgen/src/main2.rs
new file mode 100644
index 0000000..a3c28d7
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/main2.rs
@@ -0,0 +1,15 @@
+
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!("gen.rs");
+
+fn main() {
+ unsafe {
+ std::process::exit(add(0, 0));
+ };
+}
diff --git a/test cases/rust/12 bindgen/src/source.c b/test cases/rust/12 bindgen/src/source.c
new file mode 100644
index 0000000..d652d28
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/source.c
@@ -0,0 +1,8 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2021 Intel Corporation
+
+#include "header.h"
+
+int32_t add(const int32_t first, const int32_t second) {
+ return first + second;
+}
diff --git a/test cases/rust/12 bindgen/sub/meson.build b/test cases/rust/12 bindgen/sub/meson.build
new file mode 100644
index 0000000..1da360e
--- /dev/null
+++ b/test cases/rust/12 bindgen/sub/meson.build
@@ -0,0 +1,39 @@
+gen_rs3 = rust.bindgen(
+ input : [gen_h, gen2_h],
+ output : 'gen.rs',
+)
+
+f3 = configure_file(
+ input : '../src/main2.rs',
+ output : 'main3.rs',
+ copy : true,
+)
+
+rust_bin3 = executable(
+ 'rust_bin3',
+ [f3, gen_rs3],
+ link_with : c_lib,
+)
+
+test('generated header (subdir)', rust_bin3)
+
+gen4 = rust.bindgen(
+ input : '../src/header.h',
+ output : 'header.rs',
+ include_directories : inc,
+)
+
+# see: https://github.com/mesonbuild/meson/issues/8160
+f4 = configure_file(
+ input : '../src/main.rs',
+ output : 'main.rs',
+ copy : true,
+)
+
+rust_bin4 = executable(
+ 'rust_bin_subdir',
+ [f4, gen4],
+ link_with : c_lib,
+)
+
+test('static header (subdir)', rust_bin4)
diff --git a/test cases/rust/12 bindgen/test.json b/test cases/rust/12 bindgen/test.json
new file mode 100644
index 0000000..11cefc3
--- /dev/null
+++ b/test cases/rust/12 bindgen/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/rust/12 bindgen/meson.build:30: WARNING: Project targets '>= 0.63' but uses feature introduced in '1.0.0': include_directories kwarg of type string. Use include_directories('include') instead"
+ }
+ ]
+}
diff --git a/test cases/rust/13 external c dependencies/c_accessing_zlib.c b/test cases/rust/13 external c dependencies/c_accessing_zlib.c
new file mode 100644
index 0000000..358b989
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/c_accessing_zlib.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <string.h>
+#include <zlib.h>
+
+void c_accessing_zlib(void) {
+ struct z_stream_s zstream;
+ printf("Hello from C!\n");
+ memset(&zstream, 0, sizeof(zstream));
+ inflateInit(&zstream);
+}
diff --git a/test cases/rust/13 external c dependencies/meson.build b/test cases/rust/13 external c dependencies/meson.build
new file mode 100644
index 0000000..c91674c
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/meson.build
@@ -0,0 +1,23 @@
+project('rust linking to c using dependency', 'c', 'rust')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+dep_zlib = dependency('zlib', static : get_option('static'), method : get_option('method'), required : false)
+if not dep_zlib.found()
+ error('MESON_SKIP_TEST: Could not find a @0@ zlib'.format(get_option('static') ? 'static' : 'shared'))
+endif
+
+l = static_library(
+ 'c_accessing_zlib',
+ 'c_accessing_zlib.c',
+ dependencies: [dep_zlib],
+)
+
+e = executable(
+ 'prog', 'prog.rs',
+ link_with : l,
+)
+
+test('cdepstest', e)
diff --git a/test cases/rust/13 external c dependencies/meson_options.txt b/test cases/rust/13 external c dependencies/meson_options.txt
new file mode 100644
index 0000000..f501348
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/meson_options.txt
@@ -0,0 +1,2 @@
+option('static', type : 'boolean')
+option('method', type : 'string')
diff --git a/test cases/rust/13 external c dependencies/prog.rs b/test cases/rust/13 external c dependencies/prog.rs
new file mode 100644
index 0000000..b30ec24
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/prog.rs
@@ -0,0 +1,9 @@
+extern "C" {
+ fn c_accessing_zlib();
+}
+
+fn main() {
+ unsafe {
+ c_accessing_zlib();
+ }
+}
diff --git a/test cases/rust/13 external c dependencies/test.json b/test cases/rust/13 external c dependencies/test.json
new file mode 100644
index 0000000..423581f
--- /dev/null
+++ b/test cases/rust/13 external c dependencies/test.json
@@ -0,0 +1,18 @@
+{
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": true },
+ { "val": false }
+ ],
+ "method": [
+ { "val": "pkg-config" },
+ { "val": "cmake" },
+ { "val": "system" }
+ ]
+ },
+ "exclude": [
+ { "static": true, "method": "pkg-config" }
+ ]
+ }
+}
diff --git a/test cases/rust/14 external libm/meson.build b/test cases/rust/14 external libm/meson.build
new file mode 100644
index 0000000..e42eefe
--- /dev/null
+++ b/test cases/rust/14 external libm/meson.build
@@ -0,0 +1,24 @@
+project('rust linking to libm', 'c', 'rust')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+cc = meson.get_compiler('c')
+dep_m = cc.find_library('m', required : false, static : get_option('static'))
+if not dep_m.found()
+ error('MESON_SKIP_TEST: Could not find a @0@ libm'.format(get_option('static') ? 'static' : 'shared'))
+endif
+
+librs_math = static_library(
+ 'rs_math',
+ 'rs_math.rs',
+ dependencies : [dep_m],
+)
+
+e = executable(
+ 'prog', 'prog.rs',
+ link_with : [librs_math],
+)
+
+test('cdepstest', e)
diff --git a/test cases/rust/14 external libm/meson_options.txt b/test cases/rust/14 external libm/meson_options.txt
new file mode 100644
index 0000000..f501348
--- /dev/null
+++ b/test cases/rust/14 external libm/meson_options.txt
@@ -0,0 +1,2 @@
+option('static', type : 'boolean')
+option('method', type : 'string')
diff --git a/test cases/rust/14 external libm/prog.rs b/test cases/rust/14 external libm/prog.rs
new file mode 100644
index 0000000..6745977
--- /dev/null
+++ b/test cases/rust/14 external libm/prog.rs
@@ -0,0 +1,5 @@
+extern crate rs_math;
+
+fn main() {
+ assert_eq!(rs_math::rs_log2(8.0), 3.0);
+}
diff --git a/test cases/rust/14 external libm/rs_math.rs b/test cases/rust/14 external libm/rs_math.rs
new file mode 100644
index 0000000..ef53a5c
--- /dev/null
+++ b/test cases/rust/14 external libm/rs_math.rs
@@ -0,0 +1,12 @@
+#![crate_name = "rs_math"]
+
+use std::os::raw::c_double;
+
+extern "C" {
+ fn log2(n: c_double) -> c_double;
+}
+
+#[no_mangle]
+pub extern fn rs_log2(n: c_double) -> c_double {
+ unsafe { log2(n) }
+}
diff --git a/test cases/rust/14 external libm/test.json b/test cases/rust/14 external libm/test.json
new file mode 100644
index 0000000..42d8fe9
--- /dev/null
+++ b/test cases/rust/14 external libm/test.json
@@ -0,0 +1,10 @@
+{
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": true },
+ { "val": false }
+ ]
+ }
+ }
+}
diff --git a/test cases/rust/15 polyglot sharedlib/adder.c b/test cases/rust/15 polyglot sharedlib/adder.c
new file mode 100644
index 0000000..66613ed
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/adder.c
@@ -0,0 +1,18 @@
+#include<adder.h>
+#include<stdlib.h>
+
+struct _Adder {
+ int number;
+};
+
+adder* adder_create(int number) {
+ adder *a = malloc(sizeof(struct _Adder));
+ a->number = number;
+ return a;
+}
+
+// adder_add is implemented in the Rust file.
+
+void adder_destroy(adder *a) {
+ free(a);
+}
diff --git a/test cases/rust/15 polyglot sharedlib/adder.h b/test cases/rust/15 polyglot sharedlib/adder.h
new file mode 100644
index 0000000..fb2105e
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/adder.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined _WIN32 || defined __CYGWIN__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #if defined __GNUC__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #define DLL_PUBLIC
+ #endif
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+typedef struct _Adder adder;
+
+DLL_PUBLIC extern adder* adder_create(int number);
+DLL_PUBLIC extern int adder_add(adder *a, int number);
+DLL_PUBLIC extern void adder_destroy(adder*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test cases/rust/15 polyglot sharedlib/adder.rs b/test cases/rust/15 polyglot sharedlib/adder.rs
new file mode 100644
index 0000000..9095350
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/adder.rs
@@ -0,0 +1,9 @@
+#[repr(C)]
+pub struct Adder {
+ pub number: i32
+}
+
+#[no_mangle]
+pub extern fn adder_add(a: &Adder, number: i32) -> i32 {
+ return a.number + number;
+}
diff --git a/test cases/rust/15 polyglot sharedlib/addertest.c b/test cases/rust/15 polyglot sharedlib/addertest.c
new file mode 100644
index 0000000..87e45b6
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/addertest.c
@@ -0,0 +1,12 @@
+#include<stdlib.h>
+#include<adder.h>
+
+int main(int argc, char **argv) {
+ adder *a = adder_create(3);
+ int result = adder_add(a, 4);
+ if(result != 7) {
+ return 1;
+ }
+ adder_destroy(a);
+ return 0;
+}
diff --git a/test cases/rust/15 polyglot sharedlib/meson.build b/test cases/rust/15 polyglot sharedlib/meson.build
new file mode 100644
index 0000000..13fc8fd
--- /dev/null
+++ b/test cases/rust/15 polyglot sharedlib/meson.build
@@ -0,0 +1,20 @@
+project('adder', 'c', 'rust', version: '1.0.0')
+
+if build_machine.system() != 'linux'
+ error('MESON_SKIP_TEST, this test only works on Linux. Patches welcome.')
+endif
+
+thread_dep = dependency('threads')
+dl_dep = meson.get_compiler('c').find_library('dl', required: false)
+m_dep = meson.get_compiler('c').find_library('m', required: false)
+
+rl = static_library('radder', 'adder.rs', rust_crate_type: 'staticlib')
+
+l = shared_library('adder', 'adder.c',
+ c_args: '-DBUILDING_ADDER',
+ link_with: rl,
+ version: '1.0.0',
+ soversion: '1',
+ link_args: '-Wl,-u,adder_add', # Ensure that Rust code is not removed as unused.
+ dependencies: [thread_dep, dl_dep, m_dep])
+test('adder', executable('addertest', 'addertest.c', link_with: l))
diff --git a/test cases/rust/16 internal c dependencies/lib.c b/test cases/rust/16 internal c dependencies/lib.c
new file mode 100644
index 0000000..e852de6
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/lib.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+#include "lib.h"
+
+void c_func(void) {
+ printf("This is a " MODE " C library\n");
+}
diff --git a/test cases/rust/16 internal c dependencies/lib.h b/test cases/rust/16 internal c dependencies/lib.h
new file mode 100644
index 0000000..847bd16
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/lib.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __declspec(dllexport)
+ #else
+ #define DLL_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #if defined __GNUC__
+ #if defined BUILDING_ADDER
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #define DLL_PUBLIC
+ #endif
+ #else
+ #pragma message("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+DLL_PUBLIC void c_func(void);
diff --git a/test cases/rust/16 internal c dependencies/main.rs b/test cases/rust/16 internal c dependencies/main.rs
new file mode 100644
index 0000000..5383599
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/main.rs
@@ -0,0 +1,9 @@
+extern "C" {
+ fn c_func();
+}
+
+fn main() {
+ unsafe {
+ c_func();
+ }
+}
diff --git a/test cases/rust/16 internal c dependencies/meson.build b/test cases/rust/16 internal c dependencies/meson.build
new file mode 100644
index 0000000..c7476d7
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/meson.build
@@ -0,0 +1,14 @@
+project('internal dependencies', 'c', 'rust')
+
+test_prog = find_program('test.py')
+
+static = static_library('static', 'lib.c', c_args : '-DMODE="static"')
+exe = executable('static', 'main.rs', link_with : static)
+test('static linkage', test_prog, args : [exe, 'This is a static C library'])
+
+# Shared linkage with rust doesn't work on macOS with meson, yet
+if host_machine.system() != 'darwin'
+ shared = shared_library('shared', 'lib.c', c_args : '-DMODE="shared"')
+ exe = executable('shared', 'main.rs', link_with : shared)
+ test('shared linkage', test_prog, args : [exe, 'This is a shared C library'])
+endif
diff --git a/test cases/rust/16 internal c dependencies/test.py b/test cases/rust/16 internal c dependencies/test.py
new file mode 100755
index 0000000..dacec12
--- /dev/null
+++ b/test cases/rust/16 internal c dependencies/test.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+
+import argparse
+import subprocess
+import sys
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('command')
+ parser.add_argument('expected')
+ args = parser.parse_args()
+
+ out = subprocess.run(args.command, stdout=subprocess.PIPE)
+ actual = out.stdout.decode().strip()
+
+ if args.expected != actual:
+ print('expected:', args.expected, file=sys.stderr)
+ print('actual: ', actual, file=sys.stderr)
+ sys.exit(1)
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/17 staticlib link staticlib/branch.rs b/test cases/rust/17 staticlib link staticlib/branch.rs
new file mode 100644
index 0000000..29e1cd0
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/branch.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub extern "C" fn what_have_we_here() -> i32 {
+ leaf::HOW_MANY * leaf::HOW_MANY
+}
diff --git a/test cases/rust/17 staticlib link staticlib/leaf.rs b/test cases/rust/17 staticlib link staticlib/leaf.rs
new file mode 100644
index 0000000..2c697f7
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/leaf.rs
@@ -0,0 +1 @@
+pub const HOW_MANY: i32 = 5;
diff --git a/test cases/rust/17 staticlib link staticlib/meson.build b/test cases/rust/17 staticlib link staticlib/meson.build
new file mode 100644
index 0000000..68d08f3
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/meson.build
@@ -0,0 +1,8 @@
+project('staticlib link staticlib', 'c', 'rust')
+
+leaf = static_library('leaf', 'leaf.rs', rust_crate_type : 'rlib')
+# Even though leaf is linked using link_with, this gets implicitly promoted to link_whole because
+# it is an internal Rust project.
+branch = static_library('branch', 'branch.rs', link_with: leaf, rust_crate_type : 'staticlib', install : true)
+e = executable('prog', 'prog.c', link_with : branch, install : true)
+test('linktest', e)
diff --git a/test cases/rust/17 staticlib link staticlib/prog.c b/test cases/rust/17 staticlib link staticlib/prog.c
new file mode 100644
index 0000000..853391e
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/prog.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int what_have_we_here();
+
+int main(void) {
+ printf("printing %d\n", what_have_we_here());
+}
diff --git a/test cases/rust/17 staticlib link staticlib/test.json b/test cases/rust/17 staticlib link staticlib/test.json
new file mode 100644
index 0000000..c08ffea
--- /dev/null
+++ b/test cases/rust/17 staticlib link staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libbranch.a"}
+ ]
+}
diff --git a/test cases/rust/18 proc-macro/meson.build b/test cases/rust/18 proc-macro/meson.build
new file mode 100644
index 0000000..01c4cbe
--- /dev/null
+++ b/test cases/rust/18 proc-macro/meson.build
@@ -0,0 +1,19 @@
+project('rust proc-macro', 'rust')
+
+if build_machine.system() != 'linux'
+ error('MESON_SKIP_TEST, this test only works on Linux. Patches welcome.')
+endif
+
+pm = shared_library(
+ 'proc_macro_examples',
+ 'proc.rs',
+ rust_crate_type : 'proc-macro',
+)
+
+main = executable(
+ 'main',
+ 'use.rs',
+ link_with : pm
+)
+
+test('main_test', main)
diff --git a/test cases/rust/18 proc-macro/proc.rs b/test cases/rust/18 proc-macro/proc.rs
new file mode 100644
index 0000000..53935e4
--- /dev/null
+++ b/test cases/rust/18 proc-macro/proc.rs
@@ -0,0 +1,7 @@
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn make_answer(_item: TokenStream) -> TokenStream {
+ "fn answer() -> u32 { 42 }".parse().unwrap()
+}
diff --git a/test cases/rust/18 proc-macro/use.rs b/test cases/rust/18 proc-macro/use.rs
new file mode 100644
index 0000000..0b6342b
--- /dev/null
+++ b/test cases/rust/18 proc-macro/use.rs
@@ -0,0 +1,8 @@
+extern crate proc_macro_examples;
+use proc_macro_examples::make_answer;
+
+make_answer!();
+
+fn main() {
+ assert_eq!(42, answer());
+}
diff --git a/test cases/rust/19 structured sources/gen.py b/test cases/rust/19 structured sources/gen.py
new file mode 100755
index 0000000..16e5c04
--- /dev/null
+++ b/test cases/rust/19 structured sources/gen.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import argparse
+import textwrap
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('output')
+ args = parser.parse_args()
+
+ with open(args.output, 'w') as f:
+ f.write(textwrap.dedent('''\
+ pub fn bar() -> () {
+ println!("Hello, World!");
+ }'''))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/19 structured sources/main-gen-copy.rs b/test cases/rust/19 structured sources/main-gen-copy.rs
new file mode 100644
index 0000000..db66a51
--- /dev/null
+++ b/test cases/rust/19 structured sources/main-gen-copy.rs
@@ -0,0 +1,5 @@
+include!(r#"@dir@/include.rs"#);
+
+pub fn main() {
+ priv_func();
+}
diff --git a/test cases/rust/19 structured sources/meson.build b/test cases/rust/19 structured sources/meson.build
new file mode 100644
index 0000000..d84e83f
--- /dev/null
+++ b/test cases/rust/19 structured sources/meson.build
@@ -0,0 +1,58 @@
+project('structured input', 'rust')
+
+foo_mod_rs = configure_file(
+ input : 'src/foo.rs.in',
+ output : 'mod.rs',
+ configuration : {'message' : 'Hello, World!'},
+)
+
+conf_file = executable(
+ 'main_conf_file',
+ structured_sources(
+ 'src/main.rs',
+ {'foo' : [foo_mod_rs]},
+ ),
+)
+
+ct = custom_target(
+ 'foo.rs',
+ output : 'foo.rs',
+ command : ['gen.py', '@OUTPUT@'],
+)
+
+target = executable(
+ 'main_custom_target',
+ structured_sources(
+ ['src/main.rs', ct],
+ ),
+)
+
+# Should not be coppied
+executable(
+ 'no_copy_target',
+ structured_sources(
+ ['src2/main-unique.rs'],
+ {'foo': 'src2/foo/mod.rs'},
+ ),
+)
+
+test('no-copy', find_program('no_copy_test.py'), args : meson.current_build_dir())
+
+subdir('src2')
+
+executable('copy-no-gen', srcs2)
+
+m_src = configure_file(
+ input : 'main-gen-copy.rs',
+ output : 'main-gen-copy.rs',
+ configuration : {'dir' : meson.current_build_dir().replace('\\', '/')},
+)
+
+m_src2 = configure_file(
+ input : 'priv.rs',
+ output : 'include.rs',
+ copy : true
+)
+
+executable('gen-no-copy', structured_sources([m_src, m_src2]))
+
diff --git a/test cases/rust/19 structured sources/no_copy_test.py b/test cases/rust/19 structured sources/no_copy_test.py
new file mode 100755
index 0000000..91506b2
--- /dev/null
+++ b/test cases/rust/19 structured sources/no_copy_test.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('builddir')
+ args = parser.parse_args()
+
+ for _, _, files in os.walk(args.builddir):
+ if 'main-unique.rs' in files:
+ exit(1)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/19 structured sources/priv.rs b/test cases/rust/19 structured sources/priv.rs
new file mode 100644
index 0000000..aad196b
--- /dev/null
+++ b/test cases/rust/19 structured sources/priv.rs
@@ -0,0 +1,3 @@
+fn priv_func() {
+ std::process::exit(0);
+}
diff --git a/test cases/rust/19 structured sources/src/foo.rs.in b/test cases/rust/19 structured sources/src/foo.rs.in
new file mode 100644
index 0000000..4f3fc42
--- /dev/null
+++ b/test cases/rust/19 structured sources/src/foo.rs.in
@@ -0,0 +1,4 @@
+
+pub fn bar() -> () {
+ println!("@message@");
+}
diff --git a/test cases/rust/19 structured sources/src/main.rs b/test cases/rust/19 structured sources/src/main.rs
new file mode 100644
index 0000000..3ffeee2
--- /dev/null
+++ b/test cases/rust/19 structured sources/src/main.rs
@@ -0,0 +1,5 @@
+mod foo;
+
+fn main() {
+ foo::bar();
+}
diff --git a/test cases/rust/19 structured sources/src2/foo/mod.rs b/test cases/rust/19 structured sources/src2/foo/mod.rs
new file mode 100644
index 0000000..9463d95
--- /dev/null
+++ b/test cases/rust/19 structured sources/src2/foo/mod.rs
@@ -0,0 +1,4 @@
+
+pub fn bar() -> () {
+ println!("Hello, World!");
+}
diff --git a/test cases/rust/19 structured sources/src2/main-unique.rs b/test cases/rust/19 structured sources/src2/main-unique.rs
new file mode 100644
index 0000000..3ffeee2
--- /dev/null
+++ b/test cases/rust/19 structured sources/src2/main-unique.rs
@@ -0,0 +1,5 @@
+mod foo;
+
+fn main() {
+ foo::bar();
+}
diff --git a/test cases/rust/19 structured sources/src2/meson.build b/test cases/rust/19 structured sources/src2/meson.build
new file mode 100644
index 0000000..b4844d2
--- /dev/null
+++ b/test cases/rust/19 structured sources/src2/meson.build
@@ -0,0 +1,4 @@
+srcs2 = structured_sources(
+ ['main-unique.rs'],
+ {'foo': 'foo/mod.rs'},
+)
diff --git a/test cases/rust/2 sharedlib/meson.build b/test cases/rust/2 sharedlib/meson.build
new file mode 100644
index 0000000..295fa04
--- /dev/null
+++ b/test cases/rust/2 sharedlib/meson.build
@@ -0,0 +1,17 @@
+project('rust shared library', 'rust', 'c')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+s = static_library('static', 'value.c')
+l = shared_library('stuff', 'stuff.rs', link_whole : s, install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+
+if build_machine.system() == 'windows'
+ rustup = find_program('rustup')
+ test('linktest', rustup,
+ args: ['run', 'stable', e])
+else
+ test('linktest', e)
+endif
diff --git a/test cases/rust/2 sharedlib/prog.rs b/test cases/rust/2 sharedlib/prog.rs
new file mode 100644
index 0000000..fbf3181
--- /dev/null
+++ b/test cases/rust/2 sharedlib/prog.rs
@@ -0,0 +1,3 @@
+extern crate stuff;
+
+fn main() { println!("printing: {}", stuff::explore()); }
diff --git a/test cases/rust/2 sharedlib/stuff.rs b/test cases/rust/2 sharedlib/stuff.rs
new file mode 100644
index 0000000..e7c0521
--- /dev/null
+++ b/test cases/rust/2 sharedlib/stuff.rs
@@ -0,0 +1,11 @@
+#![crate_name = "stuff"]
+
+extern "C" {
+ fn c_value() -> i32;
+}
+
+pub fn explore() -> String {
+ unsafe {
+ format!("library{}string", c_value())
+ }
+}
diff --git a/test cases/rust/2 sharedlib/test.json b/test cases/rust/2 sharedlib/test.json
new file mode 100644
index 0000000..585fdeb
--- /dev/null
+++ b/test cases/rust/2 sharedlib/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "pdb", "file": "usr/bin/stuff"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.dll.lib"}
+ ]
+}
diff --git a/test cases/rust/2 sharedlib/value.c b/test cases/rust/2 sharedlib/value.c
new file mode 100644
index 0000000..d17b6de
--- /dev/null
+++ b/test cases/rust/2 sharedlib/value.c
@@ -0,0 +1,3 @@
+int c_value(void) {
+ return 7;
+}
diff --git a/test cases/rust/3 staticlib/meson.build b/test cases/rust/3 staticlib/meson.build
new file mode 100644
index 0000000..cf8e103
--- /dev/null
+++ b/test cases/rust/3 staticlib/meson.build
@@ -0,0 +1,7 @@
+project('rust static library', 'rust', 'c')
+
+o = static_library('other', 'other.rs')
+v = static_library('value', 'value.c')
+l = static_library('stuff', 'stuff.rs', link_whole : [o, v], install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+test('linktest', e)
diff --git a/test cases/rust/3 staticlib/other.rs b/test cases/rust/3 staticlib/other.rs
new file mode 100644
index 0000000..037be33
--- /dev/null
+++ b/test cases/rust/3 staticlib/other.rs
@@ -0,0 +1,5 @@
+pub fn explore(
+ value: i32,
+) -> String {
+ format!("library{}string", value)
+}
diff --git a/test cases/rust/3 staticlib/prog.rs b/test cases/rust/3 staticlib/prog.rs
new file mode 100644
index 0000000..eee2653
--- /dev/null
+++ b/test cases/rust/3 staticlib/prog.rs
@@ -0,0 +1,5 @@
+extern crate stuff;
+
+fn main() {
+ println!("printing: {}", stuff::explore());
+}
diff --git a/test cases/rust/3 staticlib/stuff.rs b/test cases/rust/3 staticlib/stuff.rs
new file mode 100644
index 0000000..7cfcdff
--- /dev/null
+++ b/test cases/rust/3 staticlib/stuff.rs
@@ -0,0 +1,14 @@
+#![crate_name = "stuff"]
+
+extern crate other;
+
+extern "C" {
+ fn c_explore_value() -> i32;
+}
+
+pub fn explore(
+) -> String {
+ unsafe {
+ other::explore(c_explore_value())
+ }
+}
diff --git a/test cases/rust/3 staticlib/test.json b/test cases/rust/3 staticlib/test.json
new file mode 100644
index 0000000..ca29225
--- /dev/null
+++ b/test cases/rust/3 staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstuff.rlib"}
+ ]
+}
diff --git a/test cases/rust/3 staticlib/value.c b/test cases/rust/3 staticlib/value.c
new file mode 100644
index 0000000..b71c806
--- /dev/null
+++ b/test cases/rust/3 staticlib/value.c
@@ -0,0 +1,5 @@
+int
+c_explore_value (void)
+{
+ return 42;
+}
diff --git a/test cases/rust/4 polyglot/meson.build b/test cases/rust/4 polyglot/meson.build
new file mode 100644
index 0000000..3601d5e
--- /dev/null
+++ b/test cases/rust/4 polyglot/meson.build
@@ -0,0 +1,9 @@
+project('rust and c polyglot executable', 'c', 'rust')
+
+if host_machine.system() == 'darwin'
+ error('MESON_SKIP_TEST: does not work right on macos, please fix!')
+endif
+
+l = shared_library('stuff', 'stuff.rs', rust_crate_type: 'cdylib', install : true)
+e = executable('prog', 'prog.c', link_with : l, install : true)
+test('polyglottest', e)
diff --git a/test cases/rust/4 polyglot/prog.c b/test cases/rust/4 polyglot/prog.c
new file mode 100644
index 0000000..dbbd880
--- /dev/null
+++ b/test cases/rust/4 polyglot/prog.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+void f();
+
+int main(void) {
+ printf("Hello from C!\n");
+ f();
+}
diff --git a/test cases/rust/4 polyglot/stuff.rs b/test cases/rust/4 polyglot/stuff.rs
new file mode 100644
index 0000000..ecf623c
--- /dev/null
+++ b/test cases/rust/4 polyglot/stuff.rs
@@ -0,0 +1,6 @@
+#![crate_name = "stuff"]
+
+#[no_mangle]
+pub extern fn f() {
+ println!("Hello from Rust!");
+}
diff --git a/test cases/rust/4 polyglot/test.json b/test cases/rust/4 polyglot/test.json
new file mode 100644
index 0000000..a8837a1
--- /dev/null
+++ b/test cases/rust/4 polyglot/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.dll.lib"},
+ {"type": "pdb", "file": "usr/bin/stuff"}
+ ]
+}
diff --git a/test cases/rust/5 polyglot static/clib.c b/test cases/rust/5 polyglot static/clib.c
new file mode 100644
index 0000000..366dbe5
--- /dev/null
+++ b/test cases/rust/5 polyglot static/clib.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+void hello_from_rust(void);
+
+static void hello_from_c(void) {
+ printf("Hello from C!\n");
+}
+
+void hello_from_both(void) {
+ hello_from_c();
+ hello_from_rust();
+}
diff --git a/test cases/rust/5 polyglot static/meson.build b/test cases/rust/5 polyglot static/meson.build
new file mode 100644
index 0000000..bed7977
--- /dev/null
+++ b/test cases/rust/5 polyglot static/meson.build
@@ -0,0 +1,18 @@
+project('static rust and c polyglot executable', 'c', 'rust')
+
+deps = [
+ meson.get_compiler('c').find_library('dl', required: false),
+ meson.get_compiler('c').find_library('m', required: false),
+ dependency('threads'),
+]
+
+extra_winlibs = meson.get_compiler('c').get_id() in ['msvc', 'clang-cl'] ? ['userenv.lib', 'ws2_32.lib', 'bcrypt.lib'] : []
+
+r = static_library('stuff', 'stuff.rs', rust_crate_type : 'staticlib')
+l = static_library('clib', 'clib.c', link_with : r, install : true)
+e = executable('prog', 'prog.c',
+ dependencies: deps,
+ link_with : l,
+ link_args: extra_winlibs,
+ install : true)
+test('polyglottest', e)
diff --git a/test cases/rust/5 polyglot static/prog.c b/test cases/rust/5 polyglot static/prog.c
new file mode 100644
index 0000000..0a8e0d1
--- /dev/null
+++ b/test cases/rust/5 polyglot static/prog.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void hello_from_both();
+
+int main(void) {
+ hello_from_both();
+}
diff --git a/test cases/rust/5 polyglot static/stuff.rs b/test cases/rust/5 polyglot static/stuff.rs
new file mode 100644
index 0000000..3777ae8
--- /dev/null
+++ b/test cases/rust/5 polyglot static/stuff.rs
@@ -0,0 +1,6 @@
+#![crate_name = "stuff"]
+
+#[no_mangle]
+pub extern "C" fn hello_from_rust() {
+ println!("Hello from Rust!");
+}
diff --git a/test cases/rust/5 polyglot static/test.json b/test cases/rust/5 polyglot static/test.json
new file mode 100644
index 0000000..cc0d2da
--- /dev/null
+++ b/test cases/rust/5 polyglot static/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libclib.a"}
+ ]
+}
diff --git a/test cases/rust/6 named staticlib/meson.build b/test cases/rust/6 named staticlib/meson.build
new file mode 100644
index 0000000..f91b7a1
--- /dev/null
+++ b/test cases/rust/6 named staticlib/meson.build
@@ -0,0 +1,5 @@
+project('rust static library', 'rust')
+
+l = static_library('named_stuff', 'stuff.rs', install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+test('linktest', e)
diff --git a/test cases/rust/6 named staticlib/prog.rs b/test cases/rust/6 named staticlib/prog.rs
new file mode 100644
index 0000000..856c4b7
--- /dev/null
+++ b/test cases/rust/6 named staticlib/prog.rs
@@ -0,0 +1,3 @@
+extern crate named_stuff;
+
+fn main() { println!("printing: {}", named_stuff::explore()); }
diff --git a/test cases/rust/6 named staticlib/stuff.rs b/test cases/rust/6 named staticlib/stuff.rs
new file mode 100644
index 0000000..9b36e57
--- /dev/null
+++ b/test cases/rust/6 named staticlib/stuff.rs
@@ -0,0 +1 @@
+pub fn explore() -> &'static str { "librarystring" }
diff --git a/test cases/rust/6 named staticlib/test.json b/test cases/rust/6 named staticlib/test.json
new file mode 100644
index 0000000..3ac3e0b
--- /dev/null
+++ b/test cases/rust/6 named staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libnamed_stuff.rlib"}
+ ]
+}
diff --git a/test cases/rust/7 private crate collision/meson.build b/test cases/rust/7 private crate collision/meson.build
new file mode 100644
index 0000000..81b6aab
--- /dev/null
+++ b/test cases/rust/7 private crate collision/meson.build
@@ -0,0 +1,5 @@
+project('rust private crate collision', 'rust')
+
+l = static_library('rand', 'rand.rs', install : true)
+e = executable('prog', 'prog.rs', link_with : l, install : true)
+test('linktest', e)
diff --git a/test cases/rust/7 private crate collision/prog.rs b/test cases/rust/7 private crate collision/prog.rs
new file mode 100644
index 0000000..b9a30f1
--- /dev/null
+++ b/test cases/rust/7 private crate collision/prog.rs
@@ -0,0 +1,3 @@
+extern crate rand;
+
+fn main() { println!("printing: {}", rand::explore()); }
diff --git a/test cases/rust/7 private crate collision/rand.rs b/test cases/rust/7 private crate collision/rand.rs
new file mode 100644
index 0000000..8a3d427
--- /dev/null
+++ b/test cases/rust/7 private crate collision/rand.rs
@@ -0,0 +1,4 @@
+// use a name that collides with one of the rustc_private libraries
+#![crate_name = "rand"]
+
+pub fn explore() -> &'static str { "librarystring" }
diff --git a/test cases/rust/7 private crate collision/test.json b/test cases/rust/7 private crate collision/test.json
new file mode 100644
index 0000000..e35f6ff
--- /dev/null
+++ b/test cases/rust/7 private crate collision/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/librand.rlib"}
+ ]
+}
diff --git a/test cases/rust/8 many files/foo.rs b/test cases/rust/8 many files/foo.rs
new file mode 100644
index 0000000..0899dc0
--- /dev/null
+++ b/test cases/rust/8 many files/foo.rs
@@ -0,0 +1,3 @@
+pub fn bar() -> () {
+ println!("Hello, world!");
+}
diff --git a/test cases/rust/8 many files/main.rs b/test cases/rust/8 many files/main.rs
new file mode 100644
index 0000000..3ffeee2
--- /dev/null
+++ b/test cases/rust/8 many files/main.rs
@@ -0,0 +1,5 @@
+mod foo;
+
+fn main() {
+ foo::bar();
+}
diff --git a/test cases/rust/8 many files/meson.build b/test cases/rust/8 many files/meson.build
new file mode 100644
index 0000000..1d906b3
--- /dev/null
+++ b/test cases/rust/8 many files/meson.build
@@ -0,0 +1,3 @@
+project('manyfiles', 'rust')
+
+test('manyfiles', executable('manyfiles', 'main.rs', 'foo.rs'))
diff --git a/test cases/rust/9 unit tests/meson.build b/test cases/rust/9 unit tests/meson.build
new file mode 100644
index 0000000..b649abb
--- /dev/null
+++ b/test cases/rust/9 unit tests/meson.build
@@ -0,0 +1,43 @@
+project('rust unit tests', 'rust')
+
+t = executable(
+ 'rust_test',
+ ['test.rs'],
+ rust_args : ['--test'],
+)
+
+test(
+ 'rust test (should fail)',
+ t,
+ protocol : 'rust',
+ suite : ['foo'],
+ should_fail : true,
+)
+
+test(
+ 'rust test (should pass)',
+ t,
+ args : ['--skip', 'test_add_intentional_fail'],
+ protocol : 'rust',
+ suite : ['foo'],
+)
+
+
+test(
+ 'rust test (should skip)',
+ t,
+ args : ['--skip', 'test_add'],
+ protocol : 'rust',
+ suite : ['foo'],
+)
+
+exe = executable('rust_exe', ['test2.rs', 'test.rs'])
+
+rust = import('unstable-rust')
+rust.test('rust_test_from_exe', exe, should_fail : true)
+
+lib = static_library('rust_static', ['test.rs'])
+rust.test('rust_test_from_static', lib, args: ['--skip', 'test_add_intentional_fail'])
+
+lib = shared_library('rust_shared', ['test.rs'])
+rust.test('rust_test_from_shared', lib, args: ['--skip', 'test_add_intentional_fail'])
diff --git a/test cases/rust/9 unit tests/test.rs b/test cases/rust/9 unit tests/test.rs
new file mode 100644
index 0000000..0225be5
--- /dev/null
+++ b/test cases/rust/9 unit tests/test.rs
@@ -0,0 +1,24 @@
+pub fn add(a: i32, b: i32) -> i32 {
+ return a + b;
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_add() {
+ assert_eq!(add(1, 2), 3);
+ }
+
+ #[test]
+ fn test_add_intentional_fail() {
+ assert_eq!(add(1, 2), 5);
+ }
+
+ #[test]
+ #[ignore]
+ fn test_add_intentional_fail2() {
+ assert_eq!(add(1, 7), 5);
+ }
+}
diff --git a/test cases/rust/9 unit tests/test2.rs b/test cases/rust/9 unit tests/test2.rs
new file mode 100644
index 0000000..9623c7c
--- /dev/null
+++ b/test cases/rust/9 unit tests/test2.rs
@@ -0,0 +1,11 @@
+mod test;
+use std::env;
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ let first = args[1].parse::<i32>().expect("Invliad value for first argument.");
+ let second = args[2].parse::<i32>().expect("Invliad value for second argument.");
+
+ let new = test::add(first, second);
+ println!("New value: {}", new);
+}
diff --git a/test cases/swift/1 exe/main.swift b/test cases/swift/1 exe/main.swift
new file mode 100644
index 0000000..1b489de
--- /dev/null
+++ b/test cases/swift/1 exe/main.swift
@@ -0,0 +1 @@
+print("Swift executable is working.")
diff --git a/test cases/swift/1 exe/meson.build b/test cases/swift/1 exe/meson.build
new file mode 100644
index 0000000..4436a8e
--- /dev/null
+++ b/test cases/swift/1 exe/meson.build
@@ -0,0 +1,3 @@
+project('swift exe', 'swift')
+
+test('swifttest', executable('swifttest', 'main.swift'))
diff --git a/test cases/swift/2 multifile/libfile.swift b/test cases/swift/2 multifile/libfile.swift
new file mode 100644
index 0000000..45f941c
--- /dev/null
+++ b/test cases/swift/2 multifile/libfile.swift
@@ -0,0 +1,3 @@
+func printSomething(text: String) {
+ print("Got this: \(text)")
+}
diff --git a/test cases/swift/2 multifile/main.swift b/test cases/swift/2 multifile/main.swift
new file mode 100644
index 0000000..9867e85
--- /dev/null
+++ b/test cases/swift/2 multifile/main.swift
@@ -0,0 +1,5 @@
+#if swift(>=3.0)
+printSomething(text:"String from main")
+#else
+printSomething("String from main")
+#endif
diff --git a/test cases/swift/2 multifile/meson.build b/test cases/swift/2 multifile/meson.build
new file mode 100644
index 0000000..9012f3d
--- /dev/null
+++ b/test cases/swift/2 multifile/meson.build
@@ -0,0 +1,3 @@
+project('2 files', 'swift')
+
+test('2files', executable('twofiles', 'main.swift', 'libfile.swift'))
diff --git a/test cases/swift/3 library/exe/main.swift b/test cases/swift/3 library/exe/main.swift
new file mode 100644
index 0000000..c5de373
--- /dev/null
+++ b/test cases/swift/3 library/exe/main.swift
@@ -0,0 +1,7 @@
+import DataSource
+
+let data = getData()
+let data2 = getOther()
+
+print("String from module: \(data)")
+print("Other string: \(data2)")
diff --git a/test cases/swift/3 library/exe/meson.build b/test cases/swift/3 library/exe/meson.build
new file mode 100644
index 0000000..6c13957
--- /dev/null
+++ b/test cases/swift/3 library/exe/meson.build
@@ -0,0 +1,2 @@
+exe = executable('dataprog', 'main.swift', link_with : datasource)
+test('dataprog', exe)
diff --git a/test cases/swift/3 library/lib/datasource.swift b/test cases/swift/3 library/lib/datasource.swift
new file mode 100644
index 0000000..4ac7c2a
--- /dev/null
+++ b/test cases/swift/3 library/lib/datasource.swift
@@ -0,0 +1,3 @@
+public func getData() -> String {
+ return "String from module."
+}
diff --git a/test cases/swift/3 library/lib/meson.build b/test cases/swift/3 library/lib/meson.build
new file mode 100644
index 0000000..fc65556
--- /dev/null
+++ b/test cases/swift/3 library/lib/meson.build
@@ -0,0 +1 @@
+datasource = static_library('DataSource', 'datasource.swift', 'othersource.swift')
diff --git a/test cases/swift/3 library/lib/othersource.swift b/test cases/swift/3 library/lib/othersource.swift
new file mode 100644
index 0000000..fb668ba
--- /dev/null
+++ b/test cases/swift/3 library/lib/othersource.swift
@@ -0,0 +1,3 @@
+public func getOther() -> String {
+ return "String from other source."
+}
diff --git a/test cases/swift/3 library/meson.build b/test cases/swift/3 library/meson.build
new file mode 100644
index 0000000..d601721
--- /dev/null
+++ b/test cases/swift/3 library/meson.build
@@ -0,0 +1,4 @@
+project('linking', 'swift')
+
+subdir('lib')
+subdir('exe')
diff --git a/test cases/swift/4 generate/gen/main.swift b/test cases/swift/4 generate/gen/main.swift
new file mode 100644
index 0000000..03acdbb
--- /dev/null
+++ b/test cases/swift/4 generate/gen/main.swift
@@ -0,0 +1,18 @@
+#if os(OSX)
+ import Darwin
+#else
+ import Glibc
+#endif
+
+#if swift(>=3.0)
+let fname = CommandLine.arguments[1]
+#else
+let fname = Process.arguments[1]
+#endif
+let code = "public func getGenerated() -> Int {\n return 42\n}\n"
+
+let f = fopen(fname, "w")
+
+fwrite(code, 1, Int(strlen(code)), f)
+print("Name: \(fname)")
+fclose(f)
diff --git a/test cases/swift/4 generate/gen/meson.build b/test cases/swift/4 generate/gen/meson.build
new file mode 100644
index 0000000..8cd7e04
--- /dev/null
+++ b/test cases/swift/4 generate/gen/meson.build
@@ -0,0 +1,6 @@
+gen = executable('gen', 'main.swift')
+
+srcs = custom_target('gensrc',
+ output : 'gen.swift',
+ command : [gen, '@OUTPUT@']
+)
diff --git a/test cases/swift/4 generate/meson.build b/test cases/swift/4 generate/meson.build
new file mode 100644
index 0000000..ccc7d5c
--- /dev/null
+++ b/test cases/swift/4 generate/meson.build
@@ -0,0 +1,4 @@
+project('swift generator', 'swift')
+
+subdir('gen')
+subdir('user')
diff --git a/test cases/swift/4 generate/user/main.swift b/test cases/swift/4 generate/user/main.swift
new file mode 100644
index 0000000..e6b46cd
--- /dev/null
+++ b/test cases/swift/4 generate/user/main.swift
@@ -0,0 +1,3 @@
+let generated = getGenerated()
+
+print("Generated number is: \(generated).")
diff --git a/test cases/swift/4 generate/user/meson.build b/test cases/swift/4 generate/user/meson.build
new file mode 100644
index 0000000..fc4722d
--- /dev/null
+++ b/test cases/swift/4 generate/user/meson.build
@@ -0,0 +1,2 @@
+user = executable('user', 'main.swift', srcs)
+test('User test', user)
diff --git a/test cases/swift/5 mixed/main.swift b/test cases/swift/5 mixed/main.swift
new file mode 100644
index 0000000..5574126
--- /dev/null
+++ b/test cases/swift/5 mixed/main.swift
@@ -0,0 +1,3 @@
+let num = getNumber()
+
+print("The number returned from C code is: \(num).")
diff --git a/test cases/swift/5 mixed/meson.build b/test cases/swift/5 mixed/meson.build
new file mode 100644
index 0000000..71cb99d
--- /dev/null
+++ b/test cases/swift/5 mixed/meson.build
@@ -0,0 +1,6 @@
+project('mixed', 'c', 'swift')
+
+lib = static_library('mylib', 'mylib.c')
+exe = executable('prog', 'main.swift', 'mylib.h',
+ link_with : lib)
+test('c interface', exe)
diff --git a/test cases/swift/5 mixed/mylib.c b/test cases/swift/5 mixed/mylib.c
new file mode 100644
index 0000000..e091836
--- /dev/null
+++ b/test cases/swift/5 mixed/mylib.c
@@ -0,0 +1,5 @@
+#include"mylib.h"
+
+int getNumber() {
+ return 42;
+}
diff --git a/test cases/swift/5 mixed/mylib.h b/test cases/swift/5 mixed/mylib.h
new file mode 100644
index 0000000..21bd9eb
--- /dev/null
+++ b/test cases/swift/5 mixed/mylib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int getNumber();
diff --git a/test cases/swift/6 modulemap/main.swift b/test cases/swift/6 modulemap/main.swift
new file mode 100644
index 0000000..1a38c25
--- /dev/null
+++ b/test cases/swift/6 modulemap/main.swift
@@ -0,0 +1,5 @@
+import mylib
+
+let num = getNumber()
+
+print("The number returned from C code is: \(num).")
diff --git a/test cases/swift/6 modulemap/meson.build b/test cases/swift/6 modulemap/meson.build
new file mode 100644
index 0000000..f1c90db
--- /dev/null
+++ b/test cases/swift/6 modulemap/meson.build
@@ -0,0 +1,8 @@
+project('mixed', 'c', 'swift')
+
+i = include_directories('.')
+lib = static_library('mylib', 'mylib.c')
+exe = executable('prog', 'main.swift',
+ include_directories : [i],
+ link_with : lib)
+test('c module', exe)
diff --git a/test cases/swift/6 modulemap/module.modulemap b/test cases/swift/6 modulemap/module.modulemap
new file mode 100644
index 0000000..5aab62e
--- /dev/null
+++ b/test cases/swift/6 modulemap/module.modulemap
@@ -0,0 +1,5 @@
+module mylib [extern_c] {
+ header "mylib.h"
+ link "mylib"
+ export *
+}
diff --git a/test cases/swift/6 modulemap/mylib.c b/test cases/swift/6 modulemap/mylib.c
new file mode 100644
index 0000000..e091836
--- /dev/null
+++ b/test cases/swift/6 modulemap/mylib.c
@@ -0,0 +1,5 @@
+#include"mylib.h"
+
+int getNumber() {
+ return 42;
+}
diff --git a/test cases/swift/6 modulemap/mylib.h b/test cases/swift/6 modulemap/mylib.h
new file mode 100644
index 0000000..21bd9eb
--- /dev/null
+++ b/test cases/swift/6 modulemap/mylib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int getNumber();
diff --git a/test cases/swift/7 modulemap subdir/main.swift b/test cases/swift/7 modulemap subdir/main.swift
new file mode 100644
index 0000000..1a38c25
--- /dev/null
+++ b/test cases/swift/7 modulemap subdir/main.swift
@@ -0,0 +1,5 @@
+import mylib
+
+let num = getNumber()
+
+print("The number returned from C code is: \(num).")
diff --git a/test cases/swift/7 modulemap subdir/meson.build b/test cases/swift/7 modulemap subdir/meson.build
new file mode 100644
index 0000000..cd769eb
--- /dev/null
+++ b/test cases/swift/7 modulemap subdir/meson.build
@@ -0,0 +1,6 @@
+project('mixed', 'c', 'swift')
+add_project_arguments('-embed-bitcode', language : 'swift')
+subdir('mylib')
+exe = executable('prog', 'main.swift',
+ dependencies : dep)
+test('c module', exe)
diff --git a/test cases/swift/7 modulemap subdir/mylib/meson.build b/test cases/swift/7 modulemap subdir/mylib/meson.build
new file mode 100644
index 0000000..2549e2b
--- /dev/null
+++ b/test cases/swift/7 modulemap subdir/mylib/meson.build
@@ -0,0 +1,4 @@
+
+i = include_directories('.')
+lib = static_library('mylib', 'mylib.c')
+dep = declare_dependency(include_directories : i, link_with : lib)
diff --git a/test cases/swift/7 modulemap subdir/mylib/module.modulemap b/test cases/swift/7 modulemap subdir/mylib/module.modulemap
new file mode 100644
index 0000000..5aab62e
--- /dev/null
+++ b/test cases/swift/7 modulemap subdir/mylib/module.modulemap
@@ -0,0 +1,5 @@
+module mylib [extern_c] {
+ header "mylib.h"
+ link "mylib"
+ export *
+}
diff --git a/test cases/swift/7 modulemap subdir/mylib/mylib.c b/test cases/swift/7 modulemap subdir/mylib/mylib.c
new file mode 100644
index 0000000..e091836
--- /dev/null
+++ b/test cases/swift/7 modulemap subdir/mylib/mylib.c
@@ -0,0 +1,5 @@
+#include"mylib.h"
+
+int getNumber() {
+ return 42;
+}
diff --git a/test cases/swift/7 modulemap subdir/mylib/mylib.h b/test cases/swift/7 modulemap subdir/mylib/mylib.h
new file mode 100644
index 0000000..21bd9eb
--- /dev/null
+++ b/test cases/swift/7 modulemap subdir/mylib/mylib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int getNumber();
diff --git a/test cases/unit/1 soname/CMakeLists.txt b/test cases/unit/1 soname/CMakeLists.txt
new file mode 100644
index 0000000..c4f2e3e
--- /dev/null
+++ b/test cases/unit/1 soname/CMakeLists.txt
@@ -0,0 +1,26 @@
+# This is a CMake version of this test. It behaves slightly differently
+# so in case you ever need to debug this, here it is.
+#
+# The biggest difference is that if SOVERSION is not set, it
+# is set to VERSION. Autotools sets it to the first number
+# of VERSION. That is, for version number 1.2.3 CMake sets
+# soname to 1.2.3 but Autotools sets it to 1.
+
+project(vertest C)
+cmake_minimum_required(VERSION 3.5)
+
+add_library(nover SHARED versioned.c)
+
+add_library(verset SHARED versioned.c)
+set_target_properties(verset PROPERTIES VERSION 4.5.6)
+
+add_library(soverset SHARED versioned.c)
+set_target_properties(soverset PROPERTIES SOVERSION 1.2.3)
+
+add_library(bothset SHARED versioned.c)
+set_target_properties(bothset PROPERTIES SOVERSION 1.2.3)
+set_target_properties(bothset PROPERTIES VERSION 4.5.6)
+
+add_library(settosame SHARED versioned.c)
+set_target_properties(settosame PROPERTIES SOVERSION 7.8.9)
+set_target_properties(settosame PROPERTIES VERSION 7.8.9)
diff --git a/test cases/unit/1 soname/main.c b/test cases/unit/1 soname/main.c
new file mode 100644
index 0000000..f5ccbb9
--- /dev/null
+++ b/test cases/unit/1 soname/main.c
@@ -0,0 +1,5 @@
+int versioned_func (void);
+
+int main (void) {
+ return versioned_func();
+}
diff --git a/test cases/unit/1 soname/meson.build b/test cases/unit/1 soname/meson.build
new file mode 100644
index 0000000..44b003a
--- /dev/null
+++ b/test cases/unit/1 soname/meson.build
@@ -0,0 +1,35 @@
+project('vertest', 'c')
+
+shared_library('nover', 'versioned.c',
+ install : true)
+
+shared_library('verset', 'versioned.c',
+ install : true,
+ version : '4.5.6')
+
+shared_library('soverset', 'versioned.c',
+ install : true,
+ soversion : '1.2.3')
+
+shared_library('bothset', 'versioned.c',
+ install : true,
+ soversion : '1.2.3',
+ version : '4.5.6')
+
+shared_library('settosame', 'versioned.c',
+ install : true,
+ soversion : '7.8.9',
+ version : '7.8.9')
+
+shared_module('some_module', 'versioned.c',
+ install: true)
+
+module1 = shared_module('linked_module1', 'versioned.c',
+ install: true)
+
+module2 = shared_module('linked_module2', 'versioned.c',
+ install: true)
+module2_dep = declare_dependency(link_with: module2)
+
+executable('main1', 'main.c', link_with: module1)
+executable('main2', 'main.c', dependencies: module2_dep)
diff --git a/test cases/unit/1 soname/versioned.c b/test cases/unit/1 soname/versioned.c
new file mode 100644
index 0000000..f48d2b0
--- /dev/null
+++ b/test cases/unit/1 soname/versioned.c
@@ -0,0 +1,3 @@
+int versioned_func() {
+ return 0;
+}
diff --git a/test cases/unit/10 build_rpath/meson.build b/test cases/unit/10 build_rpath/meson.build
new file mode 100644
index 0000000..c0bc3bd
--- /dev/null
+++ b/test cases/unit/10 build_rpath/meson.build
@@ -0,0 +1,16 @@
+project('build rpath', 'c', 'cpp')
+
+subdir('sub')
+executable('prog', 'prog.c',
+ link_with : l,
+ build_rpath : '/foo/bar',
+ install_rpath : '/baz',
+ install : true,
+ )
+
+executable('progcxx', 'prog.cc',
+ link_with : l,
+ build_rpath : '/foo/bar',
+ install_rpath : 'baz',
+ install : true,
+ )
diff --git a/test cases/unit/10 build_rpath/prog.c b/test cases/unit/10 build_rpath/prog.c
new file mode 100644
index 0000000..45b2fa3
--- /dev/null
+++ b/test cases/unit/10 build_rpath/prog.c
@@ -0,0 +1,5 @@
+int get_stuff();
+
+int main(int argc, char **argv) {
+ return get_stuff();
+}
diff --git a/test cases/unit/10 build_rpath/prog.cc b/test cases/unit/10 build_rpath/prog.cc
new file mode 100644
index 0000000..c7c2123
--- /dev/null
+++ b/test cases/unit/10 build_rpath/prog.cc
@@ -0,0 +1,8 @@
+#include <string>
+#include <iostream>
+
+int main(int argc, char **argv) {
+ std::string* s = new std::string("Hello");
+ delete s;
+ return 0;
+}
diff --git a/test cases/unit/10 build_rpath/sub/meson.build b/test cases/unit/10 build_rpath/sub/meson.build
new file mode 100644
index 0000000..6879ec6
--- /dev/null
+++ b/test cases/unit/10 build_rpath/sub/meson.build
@@ -0,0 +1 @@
+l = shared_library('stuff', 'stuff.c')
diff --git a/test cases/unit/10 build_rpath/sub/stuff.c b/test cases/unit/10 build_rpath/sub/stuff.c
new file mode 100644
index 0000000..d56d8b0
--- /dev/null
+++ b/test cases/unit/10 build_rpath/sub/stuff.c
@@ -0,0 +1,3 @@
+int get_stuff() {
+ return 0;
+}
diff --git a/test cases/unit/100 relative find program/foo.py b/test cases/unit/100 relative find program/foo.py
new file mode 100755
index 0000000..21239b7
--- /dev/null
+++ b/test cases/unit/100 relative find program/foo.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+exit(0) \ No newline at end of file
diff --git a/test cases/unit/100 relative find program/meson.build b/test cases/unit/100 relative find program/meson.build
new file mode 100644
index 0000000..5745d8a
--- /dev/null
+++ b/test cases/unit/100 relative find program/meson.build
@@ -0,0 +1,3 @@
+project('relative find program')
+
+subdir('subdir') \ No newline at end of file
diff --git a/test cases/unit/100 relative find program/subdir/meson.build b/test cases/unit/100 relative find program/subdir/meson.build
new file mode 100644
index 0000000..475f5f5
--- /dev/null
+++ b/test cases/unit/100 relative find program/subdir/meson.build
@@ -0,0 +1,2 @@
+prog = find_program('./foo.py', required: false)
+assert(not prog.found()) \ No newline at end of file
diff --git a/test cases/unit/101 rlib linkage/lib2.rs b/test cases/unit/101 rlib linkage/lib2.rs
new file mode 100644
index 0000000..3487bc5
--- /dev/null
+++ b/test cases/unit/101 rlib linkage/lib2.rs
@@ -0,0 +1,5 @@
+use lib;
+
+pub fn fun() {
+ lib::fun();
+}
diff --git a/test cases/unit/101 rlib linkage/main.rs b/test cases/unit/101 rlib linkage/main.rs
new file mode 100644
index 0000000..d0f82e4
--- /dev/null
+++ b/test cases/unit/101 rlib linkage/main.rs
@@ -0,0 +1,5 @@
+use lib2::fun;
+
+fn main() {
+ fun();
+}
diff --git a/test cases/unit/101 rlib linkage/meson.build b/test cases/unit/101 rlib linkage/meson.build
new file mode 100644
index 0000000..2d15b2a
--- /dev/null
+++ b/test cases/unit/101 rlib linkage/meson.build
@@ -0,0 +1,22 @@
+project('rlib linkage', 'rust', default_options : ['rust_std=2018'])
+
+lib = static_library(
+ 'lib',
+ 'lib.rs',
+ rust_crate_type : 'rlib',
+)
+
+lib2 = static_library(
+ 'lib2',
+ 'lib2.rs',
+ rust_crate_type : 'rlib',
+ link_with : lib,
+)
+
+exe = executable(
+ 'exe',
+ 'main.rs',
+ link_with : lib2,
+)
+
+test('main', exe)
diff --git a/test cases/unit/102 python without pkgconfig/meson.build b/test cases/unit/102 python without pkgconfig/meson.build
new file mode 100644
index 0000000..014a617
--- /dev/null
+++ b/test cases/unit/102 python without pkgconfig/meson.build
@@ -0,0 +1,4 @@
+project('python without pkgconfig', 'c')
+
+# This unit test is ran with PKG_CONFIG=notfound
+import('python').find_installation().dependency()
diff --git a/test cases/unit/103 strip/lib.c b/test cases/unit/103 strip/lib.c
new file mode 100644
index 0000000..7d8163c
--- /dev/null
+++ b/test cases/unit/103 strip/lib.c
@@ -0,0 +1,3 @@
+#include <stdio.h>
+
+void func(void){ fprintf(stderr, "Test 1 2 3\n"); }
diff --git a/test cases/unit/103 strip/meson.build b/test cases/unit/103 strip/meson.build
new file mode 100644
index 0000000..dff61ab
--- /dev/null
+++ b/test cases/unit/103 strip/meson.build
@@ -0,0 +1,3 @@
+project('strip', 'c')
+
+shared_library('a', 'lib.c', install: true)
diff --git a/test cases/unit/104 debug function/meson.build b/test cases/unit/104 debug function/meson.build
new file mode 100644
index 0000000..c3f4c76
--- /dev/null
+++ b/test cases/unit/104 debug function/meson.build
@@ -0,0 +1,4 @@
+project('debug function', 'c')
+
+debug('This is an example debug output, should only end up in debug log')
+debug('Test logging other things', true, 1, ['Array'], {'Key' : 'Value'})
diff --git a/test cases/unit/105 pkgconfig relocatable with absolute path/meson.build b/test cases/unit/105 pkgconfig relocatable with absolute path/meson.build
new file mode 100644
index 0000000..ff21286
--- /dev/null
+++ b/test cases/unit/105 pkgconfig relocatable with absolute path/meson.build
@@ -0,0 +1,15 @@
+project(
+ 'pkgconfig-relocatable-with-absolute-path',
+ version : '1.0',
+ default_options: [
+ 'pkgconfig.relocatable=true',
+ ])
+
+pkgg = import('pkgconfig')
+
+pkgg.generate(
+ name : 'libsimple',
+ version : '1.0',
+ description : 'A simple pkgconfig.',
+ install_dir: get_option('prefix')/'share/misc/pkgconfig',
+)
diff --git a/test cases/unit/106 subproject symlink/cp.py b/test cases/unit/106 subproject symlink/cp.py
new file mode 100644
index 0000000..adb0547
--- /dev/null
+++ b/test cases/unit/106 subproject symlink/cp.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+from sys import argv
+from shutil import copy
+
+copy(argv[1], argv[2])
diff --git a/test cases/unit/106 subproject symlink/main.c b/test cases/unit/106 subproject symlink/main.c
new file mode 100644
index 0000000..62bd4b4
--- /dev/null
+++ b/test cases/unit/106 subproject symlink/main.c
@@ -0,0 +1,6 @@
+extern int foo(void);
+
+int main(void)
+{
+ return foo();
+}
diff --git a/test cases/unit/106 subproject symlink/meson.build b/test cases/unit/106 subproject symlink/meson.build
new file mode 100644
index 0000000..6766c8e
--- /dev/null
+++ b/test cases/unit/106 subproject symlink/meson.build
@@ -0,0 +1,15 @@
+project('foo', 'c')
+
+symlinked_subproject = subproject('symlinked_subproject').get_variable('dep')
+
+executable('foo',
+ sources : 'main.c',
+ dependencies : symlinked_subproject
+)
+
+custom_target(
+ input : symlinked_subproject.get_variable('datadir') / 'datafile',
+ output : 'datafile_copy',
+ command : [find_program('cp.py'), '@INPUT@', '@OUTPUT@'],
+ build_always : true
+)
diff --git a/test cases/unit/106 subproject symlink/symlinked_subproject/datadir/datafile b/test cases/unit/106 subproject symlink/symlinked_subproject/datadir/datafile
new file mode 100644
index 0000000..6a68294
--- /dev/null
+++ b/test cases/unit/106 subproject symlink/symlinked_subproject/datadir/datafile
@@ -0,0 +1 @@
+hello meson
diff --git a/test cases/unit/106 subproject symlink/symlinked_subproject/datadir/meson.build b/test cases/unit/106 subproject symlink/symlinked_subproject/datadir/meson.build
new file mode 100644
index 0000000..cbeb0a9
--- /dev/null
+++ b/test cases/unit/106 subproject symlink/symlinked_subproject/datadir/meson.build
@@ -0,0 +1 @@
+install_data('datafile')
diff --git a/test cases/unit/106 subproject symlink/symlinked_subproject/meson.build b/test cases/unit/106 subproject symlink/symlinked_subproject/meson.build
new file mode 100644
index 0000000..3930465
--- /dev/null
+++ b/test cases/unit/106 subproject symlink/symlinked_subproject/meson.build
@@ -0,0 +1,10 @@
+project('symlinked_subproject', 'c', version : '1.0.0')
+
+dep = declare_dependency(
+ sources : 'src.c',
+ variables : {
+ 'datadir': meson.current_source_dir() / 'datadir'
+ }
+)
+
+subdir('datadir')
diff --git a/test cases/unit/106 subproject symlink/symlinked_subproject/src.c b/test cases/unit/106 subproject symlink/symlinked_subproject/src.c
new file mode 100644
index 0000000..97d7ad1
--- /dev/null
+++ b/test cases/unit/106 subproject symlink/symlinked_subproject/src.c
@@ -0,0 +1,4 @@
+int foo(void)
+{
+ return 0;
+}
diff --git a/test cases/unit/107 new subproject on reconfigure/meson.build b/test cases/unit/107 new subproject on reconfigure/meson.build
new file mode 100644
index 0000000..7342c9a
--- /dev/null
+++ b/test cases/unit/107 new subproject on reconfigure/meson.build
@@ -0,0 +1,3 @@
+project('New subproject on reconfigure')
+
+subproject('foo', required: get_option('foo'))
diff --git a/test cases/unit/107 new subproject on reconfigure/meson_options.txt b/test cases/unit/107 new subproject on reconfigure/meson_options.txt
new file mode 100644
index 0000000..b3dd683
--- /dev/null
+++ b/test cases/unit/107 new subproject on reconfigure/meson_options.txt
@@ -0,0 +1 @@
+option('foo', type: 'feature', value: 'disabled')
diff --git a/test cases/unit/107 new subproject on reconfigure/subprojects/foo/foo.c b/test cases/unit/107 new subproject on reconfigure/subprojects/foo/foo.c
new file mode 100644
index 0000000..1edf995
--- /dev/null
+++ b/test cases/unit/107 new subproject on reconfigure/subprojects/foo/foo.c
@@ -0,0 +1,2 @@
+void foo(void);
+void foo(void) {}
diff --git a/test cases/unit/107 new subproject on reconfigure/subprojects/foo/meson.build b/test cases/unit/107 new subproject on reconfigure/subprojects/foo/meson.build
new file mode 100644
index 0000000..2a6e30a
--- /dev/null
+++ b/test cases/unit/107 new subproject on reconfigure/subprojects/foo/meson.build
@@ -0,0 +1,8 @@
+project('foo', 'c')
+
+# Ensure that builtin options have been initialised.
+assert(get_option('default_library') == 'shared')
+
+# This uses default_library option internally and used to cause a crash:
+# https://github.com/mesonbuild/meson/issues/10225.
+library('foo', 'foo.c')
diff --git a/test cases/unit/108 configure same noop/meson.build b/test cases/unit/108 configure same noop/meson.build
new file mode 100644
index 0000000..d3f1326
--- /dev/null
+++ b/test cases/unit/108 configure same noop/meson.build
@@ -0,0 +1 @@
+project('configure same noop test')
diff --git a/test cases/unit/108 configure same noop/meson_options.txt b/test cases/unit/108 configure same noop/meson_options.txt
new file mode 100644
index 0000000..c406af2
--- /dev/null
+++ b/test cases/unit/108 configure same noop/meson_options.txt
@@ -0,0 +1,5 @@
+option(
+ 'opt',
+ type : 'string',
+ value: '',
+)
diff --git a/test cases/unit/109 freeze/freeze.c b/test cases/unit/109 freeze/freeze.c
new file mode 100644
index 0000000..0a45c1a
--- /dev/null
+++ b/test cases/unit/109 freeze/freeze.c
@@ -0,0 +1,21 @@
+#include<stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+
+static void do_nothing(int signo, siginfo_t *info, void *context) {
+}
+
+int main(int argc, char **argv) {
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_sigaction = do_nothing;
+ if (sigaction(SIGTERM, &sa, NULL) == -1) {
+ printf("Could not set up signal handler.\n");
+ return 1;
+ }
+ printf("Freezing forever.\n");
+ while(1) {
+ }
+ return 0;
+}
diff --git a/test cases/unit/109 freeze/meson.build b/test cases/unit/109 freeze/meson.build
new file mode 100644
index 0000000..1a84f37
--- /dev/null
+++ b/test cases/unit/109 freeze/meson.build
@@ -0,0 +1,4 @@
+project('freeze', 'c')
+
+e = executable('freeze', 'freeze.c')
+test('freeze', e, timeout: 1)
diff --git a/test cases/unit/11 cross prog/meson.build b/test cases/unit/11 cross prog/meson.build
new file mode 100644
index 0000000..192169a
--- /dev/null
+++ b/test cases/unit/11 cross prog/meson.build
@@ -0,0 +1,16 @@
+project('cross find program', 'c')
+
+native_exe = find_program('sometool.py', native : true)
+cross_exe = find_program('sometool.py')
+cross_other_exe = find_program('someothertool.py')
+
+native_out = run_command(native_exe, check: true).stdout().strip()
+cross_out = run_command(cross_exe, check: true).stdout().strip()
+cross_other_out = run_command(cross_other_exe, check: true).stdout().strip()
+
+assert(native_out == 'native',
+ 'Native output incorrect:' + native_out)
+assert(cross_out == 'cross',
+ 'Cross output incorrect:' + cross_out)
+assert(cross_out == cross_other_out,
+ 'Cross output incorrect:' + cross_other_out)
diff --git a/test cases/unit/11 cross prog/some_cross_tool.py b/test cases/unit/11 cross prog/some_cross_tool.py
new file mode 100755
index 0000000..6c01b1a
--- /dev/null
+++ b/test cases/unit/11 cross prog/some_cross_tool.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+
+print('cross')
diff --git a/test cases/unit/11 cross prog/sometool.py b/test cases/unit/11 cross prog/sometool.py
new file mode 100755
index 0000000..06bcdc8
--- /dev/null
+++ b/test cases/unit/11 cross prog/sometool.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+
+print('native')
diff --git a/test cases/unit/110 classpath/com/mesonbuild/Simple.java b/test cases/unit/110 classpath/com/mesonbuild/Simple.java
new file mode 100644
index 0000000..325a49a
--- /dev/null
+++ b/test cases/unit/110 classpath/com/mesonbuild/Simple.java
@@ -0,0 +1,7 @@
+package com.mesonbuild;
+
+class Simple {
+ public static void main(String [] args) {
+ System.out.println("Java is working.\n");
+ }
+}
diff --git a/test cases/unit/110 classpath/meson.build b/test cases/unit/110 classpath/meson.build
new file mode 100644
index 0000000..e6b9b84
--- /dev/null
+++ b/test cases/unit/110 classpath/meson.build
@@ -0,0 +1,14 @@
+project('simplejava', 'java')
+
+one = jar('one', 'com/mesonbuild/Simple.java',
+ main_class : 'com.mesonbuild.Simple',
+ install : true,
+ install_dir : get_option('bindir'),
+)
+
+two = jar('two', 'com/mesonbuild/Simple.java',
+ main_class : 'com.mesonbuild.Simple',
+ install : true,
+ install_dir : get_option('bindir'),
+ link_with : one,
+)
diff --git a/test cases/unit/12 promote/meson.build b/test cases/unit/12 promote/meson.build
new file mode 100644
index 0000000..5012bf6
--- /dev/null
+++ b/test cases/unit/12 promote/meson.build
@@ -0,0 +1,4 @@
+project('promotion test', 'c')
+
+subproject('s1')
+subproject('s2')
diff --git a/test cases/unit/12 promote/subprojects/s1/meson.build b/test cases/unit/12 promote/subprojects/s1/meson.build
new file mode 100644
index 0000000..88c467b
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s1/meson.build
@@ -0,0 +1,7 @@
+project('s1', 'c')
+
+sc = subproject('scommon')
+s3 = subproject('s3')
+
+executable('s1', 's1.c',
+ link_with : [sc.get_variable('clib'), s3.get_variable('l')])
diff --git a/test cases/unit/12 promote/subprojects/s1/s1.c b/test cases/unit/12 promote/subprojects/s1/s1.c
new file mode 100644
index 0000000..7d1d775
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s1/s1.c
@@ -0,0 +1,6 @@
+int func();
+int func2();
+
+int main(int argc, char **argv) {
+ return func() + func2();
+}
diff --git a/test cases/unit/12 promote/subprojects/s1/subprojects/s3/meson.build b/test cases/unit/12 promote/subprojects/s1/subprojects/s3/meson.build
new file mode 100644
index 0000000..71db691
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s1/subprojects/s3/meson.build
@@ -0,0 +1,3 @@
+project('s3', 'c')
+
+l = static_library('s3', 's3.c')
diff --git a/test cases/unit/12 promote/subprojects/s1/subprojects/s3/s3.c b/test cases/unit/12 promote/subprojects/s1/subprojects/s3/s3.c
new file mode 100644
index 0000000..0166603
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s1/subprojects/s3/s3.c
@@ -0,0 +1,3 @@
+int func2() {
+ return -42;
+}
diff --git a/test cases/unit/12 promote/subprojects/s1/subprojects/scommon/meson.build b/test cases/unit/12 promote/subprojects/s1/subprojects/scommon/meson.build
new file mode 100644
index 0000000..8ca550a
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s1/subprojects/scommon/meson.build
@@ -0,0 +1,3 @@
+project('scommon', 'c')
+
+clib = static_library('scommon', 'scommon_broken.c')
diff --git a/test cases/unit/12 promote/subprojects/s1/subprojects/scommon/scommon_broken.c b/test cases/unit/12 promote/subprojects/s1/subprojects/scommon/scommon_broken.c
new file mode 100644
index 0000000..3665a9c
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s1/subprojects/scommon/scommon_broken.c
@@ -0,0 +1 @@
+#error This file must not be used. The other scommon one should be instead.
diff --git a/test cases/unit/12 promote/subprojects/s2/meson.build b/test cases/unit/12 promote/subprojects/s2/meson.build
new file mode 100644
index 0000000..4aaeb59
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s2/meson.build
@@ -0,0 +1,5 @@
+project('s2', 'c')
+
+sc = subproject('scommon')
+
+executable('s2', 's2.c', link_with : sc.get_variable('clib'))
diff --git a/test cases/unit/12 promote/subprojects/s2/s2.c b/test cases/unit/12 promote/subprojects/s2/s2.c
new file mode 100644
index 0000000..2a6d1e6
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s2/s2.c
@@ -0,0 +1,6 @@
+int func();
+
+
+int main(int argc, char **argv) {
+ return func() != 42;
+}
diff --git a/test cases/unit/12 promote/subprojects/s2/subprojects/athing.wrap b/test cases/unit/12 promote/subprojects/s2/subprojects/athing.wrap
new file mode 100644
index 0000000..11b2178
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s2/subprojects/athing.wrap
@@ -0,0 +1 @@
+[wrap-file]
diff --git a/test cases/unit/12 promote/subprojects/s2/subprojects/scommon/meson.build b/test cases/unit/12 promote/subprojects/s2/subprojects/scommon/meson.build
new file mode 100644
index 0000000..54049a8
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s2/subprojects/scommon/meson.build
@@ -0,0 +1,3 @@
+project('scommon', 'c')
+
+clib = static_library('scommon', 'scommon_ok.c')
diff --git a/test cases/unit/12 promote/subprojects/s2/subprojects/scommon/scommon_ok.c b/test cases/unit/12 promote/subprojects/s2/subprojects/scommon/scommon_ok.c
new file mode 100644
index 0000000..652f4eb
--- /dev/null
+++ b/test cases/unit/12 promote/subprojects/s2/subprojects/scommon/scommon_ok.c
@@ -0,0 +1,3 @@
+int func() {
+ return 42;
+}
diff --git a/test cases/unit/13 reconfigure/meson.build b/test cases/unit/13 reconfigure/meson.build
new file mode 100644
index 0000000..453644a
--- /dev/null
+++ b/test cases/unit/13 reconfigure/meson.build
@@ -0,0 +1,5 @@
+project('reconfigure test', ['c'])
+
+if get_option('b_coverage') != true
+ error('b_coverage not set')
+endif
diff --git a/test cases/unit/14 testsetup selection/main.c b/test cases/unit/14 testsetup selection/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/unit/14 testsetup selection/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/unit/14 testsetup selection/meson.build b/test cases/unit/14 testsetup selection/meson.build
new file mode 100644
index 0000000..ae996c5
--- /dev/null
+++ b/test cases/unit/14 testsetup selection/meson.build
@@ -0,0 +1,10 @@
+project('main', 'c')
+
+main = executable('main', 'main.c')
+test('Test main', main)
+
+add_test_setup('worksforall')
+add_test_setup('missingfromfoo')
+
+subproject('foo')
+subproject('bar')
diff --git a/test cases/unit/14 testsetup selection/subprojects/bar/bar.c b/test cases/unit/14 testsetup selection/subprojects/bar/bar.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/unit/14 testsetup selection/subprojects/bar/bar.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/unit/14 testsetup selection/subprojects/bar/meson.build b/test cases/unit/14 testsetup selection/subprojects/bar/meson.build
new file mode 100644
index 0000000..1155a88
--- /dev/null
+++ b/test cases/unit/14 testsetup selection/subprojects/bar/meson.build
@@ -0,0 +1,6 @@
+project('bar', 'c')
+bar = executable('bar', 'bar.c')
+test('Test bar', bar)
+add_test_setup('onlyinbar')
+add_test_setup('worksforall')
+add_test_setup('missingfromfoo')
diff --git a/test cases/unit/14 testsetup selection/subprojects/foo/foo.c b/test cases/unit/14 testsetup selection/subprojects/foo/foo.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/unit/14 testsetup selection/subprojects/foo/foo.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/unit/14 testsetup selection/subprojects/foo/meson.build b/test cases/unit/14 testsetup selection/subprojects/foo/meson.build
new file mode 100644
index 0000000..2eef840
--- /dev/null
+++ b/test cases/unit/14 testsetup selection/subprojects/foo/meson.build
@@ -0,0 +1,4 @@
+project('foo', 'c')
+foo = executable('foo', 'foo.c')
+test('Test foo', foo)
+add_test_setup('worksforall')
diff --git a/test cases/unit/15 prebuilt object/cp.py b/test cases/unit/15 prebuilt object/cp.py
new file mode 100644
index 0000000..cb09cf3
--- /dev/null
+++ b/test cases/unit/15 prebuilt object/cp.py
@@ -0,0 +1,5 @@
+#! /usr/bin/env python3
+
+import sys
+from shutil import copyfile
+copyfile(*sys.argv[1:])
diff --git a/test cases/unit/15 prebuilt object/main.c b/test cases/unit/15 prebuilt object/main.c
new file mode 100644
index 0000000..480bda5
--- /dev/null
+++ b/test cases/unit/15 prebuilt object/main.c
@@ -0,0 +1,5 @@
+int func();
+
+int main(int argc, char **argv) {
+ return func() == 42 ? 0 : 99;
+}
diff --git a/test cases/unit/15 prebuilt object/meson.build b/test cases/unit/15 prebuilt object/meson.build
new file mode 100644
index 0000000..b542d1c
--- /dev/null
+++ b/test cases/unit/15 prebuilt object/meson.build
@@ -0,0 +1,40 @@
+# This test is on its own because it is special.
+# To run the test you need the prebuilt object
+# file for the given platform.
+#
+# Combined with cross compilation this would make
+# the state space explode so let's just keep this
+# in its own subdir so it's not run during cross
+# compilation tests.
+
+project('prebuilt object', 'c')
+
+if host_machine.system() == 'windows'
+ prebuilt = 'prebuilt.obj'
+else
+ prebuilt = 'prebuilt.o'
+endif
+
+# Remember: do not put source.c in this
+# declaration. run_tests.py generates the
+# prebuilt object before running this test.
+
+e = []
+
+e += executable('exe1', sources: 'main.c', objects: prebuilt)
+e += executable('exe2', sources: 'main.c', objects: files(prebuilt))
+
+sl1 = static_library('lib3', objects: prebuilt)
+e += executable('exe3', sources: 'main.c', objects: sl1.extract_all_objects(recursive: true))
+
+ct = custom_target(output: 'copy-' + prebuilt, input: prebuilt,
+ command: [find_program('cp.py'), '@INPUT@', '@OUTPUT@'])
+e += executable('exe4', 'main.c', ct)
+e += executable('exe5', 'main.c', ct[0])
+
+sl2 = static_library('lib6', sources: ct)
+e += executable('exe6', sources: 'main.c', objects: sl2.extract_all_objects(recursive: true))
+
+foreach i : e
+ test(i.name(), i)
+endforeach
diff --git a/test cases/unit/15 prebuilt object/source.c b/test cases/unit/15 prebuilt object/source.c
new file mode 100644
index 0000000..f39b4f3
--- /dev/null
+++ b/test cases/unit/15 prebuilt object/source.c
@@ -0,0 +1,8 @@
+/*
+ * Compile this manually on new platforms and add the
+ * object file to revision control and Meson configuration.
+ */
+
+int func() {
+ return 42;
+}
diff --git a/test cases/unit/16 prebuilt static/libdir/best.c b/test cases/unit/16 prebuilt static/libdir/best.c
new file mode 100644
index 0000000..ab774e1
--- /dev/null
+++ b/test cases/unit/16 prebuilt static/libdir/best.c
@@ -0,0 +1,3 @@
+const char *msg() {
+ return "I am the best.";
+}
diff --git a/test cases/unit/16 prebuilt static/libdir/best.h b/test cases/unit/16 prebuilt static/libdir/best.h
new file mode 100644
index 0000000..063017f
--- /dev/null
+++ b/test cases/unit/16 prebuilt static/libdir/best.h
@@ -0,0 +1,3 @@
+#pragma once
+
+const char *msg();
diff --git a/test cases/unit/16 prebuilt static/libdir/meson.build b/test cases/unit/16 prebuilt static/libdir/meson.build
new file mode 100644
index 0000000..8d74ccf
--- /dev/null
+++ b/test cases/unit/16 prebuilt static/libdir/meson.build
@@ -0,0 +1,5 @@
+cc = meson.get_compiler('c')
+stlib = cc.find_library('best', dirs : meson.current_source_dir())
+
+best_dep = declare_dependency(dependencies : stlib,
+ include_directories : include_directories('.'))
diff --git a/test cases/unit/16 prebuilt static/main.c b/test cases/unit/16 prebuilt static/main.c
new file mode 100644
index 0000000..d172625
--- /dev/null
+++ b/test cases/unit/16 prebuilt static/main.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+#include<best.h>
+
+int main(int argc, char **argv) {
+ printf("%s\n", msg());
+ return 0;
+}
diff --git a/test cases/unit/16 prebuilt static/meson.build b/test cases/unit/16 prebuilt static/meson.build
new file mode 100644
index 0000000..9ea1d0d
--- /dev/null
+++ b/test cases/unit/16 prebuilt static/meson.build
@@ -0,0 +1,5 @@
+project('prebuilt static lib', 'c')
+
+subdir('libdir')
+
+test('static', executable('mainprog', 'main.c', dependencies : best_dep))
diff --git a/test cases/unit/17 prebuilt shared/alexandria.c b/test cases/unit/17 prebuilt shared/alexandria.c
new file mode 100644
index 0000000..2d6b848
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/alexandria.c
@@ -0,0 +1,6 @@
+#include"alexandria.h"
+#include<stdio.h>
+
+void alexandria_visit() {
+ printf("You are surrounded by wisdom and knowledge. You feel enlightened.\n");
+}
diff --git a/test cases/unit/17 prebuilt shared/alexandria.h b/test cases/unit/17 prebuilt shared/alexandria.h
new file mode 100644
index 0000000..6e507c5
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/alexandria.h
@@ -0,0 +1,20 @@
+#pragma once
+
+/* Both funcs here for simplicity. */
+
+#if defined _WIN32 || defined __CYGWIN__
+#if defined BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #define DLL_PUBLIC __declspec(dllimport)
+#endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+void DLL_PUBLIC alexandria_visit();
diff --git a/test cases/unit/17 prebuilt shared/another_visitor.c b/test cases/unit/17 prebuilt shared/another_visitor.c
new file mode 100644
index 0000000..18e5f15
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/another_visitor.c
@@ -0,0 +1,10 @@
+#include<alexandria.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("Ahh, another visitor. Stay a while.\n");
+ printf("You enter the library.\n\n");
+ alexandria_visit();
+ printf("\nYou decided not to stay forever.\n");
+ return 0;
+}
diff --git a/test cases/unit/17 prebuilt shared/meson.build b/test cases/unit/17 prebuilt shared/meson.build
new file mode 100644
index 0000000..7badcb7
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/meson.build
@@ -0,0 +1,38 @@
+project('prebuilt shared library', 'c')
+
+search_dir = get_option('search_dir')
+if search_dir == 'auto'
+ search_dir = meson.current_source_dir()
+endif
+
+cc = meson.get_compiler('c')
+shlib = cc.find_library('alexandria', dirs : search_dir)
+
+exe = executable('patron', 'patron.c', dependencies : shlib)
+test('visitation', exe)
+
+d = declare_dependency(dependencies : shlib)
+
+exe2 = executable('another_visitor', 'another_visitor.c',
+ dependencies : d)
+test('another', exe2)
+
+stlib = static_library(
+ 'rejected',
+ 'rejected.c',
+ dependencies : shlib,
+)
+
+rejected = executable(
+ 'rejected',
+ 'rejected_main.c',
+ link_with : stlib,
+)
+test('rejected', rejected)
+
+rejected_whole = executable(
+ 'rejected_whole',
+ 'rejected_main.c',
+ link_whole : stlib,
+)
+test('rejected (whole archive)', rejected_whole)
diff --git a/test cases/unit/17 prebuilt shared/meson_options.txt b/test cases/unit/17 prebuilt shared/meson_options.txt
new file mode 100644
index 0000000..7876a6f
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/meson_options.txt
@@ -0,0 +1 @@
+option('search_dir', type : 'string', value : 'auto')
diff --git a/test cases/unit/17 prebuilt shared/patron.c b/test cases/unit/17 prebuilt shared/patron.c
new file mode 100644
index 0000000..461d7b4
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/patron.c
@@ -0,0 +1,9 @@
+#include<alexandria.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("You are standing outside the Great Library of Alexandria.\n");
+ printf("You decide to go inside.\n\n");
+ alexandria_visit();
+ return 0;
+}
diff --git a/test cases/unit/17 prebuilt shared/rejected.c b/test cases/unit/17 prebuilt shared/rejected.c
new file mode 100644
index 0000000..9d7ac94
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/rejected.c
@@ -0,0 +1,8 @@
+#include "rejected.h"
+
+void say(void) {
+ printf("You are standing outside the Great Library of Alexandria.\n");
+ printf("You decide to go inside.\n\n");
+ alexandria_visit();
+ printf("The librarian tells you it's time to leave\n");
+}
diff --git a/test cases/unit/17 prebuilt shared/rejected.h b/test cases/unit/17 prebuilt shared/rejected.h
new file mode 100644
index 0000000..b9ccf31
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/rejected.h
@@ -0,0 +1,6 @@
+#include <stdio.h>
+#include <alexandria.h>
+
+#pragma once
+
+void say(void);
diff --git a/test cases/unit/17 prebuilt shared/rejected_main.c b/test cases/unit/17 prebuilt shared/rejected_main.c
new file mode 100644
index 0000000..4d35061
--- /dev/null
+++ b/test cases/unit/17 prebuilt shared/rejected_main.c
@@ -0,0 +1,6 @@
+#include "rejected.h"
+
+int main(void) {
+ say();
+ return 0;
+}
diff --git a/test cases/unit/18 pkgconfig static/foo.c b/test cases/unit/18 pkgconfig static/foo.c
new file mode 100644
index 0000000..bf7fbdd
--- /dev/null
+++ b/test cases/unit/18 pkgconfig static/foo.c
@@ -0,0 +1,8 @@
+int power_level (void)
+{
+#ifdef FOO_STATIC
+ return 9001;
+#else
+ return 8999;
+#endif
+}
diff --git a/test cases/unit/18 pkgconfig static/foo.pc.in b/test cases/unit/18 pkgconfig static/foo.pc.in
new file mode 100644
index 0000000..b26c0b0
--- /dev/null
+++ b/test cases/unit/18 pkgconfig static/foo.pc.in
@@ -0,0 +1,11 @@
+prefix=@PREFIX@
+libdir=${prefix}
+includedir=${prefix}/include
+datadir=${prefix}/data
+
+Name: libfoo
+Description: A foo library.
+Version: 1.0
+Libs: -L${libdir} -lfoo
+Libs.private: -lm
+Cflags: -I${includedir}
diff --git a/test cases/unit/18 pkgconfig static/include/foo.h b/test cases/unit/18 pkgconfig static/include/foo.h
new file mode 100644
index 0000000..88ef554
--- /dev/null
+++ b/test cases/unit/18 pkgconfig static/include/foo.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int power_level (void);
diff --git a/test cases/unit/18 pkgconfig static/main.c b/test cases/unit/18 pkgconfig static/main.c
new file mode 100644
index 0000000..cc4649f
--- /dev/null
+++ b/test cases/unit/18 pkgconfig static/main.c
@@ -0,0 +1,14 @@
+#include <foo.h>
+#include <stdio.h>
+
+int
+main (int argc, char * argv[])
+{
+ int value = power_level ();
+ if (value < 9000) {
+ printf ("Power level is %i\n", value);
+ return 1;
+ }
+ printf ("IT'S OVER 9000!!!\n");
+ return 0;
+}
diff --git a/test cases/unit/18 pkgconfig static/meson.build b/test cases/unit/18 pkgconfig static/meson.build
new file mode 100644
index 0000000..d1b0fd5
--- /dev/null
+++ b/test cases/unit/18 pkgconfig static/meson.build
@@ -0,0 +1,37 @@
+project('pkg-config static', 'c')
+
+if build_machine.system() != 'windows'
+ prefix = meson.source_root()
+else
+ # pkg-config files should not use paths with \
+ prefix_parts = meson.source_root().split('\\')
+ # If the path is C:/foo/bar, convert it to /c/foo/bar so we can test if our
+ # automatic conversion to C:/foo/bar inside PkgConfigDependency is working.
+ if prefix_parts[0][1] == ':'
+ drive = prefix_parts[0][0]
+ else
+ drive = prefix_parts[0]
+ endif
+ new_parts = []
+ foreach part : prefix_parts
+ if part != prefix_parts[0]
+ new_parts += part
+ endif
+ endforeach
+ prefix = '/@0@/@1@'.format(drive, '/'.join(new_parts))
+endif
+message(prefix)
+
+# Escape spaces
+prefix_parts = prefix.split(' ')
+prefix = '\ '.join(prefix_parts)
+
+conf = configuration_data()
+conf.set('PREFIX', prefix)
+configure_file(input : 'foo.pc.in',
+ output : 'foo.pc',
+ configuration : conf)
+
+foo_dep = dependency('foo', static : true)
+
+test('footest', executable('foomain', 'main.c', dependencies : foo_dep))
diff --git a/test cases/unit/19 array option/meson.build b/test cases/unit/19 array option/meson.build
new file mode 100644
index 0000000..2b44181
--- /dev/null
+++ b/test cases/unit/19 array option/meson.build
@@ -0,0 +1,15 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('array option test')
diff --git a/test cases/unit/19 array option/meson_options.txt b/test cases/unit/19 array option/meson_options.txt
new file mode 100644
index 0000000..0ccdcc4
--- /dev/null
+++ b/test cases/unit/19 array option/meson_options.txt
@@ -0,0 +1,20 @@
+# Copyright © 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+option(
+ 'list',
+ type : 'array',
+ value : ['foo', 'bar'],
+ choices : ['foo', 'bar', 'oink', 'boink'],
+)
diff --git a/test cases/unit/2 testsetups/buggy.c b/test cases/unit/2 testsetups/buggy.c
new file mode 100644
index 0000000..d238830
--- /dev/null
+++ b/test cases/unit/2 testsetups/buggy.c
@@ -0,0 +1,14 @@
+#include<stdio.h>
+#include<stdlib.h>
+
+#include<impl.h>
+
+int main(int argc, char **argv) {
+ char *ten = malloc(10);
+ if(getenv("TEST_ENV")) {
+ do_nasty(ten);
+ printf("TEST_ENV is set.\n");
+ }
+ free(ten);
+ return 0;
+}
diff --git a/test cases/unit/2 testsetups/envcheck.py b/test cases/unit/2 testsetups/envcheck.py
new file mode 100755
index 0000000..e41a715
--- /dev/null
+++ b/test cases/unit/2 testsetups/envcheck.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+
+import os
+
+assert 'PATH' in os.environ
diff --git a/test cases/unit/2 testsetups/impl.c b/test cases/unit/2 testsetups/impl.c
new file mode 100644
index 0000000..d87f3de
--- /dev/null
+++ b/test cases/unit/2 testsetups/impl.c
@@ -0,0 +1,5 @@
+/* Write past the end. */
+
+void do_nasty(char *ptr) {
+ ptr[10] = 'n';
+}
diff --git a/test cases/unit/2 testsetups/impl.h b/test cases/unit/2 testsetups/impl.h
new file mode 100644
index 0000000..7a08cb3
--- /dev/null
+++ b/test cases/unit/2 testsetups/impl.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void do_nasty(char *ptr);
diff --git a/test cases/unit/2 testsetups/meson.build b/test cases/unit/2 testsetups/meson.build
new file mode 100644
index 0000000..91a5fbe
--- /dev/null
+++ b/test cases/unit/2 testsetups/meson.build
@@ -0,0 +1,33 @@
+project('testsetups', 'c')
+
+vg = find_program('valgrind')
+
+cc = meson.get_compiler('c')
+# clang 14 uses dwarf 5, and valgrind 3.19 GIT does not support this
+if cc.get_id() == 'clang' and cc.version().version_compare('>=14') and \
+ vg.version().version_compare('<3.20')
+ add_project_arguments('-gdwarf-4', language: 'c')
+endif
+
+# This is only set when running under Valgrind test setup.
+env = environment()
+env.set('TEST_ENV', '1')
+
+add_test_setup('valgrind',
+ exe_wrapper : [vg, '--error-exitcode=1', '--leak-check=full'],
+ timeout_multiplier : 100,
+ env : env)
+
+buggy = executable('buggy', 'buggy.c', 'impl.c')
+test('Test buggy', buggy, suite: ['buggy'])
+
+envcheck = find_program('envcheck.py')
+test('test-env', envcheck)
+
+add_test_setup('empty')
+add_test_setup('onlyenv', env : env)
+add_test_setup('onlyenv2', env : 'TEST_ENV=1')
+add_test_setup('onlyenv3', env : ['TEST_ENV=1'])
+add_test_setup('wrapper', exe_wrapper : [vg, '--error-exitcode=1'])
+add_test_setup('timeout', timeout_multiplier : 20)
+add_test_setup('good', exclude_suites : 'buggy')
diff --git a/test cases/unit/20 subproj dep variables/meson.build b/test cases/unit/20 subproj dep variables/meson.build
new file mode 100644
index 0000000..954463b
--- /dev/null
+++ b/test cases/unit/20 subproj dep variables/meson.build
@@ -0,0 +1,16 @@
+project('subproj found dep not found', 'c')
+
+dependency('somedep', required : false,
+ fallback : ['nosubproj', 'dep_name'])
+
+dependency('somedep', required : false,
+ fallback : ['failingsubproj', 'dep_name'])
+
+dependency('somenotfounddep', required : false,
+ fallback : ['somesubproj', 'dep_name'])
+
+dependency('zlibproxy', required : true,
+ fallback : ['somesubproj', 'zlibproxy_dep'])
+
+dependency('somedep', required : false,
+ fallback : ['nestedsubproj', 'nestedsubproj_dep'])
diff --git a/test cases/unit/20 subproj dep variables/subprojects/failingsubproj/meson.build b/test cases/unit/20 subproj dep variables/subprojects/failingsubproj/meson.build
new file mode 100644
index 0000000..3a84bd2
--- /dev/null
+++ b/test cases/unit/20 subproj dep variables/subprojects/failingsubproj/meson.build
@@ -0,0 +1,3 @@
+project('failingsubproj', 'c')
+
+dep_name = declare_dependency('arg')
diff --git a/test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/meson.build b/test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/meson.build
new file mode 100644
index 0000000..4bf549e
--- /dev/null
+++ b/test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/meson.build
@@ -0,0 +1,3 @@
+project('dep', 'c')
+
+subproject('subsubproject')
diff --git a/test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/subprojects/subsubproject.wrap b/test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/subprojects/subsubproject.wrap
new file mode 100644
index 0000000..11b2178
--- /dev/null
+++ b/test cases/unit/20 subproj dep variables/subprojects/nestedsubproj/subprojects/subsubproject.wrap
@@ -0,0 +1 @@
+[wrap-file]
diff --git a/test cases/unit/20 subproj dep variables/subprojects/somesubproj/meson.build b/test cases/unit/20 subproj dep variables/subprojects/somesubproj/meson.build
new file mode 100644
index 0000000..dd65c99
--- /dev/null
+++ b/test cases/unit/20 subproj dep variables/subprojects/somesubproj/meson.build
@@ -0,0 +1,3 @@
+project('dep', 'c')
+
+zlibproxy_dep = declare_dependency(dependencies : dependency('zlib', required : false))
diff --git a/test cases/unit/21 exit status/meson.build b/test cases/unit/21 exit status/meson.build
new file mode 100644
index 0000000..4f5485b
--- /dev/null
+++ b/test cases/unit/21 exit status/meson.build
@@ -0,0 +1,2 @@
+project('exit status')
+exception()
diff --git a/test cases/unit/22 warning location/a.c b/test cases/unit/22 warning location/a.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/22 warning location/a.c
diff --git a/test cases/unit/22 warning location/b.c b/test cases/unit/22 warning location/b.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/22 warning location/b.c
diff --git a/test cases/unit/22 warning location/conf.in b/test cases/unit/22 warning location/conf.in
new file mode 100644
index 0000000..a2903ed
--- /dev/null
+++ b/test cases/unit/22 warning location/conf.in
@@ -0,0 +1 @@
+@MISSING@
diff --git a/test cases/unit/22 warning location/main.c b/test cases/unit/22 warning location/main.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/22 warning location/main.c
diff --git a/test cases/unit/22 warning location/meson.build b/test cases/unit/22 warning location/meson.build
new file mode 100644
index 0000000..132939e
--- /dev/null
+++ b/test cases/unit/22 warning location/meson.build
@@ -0,0 +1,11 @@
+project('warning location', 'c')
+a = library('liba', 'a.c')
+b = library('libb', 'b.c')
+executable('main', 'main.c', link_with: a, link_with: b)
+subdir('sub')
+warning('a warning of some sort')
+import('unstable-simd')
+
+conf_data = configuration_data()
+conf_data.set('NOTMISSING', 1)
+configure_file(input: 'conf.in' , output: 'conf', configuration: conf_data)
diff --git a/test cases/unit/22 warning location/sub/c.c b/test cases/unit/22 warning location/sub/c.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/22 warning location/sub/c.c
diff --git a/test cases/unit/22 warning location/sub/d.c b/test cases/unit/22 warning location/sub/d.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/22 warning location/sub/d.c
diff --git a/test cases/unit/22 warning location/sub/meson.build b/test cases/unit/22 warning location/sub/meson.build
new file mode 100644
index 0000000..27f6778
--- /dev/null
+++ b/test cases/unit/22 warning location/sub/meson.build
@@ -0,0 +1,4 @@
+c = library('libc', 'c.c')
+d = library('libd', 'd.c')
+executable('sub', 'sub.c', link_with: c, link_with: d)
+warning('subdir warning')
diff --git a/test cases/unit/22 warning location/sub/sub.c b/test cases/unit/22 warning location/sub/sub.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/22 warning location/sub/sub.c
diff --git a/test cases/unit/23 unfound pkgconfig/meson.build b/test cases/unit/23 unfound pkgconfig/meson.build
new file mode 100644
index 0000000..1285c0a
--- /dev/null
+++ b/test cases/unit/23 unfound pkgconfig/meson.build
@@ -0,0 +1,15 @@
+project('foobar', 'c')
+
+unfound = dependency('blub_blob_blib', required : false)
+
+pkgg = import('pkgconfig')
+
+l = shared_library('somename', 'some.c',
+ dependencies : unfound)
+
+pkgg.generate(
+ libraries : l,
+ name : 'somename',
+ version : '1.0.0',
+ description : 'A test library.',
+)
diff --git a/test cases/unit/23 unfound pkgconfig/some.c b/test cases/unit/23 unfound pkgconfig/some.c
new file mode 100644
index 0000000..fb765fb
--- /dev/null
+++ b/test cases/unit/23 unfound pkgconfig/some.c
@@ -0,0 +1,3 @@
+int some() {
+ return 6;
+}
diff --git a/test cases/unit/24 compiler run_command/meson.build b/test cases/unit/24 compiler run_command/meson.build
new file mode 100644
index 0000000..e99b880
--- /dev/null
+++ b/test cases/unit/24 compiler run_command/meson.build
@@ -0,0 +1,10 @@
+project('compiler_object_in_run_command', 'c')
+cc = meson.get_compiler('c')
+
+# This test only checks that the compiler object can be passed to
+# run_command(). If the compiler has been launched, it is expected
+# to output something either to stdout or to stderr.
+result = run_command(cc, '--version', check: false)
+if result.stdout() == '' and result.stderr() == ''
+ error('No output in stdout and stderr. Did the compiler run at all?')
+endif
diff --git a/test cases/unit/25 non-permitted kwargs/meson.build b/test cases/unit/25 non-permitted kwargs/meson.build
new file mode 100644
index 0000000..287acfd
--- /dev/null
+++ b/test cases/unit/25 non-permitted kwargs/meson.build
@@ -0,0 +1,5 @@
+project('non-permitted kwargs', 'c')
+cc = meson.get_compiler('c')
+cc.has_header_symbol('stdio.h', 'printf', prefixxx: '#define XXX')
+cc.links('int main(void){}', argsxx: '')
+cc.get_id(invalidxx: '')
diff --git a/test cases/unit/26 install umask/datafile.cat b/test cases/unit/26 install umask/datafile.cat
new file mode 100644
index 0000000..53d81fc
--- /dev/null
+++ b/test cases/unit/26 install umask/datafile.cat
@@ -0,0 +1 @@
+Installed cat is installed.
diff --git a/test cases/unit/26 install umask/meson.build b/test cases/unit/26 install umask/meson.build
new file mode 100644
index 0000000..225f71c
--- /dev/null
+++ b/test cases/unit/26 install umask/meson.build
@@ -0,0 +1,7 @@
+project('install umask', 'c')
+executable('prog', 'prog.c', install : true)
+install_headers('sample.h')
+install_man('prog.1')
+install_data('datafile.cat', install_dir : get_option('prefix') + '/share')
+install_subdir('subdir', install_dir : get_option('prefix') + '/share')
+meson.add_install_script('myinstall.py', 'share', 'file.dat')
diff --git a/test cases/unit/26 install umask/myinstall.py b/test cases/unit/26 install umask/myinstall.py
new file mode 100644
index 0000000..db6a51c
--- /dev/null
+++ b/test cases/unit/26 install umask/myinstall.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX']
+
+dirname = os.path.join(prefix, sys.argv[1])
+
+try:
+ os.makedirs(dirname)
+except FileExistsError:
+ if not os.path.isdir(dirname):
+ raise
+
+with open(os.path.join(dirname, sys.argv[2]), 'w') as f:
+ f.write('')
diff --git a/test cases/unit/26 install umask/prog.1 b/test cases/unit/26 install umask/prog.1
new file mode 100644
index 0000000..08ef7da
--- /dev/null
+++ b/test cases/unit/26 install umask/prog.1
@@ -0,0 +1 @@
+Man up, you.
diff --git a/test cases/unit/26 install umask/prog.c b/test cases/unit/26 install umask/prog.c
new file mode 100644
index 0000000..0f0061d
--- /dev/null
+++ b/test cases/unit/26 install umask/prog.c
@@ -0,0 +1,3 @@
+int main(int argc, char **arv) {
+ return 0;
+}
diff --git a/test cases/unit/26 install umask/sample.h b/test cases/unit/26 install umask/sample.h
new file mode 100644
index 0000000..dc030da
--- /dev/null
+++ b/test cases/unit/26 install umask/sample.h
@@ -0,0 +1,6 @@
+#ifndef SAMPLE_H
+#define SAMPLE_H
+
+int wackiness();
+
+#endif
diff --git a/test cases/unit/26 install umask/subdir/datafile.dog b/test cases/unit/26 install umask/subdir/datafile.dog
new file mode 100644
index 0000000..7a5bcb7
--- /dev/null
+++ b/test cases/unit/26 install umask/subdir/datafile.dog
@@ -0,0 +1 @@
+Installed dog is installed.
diff --git a/test cases/unit/26 install umask/subdir/sayhello b/test cases/unit/26 install umask/subdir/sayhello
new file mode 100755
index 0000000..1e1c90a
--- /dev/null
+++ b/test cases/unit/26 install umask/subdir/sayhello
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo 'Hello, World!'
diff --git a/test cases/unit/27 pkgconfig usage/dependee/meson.build b/test cases/unit/27 pkgconfig usage/dependee/meson.build
new file mode 100644
index 0000000..03e294e
--- /dev/null
+++ b/test cases/unit/27 pkgconfig usage/dependee/meson.build
@@ -0,0 +1,6 @@
+project('pkgconfig user', 'c')
+
+pkgdep = dependency('libpkgdep')
+
+executable('pkguser', 'pkguser.c',
+ dependencies : pkgdep)
diff --git a/test cases/unit/27 pkgconfig usage/dependee/pkguser.c b/test cases/unit/27 pkgconfig usage/dependee/pkguser.c
new file mode 100644
index 0000000..2bff316
--- /dev/null
+++ b/test cases/unit/27 pkgconfig usage/dependee/pkguser.c
@@ -0,0 +1,6 @@
+#include<pkgdep.h>
+
+int main(int argc, char **argv) {
+ int res = pkgdep();
+ return res != 99;
+}
diff --git a/test cases/unit/27 pkgconfig usage/dependency/meson.build b/test cases/unit/27 pkgconfig usage/dependency/meson.build
new file mode 100644
index 0000000..ee0f1da
--- /dev/null
+++ b/test cases/unit/27 pkgconfig usage/dependency/meson.build
@@ -0,0 +1,24 @@
+project('pkgconfig dep', 'c',
+ version : '1.0.0')
+
+# This is not used in the code, only to check that it does not
+# leak out to --libs.
+glib_dep = dependency('glib-2.0')
+
+pkgconfig = import('pkgconfig')
+
+intlib = static_library('libpkgdep-int', 'privatelib.c')
+intdep = declare_dependency(link_with : intlib)
+
+lib = shared_library('pkgdep', 'pkgdep.c',
+ dependencies : [glib_dep, intdep],
+ install : true)
+
+install_headers('pkgdep.h')
+
+pkgconfig.generate(
+ filebase : 'libpkgdep',
+ name : 'Libpkgdep',
+ description : 'Sample pkgconfig dependency library',
+ version : meson.project_version(),
+ libraries : lib)
diff --git a/test cases/unit/27 pkgconfig usage/dependency/pkgdep.c b/test cases/unit/27 pkgconfig usage/dependency/pkgdep.c
new file mode 100644
index 0000000..bd5c3f4
--- /dev/null
+++ b/test cases/unit/27 pkgconfig usage/dependency/pkgdep.c
@@ -0,0 +1,7 @@
+#include<pkgdep.h>
+
+int internal_thingy();
+
+int pkgdep() {
+ return internal_thingy();
+}
diff --git a/test cases/unit/27 pkgconfig usage/dependency/pkgdep.h b/test cases/unit/27 pkgconfig usage/dependency/pkgdep.h
new file mode 100644
index 0000000..16d622e
--- /dev/null
+++ b/test cases/unit/27 pkgconfig usage/dependency/pkgdep.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int pkgdep();
diff --git a/test cases/unit/27 pkgconfig usage/dependency/privatelib.c b/test cases/unit/27 pkgconfig usage/dependency/privatelib.c
new file mode 100644
index 0000000..71d2179
--- /dev/null
+++ b/test cases/unit/27 pkgconfig usage/dependency/privatelib.c
@@ -0,0 +1,3 @@
+int internal_thingy() {
+ return 99;
+}
diff --git a/test cases/unit/28 ndebug if-release/main.c b/test cases/unit/28 ndebug if-release/main.c
new file mode 100644
index 0000000..70b3d04
--- /dev/null
+++ b/test cases/unit/28 ndebug if-release/main.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(void) {
+#ifdef NDEBUG
+ printf("NDEBUG=1\n");
+#else
+ printf("NDEBUG=0\n");
+#endif
+ return 0;
+}
diff --git a/test cases/unit/28 ndebug if-release/meson.build b/test cases/unit/28 ndebug if-release/meson.build
new file mode 100644
index 0000000..4af2406
--- /dev/null
+++ b/test cases/unit/28 ndebug if-release/meson.build
@@ -0,0 +1,3 @@
+project('ndebug enabled', 'c')
+
+executable('main', 'main.c')
diff --git a/test cases/unit/29 guessed linker dependencies/exe/app.c b/test cases/unit/29 guessed linker dependencies/exe/app.c
new file mode 100644
index 0000000..29c8d9c
--- /dev/null
+++ b/test cases/unit/29 guessed linker dependencies/exe/app.c
@@ -0,0 +1,6 @@
+void liba_func();
+
+int main(void) {
+ liba_func();
+ return 0;
+}
diff --git a/test cases/unit/29 guessed linker dependencies/exe/meson.build b/test cases/unit/29 guessed linker dependencies/exe/meson.build
new file mode 100644
index 0000000..8bb1bd7
--- /dev/null
+++ b/test cases/unit/29 guessed linker dependencies/exe/meson.build
@@ -0,0 +1,7 @@
+project('exe', ['c'])
+
+executable('app',
+ 'app.c',
+ # Use uninterpreted strings to avoid path finding by dependency or compiler.find_library
+ link_args: ['-ltest-lib']
+ )
diff --git a/test cases/unit/29 guessed linker dependencies/lib/lib.c b/test cases/unit/29 guessed linker dependencies/lib/lib.c
new file mode 100644
index 0000000..1a8f94d
--- /dev/null
+++ b/test cases/unit/29 guessed linker dependencies/lib/lib.c
@@ -0,0 +1,20 @@
+#if defined _WIN32
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+void DLL_PUBLIC liba_func() {
+}
+
+#ifdef MORE_EXPORTS
+
+void DLL_PUBLIC libb_func() {
+}
+
+#endif
diff --git a/test cases/unit/29 guessed linker dependencies/lib/meson.build b/test cases/unit/29 guessed linker dependencies/lib/meson.build
new file mode 100644
index 0000000..36df112
--- /dev/null
+++ b/test cases/unit/29 guessed linker dependencies/lib/meson.build
@@ -0,0 +1,11 @@
+project('lib1', ['c'])
+
+c_args = []
+
+# Microsoft's compiler is quite smart about touching import libs on changes,
+# so ensure that there is actually a change in symbols.
+if get_option('more_exports')
+ c_args += '-DMORE_EXPORTS'
+endif
+
+a = library('test-lib', 'lib.c', c_args: c_args, install: true)
diff --git a/test cases/unit/29 guessed linker dependencies/lib/meson_options.txt b/test cases/unit/29 guessed linker dependencies/lib/meson_options.txt
new file mode 100644
index 0000000..2123e45
--- /dev/null
+++ b/test cases/unit/29 guessed linker dependencies/lib/meson_options.txt
@@ -0,0 +1 @@
+option('more_exports', type : 'boolean', value : false)
diff --git a/test cases/unit/3 subproject defaults/meson.build b/test cases/unit/3 subproject defaults/meson.build
new file mode 100644
index 0000000..dafa40a
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/meson.build
@@ -0,0 +1,10 @@
+project('subproject defaults', 'c',
+ default_options : ['defopoverride=defopt', # This should be overridden.
+ 'fromcmdline=defopt'] # This should get the value set in command line.
+ )
+
+subproject('foob', default_options : ['fromspfunc=spfunc', 'fromspfunconly=spfunc'])
+
+assert(get_option('fromcmdline') == 'cmdline', 'Default option defined in cmd line is incorrect: ' + get_option('fromcmdline'))
+assert(get_option('defopoverride') == 'defopt', 'Default option without cmd line override is incorrect: ' + get_option('defopoverride'))
+assert(get_option('fromoptfile') == 'optfile', 'Default value from option file is incorrect: ' + get_option('fromoptfile'))
diff --git a/test cases/unit/3 subproject defaults/meson_options.txt b/test cases/unit/3 subproject defaults/meson_options.txt
new file mode 100644
index 0000000..b63f512
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/meson_options.txt
@@ -0,0 +1,3 @@
+option('defopoverride', type : 'string', value : 'optfile', description : 'A value for overriding.')
+option('fromcmdline', type : 'string', value : 'optfile', description : 'A value for overriding.')
+option('fromoptfile', type : 'string', value : 'optfile', description : 'A value for not overriding.')
diff --git a/test cases/unit/3 subproject defaults/subprojects/foob/meson.build b/test cases/unit/3 subproject defaults/subprojects/foob/meson.build
new file mode 100644
index 0000000..9a611a9
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/subprojects/foob/meson.build
@@ -0,0 +1,11 @@
+project('foob', 'c',
+ default_options : ['defopoverride=s_defopt', # This should be overridden.
+ 'fromspfunc=s_defopt', # This is specified with a default_options kwarg to subproject()
+ 'fromcmdline=s_defopt'] # This should get the value set in command line.
+ )
+
+assert(get_option('fromcmdline') == 's_cmdline', 'Default option defined in cmd line is incorrect: ' + get_option('fromcmdline'))
+assert(get_option('fromspfunc') == 'spfunc', 'Default option set with subproject() incorrect: ' + get_option('fromspfunc'))
+assert(get_option('fromspfunconly') == 'spfunc', 'Default option set with subproject() incorrect: ' + get_option('fromspfunc'))
+assert(get_option('defopoverride') == 's_defopt', 'Default option without cmd line override is incorrect: ' + get_option('defopoverride'))
+assert(get_option('fromoptfile') == 's_optfile', 'Default value from option file is incorrect: ' + get_option('fromoptfile'))
diff --git a/test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt b/test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt
new file mode 100644
index 0000000..a9a615e
--- /dev/null
+++ b/test cases/unit/3 subproject defaults/subprojects/foob/meson_options.txt
@@ -0,0 +1,5 @@
+option('defopoverride', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromcmdline', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromspfunc', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromspfunconly', type : 'string', value : 's_optfile', description : 'A value for overriding.')
+option('fromoptfile', type : 'string', value : 's_optfile', description : 'A value for not overriding.')
diff --git a/test cases/unit/30 shared_mod linking/libfile.c b/test cases/unit/30 shared_mod linking/libfile.c
new file mode 100644
index 0000000..44f7667
--- /dev/null
+++ b/test cases/unit/30 shared_mod linking/libfile.c
@@ -0,0 +1,14 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC func() {
+ return 0;
+}
diff --git a/test cases/unit/30 shared_mod linking/main.c b/test cases/unit/30 shared_mod linking/main.c
new file mode 100644
index 0000000..12f9c98
--- /dev/null
+++ b/test cases/unit/30 shared_mod linking/main.c
@@ -0,0 +1,11 @@
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_IMPORT __declspec(dllimport)
+#else
+ #define DLL_IMPORT
+#endif
+
+int DLL_IMPORT func();
+
+int main(int argc, char **arg) {
+ return func();
+}
diff --git a/test cases/unit/30 shared_mod linking/meson.build b/test cases/unit/30 shared_mod linking/meson.build
new file mode 100644
index 0000000..994a5d3
--- /dev/null
+++ b/test cases/unit/30 shared_mod linking/meson.build
@@ -0,0 +1,5 @@
+project('shared library linking test', 'c', 'cpp')
+
+mod = shared_module('mymod', 'libfile.c')
+
+exe = executable('prog', 'main.c', link_with : mod, install : true) \ No newline at end of file
diff --git a/test cases/unit/31 forcefallback/meson.build b/test cases/unit/31 forcefallback/meson.build
new file mode 100644
index 0000000..8d84a60
--- /dev/null
+++ b/test cases/unit/31 forcefallback/meson.build
@@ -0,0 +1,9 @@
+project('mainproj', 'c',
+ default_options : [])
+
+zlib_dep = dependency('zlib', fallback: ['notzlib', 'zlib_dep'])
+notfound_dep = dependency('cannotabletofind', fallback: ['definitelynotfound', 'some_var'], required : false)
+
+test_not_zlib = executable('test_not_zlib', ['test_not_zlib.c'], dependencies: [zlib_dep, notfound_dep])
+
+test('test_not_zlib', test_not_zlib)
diff --git a/test cases/unit/31 forcefallback/subprojects/notzlib/meson.build b/test cases/unit/31 forcefallback/subprojects/notzlib/meson.build
new file mode 100644
index 0000000..254a136
--- /dev/null
+++ b/test cases/unit/31 forcefallback/subprojects/notzlib/meson.build
@@ -0,0 +1,7 @@
+project('notzlib', 'c')
+
+notzlib_sources = ['notzlib.c']
+
+notzlib = library('notzlib', notzlib_sources)
+
+zlib_dep = declare_dependency(link_with: notzlib, include_directories: include_directories(['.']))
diff --git a/test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.c b/test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.c
new file mode 100644
index 0000000..c3b6bf9
--- /dev/null
+++ b/test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.c
@@ -0,0 +1,6 @@
+#include "notzlib.h"
+
+int not_a_zlib_function (void)
+{
+ return 42;
+}
diff --git a/test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.h b/test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.h
new file mode 100644
index 0000000..695921d
--- /dev/null
+++ b/test cases/unit/31 forcefallback/subprojects/notzlib/notzlib.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+#if defined BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #define DLL_PUBLIC __declspec(dllimport)
+#endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+int DLL_PUBLIC not_a_zlib_function (void);
diff --git a/test cases/unit/31 forcefallback/test_not_zlib.c b/test cases/unit/31 forcefallback/test_not_zlib.c
new file mode 100644
index 0000000..36256af
--- /dev/null
+++ b/test cases/unit/31 forcefallback/test_not_zlib.c
@@ -0,0 +1,8 @@
+#include <notzlib.h>
+
+int main (int ac, char **av)
+{
+ if (not_a_zlib_function () != 42)
+ return 1;
+ return 0;
+}
diff --git a/test cases/unit/32 pkgconfig use libraries/app/app.c b/test cases/unit/32 pkgconfig use libraries/app/app.c
new file mode 100644
index 0000000..7b8d8fa
--- /dev/null
+++ b/test cases/unit/32 pkgconfig use libraries/app/app.c
@@ -0,0 +1,6 @@
+void libb_func();
+
+int main(void) {
+ libb_func();
+ return 0;
+}
diff --git a/test cases/unit/32 pkgconfig use libraries/app/meson.build b/test cases/unit/32 pkgconfig use libraries/app/meson.build
new file mode 100644
index 0000000..3d85a32
--- /dev/null
+++ b/test cases/unit/32 pkgconfig use libraries/app/meson.build
@@ -0,0 +1,5 @@
+project('app', ['c'])
+
+b = dependency('test-b')
+
+executable('app', 'app.c', dependencies : [b])
diff --git a/test cases/unit/32 pkgconfig use libraries/lib/liba.c b/test cases/unit/32 pkgconfig use libraries/lib/liba.c
new file mode 100644
index 0000000..e98906b
--- /dev/null
+++ b/test cases/unit/32 pkgconfig use libraries/lib/liba.c
@@ -0,0 +1,2 @@
+void liba_func() {
+}
diff --git a/test cases/unit/32 pkgconfig use libraries/lib/libb.c b/test cases/unit/32 pkgconfig use libraries/lib/libb.c
new file mode 100644
index 0000000..3160e5f
--- /dev/null
+++ b/test cases/unit/32 pkgconfig use libraries/lib/libb.c
@@ -0,0 +1,5 @@
+void liba_func();
+
+void libb_func() {
+ liba_func();
+}
diff --git a/test cases/unit/32 pkgconfig use libraries/lib/meson.build b/test cases/unit/32 pkgconfig use libraries/lib/meson.build
new file mode 100644
index 0000000..e9918ce
--- /dev/null
+++ b/test cases/unit/32 pkgconfig use libraries/lib/meson.build
@@ -0,0 +1,14 @@
+project('lib', ['c'])
+
+a = library('test-a', 'liba.c', install: true)
+
+b = library('test-b', 'libb.c', link_with: a, install: true)
+
+import('pkgconfig').generate(
+ version: '0.0',
+ description: 'test library',
+ filebase: 'test-b',
+ name: 'test library',
+ libraries: [b],
+ subdirs: ['.']
+)
diff --git a/test cases/unit/33 cross file overrides always args/meson.build b/test cases/unit/33 cross file overrides always args/meson.build
new file mode 100644
index 0000000..ef6556e
--- /dev/null
+++ b/test cases/unit/33 cross file overrides always args/meson.build
@@ -0,0 +1,3 @@
+project('cross compile args override always args', 'c')
+
+executable('no-file-offset-bits', 'test.c')
diff --git a/test cases/unit/33 cross file overrides always args/test.c b/test cases/unit/33 cross file overrides always args/test.c
new file mode 100644
index 0000000..315f92e
--- /dev/null
+++ b/test cases/unit/33 cross file overrides always args/test.c
@@ -0,0 +1,8 @@
+#ifdef _FILE_OFFSET_BITS
+ #error "_FILE_OFFSET_BITS should not be set"
+#endif
+
+int main(int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt b/test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt
new file mode 100644
index 0000000..a00a7d1
--- /dev/null
+++ b/test cases/unit/33 cross file overrides always args/ubuntu-armhf-overrides.txt
@@ -0,0 +1,19 @@
+[binaries]
+# we could set exe_wrapper = qemu-arm-static but to test the case
+# when cross compiled binaries can't be run we don't do that
+c = '/usr/bin/arm-linux-gnueabihf-gcc'
+cpp = '/usr/bin/arm-linux-gnueabihf-g++'
+rust = ['rustc', '--target', 'arm-unknown-linux-gnueabihf', '-C', 'linker=/usr/bin/arm-linux-gnueabihf-gcc-7']
+ar = '/usr/arm-linux-gnueabihf/bin/ar'
+strip = '/usr/arm-linux-gnueabihf/bin/strip'
+pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'
+
+[properties]
+root = '/usr/arm-linux-gnueabihf'
+c_args = ['-U_FILE_OFFSET_BITS']
+
+[host_machine]
+system = 'linux'
+cpu_family = 'arm'
+cpu = 'armv7' # Not sure if correct.
+endian = 'little'
diff --git a/test cases/unit/34 command line/meson.build b/test cases/unit/34 command line/meson.build
new file mode 100644
index 0000000..6207ca5
--- /dev/null
+++ b/test cases/unit/34 command line/meson.build
@@ -0,0 +1,9 @@
+project('command line test', 'c',
+ default_options : ['default_library=static', 'set_sub_opt=true']
+)
+
+if get_option('set_sub_opt')
+ subproject('subp', default_options : ['subp_opt=default3'])
+else
+ subproject('subp')
+endif
diff --git a/test cases/unit/34 command line/meson_options.txt b/test cases/unit/34 command line/meson_options.txt
new file mode 100644
index 0000000..244f570
--- /dev/null
+++ b/test cases/unit/34 command line/meson_options.txt
@@ -0,0 +1,2 @@
+option('set_sub_opt', type : 'boolean', value : false)
+option('set_percent_opt', type : 'string', value: 'not_set')
diff --git a/test cases/unit/34 command line/subprojects/subp/meson.build b/test cases/unit/34 command line/subprojects/subp/meson.build
new file mode 100644
index 0000000..cf79fa4
--- /dev/null
+++ b/test cases/unit/34 command line/subprojects/subp/meson.build
@@ -0,0 +1,3 @@
+project('subp',
+ default_options : ['subp_opt=default2']
+)
diff --git a/test cases/unit/34 command line/subprojects/subp/meson_options.txt b/test cases/unit/34 command line/subprojects/subp/meson_options.txt
new file mode 100644
index 0000000..8c50615
--- /dev/null
+++ b/test cases/unit/34 command line/subprojects/subp/meson_options.txt
@@ -0,0 +1 @@
+option('subp_opt', type : 'string', value : 'default1')
diff --git a/test cases/unit/35 dist script/meson.build b/test cases/unit/35 dist script/meson.build
new file mode 100644
index 0000000..8db4235
--- /dev/null
+++ b/test cases/unit/35 dist script/meson.build
@@ -0,0 +1,10 @@
+project('dist script', 'c',
+ version : '1.0.0')
+
+exe = executable('comparer', 'prog.c')
+test('compare', exe)
+
+meson.add_dist_script('replacer.py', '"incorrect"', '"correct"')
+meson.add_dist_script(find_program('replacer.py'), '"incorrect"', '"correct"')
+
+subproject('sub')
diff --git a/test cases/unit/35 dist script/prog.c b/test cases/unit/35 dist script/prog.c
new file mode 100644
index 0000000..1bb6b05
--- /dev/null
+++ b/test cases/unit/35 dist script/prog.c
@@ -0,0 +1,7 @@
+#include<string.h>
+
+#define REPLACEME "incorrect"
+
+int main(int argc, char **argv) {
+ return strcmp(REPLACEME, "correct");
+}
diff --git a/test cases/unit/35 dist script/replacer.py b/test cases/unit/35 dist script/replacer.py
new file mode 100755
index 0000000..96ccdcc
--- /dev/null
+++ b/test cases/unit/35 dist script/replacer.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import os
+import pathlib
+import sys
+
+if len(sys.argv) < 3:
+ sys.exit('usage: replacer.py <pattern> <replacement>')
+
+source_root = pathlib.Path(os.environ['MESON_DIST_ROOT'])
+
+modfile = source_root / 'prog.c'
+
+contents = modfile.read_text()
+contents = contents.replace(sys.argv[1], sys.argv[2])
+modfile.write_text(contents)
diff --git a/test cases/unit/35 dist script/subprojects/sub/dist-script.py b/test cases/unit/35 dist script/subprojects/sub/dist-script.py
new file mode 100644
index 0000000..1274f29
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/dist-script.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import os
+import pathlib
+import sys
+
+assert sys.argv[1] == 'success'
+
+source_root = pathlib.Path(os.environ['MESON_PROJECT_DIST_ROOT'])
+modfile = source_root / 'prog.c'
+with modfile.open('w') as f:
+ f.write('int main(){return 0;}')
diff --git a/test cases/unit/35 dist script/subprojects/sub/meson.build b/test cases/unit/35 dist script/subprojects/sub/meson.build
new file mode 100644
index 0000000..a41a3b6
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/meson.build
@@ -0,0 +1,11 @@
+project('sub', 'c')
+
+if get_option('broken_dist_script')
+ # Make sure we can add a dist script in a subproject, but it won't be run
+ # if not using --include-subprojects.
+ meson.add_dist_script('dist-script.py', 'broken')
+else
+ # The dist script replace prog.c with something that actually build.
+ meson.add_dist_script('dist-script.py', 'success')
+ executable('prog', 'prog.c')
+endif
diff --git a/test cases/unit/35 dist script/subprojects/sub/meson_options.txt b/test cases/unit/35 dist script/subprojects/sub/meson_options.txt
new file mode 100644
index 0000000..8f52e0f
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/meson_options.txt
@@ -0,0 +1 @@
+option('broken_dist_script', type: 'boolean', value: true)
diff --git a/test cases/unit/35 dist script/subprojects/sub/prog.c b/test cases/unit/35 dist script/subprojects/sub/prog.c
new file mode 100644
index 0000000..049b36a
--- /dev/null
+++ b/test cases/unit/35 dist script/subprojects/sub/prog.c
@@ -0,0 +1 @@
+#error This should be replaced by a program during dist
diff --git a/test cases/unit/36 exe_wrapper behaviour/broken-cross.txt b/test cases/unit/36 exe_wrapper behaviour/broken-cross.txt
new file mode 100644
index 0000000..a5a3931
--- /dev/null
+++ b/test cases/unit/36 exe_wrapper behaviour/broken-cross.txt
@@ -0,0 +1,20 @@
+[binaries]
+c = '/usr/bin/x86_64-w64-mingw32-gcc'
+cpp = '/usr/bin/x86_64-w64-mingw32-g++'
+ar = '/usr/bin/x86_64-w64-mingw32-ar'
+strip = '/usr/bin/x86_64-w64-mingw32-strip'
+pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config'
+windres = '/usr/bin/x86_64-w64-mingw32-windres'
+exe_wrapper = 'broken'
+
+[properties]
+# Directory that contains 'bin', 'lib', etc
+root = '/usr/x86_64-w64-mingw32'
+# Directory that contains 'bin', 'lib', etc for the toolchain and system libraries
+sys_root = '/usr/x86_64-w64-mingw32/sys-root/mingw'
+
+[host_machine]
+system = 'windows'
+cpu_family = 'x86_64'
+cpu = 'x86_64'
+endian = 'little'
diff --git a/test cases/unit/36 exe_wrapper behaviour/meson.build b/test cases/unit/36 exe_wrapper behaviour/meson.build
new file mode 100644
index 0000000..d0817ba
--- /dev/null
+++ b/test cases/unit/36 exe_wrapper behaviour/meson.build
@@ -0,0 +1,19 @@
+project('exe wrapper behaviour', 'c')
+
+assert(meson.is_cross_build(), 'not setup as cross build')
+assert(meson.has_exe_wrapper(), 'exe wrapper not defined?') # intentionally not changed to can_run_host_binaries,
+
+exe = executable('prog', 'prog.c')
+
+if get_option('custom-target')
+ custom_target('use-exe-wrapper',
+ build_by_default: true,
+ output: 'out.txt',
+ command: [exe, '@OUTPUT@'])
+endif
+
+test('test-prog', exe)
+
+if get_option('run-target')
+ run_target('run-prog', command : exe)
+endif
diff --git a/test cases/unit/36 exe_wrapper behaviour/meson_options.txt b/test cases/unit/36 exe_wrapper behaviour/meson_options.txt
new file mode 100644
index 0000000..e5645a0
--- /dev/null
+++ b/test cases/unit/36 exe_wrapper behaviour/meson_options.txt
@@ -0,0 +1,2 @@
+option('custom-target', type: 'boolean', value: true)
+option('run-target', type: 'boolean', value: true)
diff --git a/test cases/unit/36 exe_wrapper behaviour/prog.c b/test cases/unit/36 exe_wrapper behaviour/prog.c
new file mode 100644
index 0000000..3213780
--- /dev/null
+++ b/test cases/unit/36 exe_wrapper behaviour/prog.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main (int argc, char * argv[])
+{
+ const char *out = "SUCCESS!";
+
+ if (argc != 2) {
+ printf ("%s\n", out);
+ } else {
+ int ret;
+ FILE *f = fopen (argv[1], "w");
+ ret = fwrite (out, sizeof (out), 1, f);
+ if (ret != 1)
+ return -1;
+ }
+ return 0;
+}
diff --git a/test cases/unit/37 mixed command line args/meson.build b/test cases/unit/37 mixed command line args/meson.build
new file mode 100644
index 0000000..af5cdc7
--- /dev/null
+++ b/test cases/unit/37 mixed command line args/meson.build
@@ -0,0 +1 @@
+project('Mixed command line arguments')
diff --git a/test cases/unit/37 mixed command line args/meson_options.txt b/test cases/unit/37 mixed command line args/meson_options.txt
new file mode 100644
index 0000000..5a4bc22
--- /dev/null
+++ b/test cases/unit/37 mixed command line args/meson_options.txt
@@ -0,0 +1,10 @@
+option(
+ 'one',
+ type : 'string',
+)
+option(
+ 'two',
+ type : 'combo',
+ choices : ['foo', 'bar'],
+ value : 'foo',
+)
diff --git a/test cases/unit/38 pkgconfig format/meson.build b/test cases/unit/38 pkgconfig format/meson.build
new file mode 100644
index 0000000..ea00f5d
--- /dev/null
+++ b/test cases/unit/38 pkgconfig format/meson.build
@@ -0,0 +1,18 @@
+project('pkgformat', 'c',
+ version : '1.0')
+
+gio = dependency('gio-2.0', required: false)
+if not gio.found()
+ error('MESON_SKIP_TEST glib not found.')
+endif
+
+pkgg = import('pkgconfig')
+
+s = static_library('returner', 'someret.c')
+l = library('something', 'somelib.c', link_whole: s)
+
+pkgg.generate(libraries: l,
+ version: '1.0',
+ name: 'libsomething',
+ description: 'A library that does something',
+ requires: 'gobject-2.0 >= 2.0, gio-2.0 >= 2.0')
diff --git a/test cases/unit/38 pkgconfig format/somelib.c b/test cases/unit/38 pkgconfig format/somelib.c
new file mode 100644
index 0000000..0558024
--- /dev/null
+++ b/test cases/unit/38 pkgconfig format/somelib.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+
+int get_returnvalue (void);
+
+int some_func() {
+ return get_returnvalue();
+}
diff --git a/test cases/unit/38 pkgconfig format/someret.c b/test cases/unit/38 pkgconfig format/someret.c
new file mode 100644
index 0000000..69f4299
--- /dev/null
+++ b/test cases/unit/38 pkgconfig format/someret.c
@@ -0,0 +1,3 @@
+int get_returnvalue (void) {
+ return 0;
+}
diff --git a/test cases/unit/39 external, internal library rpath/built library/bar.c b/test cases/unit/39 external, internal library rpath/built library/bar.c
new file mode 100644
index 0000000..4f5662e
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/built library/bar.c
@@ -0,0 +1,7 @@
+int foo_system_value (void);
+int faa_system_value (void);
+
+int bar_built_value (int in)
+{
+ return faa_system_value() + foo_system_value() + in;
+}
diff --git a/test cases/unit/39 external, internal library rpath/built library/meson.build b/test cases/unit/39 external, internal library rpath/built library/meson.build
new file mode 100644
index 0000000..07fe7bb
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/built library/meson.build
@@ -0,0 +1,26 @@
+project('built library', 'c')
+
+cc = meson.get_compiler('c')
+
+if host_machine.system() != 'cygwin'
+ # bar_in_system has undefined symbols, but still must be found
+ bar_system_dep = cc.find_library('bar_in_system')
+endif
+
+foo_system_dep = cc.find_library('foo_in_system')
+
+faa_pkg_dep = dependency('faa_pkg')
+
+l = shared_library('bar_built', 'bar.c',
+ install: true,
+ dependencies : [foo_system_dep, faa_pkg_dep])
+
+if host_machine.system() == 'darwin'
+ e = executable('prog', 'prog.c', link_with: l, install: true)
+ test('testprog', e)
+elif host_machine.system() == 'linux'
+ e = executable('prog', 'prog.c', link_with: l, install: true,
+ install_rpath: '$ORIGIN/..' / get_option('libdir'),
+ )
+ test('testprog', e)
+endif
diff --git a/test cases/unit/39 external, internal library rpath/built library/meson_options.txt b/test cases/unit/39 external, internal library rpath/built library/meson_options.txt
new file mode 100644
index 0000000..aa1d2ec
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/built library/meson_options.txt
@@ -0,0 +1 @@
+option('foo_system_path', type: 'string', value: '')
diff --git a/test cases/unit/39 external, internal library rpath/built library/prog.c b/test cases/unit/39 external, internal library rpath/built library/prog.c
new file mode 100644
index 0000000..e3d4cf6
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/built library/prog.c
@@ -0,0 +1,7 @@
+int bar_built_value (int in);
+
+int main (int argc, char *argv[])
+{
+ // this will evaluate to 0
+ return bar_built_value(10) - (42 + 1969 + 10);
+}
diff --git a/test cases/unit/39 external, internal library rpath/external library/bar.c b/test cases/unit/39 external, internal library rpath/external library/bar.c
new file mode 100644
index 0000000..c6f42d6
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/external library/bar.c
@@ -0,0 +1,6 @@
+int some_undefined_func (void);
+
+int bar_system_value (void)
+{
+ return some_undefined_func ();
+}
diff --git a/test cases/unit/39 external, internal library rpath/external library/faa.c b/test cases/unit/39 external, internal library rpath/external library/faa.c
new file mode 100644
index 0000000..4733575
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/external library/faa.c
@@ -0,0 +1,4 @@
+int faa_system_value (void)
+{
+ return 1969;
+}
diff --git a/test cases/unit/39 external, internal library rpath/external library/foo.c b/test cases/unit/39 external, internal library rpath/external library/foo.c
new file mode 100644
index 0000000..a34e4a8
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/external library/foo.c
@@ -0,0 +1,4 @@
+int foo_system_value (void)
+{
+ return 42;
+}
diff --git a/test cases/unit/39 external, internal library rpath/external library/meson.build b/test cases/unit/39 external, internal library rpath/external library/meson.build
new file mode 100644
index 0000000..06ffa0f
--- /dev/null
+++ b/test cases/unit/39 external, internal library rpath/external library/meson.build
@@ -0,0 +1,22 @@
+project('system library', 'c', default_options : ['b_lundef=false'])
+
+shared_library('foo_in_system', 'foo.c', install : true)
+l = shared_library('faa_pkg', 'faa.c', install: true)
+
+if host_machine.system() == 'darwin'
+ ldflags = ['-framework', 'CoreFoundation', '-framework', 'CoreMedia']
+ allow_undef_args = ['-Wl,-undefined,dynamic_lookup']
+else
+ ldflags = ['-Wl,-rpath,${libdir}']
+ allow_undef_args = []
+endif
+
+pkg = import('pkgconfig')
+pkg.generate(name: 'faa_pkg',
+ libraries: [l] + ldflags,
+ description: 'FAA, a pkg-config test library')
+
+# cygwin DLLs can't have undefined symbols
+if host_machine.system() != 'cygwin'
+ shared_library('bar_in_system', 'bar.c', install : true, link_args : allow_undef_args)
+endif
diff --git a/test cases/unit/4 suite selection/failing_test.c b/test cases/unit/4 suite selection/failing_test.c
new file mode 100644
index 0000000..393344d
--- /dev/null
+++ b/test cases/unit/4 suite selection/failing_test.c
@@ -0,0 +1 @@
+int main(void) { return -1 ; }
diff --git a/test cases/unit/4 suite selection/meson.build b/test cases/unit/4 suite selection/meson.build
new file mode 100644
index 0000000..ea6db92
--- /dev/null
+++ b/test cases/unit/4 suite selection/meson.build
@@ -0,0 +1,17 @@
+project('mainprj', 'c')
+
+subproject('subprjfail')
+subproject('subprjsucc')
+subproject('subprjmix')
+
+test('mainprj-failing_test',
+ executable('failing_test', 'failing_test.c'),
+ suite : 'fail')
+
+test('mainprj-successful_test',
+ executable('successful_test', 'successful_test.c'),
+ suite : 'success')
+
+test('mainprj-successful_test_no_suite',
+ executable('no_suite_test', 'successful_test.c'),
+ suite : [])
diff --git a/test cases/unit/4 suite selection/subprojects/subprjfail/failing_test.c b/test cases/unit/4 suite selection/subprojects/subprjfail/failing_test.c
new file mode 100644
index 0000000..393344d
--- /dev/null
+++ b/test cases/unit/4 suite selection/subprojects/subprjfail/failing_test.c
@@ -0,0 +1 @@
+int main(void) { return -1 ; }
diff --git a/test cases/unit/4 suite selection/subprojects/subprjfail/meson.build b/test cases/unit/4 suite selection/subprojects/subprjfail/meson.build
new file mode 100644
index 0000000..e6270a8
--- /dev/null
+++ b/test cases/unit/4 suite selection/subprojects/subprjfail/meson.build
@@ -0,0 +1,9 @@
+project('subprjfail', 'c')
+
+test('subprjfail-failing_test',
+ executable('failing_test', 'failing_test.c'),
+ suite : 'fail')
+
+test('subprjfail-failing_test_no_suite',
+ executable('failing_test_no_suite', 'failing_test.c'),
+ suite : [])
diff --git a/test cases/unit/4 suite selection/subprojects/subprjmix/failing_test.c b/test cases/unit/4 suite selection/subprojects/subprjmix/failing_test.c
new file mode 100644
index 0000000..393344d
--- /dev/null
+++ b/test cases/unit/4 suite selection/subprojects/subprjmix/failing_test.c
@@ -0,0 +1 @@
+int main(void) { return -1 ; }
diff --git a/test cases/unit/4 suite selection/subprojects/subprjmix/meson.build b/test cases/unit/4 suite selection/subprojects/subprjmix/meson.build
new file mode 100644
index 0000000..1d0eeff
--- /dev/null
+++ b/test cases/unit/4 suite selection/subprojects/subprjmix/meson.build
@@ -0,0 +1,9 @@
+project('subprjmix', 'c')
+
+test('subprjmix-failing_test',
+ executable('failing_test', 'failing_test.c'),
+ suite : 'fail')
+
+test('subprjmix-successful_test',
+ executable('successful_test', 'successful_test.c'),
+ suite : 'success')
diff --git a/test cases/unit/4 suite selection/subprojects/subprjmix/successful_test.c b/test cases/unit/4 suite selection/subprojects/subprjmix/successful_test.c
new file mode 100644
index 0000000..8842fc1
--- /dev/null
+++ b/test cases/unit/4 suite selection/subprojects/subprjmix/successful_test.c
@@ -0,0 +1 @@
+int main(void) { return 0 ; }
diff --git a/test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build b/test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build
new file mode 100644
index 0000000..b5ffaa4
--- /dev/null
+++ b/test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build
@@ -0,0 +1,9 @@
+project('subprjsucc', 'c')
+
+test('subprjsucc-successful_test',
+ executable('successful_test', 'successful_test.c'),
+ suite : 'success')
+
+test('subprjsucc-successful_test_no_suite',
+ executable('successful_test_no_suite', 'successful_test.c'),
+ suite : [])
diff --git a/test cases/unit/4 suite selection/subprojects/subprjsucc/successful_test.c b/test cases/unit/4 suite selection/subprojects/subprjsucc/successful_test.c
new file mode 100644
index 0000000..8842fc1
--- /dev/null
+++ b/test cases/unit/4 suite selection/subprojects/subprjsucc/successful_test.c
@@ -0,0 +1 @@
+int main(void) { return 0 ; }
diff --git a/test cases/unit/4 suite selection/successful_test.c b/test cases/unit/4 suite selection/successful_test.c
new file mode 100644
index 0000000..8842fc1
--- /dev/null
+++ b/test cases/unit/4 suite selection/successful_test.c
@@ -0,0 +1 @@
+int main(void) { return 0 ; }
diff --git a/test cases/unit/40 featurenew subprojects/meson.build b/test cases/unit/40 featurenew subprojects/meson.build
new file mode 100644
index 0000000..d136bed
--- /dev/null
+++ b/test cases/unit/40 featurenew subprojects/meson.build
@@ -0,0 +1,7 @@
+project('featurenew subproject', meson_version: '>=0.45')
+
+foo = {}
+
+subproject('foo')
+subproject('bar')
+subproject('baz')
diff --git a/test cases/unit/40 featurenew subprojects/subprojects/bar/meson.build b/test cases/unit/40 featurenew subprojects/subprojects/bar/meson.build
new file mode 100644
index 0000000..712a125
--- /dev/null
+++ b/test cases/unit/40 featurenew subprojects/subprojects/bar/meson.build
@@ -0,0 +1,3 @@
+project('foo subproject', meson_version: '>=0.46')
+
+import('python')
diff --git a/test cases/unit/40 featurenew subprojects/subprojects/baz/meson.build b/test cases/unit/40 featurenew subprojects/subprojects/baz/meson.build
new file mode 100644
index 0000000..811e7aa
--- /dev/null
+++ b/test cases/unit/40 featurenew subprojects/subprojects/baz/meson.build
@@ -0,0 +1,3 @@
+project('baz subproject', meson_version: '!=0.40')
+
+disabler()
diff --git a/test cases/unit/40 featurenew subprojects/subprojects/foo/meson.build b/test cases/unit/40 featurenew subprojects/subprojects/foo/meson.build
new file mode 100644
index 0000000..0ef4472
--- /dev/null
+++ b/test cases/unit/40 featurenew subprojects/subprojects/foo/meson.build
@@ -0,0 +1,3 @@
+project('foo subproject', meson_version: '>=0.40')
+
+disabler()
diff --git a/test cases/unit/41 rpath order/meson.build b/test cases/unit/41 rpath order/meson.build
new file mode 100644
index 0000000..a722894
--- /dev/null
+++ b/test cases/unit/41 rpath order/meson.build
@@ -0,0 +1,11 @@
+project('myexe', 'c')
+
+sub1 = subproject('sub1')
+sub1_dep = sub1.get_variable('sub1_dep')
+
+sub2 = subproject('sub2')
+sub2_dep = sub2.get_variable('sub2_dep')
+
+executable('myexe',
+ 'myexe.c',
+ dependencies: [sub1_dep, sub2_dep])
diff --git a/test cases/unit/41 rpath order/myexe.c b/test cases/unit/41 rpath order/myexe.c
new file mode 100644
index 0000000..03b2213
--- /dev/null
+++ b/test cases/unit/41 rpath order/myexe.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/unit/41 rpath order/subprojects/sub1/lib.c b/test cases/unit/41 rpath order/subprojects/sub1/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/41 rpath order/subprojects/sub1/lib.c
diff --git a/test cases/unit/41 rpath order/subprojects/sub1/meson.build b/test cases/unit/41 rpath order/subprojects/sub1/meson.build
new file mode 100644
index 0000000..4dd5d08
--- /dev/null
+++ b/test cases/unit/41 rpath order/subprojects/sub1/meson.build
@@ -0,0 +1,5 @@
+project('sub1', 'c')
+
+sub1_lib = library('sub1', 'lib.c')
+
+sub1_dep = declare_dependency(link_with : sub1_lib)
diff --git a/test cases/unit/41 rpath order/subprojects/sub2/lib.c b/test cases/unit/41 rpath order/subprojects/sub2/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/41 rpath order/subprojects/sub2/lib.c
diff --git a/test cases/unit/41 rpath order/subprojects/sub2/meson.build b/test cases/unit/41 rpath order/subprojects/sub2/meson.build
new file mode 100644
index 0000000..bc3510d
--- /dev/null
+++ b/test cases/unit/41 rpath order/subprojects/sub2/meson.build
@@ -0,0 +1,5 @@
+project('sub2', 'c')
+
+sub2_lib = library('sub2', 'lib.c')
+
+sub2_dep = declare_dependency(link_with : sub2_lib)
diff --git a/test cases/unit/42 dep order/lib1.c b/test cases/unit/42 dep order/lib1.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/42 dep order/lib1.c
diff --git a/test cases/unit/42 dep order/lib2.c b/test cases/unit/42 dep order/lib2.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/42 dep order/lib2.c
diff --git a/test cases/unit/42 dep order/meson.build b/test cases/unit/42 dep order/meson.build
new file mode 100644
index 0000000..17cf9df
--- /dev/null
+++ b/test cases/unit/42 dep order/meson.build
@@ -0,0 +1,8 @@
+project('myexe', 'c')
+
+lib1 = static_library('lib1', 'lib1.c')
+lib2 = static_library('lib2', 'lib2.c')
+
+executable('myexe',
+ 'myexe.c',
+ link_with: [lib1, lib2])
diff --git a/test cases/unit/42 dep order/myexe.c b/test cases/unit/42 dep order/myexe.c
new file mode 100644
index 0000000..8f4c045
--- /dev/null
+++ b/test cases/unit/42 dep order/myexe.c
@@ -0,0 +1,3 @@
+int main(int ac, char** av) {
+ return 0;
+}
diff --git a/test cases/unit/43 promote wrap/meson.build b/test cases/unit/43 promote wrap/meson.build
new file mode 100644
index 0000000..5012bf6
--- /dev/null
+++ b/test cases/unit/43 promote wrap/meson.build
@@ -0,0 +1,4 @@
+project('promotion test', 'c')
+
+subproject('s1')
+subproject('s2')
diff --git a/test cases/unit/43 promote wrap/subprojects/s1/meson.build b/test cases/unit/43 promote wrap/subprojects/s1/meson.build
new file mode 100644
index 0000000..48dc853
--- /dev/null
+++ b/test cases/unit/43 promote wrap/subprojects/s1/meson.build
@@ -0,0 +1 @@
+project('s1', 'c')
diff --git a/test cases/unit/43 promote wrap/subprojects/s1/subprojects/ambiguous/meson.build b/test cases/unit/43 promote wrap/subprojects/s1/subprojects/ambiguous/meson.build
new file mode 100644
index 0000000..b485d83
--- /dev/null
+++ b/test cases/unit/43 promote wrap/subprojects/s1/subprojects/ambiguous/meson.build
@@ -0,0 +1 @@
+project('ambiguous', 'c')
diff --git a/test cases/unit/43 promote wrap/subprojects/s2/meson.build b/test cases/unit/43 promote wrap/subprojects/s2/meson.build
new file mode 100644
index 0000000..901bc2a
--- /dev/null
+++ b/test cases/unit/43 promote wrap/subprojects/s2/meson.build
@@ -0,0 +1 @@
+project('s2', 'c')
diff --git a/test cases/unit/43 promote wrap/subprojects/s2/subprojects/ambiguous.wrap b/test cases/unit/43 promote wrap/subprojects/s2/subprojects/ambiguous.wrap
new file mode 100644
index 0000000..09ba4e8
--- /dev/null
+++ b/test cases/unit/43 promote wrap/subprojects/s2/subprojects/ambiguous.wrap
@@ -0,0 +1,2 @@
+The contents of this wrap file are never evaluated so they
+can be anything.
diff --git a/test cases/unit/44 vscpp17/main.cpp b/test cases/unit/44 vscpp17/main.cpp
new file mode 100644
index 0000000..3d07d4c
--- /dev/null
+++ b/test cases/unit/44 vscpp17/main.cpp
@@ -0,0 +1,29 @@
+#include <iostream>
+
+#if __cpp_lib_filesystem || (defined(__cplusplus) && __cplusplus >= 201703L)
+#include <filesystem>
+#endif
+
+int main(){
+
+#if __cpp_lib_filesystem || (defined(__cplusplus) && __cplusplus >= 201703L)
+char fs = std::filesystem::path::preferred_separator;
+std::cout << "OK: C++17 filesystem enabled" << std::endl;
+#endif
+
+#if defined(_MSC_VER)
+#if _HAS_CXX17
+std::cout << "OK: MSVC has C++17 enabled" << std::endl;
+return EXIT_SUCCESS;
+#else
+std::cerr << "ERROR: MSVC does not have C++17 enabled" << std::endl;
+return EXIT_FAILURE;
+#endif
+#elif defined(__cplusplus) && __cplusplus >= 201703L
+std::cout << "OK: C++17 enabled" << std::endl;
+return EXIT_SUCCESS;
+#else
+std::cerr << "ERROR: C++17 not enabled" << std::endl;
+return EXIT_FAILURE;
+#endif
+}
diff --git a/test cases/unit/44 vscpp17/meson.build b/test cases/unit/44 vscpp17/meson.build
new file mode 100644
index 0000000..afe740b
--- /dev/null
+++ b/test cases/unit/44 vscpp17/meson.build
@@ -0,0 +1,4 @@
+project('msvc_cpp17', 'cpp', default_options: ['cpp_std=c++17'])
+
+exe = executable('msvc_cpp17', 'main.cpp')
+test('msvc_cpp17', exe)
diff --git a/test cases/unit/45 native dep pkgconfig var/cross_pkgconfig.py b/test cases/unit/45 native dep pkgconfig var/cross_pkgconfig.py
new file mode 100755
index 0000000..f0d89ee
--- /dev/null
+++ b/test cases/unit/45 native dep pkgconfig var/cross_pkgconfig.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import subprocess
+
+environ = os.environ.copy()
+environ['PKG_CONFIG_LIBDIR'] = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)), 'cross_pkgconfig')
+
+sys.exit(
+ subprocess.run(['pkg-config'] + sys.argv[1:], env=environ).returncode)
diff --git a/test cases/unit/45 native dep pkgconfig var/cross_pkgconfig/dep_tester.pc b/test cases/unit/45 native dep pkgconfig var/cross_pkgconfig/dep_tester.pc
new file mode 100644
index 0000000..67d7afa
--- /dev/null
+++ b/test cases/unit/45 native dep pkgconfig var/cross_pkgconfig/dep_tester.pc
@@ -0,0 +1,5 @@
+dep_type=cross
+
+Name: dependency() test
+Description: dependency() test
+Version: 0
diff --git a/test cases/unit/45 native dep pkgconfig var/meson.build b/test cases/unit/45 native dep pkgconfig var/meson.build
new file mode 100644
index 0000000..d95dbcd
--- /dev/null
+++ b/test cases/unit/45 native dep pkgconfig var/meson.build
@@ -0,0 +1,15 @@
+project('native dep pkgconfig test')
+
+if get_option('start_native')
+ dep_native = dependency('dep_tester', native: true, method: 'pkg-config')
+ dep_cross = dependency('dep_tester', native: false, method: 'pkg-config')
+else
+ dep_cross = dependency('dep_tester', native: false, method: 'pkg-config')
+ dep_native = dependency('dep_tester', native: true, method: 'pkg-config')
+endif
+
+dep_type = dep_native.get_pkgconfig_variable('dep_type')
+assert(dep_type == 'native', 'Expected native')
+
+dep_type = dep_cross.get_pkgconfig_variable('dep_type')
+assert(dep_type == 'cross', 'Expected cross')
diff --git a/test cases/unit/45 native dep pkgconfig var/meson_options.txt b/test cases/unit/45 native dep pkgconfig var/meson_options.txt
new file mode 100644
index 0000000..37006dd
--- /dev/null
+++ b/test cases/unit/45 native dep pkgconfig var/meson_options.txt
@@ -0,0 +1,6 @@
+option(
+ 'start_native',
+ type : 'boolean',
+ value : 'false',
+ description : 'Start by creating a dependency() with native : true',
+)
diff --git a/test cases/unit/45 native dep pkgconfig var/native_pkgconfig/dep_tester.pc b/test cases/unit/45 native dep pkgconfig var/native_pkgconfig/dep_tester.pc
new file mode 100644
index 0000000..affaa97
--- /dev/null
+++ b/test cases/unit/45 native dep pkgconfig var/native_pkgconfig/dep_tester.pc
@@ -0,0 +1,5 @@
+dep_type=native
+
+Name: dependency() test
+Description: dependency() test
+Version: 0
diff --git a/test cases/unit/46 native file binary/meson.build b/test cases/unit/46 native file binary/meson.build
new file mode 100644
index 0000000..2f55fe2
--- /dev/null
+++ b/test cases/unit/46 native file binary/meson.build
@@ -0,0 +1,21 @@
+project('test project')
+
+case = get_option('case')
+
+if case == 'find_program'
+ prog = find_program('bash')
+ result = run_command(prog, ['--version'], check: true)
+ assert(result.stdout().strip().endswith('12345'), 'Didn\'t load bash from config file')
+elif case == 'config_dep'
+ add_languages('cpp')
+ dep = dependency('llvm', method : 'config-tool')
+ assert(dep.get_configtool_variable('version').endswith('12345'), 'Didn\'t load llvm from config file')
+elif case == 'python3'
+ prog = import('python3').find_python()
+ result = run_command(prog, ['--version'], check: true)
+ assert(result.stdout().strip().endswith('12345'), 'Didn\'t load python3 from config file')
+elif case == 'python'
+ prog = import('python').find_installation()
+ result = run_command(prog, ['--version'], check: true)
+ assert(result.stdout().strip().endswith('12345'), 'Didn\'t load python from config file')
+endif
diff --git a/test cases/unit/46 native file binary/meson_options.txt b/test cases/unit/46 native file binary/meson_options.txt
new file mode 100644
index 0000000..651da0e
--- /dev/null
+++ b/test cases/unit/46 native file binary/meson_options.txt
@@ -0,0 +1,5 @@
+option(
+ 'case',
+ type : 'combo',
+ choices : ['find_program', 'config_dep', 'python3', 'python']
+)
diff --git a/test cases/unit/47 reconfigure/main.c b/test cases/unit/47 reconfigure/main.c
new file mode 100644
index 0000000..25927f5
--- /dev/null
+++ b/test cases/unit/47 reconfigure/main.c
@@ -0,0 +1,4 @@
+int main(int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/test cases/unit/47 reconfigure/meson.build b/test cases/unit/47 reconfigure/meson.build
new file mode 100644
index 0000000..4f35458
--- /dev/null
+++ b/test cases/unit/47 reconfigure/meson.build
@@ -0,0 +1,11 @@
+project('test-reconfigure', 'c')
+
+message('opt1 ' + get_option('opt1'))
+message('opt2 ' + get_option('opt2'))
+message('opt3 ' + get_option('opt3'))
+message('opt4 ' + get_option('opt4'))
+
+exe = executable('test1', 'main.c')
+test('test1', exe)
+
+sub1 = subproject('sub1')
diff --git a/test cases/unit/47 reconfigure/meson_options.txt b/test cases/unit/47 reconfigure/meson_options.txt
new file mode 100644
index 0000000..728f7b7
--- /dev/null
+++ b/test cases/unit/47 reconfigure/meson_options.txt
@@ -0,0 +1,4 @@
+option('opt1', type : 'string', value : 'default1')
+option('opt2', type : 'string', value : 'default2')
+option('opt3', type : 'string', value : 'default3')
+option('opt4', type : 'string', value : 'default4')
diff --git a/test cases/unit/47 reconfigure/subprojects/sub1/meson.build b/test cases/unit/47 reconfigure/subprojects/sub1/meson.build
new file mode 100644
index 0000000..30fd19d
--- /dev/null
+++ b/test cases/unit/47 reconfigure/subprojects/sub1/meson.build
@@ -0,0 +1,3 @@
+project('sub1')
+
+message('sub1:werror @0@'.format(get_option('werror')))
diff --git a/test cases/unit/48 testsetup default/envcheck.py b/test cases/unit/48 testsetup default/envcheck.py
new file mode 100644
index 0000000..34ad76d
--- /dev/null
+++ b/test cases/unit/48 testsetup default/envcheck.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+
+import os
+
+assert 'ENV_A' in os.environ
+assert 'ENV_B' in os.environ
+assert 'ENV_C' in os.environ
+
+print('ENV_A is', os.environ['ENV_A'])
+print('ENV_B is', os.environ['ENV_B'])
+print('ENV_C is', os.environ['ENV_C'])
diff --git a/test cases/unit/48 testsetup default/meson.build b/test cases/unit/48 testsetup default/meson.build
new file mode 100644
index 0000000..bdd35b8
--- /dev/null
+++ b/test cases/unit/48 testsetup default/meson.build
@@ -0,0 +1,23 @@
+project('testsetup default', 'c')
+
+envcheck = find_program('envcheck.py')
+
+# Defining ENV_A in test-env should overwrite ENV_A from test setup
+env_1 = environment()
+env_1.set('ENV_A', '1')
+test('test-env', envcheck, env: env_1)
+
+# Defining default env which is used unless --setup is given or the
+# env variable is defined in the test.
+env_2 = environment()
+env_2.set('ENV_A', '2')
+env_2.set('ENV_B', '2')
+env_2.set('ENV_C', '2')
+add_test_setup('mydefault', env: env_2, is_default: true)
+
+# Defining a test setup that will update some of the env variables
+# from the default test setup.
+env_3 = env_2
+env_3.set('ENV_A', '3')
+env_3.set('ENV_B', '3')
+add_test_setup('other', env: env_3)
diff --git a/test cases/unit/49 pkgconfig csharp library/meson.build b/test cases/unit/49 pkgconfig csharp library/meson.build
new file mode 100644
index 0000000..148d40f
--- /dev/null
+++ b/test cases/unit/49 pkgconfig csharp library/meson.build
@@ -0,0 +1,10 @@
+project('pkgformat', 'cs',
+ version : '1.0')
+
+pkgg = import('pkgconfig')
+
+l = library('libsomething', 'somelib.cs')
+
+pkgg.generate(l,
+ version: '1.0',
+ description: 'A library that does something')
diff --git a/test cases/unit/49 pkgconfig csharp library/somelib.cs b/test cases/unit/49 pkgconfig csharp library/somelib.cs
new file mode 100644
index 0000000..24d37ed
--- /dev/null
+++ b/test cases/unit/49 pkgconfig csharp library/somelib.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Abc
+{
+ public static class Something
+ {
+ public static bool Api1(this String str)
+ {
+ return str == "foo";
+ }
+ }
+}
diff --git a/test cases/unit/5 compiler detection/compiler wrapper.py b/test cases/unit/5 compiler detection/compiler wrapper.py
new file mode 100644
index 0000000..fedd343
--- /dev/null
+++ b/test cases/unit/5 compiler detection/compiler wrapper.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import subprocess
+
+sys.exit(subprocess.call(sys.argv[1:]))
diff --git a/test cases/unit/5 compiler detection/meson.build b/test cases/unit/5 compiler detection/meson.build
new file mode 100644
index 0000000..8b47bd4
--- /dev/null
+++ b/test cases/unit/5 compiler detection/meson.build
@@ -0,0 +1,8 @@
+project('trivial test',
+ ['c', 'cpp', 'objc', 'objcpp'],
+ meson_version : '>=0.27.0')
+
+executable('trivialc', 'trivial.c')
+executable('trivialcpp', 'trivial.cc')
+executable('trivialobjc', 'trivial.m')
+executable('trivialobjcpp', 'trivial.mm')
diff --git a/test cases/unit/5 compiler detection/trivial.c b/test cases/unit/5 compiler detection/trivial.c
new file mode 100644
index 0000000..24ac454
--- /dev/null
+++ b/test cases/unit/5 compiler detection/trivial.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("Trivial test is working.\n");
+ return 0;
+}
diff --git a/test cases/unit/5 compiler detection/trivial.cc b/test cases/unit/5 compiler detection/trivial.cc
new file mode 100644
index 0000000..8aa907b
--- /dev/null
+++ b/test cases/unit/5 compiler detection/trivial.cc
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int argc, char **argv) {
+ std::cout << "C++ seems to be working." << std::endl;
+ return 0;
+}
diff --git a/test cases/unit/5 compiler detection/trivial.m b/test cases/unit/5 compiler detection/trivial.m
new file mode 100644
index 0000000..f2e2315
--- /dev/null
+++ b/test cases/unit/5 compiler detection/trivial.m
@@ -0,0 +1,5 @@
+#import<stdio.h>
+
+int main(int argc, char **argv) {
+ return 0;
+} \ No newline at end of file
diff --git a/test cases/unit/5 compiler detection/trivial.mm b/test cases/unit/5 compiler detection/trivial.mm
new file mode 100644
index 0000000..f9d4e19
--- /dev/null
+++ b/test cases/unit/5 compiler detection/trivial.mm
@@ -0,0 +1,8 @@
+#import<stdio.h>
+
+class MyClass {
+};
+
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/unit/50 noncross options/meson.build b/test cases/unit/50 noncross options/meson.build
new file mode 100644
index 0000000..6d479d6
--- /dev/null
+++ b/test cases/unit/50 noncross options/meson.build
@@ -0,0 +1,14 @@
+project('std_remains', 'c', default_options: ['c_std=c99'])
+
+executable('prog', 'prog.c')
+
+# Check that native: true does not affect the use of c_std in
+# non-cross builds
+
+if not meson.is_cross_build()
+ executable('prog2', 'prog.c', native: true)
+
+ # Check that even deps marked as native are found
+ # by default when not cross compiling.
+ dependency('ylib', method: 'pkg-config')
+endif
diff --git a/test cases/unit/50 noncross options/prog.c b/test cases/unit/50 noncross options/prog.c
new file mode 100644
index 0000000..0314ff1
--- /dev/null
+++ b/test cases/unit/50 noncross options/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/unit/50 noncross options/ylib.pc b/test cases/unit/50 noncross options/ylib.pc
new file mode 100644
index 0000000..afec2d3
--- /dev/null
+++ b/test cases/unit/50 noncross options/ylib.pc
@@ -0,0 +1,13 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib/x86_64-linux-gnu
+sharedlibdir=${libdir}
+includedir=${prefix}/include
+
+Name: ylib
+Description: ylib compression library
+Version: 1.2.3
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -ly
+Cflags: -I${includedir}
diff --git a/test cases/unit/51 ldflagdedup/bob.c b/test cases/unit/51 ldflagdedup/bob.c
new file mode 100644
index 0000000..a68d4b1
--- /dev/null
+++ b/test cases/unit/51 ldflagdedup/bob.c
@@ -0,0 +1,5 @@
+#include<gmodule.h>
+
+int func() {
+ return 0;
+}
diff --git a/test cases/unit/51 ldflagdedup/meson.build b/test cases/unit/51 ldflagdedup/meson.build
new file mode 100644
index 0000000..0bbcc50
--- /dev/null
+++ b/test cases/unit/51 ldflagdedup/meson.build
@@ -0,0 +1,12 @@
+project('lddedup', 'c')
+
+# Chosen because its ldflags contains -Wl,--export-dynamic,
+# which must be deduplicated.
+gm = dependency('gmodule-2.0')
+
+lib = static_library('bob', 'bob.c',
+ dependencies: gm)
+
+executable('prog', 'prog.c',
+ link_with: lib,
+ dependencies: gm)
diff --git a/test cases/unit/51 ldflagdedup/prog.c b/test cases/unit/51 ldflagdedup/prog.c
new file mode 100644
index 0000000..02c599d
--- /dev/null
+++ b/test cases/unit/51 ldflagdedup/prog.c
@@ -0,0 +1,7 @@
+#include<gmodule.h>
+
+int func();
+
+int main(int argc, char **argv) {
+ return func();
+}
diff --git a/test cases/unit/52 pkgconfig static link order/dummy.c b/test cases/unit/52 pkgconfig static link order/dummy.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/52 pkgconfig static link order/dummy.c
diff --git a/test cases/unit/52 pkgconfig static link order/meson.build b/test cases/unit/52 pkgconfig static link order/meson.build
new file mode 100644
index 0000000..31449e5
--- /dev/null
+++ b/test cases/unit/52 pkgconfig static link order/meson.build
@@ -0,0 +1,11 @@
+project('link order test', 'c')
+
+dep = library('dependency', 'dummy.c')
+lib = static_library('something', 'dummy.c', link_with: dep)
+
+import('pkgconfig').generate(
+ name: 'libsomething',
+ description: 'test library',
+ libraries: lib,
+ version: '1'
+)
diff --git a/test cases/unit/53 clang-format/.clang-format b/test cases/unit/53 clang-format/.clang-format
new file mode 100644
index 0000000..5c60ac9
--- /dev/null
+++ b/test cases/unit/53 clang-format/.clang-format
@@ -0,0 +1,5 @@
+---
+BasedOnStyle: LLVM
+IndentWidth: 4
+UseTab: Never
+---
diff --git a/test cases/unit/53 clang-format/dummydir.h/dummy.dat b/test cases/unit/53 clang-format/dummydir.h/dummy.dat
new file mode 100644
index 0000000..80c6165
--- /dev/null
+++ b/test cases/unit/53 clang-format/dummydir.h/dummy.dat
@@ -0,0 +1 @@
+Placeholder to track enclosing directory in git. Not to be analyzed.
diff --git a/test cases/unit/53 clang-format/header_expected_h b/test cases/unit/53 clang-format/header_expected_h
new file mode 100644
index 0000000..4303176
--- /dev/null
+++ b/test cases/unit/53 clang-format/header_expected_h
@@ -0,0 +1,3 @@
+#pragma once
+
+int fun(int argc);
diff --git a/test cases/unit/53 clang-format/header_orig_h b/test cases/unit/53 clang-format/header_orig_h
new file mode 100644
index 0000000..f2222f3
--- /dev/null
+++ b/test cases/unit/53 clang-format/header_orig_h
@@ -0,0 +1,9 @@
+#pragma once
+
+int
+fun
+(
+int
+argc
+)
+;
diff --git a/test cases/unit/53 clang-format/meson.build b/test cases/unit/53 clang-format/meson.build
new file mode 100644
index 0000000..09973db
--- /dev/null
+++ b/test cases/unit/53 clang-format/meson.build
@@ -0,0 +1,3 @@
+project('clangformat', 'c')
+
+executable('prog', 'prog.c')
diff --git a/test cases/unit/53 clang-format/prog_expected_c b/test cases/unit/53 clang-format/prog_expected_c
new file mode 100644
index 0000000..a045966
--- /dev/null
+++ b/test cases/unit/53 clang-format/prog_expected_c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ printf("Awful.\n");
+ return 0;
+}
diff --git a/test cases/unit/53 clang-format/prog_orig_c b/test cases/unit/53 clang-format/prog_orig_c
new file mode 100644
index 0000000..23a2b57
--- /dev/null
+++ b/test cases/unit/53 clang-format/prog_orig_c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+
+
+
+int
+main(
+int
+argc,
+char**
+argv)
+{
+printf(
+"Awful.\n"
+)
+;
+return
+0
+;
+}
diff --git a/test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson.build b/test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson.build
new file mode 100644
index 0000000..4d0aeeb
--- /dev/null
+++ b/test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson.build
@@ -0,0 +1,9 @@
+pfggggaergaeg(sdgrgjgn)aga
+
+rgqeh
+th
+thtr
+e
+tb
+tbqebt
+tbqebttrtt
diff --git a/test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson_options.txt b/test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson_options.txt
new file mode 100644
index 0000000..f15d352
--- /dev/null
+++ b/test cases/unit/54 introspect buildoptions/subprojects/projectBad/meson_options.txt
@@ -0,0 +1 @@
+option('should_not_appear', type: 'integer', min: 0, value: 125)
diff --git a/test cases/unit/55 dedup compiler libs/app/app.c b/test cases/unit/55 dedup compiler libs/app/app.c
new file mode 100644
index 0000000..4e215b3
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/app/app.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <liba.h>
+#include <libb.h>
+
+int
+main(void)
+{
+ printf("start value = %d\n", liba_get());
+ liba_add(2);
+ libb_mul(5);
+ printf("end value = %d\n", liba_get());
+ return 0;
+}
diff --git a/test cases/unit/55 dedup compiler libs/app/meson.build b/test cases/unit/55 dedup compiler libs/app/meson.build
new file mode 100644
index 0000000..82ac306
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/app/meson.build
@@ -0,0 +1,2 @@
+executable('app', 'app.c',
+ dependencies: [liba_dep, libb_dep])
diff --git a/test cases/unit/55 dedup compiler libs/liba/liba.c b/test cases/unit/55 dedup compiler libs/liba/liba.c
new file mode 100644
index 0000000..962d47f
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/liba/liba.c
@@ -0,0 +1,18 @@
+#include "liba.h"
+
+static int val;
+
+void liba_add(int x)
+{
+ val += x;
+}
+
+void liba_sub(int x)
+{
+ val -= x;
+}
+
+int liba_get(void)
+{
+ return val;
+}
diff --git a/test cases/unit/55 dedup compiler libs/liba/liba.h b/test cases/unit/55 dedup compiler libs/liba/liba.h
new file mode 100644
index 0000000..a980cdc
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/liba/liba.h
@@ -0,0 +1,8 @@
+#ifndef LIBA_H_
+#define LIBA_H_
+
+void liba_add(int x);
+void liba_sub(int x);
+int liba_get(void);
+
+#endif
diff --git a/test cases/unit/55 dedup compiler libs/liba/meson.build b/test cases/unit/55 dedup compiler libs/liba/meson.build
new file mode 100644
index 0000000..eccfa46
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/liba/meson.build
@@ -0,0 +1,8 @@
+deps = [dependency('threads'), cc.find_library('dl'), cc.find_library('m')]
+
+liba = library('a', 'liba.c',
+ dependencies: deps)
+
+liba_dep = declare_dependency(link_with: liba,
+ include_directories: include_directories('.'),
+ dependencies: deps)
diff --git a/test cases/unit/55 dedup compiler libs/libb/libb.c b/test cases/unit/55 dedup compiler libs/libb/libb.c
new file mode 100644
index 0000000..3720868
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/libb/libb.c
@@ -0,0 +1,7 @@
+#include <liba.h>
+#include "libb.h"
+
+void libb_mul(int x)
+{
+ liba_add(liba_get() * (x - 1));
+}
diff --git a/test cases/unit/55 dedup compiler libs/libb/libb.h b/test cases/unit/55 dedup compiler libs/libb/libb.h
new file mode 100644
index 0000000..2e4ddd0
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/libb/libb.h
@@ -0,0 +1,6 @@
+#ifndef _LIBB_H_
+#define _LIBB_H_
+
+void libb_mul(int x);
+
+#endif
diff --git a/test cases/unit/55 dedup compiler libs/libb/meson.build b/test cases/unit/55 dedup compiler libs/libb/meson.build
new file mode 100644
index 0000000..d59206f
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/libb/meson.build
@@ -0,0 +1,6 @@
+libb = library('b', 'libb.c',
+ dependencies: liba_dep)
+
+libb_dep = declare_dependency(link_with: libb,
+ include_directories: include_directories('.'),
+ dependencies: liba_dep)
diff --git a/test cases/unit/55 dedup compiler libs/meson.build b/test cases/unit/55 dedup compiler libs/meson.build
new file mode 100644
index 0000000..fad0ed5
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/meson.build
@@ -0,0 +1,7 @@
+project('temp', 'c')
+
+cc = meson.get_compiler('c')
+
+subdir('liba')
+subdir('libb')
+subdir('app')
diff --git a/test cases/unit/56 introspection/cp.py b/test cases/unit/56 introspection/cp.py
new file mode 100644
index 0000000..cb09cf3
--- /dev/null
+++ b/test cases/unit/56 introspection/cp.py
@@ -0,0 +1,5 @@
+#! /usr/bin/env python3
+
+import sys
+from shutil import copyfile
+copyfile(*sys.argv[1:])
diff --git a/test cases/unit/56 introspection/meson.build b/test cases/unit/56 introspection/meson.build
new file mode 100644
index 0000000..568d5cc
--- /dev/null
+++ b/test cases/unit/56 introspection/meson.build
@@ -0,0 +1,72 @@
+project('introspection', ['c', 'cpp'], version: '1.2.3', default_options: ['cpp_std=c++11', 'buildtype=debug'])
+
+dep1 = dependency('threads')
+dep2 = dependency('zlib', required: false)
+dep3 = dependency('bugDep1', required: get_option('test_opt1'))
+
+b1 = get_option('test_opt1')
+b2 = get_option('test_opt2')
+test_bool = b1 or b2
+test_bool = b1 and b2
+test_bool = not test_bool
+
+set_variable('list_test_plusassign', [])
+list_test_plusassign += ['bugs everywhere']
+dict_test = {list_test_plusassign[0]: 'even more bugs'}
+
+if not true
+ vers_str = '<=99.9.9'
+ dependency('somethingthatdoesnotexist', required: true, version: '>=1.2.3')
+ dependency('look_i_have_a_fallback', version: ['>=1.0.0', vers_str], fallback: ['oh_no', 'the_subproject_does_not_exist'])
+endif
+
+subdir('sharedlib')
+subdir('staticlib')
+
+var1 = '1'
+var2 = 2.to_string()
+var3 = 'test3'
+
+var4 = f'test @var1@ string' # TODO: Actually implement fstrings
+
+cus1 = custom_target('custom target test 1', output: 'file2', input: 'cp.py',
+ command: [find_program('cp.py'), '@INPUT@', '@OUTPUT@'])
+cus2 = custom_target('custom target test 2', output: 'file3', input: cus1,
+ command: [find_program('cp.py'), '@INPUT@', '@OUTPUT@'])
+
+t1 = executable('test' + var1, ['t1.cpp'], link_with: [sharedlib], install: not false, build_by_default: get_option('test_opt2'))
+t2 = executable('test@0@'.format('@0@'.format(var2)), sources: ['t2.cpp'], link_with: [staticlib])
+t3 = executable(var3, 't3.cpp', link_with: [sharedlib, staticlib], dependencies: [dep1])
+
+cus3 = custom_target('custom target test 3', output: 'file4', input: t3,
+ command: [find_program('cp.py'), '@INPUT@', '@OUTPUT@'])
+
+### BEGIN: Test inspired by taisei: https://github.com/taisei-project/taisei/blob/master/meson.build#L293
+systype = '@0@'.format(host_machine.system())
+systype = '@0@, @1@, @2@'.format(systype, host_machine.cpu_family(), host_machine.cpu())
+message(systype)
+### END: Test inspired by taisei
+
+# Minimal code version to produce bug #5376
+# Code inspired by https://github.com/mesa3d/mesa/blob/974c4d679c23373dbed386c696e3e3bc1bfa23ae/meson.build#L1341-L1347
+osmesa_lib_name = 'OSMesa'
+osmesa_bits = '8'
+osmesa_lib_name = osmesa_lib_name + osmesa_bits
+message(osmesa_lib_name) # Infinite recursion gets triggered here when the parameter osmesa_lib_name is resolved
+
+test('test case 1', t1)
+test('test case 2', t2, depends: t3)
+benchmark('benchmark 1', t3, args: [cus1, cus2, cus3])
+
+### Stuff to test the AST JSON printer
+foreach x : ['a', 'b', 'c']
+ if x == 'a'
+ message('a')
+ elif x == 'b'
+ message('a')
+ else
+ continue
+ endif
+ break
+ continue
+endforeach
diff --git a/test cases/unit/56 introspection/meson_options.txt b/test cases/unit/56 introspection/meson_options.txt
new file mode 100644
index 0000000..fc5cb4d
--- /dev/null
+++ b/test cases/unit/56 introspection/meson_options.txt
@@ -0,0 +1,2 @@
+option('test_opt1', type: 'boolean', value: false, description: 'simple boolean flag')
+option('test_opt2', type: 'boolean', value: true, description: 'simple boolean flag')
diff --git a/test cases/unit/56 introspection/sharedlib/meson.build b/test cases/unit/56 introspection/sharedlib/meson.build
new file mode 100644
index 0000000..7640bc7
--- /dev/null
+++ b/test cases/unit/56 introspection/sharedlib/meson.build
@@ -0,0 +1,2 @@
+SRC_shared = ['shared.cpp']
+sharedlib = shared_library('sharedTestLib', SRC_shared, extra_files: ['shared.hpp'])
diff --git a/test cases/unit/56 introspection/sharedlib/shared.cpp b/test cases/unit/56 introspection/sharedlib/shared.cpp
new file mode 100644
index 0000000..5030ab7
--- /dev/null
+++ b/test cases/unit/56 introspection/sharedlib/shared.cpp
@@ -0,0 +1,9 @@
+#include "shared.hpp"
+
+void SharedClass::doStuff() {
+ number++;
+}
+
+int SharedClass::getNumber() const {
+ return number;
+}
diff --git a/test cases/unit/56 introspection/sharedlib/shared.hpp b/test cases/unit/56 introspection/sharedlib/shared.hpp
new file mode 100644
index 0000000..dc9b2da
--- /dev/null
+++ b/test cases/unit/56 introspection/sharedlib/shared.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+class SharedClass {
+ private:
+ int number = 42;
+ public:
+ SharedClass() = default;
+ void doStuff();
+ int getNumber() const;
+}; \ No newline at end of file
diff --git a/test cases/unit/56 introspection/staticlib/meson.build b/test cases/unit/56 introspection/staticlib/meson.build
new file mode 100644
index 0000000..1cbb020
--- /dev/null
+++ b/test cases/unit/56 introspection/staticlib/meson.build
@@ -0,0 +1,3 @@
+SRC_static = ['static.c']
+extra_static = files(['static.h'])
+staticlib = static_library('staticTestLib', SRC_static, extra_files: extra_static)
diff --git a/test cases/unit/56 introspection/staticlib/static.c b/test cases/unit/56 introspection/staticlib/static.c
new file mode 100644
index 0000000..37ebc0d
--- /dev/null
+++ b/test cases/unit/56 introspection/staticlib/static.c
@@ -0,0 +1,5 @@
+#include "static.h"
+
+int add_numbers(int a, int b) {
+ return a + b;
+} \ No newline at end of file
diff --git a/test cases/unit/56 introspection/staticlib/static.h b/test cases/unit/56 introspection/staticlib/static.h
new file mode 100644
index 0000000..06da508
--- /dev/null
+++ b/test cases/unit/56 introspection/staticlib/static.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add_numbers(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test cases/unit/56 introspection/t1.cpp b/test cases/unit/56 introspection/t1.cpp
new file mode 100644
index 0000000..901e3f1
--- /dev/null
+++ b/test cases/unit/56 introspection/t1.cpp
@@ -0,0 +1,13 @@
+#include "sharedlib/shared.hpp"
+
+int main(void) {
+ SharedClass cl1;
+ if(cl1.getNumber() != 42) {
+ return 1;
+ }
+ cl1.doStuff();
+ if(cl1.getNumber() != 43) {
+ return 2;
+ }
+ return 0;
+}
diff --git a/test cases/unit/56 introspection/t2.cpp b/test cases/unit/56 introspection/t2.cpp
new file mode 100644
index 0000000..8323f46
--- /dev/null
+++ b/test cases/unit/56 introspection/t2.cpp
@@ -0,0 +1,8 @@
+#include "staticlib/static.h"
+
+int main(void) {
+ if(add_numbers(1, 2) != 3) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/unit/56 introspection/t3.cpp b/test cases/unit/56 introspection/t3.cpp
new file mode 100644
index 0000000..dd518e8
--- /dev/null
+++ b/test cases/unit/56 introspection/t3.cpp
@@ -0,0 +1,16 @@
+#include "sharedlib/shared.hpp"
+#include "staticlib/static.h"
+
+int main(void) {
+ for(int i = 0; i < 1000; add_numbers(i, 1)) {
+ SharedClass cl1;
+ if(cl1.getNumber() != 42) {
+ return 1;
+ }
+ cl1.doStuff();
+ if(cl1.getNumber() != 43) {
+ return 2;
+ }
+ }
+ return 0;
+}
diff --git a/test cases/unit/57 pkg_config_path option/build_extra_path/totally_made_up_dep.pc b/test cases/unit/57 pkg_config_path option/build_extra_path/totally_made_up_dep.pc
new file mode 100644
index 0000000..5b149f6
--- /dev/null
+++ b/test cases/unit/57 pkg_config_path option/build_extra_path/totally_made_up_dep.pc
@@ -0,0 +1,7 @@
+prefix=/
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: totally_made_up_dep
+Description: completely and totally made up for a test case
+Version: 4.5.6
diff --git a/test cases/unit/57 pkg_config_path option/host_extra_path/totally_made_up_dep.pc b/test cases/unit/57 pkg_config_path option/host_extra_path/totally_made_up_dep.pc
new file mode 100644
index 0000000..6d08687
--- /dev/null
+++ b/test cases/unit/57 pkg_config_path option/host_extra_path/totally_made_up_dep.pc
@@ -0,0 +1,7 @@
+prefix=/
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: totally_made_up_dep
+Description: completely and totally made up for a test case
+Version: 1.2.3 \ No newline at end of file
diff --git a/test cases/unit/57 pkg_config_path option/meson.build b/test cases/unit/57 pkg_config_path option/meson.build
new file mode 100644
index 0000000..f9ceead
--- /dev/null
+++ b/test cases/unit/57 pkg_config_path option/meson.build
@@ -0,0 +1,7 @@
+project('pkg_config_path option')
+
+build = dependency('totally_made_up_dep', native: true, method : 'pkg-config')
+host = dependency('totally_made_up_dep', native: false, method : 'pkg-config')
+
+assert(build.version() == '4.5.6', 'wrong version for build machine dependency')
+assert(host.version() == '1.2.3', 'wrong version for host machine dependency')
diff --git a/test cases/unit/58 introspect buildoptions/c_compiler.py b/test cases/unit/58 introspect buildoptions/c_compiler.py
new file mode 100644
index 0000000..c7241e7
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/c_compiler.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('c')
diff --git a/test cases/unit/58 introspect buildoptions/main.c b/test cases/unit/58 introspect buildoptions/main.c
new file mode 100644
index 0000000..709730f
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void) {
+ printf("Hello World");
+ return 0;
+}
diff --git a/test cases/unit/58 introspect buildoptions/meson.build b/test cases/unit/58 introspect buildoptions/meson.build
new file mode 100644
index 0000000..36e03e0
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/meson.build
@@ -0,0 +1,18 @@
+project('introspect buildargs', ['c'], default_options: ['c_std=c99', 'cpp_std=c++14', 'buildtype=release'])
+
+subA = subproject('projectA')
+
+target_name = 'MAIN'
+target_src = ['main.c']
+
+foo = false
+
+executable(target_name, target_src, build_by_default : foo)
+
+r = run_command(find_program('c_compiler.py'), check: false)
+if r.returncode() != 0
+ error('FAILED')
+endif
+
+add_languages(r.stdout().strip(), required: true)
+add_languages('afgggergearvearghergervergreaergaergasv', required: false)
diff --git a/test cases/unit/58 introspect buildoptions/meson_options.txt b/test cases/unit/58 introspect buildoptions/meson_options.txt
new file mode 100644
index 0000000..61f9a8d
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/meson_options.txt
@@ -0,0 +1,2 @@
+option('max_register_count', type: 'integer', min: 0, value: 125)
+option('use_external_fmt', type: 'boolean', value: false)
diff --git a/test cases/unit/58 introspect buildoptions/subprojects/evilFile.txt b/test cases/unit/58 introspect buildoptions/subprojects/evilFile.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/subprojects/evilFile.txt
diff --git a/test cases/unit/58 introspect buildoptions/subprojects/projectA/meson.build b/test cases/unit/58 introspect buildoptions/subprojects/projectA/meson.build
new file mode 100644
index 0000000..1ab9ee8
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/subprojects/projectA/meson.build
@@ -0,0 +1,3 @@
+project('introspect subproject A', 'c', default_options: ['cpp_std=c++11', 'buildtype=debug'])
+
+add_languages('cpp')
diff --git a/test cases/unit/58 introspect buildoptions/subprojects/projectA/meson_options.txt b/test cases/unit/58 introspect buildoptions/subprojects/projectA/meson_options.txt
new file mode 100644
index 0000000..fa77f95
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/subprojects/projectA/meson_options.txt
@@ -0,0 +1 @@
+option('subproj_var', type: 'boolean', value: false)
diff --git a/test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson.build b/test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson.build
new file mode 100644
index 0000000..500c1b9
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson.build
@@ -0,0 +1,9 @@
+pfggggaergaeg(sdgrgjgn)aga
+
+rgqeh
+th
+thtr
+e
+tb
+tbqebt
+tbqebttrtt \ No newline at end of file
diff --git a/test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson_options.txt b/test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson_options.txt
new file mode 100644
index 0000000..f15d352
--- /dev/null
+++ b/test cases/unit/58 introspect buildoptions/subprojects/projectBad/meson_options.txt
@@ -0,0 +1 @@
+option('should_not_appear', type: 'integer', min: 0, value: 125)
diff --git a/test cases/unit/59 native file override/crossfile b/test cases/unit/59 native file override/crossfile
new file mode 100644
index 0000000..9dc4fbc
--- /dev/null
+++ b/test cases/unit/59 native file override/crossfile
@@ -0,0 +1,16 @@
+[paths]
+bindir = 'binbar'
+datadir = 'databar'
+includedir = 'includebar'
+infodir = 'infobar'
+libdir = 'libbar'
+libexecdir = 'libexecbar'
+localedir = 'localebar'
+localstatedir = 'localstatebar'
+mandir = 'manbar'
+prefix = '/prefix'
+sbindir = 'sbinbar'
+sharedstatedir = 'sharedstatebar'
+sysconfdir = 'sysconfbar'
+
+; vim: ft=dosini
diff --git a/test cases/unit/59 native file override/crossfile2 b/test cases/unit/59 native file override/crossfile2
new file mode 100644
index 0000000..70946c9
--- /dev/null
+++ b/test cases/unit/59 native file override/crossfile2
@@ -0,0 +1,4 @@
+[paths]
+bindir = 'binbar2'
+
+; vim: ft=dosini
diff --git a/test cases/unit/59 native file override/meson.build b/test cases/unit/59 native file override/meson.build
new file mode 100644
index 0000000..6ada560
--- /dev/null
+++ b/test cases/unit/59 native file override/meson.build
@@ -0,0 +1,10 @@
+project('native file overrides')
+
+foreach o : ['bindir', 'datadir', 'includedir', 'infodir', 'libdir',
+ 'libexecdir', 'localedir', 'localstatedir', 'mandir', 'prefix',
+ 'sbindir', 'sharedstatedir', 'sysconfdir']
+ expected = get_option('def_' + o)
+ actual = get_option(o)
+ assert(expected == actual,
+ '@0@ should have been @1@, but was @2@!'.format(o, expected, actual))
+endforeach
diff --git a/test cases/unit/59 native file override/meson_options.txt b/test cases/unit/59 native file override/meson_options.txt
new file mode 100644
index 0000000..4d2abf9
--- /dev/null
+++ b/test cases/unit/59 native file override/meson_options.txt
@@ -0,0 +1,13 @@
+option('def_bindir', type: 'string', value : 'binfoo',)
+option('def_datadir', type: 'string', value : 'datafoo',)
+option('def_includedir', type: 'string', value : 'includefoo',)
+option('def_infodir', type: 'string', value : 'infofoo',)
+option('def_libdir', type: 'string', value : 'libfoo',)
+option('def_libexecdir', type: 'string', value : 'libexecfoo',)
+option('def_localedir', type: 'string', value : 'localefoo',)
+option('def_localstatedir', type: 'string', value : 'localstatefoo',)
+option('def_mandir', type: 'string', value : 'manfoo',)
+option('def_prefix', type: 'string', value : '/prefix',)
+option('def_sbindir', type: 'string', value : 'sbinfoo',)
+option('def_sharedstatedir', type: 'string', value : 'sharedstatefoo',)
+option('def_sysconfdir', type: 'string', value : 'sysconffoo',)
diff --git a/test cases/unit/59 native file override/nativefile b/test cases/unit/59 native file override/nativefile
new file mode 100644
index 0000000..a390725
--- /dev/null
+++ b/test cases/unit/59 native file override/nativefile
@@ -0,0 +1,16 @@
+[paths]
+bindir = 'binfoo'
+datadir = 'datafoo'
+includedir = 'includefoo'
+infodir = 'infofoo'
+libdir = 'libfoo'
+libexecdir = 'libexecfoo'
+localedir = 'localefoo'
+localstatedir = 'localstatefoo'
+mandir = 'manfoo'
+prefix = '/prefix'
+sbindir = 'sbinfoo'
+sharedstatedir = 'sharedstatefoo'
+sysconfdir = 'sysconffoo'
+
+; vim: ft=dosini
diff --git a/test cases/unit/6 std override/meson.build b/test cases/unit/6 std override/meson.build
new file mode 100644
index 0000000..0eac752
--- /dev/null
+++ b/test cases/unit/6 std override/meson.build
@@ -0,0 +1,10 @@
+project('cpp std override', 'cpp',
+ default_options : ['cpp_std=c++98',
+ 'werror=true'])
+
+executable('plain', 'progp.cpp',
+ override_options : 'cpp_std=none')
+executable('v98', 'prog98.cpp',
+ override_options : 'werror=false')
+executable('v11', 'prog11.cpp',
+ override_options : 'cpp_std=c++11')
diff --git a/test cases/unit/6 std override/prog11.cpp b/test cases/unit/6 std override/prog11.cpp
new file mode 100644
index 0000000..dde1fc0
--- /dev/null
+++ b/test cases/unit/6 std override/prog11.cpp
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int argc, char **argv) {
+ std::cout << "I am a C++11 test program.\n";
+ return 0;
+}
diff --git a/test cases/unit/6 std override/prog98.cpp b/test cases/unit/6 std override/prog98.cpp
new file mode 100644
index 0000000..67c326d
--- /dev/null
+++ b/test cases/unit/6 std override/prog98.cpp
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int argc, char **argv) {
+ std::cout << "I am a c++98 test program.\n";
+ return 0;
+}
diff --git a/test cases/unit/6 std override/progp.cpp b/test cases/unit/6 std override/progp.cpp
new file mode 100644
index 0000000..b9bd97f
--- /dev/null
+++ b/test cases/unit/6 std override/progp.cpp
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int argc, char **argv) {
+ std::cout << "I am a test program of undefined C++ standard.\n";
+ return 0;
+}
diff --git a/test cases/unit/60 identity cross/build_wrapper.py b/test cases/unit/60 identity cross/build_wrapper.py
new file mode 100755
index 0000000..15d5c07
--- /dev/null
+++ b/test cases/unit/60 identity cross/build_wrapper.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+
+import subprocess, sys, platform
+
+# Meson does not yet support Studio cc on Solaris, only gcc or clang
+if platform.system() == 'SunOS':
+ cc = 'gcc'
+else:
+ cc = 'cc'
+
+subprocess.call([cc, "-DEXTERNAL_BUILD"] + sys.argv[1:])
diff --git a/test cases/unit/60 identity cross/host_wrapper.py b/test cases/unit/60 identity cross/host_wrapper.py
new file mode 100755
index 0000000..a3a694a
--- /dev/null
+++ b/test cases/unit/60 identity cross/host_wrapper.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+
+import subprocess, sys, platform
+
+# Meson does not yet support Studio cc on Solaris, only gcc or clang
+if platform.system() == 'SunOS':
+ cc = 'gcc'
+else:
+ cc = 'cc'
+
+subprocess.call([cc, "-DEXTERNAL_HOST"] + sys.argv[1:])
diff --git a/test cases/unit/60 identity cross/meson.build b/test cases/unit/60 identity cross/meson.build
new file mode 100644
index 0000000..950137a
--- /dev/null
+++ b/test cases/unit/60 identity cross/meson.build
@@ -0,0 +1,15 @@
+project('identity cross test', 'c')
+
+assert(meson.get_compiler('c', native: true).get_define(
+ 'GOT',
+ args : [ '-DARG_BUILD' ],
+ prefix : '#include "stuff.h"',
+ include_directories: include_directories('.'),
+) == 'BUILD', 'did not get BUILD from native: true compiler')
+
+assert(meson.get_compiler('c', native: false).get_define(
+ 'GOT',
+ args : [ '-DARG_HOST' ],
+ prefix : '#include "stuff.h"',
+ include_directories: include_directories('.'),
+) == 'HOST', 'did not get HOST from native: false compiler')
diff --git a/test cases/unit/60 identity cross/stuff.h b/test cases/unit/60 identity cross/stuff.h
new file mode 100644
index 0000000..62f1cc9
--- /dev/null
+++ b/test cases/unit/60 identity cross/stuff.h
@@ -0,0 +1,27 @@
+#ifdef EXTERNAL_BUILD
+ #ifndef ARG_BUILD
+ #error "External is build but arg_build is not set."
+ #elif defined(ARG_HOST)
+ #error "External is build but arg_host is set."
+ #else
+ #define GOT BUILD
+ #endif
+#endif
+
+#ifdef EXTERNAL_HOST
+ #ifndef ARG_HOST
+ #error "External is host but arg_host is not set."
+ #elif defined(ARG_BUILD)
+ #error "External is host but arg_build is set."
+ #else
+ #define GOT HOST
+ #endif
+#endif
+
+#if defined(EXTERNAL_BUILD) && defined(EXTERNAL_HOST)
+ #error "Both external build and external host set."
+#endif
+
+#if !defined(EXTERNAL_BUILD) && !defined(EXTERNAL_HOST)
+ #error "Neither external build nor external host is set."
+#endif
diff --git a/test cases/unit/61 pkgconfig relative paths/pkgconfig/librelativepath.pc b/test cases/unit/61 pkgconfig relative paths/pkgconfig/librelativepath.pc
new file mode 100644
index 0000000..dae1eed
--- /dev/null
+++ b/test cases/unit/61 pkgconfig relative paths/pkgconfig/librelativepath.pc
@@ -0,0 +1,9 @@
+prefix=../relativepath
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+
+Name: Relative path
+Description: Relative path library
+Version: 0.0.1
+Libs: -L${libdir} -lrelativepath
+Cflags:
diff --git a/test cases/unit/62 cmake_prefix_path/meson.build b/test cases/unit/62 cmake_prefix_path/meson.build
new file mode 100644
index 0000000..442bbd3
--- /dev/null
+++ b/test cases/unit/62 cmake_prefix_path/meson.build
@@ -0,0 +1,4 @@
+project('cmake prefix path test')
+
+d = dependency('mesontest', method : 'cmake')
+assert(d.version() == '1.2.3', 'Got the wrong version!')
diff --git a/test cases/unit/62 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake b/test cases/unit/62 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake
new file mode 100644
index 0000000..289b349
--- /dev/null
+++ b/test cases/unit/62 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake
@@ -0,0 +1,4 @@
+set(MESONTEST_VERSION "1.2.3")
+set(MESONTEST_LIBRARIES "foo.so")
+set(MESONTEST_INCLUDE_DIR "")
+set(MESONTEST_FOUND "TRUE")
diff --git a/test cases/unit/63 cmake parser/meson.build b/test cases/unit/63 cmake parser/meson.build
new file mode 100644
index 0000000..472561d
--- /dev/null
+++ b/test cases/unit/63 cmake parser/meson.build
@@ -0,0 +1,19 @@
+project('61 cmake parser')
+
+dep = dependency('mesontest')
+
+# Test a bunch of variations of the set() command
+assert(dep.get_variable(cmake : 'VAR_WITHOUT_SPACES') == 'NoSpaces', 'set() without spaces incorrect')
+assert(dep.get_variable(cmake : 'VAR_WITH_SPACES') == 'With Spaces', 'set() with spaces incorrect')
+
+assert(dep.get_variable(cmake : 'VAR_WITHOUT_SPACES_PS') == 'NoSpaces', 'set(PARENT_SCOPE) without spaces incorrect')
+assert(dep.get_variable(cmake : 'VAR_WITH_SPACES_PS') == 'With Spaces', 'set(PARENT_SCOPE) with spaces incorrect')
+
+assert(dep.get_variable(cmake : 'VAR_THAT_IS_UNSET', default_value : 'sentinal') == 'sentinal', 'set() to unset is incorrect')
+assert(dep.get_variable(cmake : 'CACHED_STRING_NS') == 'foo', 'set(CACHED) without spaces is incorrect')
+assert(dep.get_variable(cmake : 'CACHED_STRING_WS') == 'foo bar', 'set(CACHED STRING) with spaces is incorrect')
+assert(dep.get_variable(cmake : 'CACHED_STRING_ARRAY_NS') == 'foo;bar', 'set(CACHED STRING) without spaces is incorrect')
+assert(dep.get_variable(cmake : 'CACHED_STRING_ARRAY_WS') == 'foo;foo bar;bar', 'set(CACHED STRING[]) with spaces is incorrect')
+
+# We don't support this, so it should be unset.
+assert(dep.get_variable(cmake : 'ENV{var}', default_value : 'sentinal') == 'sentinal', 'set(ENV) should be ignored')
diff --git a/test cases/unit/63 cmake parser/prefix/lib/cmake/mesontest/mesontest-config.cmake b/test cases/unit/63 cmake parser/prefix/lib/cmake/mesontest/mesontest-config.cmake
new file mode 100644
index 0000000..7474eb7
--- /dev/null
+++ b/test cases/unit/63 cmake parser/prefix/lib/cmake/mesontest/mesontest-config.cmake
@@ -0,0 +1,63 @@
+# This should be enough to satisfy the basic parser
+set(MESONTEST_VERSION "1.2.3")
+set(MESONTEST_LIBRARIES "foo.so")
+set(MESONTEST_INCLUDE_DIR "")
+set(MESONTEST_FOUND "TRUE")
+
+## Tests for set() in its various forms
+
+# Basic usage
+set(VAR_WITHOUT_SPACES "NoSpaces")
+set(VAR_WITH_SPACES "With Spaces")
+
+# test of PARENT_SCOPE, requires a function to have a parent scope obviously...
+function(foo)
+ set(VAR_WITHOUT_SPACES_PS "NoSpaces" PARENT_SCOPE)
+ set(VAR_WITH_SPACES_PS "With Spaces" PARENT_SCOPE)
+endfunction(foo)
+foo()
+
+# Using set() to unset values
+set(VAR_THAT_IS_UNSET "foo")
+set(VAR_THAT_IS_UNSET)
+
+# The more advanced form that uses CACHE
+# XXX: Why don't we read the type and use that instead of always treat things as strings?
+set(CACHED_STRING_NS "foo" CACHE STRING "docstring")
+set(CACHED_STRING_WS "foo bar" CACHE STRING "docstring")
+set(CACHED_STRING_ARRAY_NS "foo;bar" CACHE STRING "doc string")
+set(CACHED_STRING_ARRAY_WS "foo;foo bar;bar" CACHE STRING "stuff" FORCE)
+
+set(CACHED_BOOL ON CACHE BOOL "docstring")
+
+set(CACHED_PATH_NS "foo/bar" CACHE PATH "docstring")
+set(CACHED_PATH_WS "foo bar/fin" CACHE PATH "docstring")
+
+set(CACHED_FILEPATH_NS "foo/bar.txt" CACHE FILEPATH "docstring")
+set(CACHED_FILEPATH_WS "foo bar/fin.txt" CACHE FILEPATH "docstring")
+
+# Set ENV, we don't support this so it shouldn't be showing up
+set(ENV{var}, "foo")
+
+
+## Tests for set_properties()
+# We need something to attach properties too
+add_custom_target(MESONTEST_FOO ALL)
+
+set_property(TARGET MESONTEST_FOO PROPERTY FOLDER "value")
+set_property(TARGET MESONTEST_FOO APPEND PROPERTY FOLDER "name")
+set_property(TARGET MESONTEST_FOO PROPERTY FOLDER "value")
+set_property(TARGET MESONTEST_FOO APPEND_STRING PROPERTY FOLDER "name")
+
+set_property(TARGET MESONTEST_FOO PROPERTY FOLDER "value space")
+set_property(TARGET MESONTEST_FOO PROPERTY FOLDER "value space")
+set_property(TARGET MESONTEST_FOO APPEND PROPERTY FOLDER "name space")
+set_property(TARGET MESONTEST_FOO PROPERTY FOLDER "value space")
+set_property(TARGET MESONTEST_FOO APPEND_STRING PROPERTY FOLDER "name space")
+
+## Tests for set_target_properties()
+set_target_properties(MESONTEST_FOO PROPERTIES FOLDER "value")
+set_target_properties(MESONTEST_FOO PROPERTIES FOLDER "value space")
+set_target_properties(MESONTEST_FOO PROPERTIES FOLDER "value" OUTPUT_NAME "another value")
+set_target_properties(MESONTEST_FOO PROPERTIES FOLDER "value space" OUTPUT_NAME "another value")
+set_target_properties(MESONTEST_FOO PROPERTIES FOLDER "value space" OUTPUT_NAME "value") \ No newline at end of file
diff --git a/test cases/unit/64 alias target/main.c b/test cases/unit/64 alias target/main.c
new file mode 100644
index 0000000..0fb4389
--- /dev/null
+++ b/test cases/unit/64 alias target/main.c
@@ -0,0 +1,3 @@
+int main(int argc, char *argv[]) {
+ return 0;
+}
diff --git a/test cases/unit/64 alias target/meson.build b/test cases/unit/64 alias target/meson.build
new file mode 100644
index 0000000..bcd4005
--- /dev/null
+++ b/test cases/unit/64 alias target/meson.build
@@ -0,0 +1,17 @@
+project('alias target', 'c')
+
+python3 = import('python').find_installation()
+
+exe_target = executable('prog', 'main.c',
+ build_by_default : false)
+
+custom_target = custom_target('custom-target',
+ output : 'hello.txt',
+ command : [python3, '-c', 'print("hello")'],
+ capture : true,
+ build_by_default : false
+)
+
+alias_target('build-all', [exe_target, custom_target])
+
+subdir('subdir')
diff --git a/test cases/unit/64 alias target/subdir/meson.build b/test cases/unit/64 alias target/subdir/meson.build
new file mode 100644
index 0000000..b3f5480
--- /dev/null
+++ b/test cases/unit/64 alias target/subdir/meson.build
@@ -0,0 +1,6 @@
+r = run_target('run-target',
+ command: [python3, '-c', 'print("a run target was here")']
+)
+
+alias_target('aliased-run', r)
+
diff --git a/test cases/unit/65 static archive stripping/app/appA.c b/test cases/unit/65 static archive stripping/app/appA.c
new file mode 100644
index 0000000..e44b54a
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/app/appA.c
@@ -0,0 +1,4 @@
+#include <stdio.h>
+#include <libA.h>
+
+int main(void) { printf("The answer is: %d\n", libA_func()); }
diff --git a/test cases/unit/65 static archive stripping/app/appB.c b/test cases/unit/65 static archive stripping/app/appB.c
new file mode 100644
index 0000000..0ec0b62
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/app/appB.c
@@ -0,0 +1,4 @@
+#include <stdio.h>
+#include <libB.h>
+
+int main(void) { printf("The answer is: %d\n", libB_func()); }
diff --git a/test cases/unit/65 static archive stripping/app/meson.build b/test cases/unit/65 static archive stripping/app/meson.build
new file mode 100644
index 0000000..118719d
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/app/meson.build
@@ -0,0 +1,7 @@
+project('app', ['c'])
+
+a = dependency('test-a')
+b = dependency('test-b')
+
+executable('appA', files('appA.c'), dependencies : a)
+executable('appB', files('appB.c'), dependencies : b)
diff --git a/test cases/unit/65 static archive stripping/lib/libA.c b/test cases/unit/65 static archive stripping/lib/libA.c
new file mode 100644
index 0000000..a97185e
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/lib/libA.c
@@ -0,0 +1,5 @@
+#include <libA.h>
+
+static int libA_func_impl(void) { return 0; }
+
+int libA_func(void) { return libA_func_impl(); }
diff --git a/test cases/unit/65 static archive stripping/lib/libA.h b/test cases/unit/65 static archive stripping/lib/libA.h
new file mode 100644
index 0000000..e6450cd
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/lib/libA.h
@@ -0,0 +1 @@
+int libA_func(void);
diff --git a/test cases/unit/65 static archive stripping/lib/libB.c b/test cases/unit/65 static archive stripping/lib/libB.c
new file mode 100644
index 0000000..0200b1f
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/lib/libB.c
@@ -0,0 +1,5 @@
+#include <libB.h>
+
+static int libB_func_impl(void) { return 0; }
+
+int libB_func(void) { return libB_func_impl(); }
diff --git a/test cases/unit/65 static archive stripping/lib/libB.h b/test cases/unit/65 static archive stripping/lib/libB.h
new file mode 100644
index 0000000..065a4a4
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/lib/libB.h
@@ -0,0 +1 @@
+int libB_func(void);
diff --git a/test cases/unit/65 static archive stripping/lib/meson.build b/test cases/unit/65 static archive stripping/lib/meson.build
new file mode 100644
index 0000000..ae50fa7
--- /dev/null
+++ b/test cases/unit/65 static archive stripping/lib/meson.build
@@ -0,0 +1,23 @@
+project('lib', ['c'])
+
+pkg = import('pkgconfig')
+
+a = library('test-a', files('libA.c'), install: true)
+install_headers(files('libA.h'), subdir: 'libA')
+pkg.generate(
+ a,
+ version: '0.0',
+ description: 'test library libA',
+ filebase: 'test-a',
+ name: 'test library libA',
+ subdirs: 'libA')
+
+b = static_library('test-b', files('libB.c'), install: true)
+install_headers(files('libB.h'), subdir: 'libB')
+pkg.generate(
+ b,
+ version: '0.0',
+ description: 'test library libB',
+ filebase: 'test-b',
+ name: 'test library libB',
+ subdirs: 'libB')
diff --git a/test cases/unit/66 static link/lib/func1.c b/test cases/unit/66 static link/lib/func1.c
new file mode 100644
index 0000000..cc934ad
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func1.c
@@ -0,0 +1,9 @@
+int func1()
+{
+ return 1;
+}
+
+int func1b()
+{
+ return 1;
+}
diff --git a/test cases/unit/66 static link/lib/func10.c b/test cases/unit/66 static link/lib/func10.c
new file mode 100644
index 0000000..75a911f
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func10.c
@@ -0,0 +1,4 @@
+int func10()
+{
+ return 1;
+}
diff --git a/test cases/unit/66 static link/lib/func11.c b/test cases/unit/66 static link/lib/func11.c
new file mode 100644
index 0000000..1d5119b
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func11.c
@@ -0,0 +1,6 @@
+int func10();
+
+int func11()
+{
+ return func10() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func12.c b/test cases/unit/66 static link/lib/func12.c
new file mode 100644
index 0000000..73db5c0
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func12.c
@@ -0,0 +1,7 @@
+int func10();
+int func11();
+
+int func12()
+{
+ return func10() + func11();
+}
diff --git a/test cases/unit/66 static link/lib/func14.c b/test cases/unit/66 static link/lib/func14.c
new file mode 100644
index 0000000..0277319
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func14.c
@@ -0,0 +1,4 @@
+int func14()
+{
+ return 1;
+}
diff --git a/test cases/unit/66 static link/lib/func15.c b/test cases/unit/66 static link/lib/func15.c
new file mode 100644
index 0000000..78303cc
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func15.c
@@ -0,0 +1,6 @@
+int func14();
+
+int func15()
+{
+ return func14() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func16.c b/test cases/unit/66 static link/lib/func16.c
new file mode 100644
index 0000000..379b682
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func16.c
@@ -0,0 +1,6 @@
+int func15();
+
+int func16()
+{
+ return func15() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func17.c b/test cases/unit/66 static link/lib/func17.c
new file mode 100644
index 0000000..d1d8ec4
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func17.c
@@ -0,0 +1,4 @@
+int func17()
+{
+ return 1;
+}
diff --git a/test cases/unit/66 static link/lib/func18.c b/test cases/unit/66 static link/lib/func18.c
new file mode 100644
index 0000000..c149085
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func18.c
@@ -0,0 +1,6 @@
+int func17();
+
+int func18()
+{
+ return func17() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func19.c b/test cases/unit/66 static link/lib/func19.c
new file mode 100644
index 0000000..69120e4
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func19.c
@@ -0,0 +1,7 @@
+int func17();
+int func18();
+
+int func19()
+{
+ return func17() + func18();
+}
diff --git a/test cases/unit/66 static link/lib/func2.c b/test cases/unit/66 static link/lib/func2.c
new file mode 100644
index 0000000..6b8f539
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func2.c
@@ -0,0 +1,6 @@
+int func1();
+
+int func2()
+{
+ return func1() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func3.c b/test cases/unit/66 static link/lib/func3.c
new file mode 100644
index 0000000..04f9f89
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func3.c
@@ -0,0 +1,4 @@
+int func3()
+{
+ return 1;
+}
diff --git a/test cases/unit/66 static link/lib/func4.c b/test cases/unit/66 static link/lib/func4.c
new file mode 100644
index 0000000..c44c990
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func4.c
@@ -0,0 +1,6 @@
+int func3();
+
+int func4()
+{
+ return func3() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func5.c b/test cases/unit/66 static link/lib/func5.c
new file mode 100644
index 0000000..8e07864
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func5.c
@@ -0,0 +1,4 @@
+int func5()
+{
+ return 1;
+}
diff --git a/test cases/unit/66 static link/lib/func6.c b/test cases/unit/66 static link/lib/func6.c
new file mode 100644
index 0000000..276fe7d
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func6.c
@@ -0,0 +1,6 @@
+int func5();
+
+int func6()
+{
+ return func5() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func7.c b/test cases/unit/66 static link/lib/func7.c
new file mode 100644
index 0000000..8c1a536
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func7.c
@@ -0,0 +1,4 @@
+int func7()
+{
+ return 1;
+}
diff --git a/test cases/unit/66 static link/lib/func8.c b/test cases/unit/66 static link/lib/func8.c
new file mode 100644
index 0000000..b7b6cd5
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func8.c
@@ -0,0 +1,6 @@
+int func7();
+
+int func8()
+{
+ return func7() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/func9.c b/test cases/unit/66 static link/lib/func9.c
new file mode 100644
index 0000000..852252d
--- /dev/null
+++ b/test cases/unit/66 static link/lib/func9.c
@@ -0,0 +1,6 @@
+int func8();
+
+int func9()
+{
+ return func8() + 1;
+}
diff --git a/test cases/unit/66 static link/lib/meson.build b/test cases/unit/66 static link/lib/meson.build
new file mode 100644
index 0000000..8f95fc4
--- /dev/null
+++ b/test cases/unit/66 static link/lib/meson.build
@@ -0,0 +1,80 @@
+project('test static link libs', 'c')
+
+pkg = import('pkgconfig')
+
+# libfunc2 should contain both func1() and func2() symbols
+libfunc1 = static_library('func1', 'func1.c',
+ install : false)
+libfunc2 = static_library('func2', 'func2.c',
+ link_whole : libfunc1,
+ install : true)
+
+# Same as above, but with link_with instead of link_whole,
+# libfunc4 should contain both func3() and func4() symbols
+libfunc3 = static_library('func3', 'func3.c',
+ install : false)
+libfunc4 = static_library('func4', 'func4.c',
+ link_with : libfunc3,
+ install : true)
+
+# Same as above, but also generate an pkg-config file. Use both_libraries() to
+# make sure a complete .pc file gets generated. libfunc5 should not be mentioned
+# into the .pc file because it's not installed.
+libfunc5 = static_library('func5', 'func5.c',
+ install : false)
+libfunc6 = both_libraries('func6', 'func6.c',
+ link_with : libfunc5,
+ install : true)
+pkg.generate(libfunc6)
+
+# libfunc9 should contain both func8() and func9() but not func7() because that
+# one gets installed. Also test that link_with and link_whole works the same way
+# because libfunc8 is uninstalled.
+libfunc7 = static_library('func7', 'func7.c',
+ install : true)
+libfunc8 = static_library('func8', 'func8.c',
+ link_with : libfunc7,
+ install : false)
+libfunc9_linkwith = static_library('func9_linkwith', 'func9.c',
+ link_with : libfunc8,
+ install : true)
+libfunc9_linkwhole = static_library('func9_linkwhole', 'func9.c',
+ link_whole : libfunc8,
+ install : true)
+
+# Pattern found in mesa:
+# - libfunc11 uses func10()
+# - libfunc12 uses both func10() and func11()
+# When a shared library link_whole on libfunc12, we ensure we don't include
+# func10.c.o twice which would fail to link.
+libfunc10 = static_library('func10', 'func10.c',
+ install : false)
+libfunc11 = static_library('func11', 'func11.c',
+ link_with : libfunc10,
+ install : false)
+libfunc12 = static_library('func12', 'func12.c',
+ link_with : [libfunc10, libfunc11],
+ install : false)
+libfunc13 = shared_library('func13', link_whole : libfunc12)
+
+# libfunc16 should contain func14(), func15() and func16()
+libfunc14 = static_library('func14', 'func14.c',
+ install : false)
+libfunc15 = static_library('func15', 'func15.c',
+ link_with : libfunc14,
+ install : false)
+libfunc16 = static_library('func16', 'func16.c',
+ link_with : libfunc15,
+ install : true)
+
+# Verify func17.c.o gets included only once into libfunc19, otherwise
+# func19-shared would failed with duplicated symbol.
+libfunc17 = static_library('func17', 'func17.c',
+ install : false)
+libfunc18 = static_library('func18', 'func18.c',
+ link_with : libfunc17,
+ install : false)
+libfunc19 = static_library('func19', 'func19.c',
+ link_whole : [libfunc17, libfunc18],
+ install : false)
+shared_library('func19-shared', link_whole : [libfunc19])
diff --git a/test cases/unit/66 static link/meson.build b/test cases/unit/66 static link/meson.build
new file mode 100644
index 0000000..dac17f8
--- /dev/null
+++ b/test cases/unit/66 static link/meson.build
@@ -0,0 +1,32 @@
+project('test static link', 'c')
+
+cc = meson.get_compiler('c')
+
+# Verify that installed libfunc2.a is usable
+func2_dep = cc.find_library('func2')
+test('test1', executable('test1', 'test1.c', dependencies : func2_dep))
+
+# Verify that installed libfunc4.a is usable
+func4_dep = cc.find_library('func4')
+test('test2', executable('test2', 'test2.c', dependencies : func4_dep))
+
+# Verify that installed pkg-config file is usable for both shared and static link
+func6_static_dep = dependency('func6', static : true)
+test('test3-static', executable('test3-static', 'test3.c',
+ dependencies : func6_static_dep))
+func6_shared_dep = dependency('func6', static : false)
+test('test3-shared', executable('test3-shared', 'test3.c',
+ dependencies : func6_shared_dep))
+
+# Verify that installed libfunc9.a contains func8() and func8() but not func7()
+func7_dep = cc.find_library('func7')
+func9_linkwhole_dep = cc.find_library('func9_linkwhole')
+test('test4-linkwhole', executable('test4-linkwhole', 'test4.c',
+ dependencies : [func7_dep, func9_linkwhole_dep]))
+func9_linkwith_dep = cc.find_library('func9_linkwith')
+test('test4-linkwith', executable('test4-linkwith', 'test4.c',
+ dependencies : [func7_dep, func9_linkwith_dep]))
+
+# Verify that installed libfunc16.a is usable
+libfunc16_dep = cc.find_library('func16')
+test('test5', executable('test5', 'test5.c', dependencies: libfunc16_dep))
diff --git a/test cases/unit/66 static link/test1.c b/test cases/unit/66 static link/test1.c
new file mode 100644
index 0000000..ffc9b9e
--- /dev/null
+++ b/test cases/unit/66 static link/test1.c
@@ -0,0 +1,7 @@
+int func1b();
+int func2();
+
+int main(int argc, char *argv[])
+{
+ return func2() + func1b() == 3 ? 0 : 1;
+}
diff --git a/test cases/unit/66 static link/test2.c b/test cases/unit/66 static link/test2.c
new file mode 100644
index 0000000..561422a
--- /dev/null
+++ b/test cases/unit/66 static link/test2.c
@@ -0,0 +1,6 @@
+int func4();
+
+int main(int argc, char *argv[])
+{
+ return func4() == 2 ? 0 : 1;
+}
diff --git a/test cases/unit/66 static link/test3.c b/test cases/unit/66 static link/test3.c
new file mode 100644
index 0000000..1216064
--- /dev/null
+++ b/test cases/unit/66 static link/test3.c
@@ -0,0 +1,6 @@
+int func6();
+
+int main(int argc, char *argv[])
+{
+ return func6() == 2 ? 0 : 1;
+}
diff --git a/test cases/unit/66 static link/test4.c b/test cases/unit/66 static link/test4.c
new file mode 100644
index 0000000..7c281e0
--- /dev/null
+++ b/test cases/unit/66 static link/test4.c
@@ -0,0 +1,6 @@
+int func9();
+
+int main(int argc, char *argv[])
+{
+ return func9() == 3 ? 0 : 1;
+}
diff --git a/test cases/unit/66 static link/test5.c b/test cases/unit/66 static link/test5.c
new file mode 100644
index 0000000..6020f0e
--- /dev/null
+++ b/test cases/unit/66 static link/test5.c
@@ -0,0 +1,6 @@
+int func16();
+
+int main(int argc, char *argv[])
+{
+ return func16() == 3 ? 0 : 1;
+}
diff --git a/test cases/unit/67 test env value/meson.build b/test cases/unit/67 test env value/meson.build
new file mode 100644
index 0000000..aa3dbc3
--- /dev/null
+++ b/test cases/unit/67 test env value/meson.build
@@ -0,0 +1,10 @@
+project('test env value')
+
+testpy = find_program('test.py')
+
+val = ['1', '2', '3']
+foreach v: val
+ test('check env', testpy, args: [v], env: {'TEST_VAR': v})
+endforeach
+test('check env', testpy, args: ['4'], env: environment({'TEST_VAR': '4'}))
+test('check env', testpy, args: ['5'], env: environment(['TEST_VAR=5']))
diff --git a/test cases/unit/67 test env value/test.py b/test cases/unit/67 test env value/test.py
new file mode 100755
index 0000000..4adf62c
--- /dev/null
+++ b/test cases/unit/67 test env value/test.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+assert os.environ['TEST_VAR'] == sys.argv[1]
diff --git a/test cases/unit/68 clang-tidy/.clang-tidy b/test cases/unit/68 clang-tidy/.clang-tidy
new file mode 100644
index 0000000..3935294
--- /dev/null
+++ b/test cases/unit/68 clang-tidy/.clang-tidy
@@ -0,0 +1 @@
+Checks: '-*,modernize-use-bool-literals'
diff --git a/test cases/unit/68 clang-tidy/cttest.cpp b/test cases/unit/68 clang-tidy/cttest.cpp
new file mode 100644
index 0000000..07b35a6
--- /dev/null
+++ b/test cases/unit/68 clang-tidy/cttest.cpp
@@ -0,0 +1,7 @@
+#include<cstdio>
+
+int main(int, char**) {
+ bool intbool = 1;
+ printf("Intbool is %d\n", (int)intbool);
+ return 0;
+}
diff --git a/test cases/unit/68 clang-tidy/dummydir.h/dummy.dat b/test cases/unit/68 clang-tidy/dummydir.h/dummy.dat
new file mode 100644
index 0000000..80c6165
--- /dev/null
+++ b/test cases/unit/68 clang-tidy/dummydir.h/dummy.dat
@@ -0,0 +1 @@
+Placeholder to track enclosing directory in git. Not to be analyzed.
diff --git a/test cases/unit/68 clang-tidy/meson.build b/test cases/unit/68 clang-tidy/meson.build
new file mode 100644
index 0000000..737474b
--- /dev/null
+++ b/test cases/unit/68 clang-tidy/meson.build
@@ -0,0 +1,3 @@
+project('clangtidytest', 'cpp', default_options: 'cpp_std=c++14')
+
+executable('cttest', 'cttest.cpp')
diff --git a/test cases/unit/69 cross/crossfile.in b/test cases/unit/69 cross/crossfile.in
new file mode 100644
index 0000000..678e8d3
--- /dev/null
+++ b/test cases/unit/69 cross/crossfile.in
@@ -0,0 +1,5 @@
+[host_machine]
+system = '@system@'
+cpu_family = '@cpu_family@'
+cpu = '@cpu@'
+endian = '@endian@'
diff --git a/test cases/unit/69 cross/meson.build b/test cases/unit/69 cross/meson.build
new file mode 100644
index 0000000..acf4f0f
--- /dev/null
+++ b/test cases/unit/69 cross/meson.build
@@ -0,0 +1,16 @@
+project('crosstest')
+
+if get_option('generate')
+ conf_data = configuration_data()
+ conf_data.set('system', build_machine.system())
+ conf_data.set('cpu', build_machine.cpu())
+ conf_data.set('cpu_family', build_machine.cpu_family())
+ conf_data.set('endian', build_machine.endian())
+
+ configure_file(input: 'crossfile.in',
+ output: 'crossfile',
+ configuration: conf_data)
+ message('Written cross file')
+else
+ assert(meson.is_cross_build(), 'not setup as cross build')
+endif
diff --git a/test cases/unit/69 cross/meson_options.txt b/test cases/unit/69 cross/meson_options.txt
new file mode 100644
index 0000000..5896d63
--- /dev/null
+++ b/test cases/unit/69 cross/meson_options.txt
@@ -0,0 +1 @@
+option('generate', type : 'boolean', value : false)
diff --git a/test cases/unit/7 run installed/foo/foo.c b/test cases/unit/7 run installed/foo/foo.c
new file mode 100644
index 0000000..402c895
--- /dev/null
+++ b/test cases/unit/7 run installed/foo/foo.c
@@ -0,0 +1,3 @@
+int foo() {
+ return 0;
+}
diff --git a/test cases/unit/7 run installed/foo/meson.build b/test cases/unit/7 run installed/foo/meson.build
new file mode 100644
index 0000000..772b181
--- /dev/null
+++ b/test cases/unit/7 run installed/foo/meson.build
@@ -0,0 +1,6 @@
+# Try to invoke linker constant string deduplication,
+# to ensure we are not clobbering shared strings.
+# Name everything possible just as "foo".
+foolib = shared_library('foo', 'foo.c',
+ install_dir : 'foo',
+ install : true)
diff --git a/test cases/unit/7 run installed/meson.build b/test cases/unit/7 run installed/meson.build
new file mode 100644
index 0000000..af307f5
--- /dev/null
+++ b/test cases/unit/7 run installed/meson.build
@@ -0,0 +1,8 @@
+project('foo', 'c',
+ default_options : 'libdir=lib')
+
+subdir('foo')
+
+executable('prog', 'prog.c',
+ link_with : foolib,
+ install : true)
diff --git a/test cases/unit/7 run installed/prog.c b/test cases/unit/7 run installed/prog.c
new file mode 100644
index 0000000..8e61e6e
--- /dev/null
+++ b/test cases/unit/7 run installed/prog.c
@@ -0,0 +1,5 @@
+int foo();
+
+int main(int argc, char **argv) {
+ return foo();
+}
diff --git a/test cases/unit/70 cross test passed/exewrapper.py b/test cases/unit/70 cross test passed/exewrapper.py
new file mode 100755
index 0000000..2c15ed6
--- /dev/null
+++ b/test cases/unit/70 cross test passed/exewrapper.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+# Test that the MESON_EXE_WRAPPER environment variable is set
+
+import argparse
+import os
+import sys
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('binary') # unused, but needed for test behavior
+ parser.add_argument('--expected', action='store_true')
+ args = parser.parse_args()
+
+ defined = 'MESON_EXE_WRAPPER' in os.environ
+
+ if args.expected != defined:
+ print(os.environ, file=sys.stderr)
+ return 1
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/test cases/unit/70 cross test passed/meson.build b/test cases/unit/70 cross test passed/meson.build
new file mode 100644
index 0000000..4deb74b
--- /dev/null
+++ b/test cases/unit/70 cross test passed/meson.build
@@ -0,0 +1,19 @@
+project(
+ 'cross test passed',
+ 'c',
+ version : '>= 0.51'
+)
+
+e = executable('exec', 'src/main.c')
+
+py = import('python').find_installation()
+
+test('root', e)
+test('main', py, args : [meson.current_source_dir() / 'script.py', e])
+
+wrapper_args = []
+if get_option('expect')
+ wrapper_args += '--expected'
+endif
+
+test('exe_wrapper in env', py, args : [meson.current_source_dir() / 'exewrapper.py', e, wrapper_args])
diff --git a/test cases/unit/70 cross test passed/meson_options.txt b/test cases/unit/70 cross test passed/meson_options.txt
new file mode 100644
index 0000000..084c776
--- /dev/null
+++ b/test cases/unit/70 cross test passed/meson_options.txt
@@ -0,0 +1,5 @@
+option(
+ 'expect',
+ type : 'boolean',
+ value : false,
+)
diff --git a/test cases/unit/70 cross test passed/script.py b/test cases/unit/70 cross test passed/script.py
new file mode 100644
index 0000000..257cd30
--- /dev/null
+++ b/test cases/unit/70 cross test passed/script.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import subprocess
+import sys
+
+if __name__ == "__main__":
+ sys.exit(subprocess.run(sys.argv[1:]).returncode)
diff --git a/test cases/unit/70 cross test passed/src/main.c b/test cases/unit/70 cross test passed/src/main.c
new file mode 100644
index 0000000..490b4a6
--- /dev/null
+++ b/test cases/unit/70 cross test passed/src/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(int argc, char const *argv[])
+{
+ return 0;
+}
diff --git a/test cases/unit/71 summary/meson.build b/test cases/unit/71 summary/meson.build
new file mode 100644
index 0000000..ce97fb3
--- /dev/null
+++ b/test cases/unit/71 summary/meson.build
@@ -0,0 +1,24 @@
+project('My Project', version : '1.0')
+
+subproject('sub')
+subproject('sub2', required : false)
+
+summary({'Some boolean': false,
+ 'Another boolean': true,
+ 'Some string': 'Hello World',
+ 'A list': ['string', 1, true],
+ 'empty list': [],
+ 'enabled_opt': get_option('enabled_opt'),
+ }, section: 'Configuration')
+summary({'missing prog': find_program('xyzzy', required: false),
+ 'existing prog': import('python').find_installation(),
+ 'missing dep': dependency('', required: false),
+ 'external dep': dependency('zlib', required: false),
+ 'internal dep': declare_dependency(),
+ 'disabler': disabler(),
+ }, section: 'Stuff')
+summary('A number', 1, section: 'Configuration')
+summary('yes', true, bool_yn : true, section: 'Configuration')
+summary('no', false, bool_yn : true, section: 'Configuration')
+summary('comma list', ['a', 'b', 'c'], list_sep: ', ', section: 'Configuration')
+summary('long comma list', ['alpha', 'alphacolor', 'apetag', 'audiofx', 'audioparsers', 'auparse', 'autodetect', 'avi'], list_sep: ', ', section: 'Plugins')
diff --git a/test cases/unit/71 summary/meson_options.txt b/test cases/unit/71 summary/meson_options.txt
new file mode 100644
index 0000000..281c3b6
--- /dev/null
+++ b/test cases/unit/71 summary/meson_options.txt
@@ -0,0 +1 @@
+option('enabled_opt', type: 'feature', value: 'auto')
diff --git a/test cases/unit/71 summary/subprojects/sub/meson.build b/test cases/unit/71 summary/subprojects/sub/meson.build
new file mode 100644
index 0000000..e7d7833
--- /dev/null
+++ b/test cases/unit/71 summary/subprojects/sub/meson.build
@@ -0,0 +1,4 @@
+project('Some Subproject', version : '2.0')
+
+summary('string', 'bar')
+summary({'integer': 1, 'boolean': true})
diff --git a/test cases/unit/71 summary/subprojects/sub2/meson.build b/test cases/unit/71 summary/subprojects/sub2/meson.build
new file mode 100644
index 0000000..2560bd0
--- /dev/null
+++ b/test cases/unit/71 summary/subprojects/sub2/meson.build
@@ -0,0 +1,6 @@
+project('sub2')
+
+subproject('subsub')
+
+summary('Section', 'Should not be seen')
+error('This subproject failed')
diff --git a/test cases/unit/71 summary/subprojects/sub2/subprojects/subsub/meson.build b/test cases/unit/71 summary/subprojects/sub2/subprojects/subsub/meson.build
new file mode 100644
index 0000000..98a5a26
--- /dev/null
+++ b/test cases/unit/71 summary/subprojects/sub2/subprojects/subsub/meson.build
@@ -0,0 +1,3 @@
+project('subsub')
+
+summary('Something', 'Some value')
diff --git a/test cases/unit/72 wrap file url/meson.build b/test cases/unit/72 wrap file url/meson.build
new file mode 100644
index 0000000..3bd3b25
--- /dev/null
+++ b/test cases/unit/72 wrap file url/meson.build
@@ -0,0 +1,4 @@
+project('test wrap with file url')
+
+exe = subproject('foo').get_variable('foo_exe')
+test('test1', exe)
diff --git a/test cases/unit/72 wrap file url/subprojects/foo-patch.tar.xz b/test cases/unit/72 wrap file url/subprojects/foo-patch.tar.xz
new file mode 100644
index 0000000..fdb026c
--- /dev/null
+++ b/test cases/unit/72 wrap file url/subprojects/foo-patch.tar.xz
Binary files differ
diff --git a/test cases/unit/72 wrap file url/subprojects/foo.tar.xz b/test cases/unit/72 wrap file url/subprojects/foo.tar.xz
new file mode 100644
index 0000000..2ed6ab4
--- /dev/null
+++ b/test cases/unit/72 wrap file url/subprojects/foo.tar.xz
Binary files differ
diff --git a/test cases/unit/73 dep files/foo.c b/test cases/unit/73 dep files/foo.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/73 dep files/foo.c
diff --git a/test cases/unit/73 dep files/meson.build b/test cases/unit/73 dep files/meson.build
new file mode 100644
index 0000000..4829f56
--- /dev/null
+++ b/test cases/unit/73 dep files/meson.build
@@ -0,0 +1,16 @@
+project('test', 'c')
+
+python = import('python').find_installation()
+
+lib = library('foo', 'foo.c')
+
+# The library does not yet exist but we can already use its path during
+# configuration. This should not trigger a reconfigure when the library is
+# rebuilt.
+configure_file(
+ output: 'out.txt',
+ capture: true,
+ command: [python, '-c', 'import sys; print(sys.argv[1])', lib.full_path()],
+)
+
+message('Project configured')
diff --git a/test cases/unit/74 pkgconfig prefixes/client/client.c b/test cases/unit/74 pkgconfig prefixes/client/client.c
new file mode 100644
index 0000000..be9bead
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/client/client.c
@@ -0,0 +1,8 @@
+#include <val2.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("%d\n", val2());
+ return 0;
+}
diff --git a/test cases/unit/74 pkgconfig prefixes/client/meson.build b/test cases/unit/74 pkgconfig prefixes/client/meson.build
new file mode 100644
index 0000000..491937b
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/client/meson.build
@@ -0,0 +1,3 @@
+project('client', 'c')
+val2_dep = dependency('val2')
+executable('client', 'client.c', dependencies : [val2_dep], install: true)
diff --git a/test cases/unit/74 pkgconfig prefixes/val1/meson.build b/test cases/unit/74 pkgconfig prefixes/val1/meson.build
new file mode 100644
index 0000000..cc63e31
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/val1/meson.build
@@ -0,0 +1,5 @@
+project('val1', 'c')
+val1 = shared_library('val1', 'val1.c', install: true)
+install_headers('val1.h')
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(val1, libraries : ['-Wl,-rpath,${libdir}'])
diff --git a/test cases/unit/74 pkgconfig prefixes/val1/val1.c b/test cases/unit/74 pkgconfig prefixes/val1/val1.c
new file mode 100644
index 0000000..591e521
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/val1/val1.c
@@ -0,0 +1,3 @@
+#include "val1.h"
+
+int val1(void) { return 1; }
diff --git a/test cases/unit/74 pkgconfig prefixes/val1/val1.h b/test cases/unit/74 pkgconfig prefixes/val1/val1.h
new file mode 100644
index 0000000..6bd435e
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/val1/val1.h
@@ -0,0 +1 @@
+int val1(void);
diff --git a/test cases/unit/74 pkgconfig prefixes/val2/meson.build b/test cases/unit/74 pkgconfig prefixes/val2/meson.build
new file mode 100644
index 0000000..ce69481
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/val2/meson.build
@@ -0,0 +1,8 @@
+project('val2', 'c')
+val1_dep = dependency('val1')
+val2 = shared_library('val2', 'val2.c',
+ dependencies : [val1_dep],
+ install: true)
+install_headers('val2.h')
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(val2, libraries : ['-Wl,-rpath,${libdir}'])
diff --git a/test cases/unit/74 pkgconfig prefixes/val2/val2.c b/test cases/unit/74 pkgconfig prefixes/val2/val2.c
new file mode 100644
index 0000000..d7d4857
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/val2/val2.c
@@ -0,0 +1,4 @@
+#include "val1.h"
+#include "val2.h"
+
+int val2(void) { return val1() + 2; }
diff --git a/test cases/unit/74 pkgconfig prefixes/val2/val2.h b/test cases/unit/74 pkgconfig prefixes/val2/val2.h
new file mode 100644
index 0000000..995023d
--- /dev/null
+++ b/test cases/unit/74 pkgconfig prefixes/val2/val2.h
@@ -0,0 +1 @@
+int val2(void);
diff --git a/test cases/unit/75 subdir libdir/meson.build b/test cases/unit/75 subdir libdir/meson.build
new file mode 100644
index 0000000..5099c91
--- /dev/null
+++ b/test cases/unit/75 subdir libdir/meson.build
@@ -0,0 +1,2 @@
+project('toplevel', 'c')
+subproject('flub')
diff --git a/test cases/unit/75 subdir libdir/subprojects/flub/meson.build b/test cases/unit/75 subdir libdir/subprojects/flub/meson.build
new file mode 100644
index 0000000..7bfd2c5
--- /dev/null
+++ b/test cases/unit/75 subdir libdir/subprojects/flub/meson.build
@@ -0,0 +1 @@
+project('subflub', 'c')
diff --git a/test cases/unit/76 as link whole/bar.c b/test cases/unit/76 as link whole/bar.c
new file mode 100644
index 0000000..79dea9d
--- /dev/null
+++ b/test cases/unit/76 as link whole/bar.c
@@ -0,0 +1,6 @@
+int bar(void);
+
+int bar(void)
+{
+ return 0;
+}
diff --git a/test cases/unit/76 as link whole/foo.c b/test cases/unit/76 as link whole/foo.c
new file mode 100644
index 0000000..ffeee82
--- /dev/null
+++ b/test cases/unit/76 as link whole/foo.c
@@ -0,0 +1,6 @@
+int foo(void);
+
+int foo(void)
+{
+ return 0;
+}
diff --git a/test cases/unit/76 as link whole/meson.build b/test cases/unit/76 as link whole/meson.build
new file mode 100644
index 0000000..6bc208f
--- /dev/null
+++ b/test cases/unit/76 as link whole/meson.build
@@ -0,0 +1,11 @@
+project('as-link-whole', 'c')
+
+foo = static_library('foo', 'foo.c', install: true)
+dep = declare_dependency(link_with: foo)
+bar1 = library('bar1', 'bar.c', dependencies: dep)
+bar2 = library('bar2', 'bar.c', dependencies: dep.as_link_whole())
+
+# bar1.pc should have -lfoo but not bar2.pc
+pkg = import('pkgconfig')
+pkg.generate(bar1)
+pkg.generate(bar2)
diff --git a/test cases/unit/77 nostdlib/meson.build b/test cases/unit/77 nostdlib/meson.build
new file mode 100644
index 0000000..9c5f949
--- /dev/null
+++ b/test cases/unit/77 nostdlib/meson.build
@@ -0,0 +1,14 @@
+project('own libc', 'c')
+
+# Not related to this test, but could not find a better place for this test.
+assert(meson.get_cross_property('nonexisting', 'defaultvalue') == 'defaultvalue',
+ 'Cross prop getting is broken.')
+
+# A simple project that uses its own libc.
+
+# Note that we don't need to specify anything, the flags to use
+# stdlib come from the cross file.
+
+exe = executable('selfcontained', 'prog.c')
+
+test('standalone test', exe)
diff --git a/test cases/unit/77 nostdlib/prog.c b/test cases/unit/77 nostdlib/prog.c
new file mode 100644
index 0000000..b9216ee
--- /dev/null
+++ b/test cases/unit/77 nostdlib/prog.c
@@ -0,0 +1,7 @@
+
+#include<stdio.h>
+
+int main(void) {
+ const char *message = "Hello without stdlib.\n";
+ return simple_print(message, simple_strlen(message));
+}
diff --git a/test cases/unit/77 nostdlib/subprojects/mylibc/libc.c b/test cases/unit/77 nostdlib/subprojects/mylibc/libc.c
new file mode 100644
index 0000000..67261cb
--- /dev/null
+++ b/test cases/unit/77 nostdlib/subprojects/mylibc/libc.c
@@ -0,0 +1,35 @@
+/* Do not use this as the basis of your own libc.
+ * The code is probably unoptimal or wonky, as I
+ * had no prior experience with this, but instead
+ * just fiddled with the code until it worked.
+ */
+
+#include<stdio.h>
+
+#define STDOUT 1
+#define SYS_WRITE 4
+
+int simple_print(const char *msg, const long bufsize) {
+ int count;
+ long total_written = 0;
+ while(total_written < bufsize) {
+ asm(
+ "int $0x80\n\t"
+ : "=a"(count)
+ : "0"(SYS_WRITE), "b"(STDOUT), "c"(msg+total_written), "d"(bufsize-total_written)
+ :);
+ if(count == 0) {
+ return 1;
+ }
+ total_written += count;
+ }
+ return 0;
+}
+
+int simple_strlen(const char *str) {
+ int len = 0;
+ while(str[len] != '\0') {
+ len++;
+ }
+ return len;
+}
diff --git a/test cases/unit/77 nostdlib/subprojects/mylibc/meson.build b/test cases/unit/77 nostdlib/subprojects/mylibc/meson.build
new file mode 100644
index 0000000..ff4bdb2
--- /dev/null
+++ b/test cases/unit/77 nostdlib/subprojects/mylibc/meson.build
@@ -0,0 +1,13 @@
+project('own libc', 'c')
+
+# A very simple libc implementation
+
+# Do not specify -nostdlib & co. They come from cross specifications.
+
+libc = static_library('c', 'libc.c', 'stubstart.s')
+
+mylibc_dep = declare_dependency(link_with : libc,
+ include_directories : include_directories('.')
+)
+
+meson.override_dependency('c_stdlib', mylibc_dep)
diff --git a/test cases/unit/77 nostdlib/subprojects/mylibc/stdio.h b/test cases/unit/77 nostdlib/subprojects/mylibc/stdio.h
new file mode 100644
index 0000000..c3f8f56
--- /dev/null
+++ b/test cases/unit/77 nostdlib/subprojects/mylibc/stdio.h
@@ -0,0 +1,5 @@
+#pragma once
+
+int simple_print(const char *msg, const long bufsize);
+
+int simple_strlen(const char *str);
diff --git a/test cases/unit/77 nostdlib/subprojects/mylibc/stubstart.s b/test cases/unit/77 nostdlib/subprojects/mylibc/stubstart.s
new file mode 100644
index 0000000..0a6d972
--- /dev/null
+++ b/test cases/unit/77 nostdlib/subprojects/mylibc/stubstart.s
@@ -0,0 +1,8 @@
+.globl _start
+
+_start:
+
+ call main
+ movl %eax, %ebx
+ movl $1, %eax
+ int $0x80
diff --git a/test cases/unit/78 user options for subproject/.gitignore b/test cases/unit/78 user options for subproject/.gitignore
new file mode 100644
index 0000000..0bec5ea
--- /dev/null
+++ b/test cases/unit/78 user options for subproject/.gitignore
@@ -0,0 +1 @@
+/subprojects
diff --git a/test cases/unit/78 user options for subproject/75 user options for subproject/.gitignore b/test cases/unit/78 user options for subproject/75 user options for subproject/.gitignore
new file mode 100644
index 0000000..4976afc
--- /dev/null
+++ b/test cases/unit/78 user options for subproject/75 user options for subproject/.gitignore
@@ -0,0 +1 @@
+subprojects/*
diff --git a/test cases/unit/78 user options for subproject/75 user options for subproject/meson.build b/test cases/unit/78 user options for subproject/75 user options for subproject/meson.build
new file mode 100644
index 0000000..0bc395b
--- /dev/null
+++ b/test cases/unit/78 user options for subproject/75 user options for subproject/meson.build
@@ -0,0 +1,3 @@
+project('user option for subproject')
+
+p = subproject('sub')
diff --git a/test cases/unit/78 user options for subproject/subprojects/sub/meson.build b/test cases/unit/78 user options for subproject/subprojects/sub/meson.build
new file mode 100644
index 0000000..2eccef7
--- /dev/null
+++ b/test cases/unit/78 user options for subproject/subprojects/sub/meson.build
@@ -0,0 +1,45 @@
+project('options', 'c')
+
+if get_option('testoption') != 'optval'
+ error('Incorrect value to test option')
+endif
+
+if get_option('other_one') != false
+ error('Incorrect value to boolean option.')
+endif
+
+if get_option('combo_opt') != 'combo'
+ error('Incorrect value to combo option.')
+endif
+
+if get_option('array_opt') != ['one', 'two']
+ message(get_option('array_opt'))
+ error('Incorrect value for array option')
+endif
+
+# If the default changes, update test cases/unit/13 reconfigure
+if get_option('b_lto') != false
+ error('Incorrect value in base option.')
+endif
+
+if get_option('includedir') != 'include'
+ error('Incorrect value in builtin option.')
+endif
+
+if get_option('integer_opt') != 3
+ error('Incorrect value in integer option.')
+endif
+
+if get_option('neg_int_opt') != -3
+ error('Incorrect value in negative integer option.')
+endif
+
+if get_option('CaseSenSiTivE') != 'Some CAPS'
+ error('Incorrect value in mixed caps option.')
+endif
+
+if get_option('CASESENSITIVE') != 'ALL CAPS'
+ error('Incorrect value in all caps option.')
+endif
+
+assert(get_option('wrap_mode') == 'default', 'Wrap mode option is broken.')
diff --git a/test cases/unit/78 user options for subproject/subprojects/sub/meson_options.txt b/test cases/unit/78 user options for subproject/subprojects/sub/meson_options.txt
new file mode 100644
index 0000000..8067eae
--- /dev/null
+++ b/test cases/unit/78 user options for subproject/subprojects/sub/meson_options.txt
@@ -0,0 +1,9 @@
+option('testoption', type : 'string', value : 'optval', description : 'An option ' + 'to do something')
+option('other_one', type : 'boolean', value : not (not (not (not false))))
+option('combo_opt', type : 'co' + 'mbo', choices : ['one', 'two', 'combo'], value : 'combo')
+option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one', 'two'])
+option('free_array_opt', type : 'array')
+option('integer_opt', type : 'integer', min : 0, max : -(-5), value : 3)
+option('neg' + '_' + 'int' + '_' + 'opt', type : 'integer', min : -5, max : 5, value : -3)
+option('CaseSenSiTivE', type : 'string', value: 'Some CAPS', description : 'An option with mixed capitaliziation')
+option('CASESENSITIVE', type : 'string', value: 'ALL CAPS', description : 'An option with all caps')
diff --git a/test cases/unit/79 global-rpath/meson.build b/test cases/unit/79 global-rpath/meson.build
new file mode 100644
index 0000000..c67d9e0
--- /dev/null
+++ b/test cases/unit/79 global-rpath/meson.build
@@ -0,0 +1,3 @@
+project('global-rpath', 'cpp')
+yonder_dep = dependency('yonder')
+executable('rpathified', 'rpathified.cpp', dependencies: [yonder_dep], install: true)
diff --git a/test cases/unit/79 global-rpath/rpathified.cpp b/test cases/unit/79 global-rpath/rpathified.cpp
new file mode 100644
index 0000000..3788906
--- /dev/null
+++ b/test cases/unit/79 global-rpath/rpathified.cpp
@@ -0,0 +1,6 @@
+#include <yonder.h>
+#include <string.h>
+int main(int argc, char **argv)
+{
+ return strcmp(yonder(), "AB54 6BR");
+}
diff --git a/test cases/unit/79 global-rpath/yonder/meson.build b/test cases/unit/79 global-rpath/yonder/meson.build
new file mode 100644
index 0000000..e32f383
--- /dev/null
+++ b/test cases/unit/79 global-rpath/yonder/meson.build
@@ -0,0 +1,5 @@
+project('yonder', 'cpp')
+yonder = shared_library('yonder', 'yonder.cpp', install: true)
+install_headers('yonder.h')
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(yonder)
diff --git a/test cases/unit/79 global-rpath/yonder/yonder.cpp b/test cases/unit/79 global-rpath/yonder/yonder.cpp
new file mode 100644
index 0000000..b182d34
--- /dev/null
+++ b/test cases/unit/79 global-rpath/yonder/yonder.cpp
@@ -0,0 +1,3 @@
+#include "yonder.h"
+
+char *yonder(void) { return "AB54 6BR"; }
diff --git a/test cases/unit/79 global-rpath/yonder/yonder.h b/test cases/unit/79 global-rpath/yonder/yonder.h
new file mode 100644
index 0000000..9d9ad16
--- /dev/null
+++ b/test cases/unit/79 global-rpath/yonder/yonder.h
@@ -0,0 +1 @@
+char *yonder(void);
diff --git a/test cases/unit/8 -L -l order/first.pc b/test cases/unit/8 -L -l order/first.pc
new file mode 100644
index 0000000..3b811b2
--- /dev/null
+++ b/test cases/unit/8 -L -l order/first.pc
@@ -0,0 +1,13 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib/x86_64-linux-gnu
+sharedlibdir=${libdir}
+includedir=${prefix}/include
+
+Name: jonne
+Description: jonne library
+Version: 1.0.0
+
+Requires:
+Libs: -L/me/first -lfoo1 -L/me/second -lfoo2
+Cflags: -I${includedir}
diff --git a/test cases/unit/8 -L -l order/meson.build b/test cases/unit/8 -L -l order/meson.build
new file mode 100644
index 0000000..cfcf033
--- /dev/null
+++ b/test cases/unit/8 -L -l order/meson.build
@@ -0,0 +1,6 @@
+project('jonne', 'c')
+
+firstdep = dependency('first')
+seconddep = dependency('second')
+
+executable('lprog', 'prog.c', dependencies : [firstdep, seconddep])
diff --git a/test cases/unit/8 -L -l order/prog.c b/test cases/unit/8 -L -l order/prog.c
new file mode 100644
index 0000000..3a16ac3
--- /dev/null
+++ b/test cases/unit/8 -L -l order/prog.c
@@ -0,0 +1,5 @@
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ return 0;
+}
diff --git a/test cases/unit/8 -L -l order/second.pc b/test cases/unit/8 -L -l order/second.pc
new file mode 100644
index 0000000..196824b
--- /dev/null
+++ b/test cases/unit/8 -L -l order/second.pc
@@ -0,0 +1,13 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib/x86_64-linux-gnu
+sharedlibdir=${libdir}
+includedir=${prefix}/include
+
+Name: jonne2
+Description: jonne2 library
+Version: 1.0.0
+
+Requires:
+Libs: -L/me/third -lfoo3 -L/me/fourth -lfoo4
+Cflags: -I${includedir}
diff --git a/test cases/unit/80 wrap-git/meson.build b/test cases/unit/80 wrap-git/meson.build
new file mode 100644
index 0000000..b0af30a
--- /dev/null
+++ b/test cases/unit/80 wrap-git/meson.build
@@ -0,0 +1,4 @@
+project('test-wrap-git')
+
+exe = subproject('wrap_git').get_variable('exe')
+test('test1', exe)
diff --git a/test cases/unit/80 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build b/test cases/unit/80 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build
new file mode 100644
index 0000000..2570f77
--- /dev/null
+++ b/test cases/unit/80 wrap-git/subprojects/packagefiles/wrap_git_builddef/meson.build
@@ -0,0 +1,3 @@
+project('foo', 'c')
+
+exe = executable('app', 'main.c')
diff --git a/test cases/unit/80 wrap-git/subprojects/wrap_git_upstream/main.c b/test cases/unit/80 wrap-git/subprojects/wrap_git_upstream/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/test cases/unit/80 wrap-git/subprojects/wrap_git_upstream/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/test cases/unit/81 meson version compare/meson.build b/test cases/unit/81 meson version compare/meson.build
new file mode 100644
index 0000000..4affe21
--- /dev/null
+++ b/test cases/unit/81 meson version compare/meson.build
@@ -0,0 +1,19 @@
+project('version compare', meson_version: '>= 0.1')
+
+if meson.version().version_compare('>= 9999')
+ error('This should not be executed')
+elif meson.version().version_compare('>= 0.55') and false
+ error('This should not be executed')
+elif not meson.version().version_compare('>= 0.55')
+ error('This should not be executed')
+elif meson.version().version_compare('>= 0.55')
+ # This Should not produce warning even when using function not available in
+ # meson 0.1.
+ foo_dep = declare_dependency()
+ meson.override_dependency('foo', foo_dep)
+endif
+
+# This will error out if elif cause did not enter
+assert(foo_dep.found(), 'meson.version_compare did not work')
+
+subproject('foo')
diff --git a/test cases/unit/81 meson version compare/subprojects/foo/meson.build b/test cases/unit/81 meson version compare/subprojects/foo/meson.build
new file mode 100644
index 0000000..4c66b70
--- /dev/null
+++ b/test cases/unit/81 meson version compare/subprojects/foo/meson.build
@@ -0,0 +1,8 @@
+project('foo', meson_version: '>= 0.1')
+
+if meson.version().version_compare('>= 0.55')
+ # This Should not produce warning even when using function not available in
+ # meson 0.1.
+ foo_dep = declare_dependency()
+ meson.override_dependency('foo2', foo_dep)
+endif
diff --git a/test cases/unit/82 cross only introspect/meson.build b/test cases/unit/82 cross only introspect/meson.build
new file mode 100644
index 0000000..ed25441
--- /dev/null
+++ b/test cases/unit/82 cross only introspect/meson.build
@@ -0,0 +1,2 @@
+project('cross only introspect')
+add_languages('c', native: false)
diff --git a/test cases/unit/83 change option choices/meson.build b/test cases/unit/83 change option choices/meson.build
new file mode 100644
index 0000000..d056d65
--- /dev/null
+++ b/test cases/unit/83 change option choices/meson.build
@@ -0,0 +1 @@
+project('change option choices')
diff --git a/test cases/unit/83 change option choices/meson_options.1.txt b/test cases/unit/83 change option choices/meson_options.1.txt
new file mode 100644
index 0000000..d0326a5
--- /dev/null
+++ b/test cases/unit/83 change option choices/meson_options.1.txt
@@ -0,0 +1,13 @@
+option(
+ 'combo',
+ type : 'combo',
+ choices : ['a', 'b', 'c'],
+ value : 'a',
+)
+
+option(
+ 'array',
+ type : 'array',
+ choices : ['a', 'b', 'c'],
+ value : ['a'],
+)
diff --git a/test cases/unit/83 change option choices/meson_options.2.txt b/test cases/unit/83 change option choices/meson_options.2.txt
new file mode 100644
index 0000000..4684673
--- /dev/null
+++ b/test cases/unit/83 change option choices/meson_options.2.txt
@@ -0,0 +1,13 @@
+option(
+ 'combo',
+ type : 'combo',
+ choices : ['b', 'c', 'd'],
+ value : 'b',
+)
+
+option(
+ 'array',
+ type : 'array',
+ choices : ['b', 'c', 'd'],
+ value : ['b'],
+)
diff --git a/test cases/unit/84 nested subproject regenerate depends/main.c b/test cases/unit/84 nested subproject regenerate depends/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/unit/84 nested subproject regenerate depends/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/unit/84 nested subproject regenerate depends/meson.build b/test cases/unit/84 nested subproject regenerate depends/meson.build
new file mode 100644
index 0000000..a8d2138
--- /dev/null
+++ b/test cases/unit/84 nested subproject regenerate depends/meson.build
@@ -0,0 +1,10 @@
+project('nested subproject regenerate depends', 'c')
+
+if not find_program('cmake', required: false, version: '>=3.14').found()
+ error('MESON_SKIP_TEST cmake >= 3.14 not available.')
+endif
+
+s = subproject('sub1')
+
+# This is needed to make msbuild noop check work correctly
+executable('exe', 'main.c')
diff --git a/test cases/unit/84 nested subproject regenerate depends/subprojects/sub1/meson.build b/test cases/unit/84 nested subproject regenerate depends/subprojects/sub1/meson.build
new file mode 100644
index 0000000..a31db4a
--- /dev/null
+++ b/test cases/unit/84 nested subproject regenerate depends/subprojects/sub1/meson.build
@@ -0,0 +1,4 @@
+project('sub1')
+
+cmake = import('cmake')
+cmake.subproject('sub2')
diff --git a/test cases/unit/84 nested subproject regenerate depends/subprojects/sub2/CMakeLists.txt b/test cases/unit/84 nested subproject regenerate depends/subprojects/sub2/CMakeLists.txt
new file mode 100644
index 0000000..f91473a
--- /dev/null
+++ b/test cases/unit/84 nested subproject regenerate depends/subprojects/sub2/CMakeLists.txt
@@ -0,0 +1 @@
+project(sub2)
diff --git a/test cases/unit/85 cpp modules/gcc/main.cpp b/test cases/unit/85 cpp modules/gcc/main.cpp
new file mode 100644
index 0000000..d825c7d
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/main.cpp
@@ -0,0 +1,7 @@
+import M0;
+#include<cstdio>
+
+int main() {
+ printf("The value is %d", func0());
+ return 0;
+}
diff --git a/test cases/unit/85 cpp modules/gcc/meson.build b/test cases/unit/85 cpp modules/gcc/meson.build
new file mode 100644
index 0000000..e405c56
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/meson.build
@@ -0,0 +1,19 @@
+# GCC does not recognize .ixx as a C++ source extension so
+# we have to do this instead.
+
+e = executable('modtest',
+ 'main.cpp',
+ 'src0.cxx',
+ 'src1.cxx',
+ 'src2.cxx',
+ 'src3.cxx',
+ 'src4.cxx',
+ 'src5.cxx',
+ 'src6.cxx',
+ 'src7.cxx',
+ 'src8.cxx',
+ 'src9.cxx',
+ cpp_args: ['-fmodules-ts'],
+ )
+
+test('modtest', e)
diff --git a/test cases/unit/85 cpp modules/gcc/src0.cxx b/test cases/unit/85 cpp modules/gcc/src0.cxx
new file mode 100644
index 0000000..3ca4d14
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src0.cxx
@@ -0,0 +1,7 @@
+export module M0;
+
+import M1;
+
+export int func0() {
+ return func1();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src1.cxx b/test cases/unit/85 cpp modules/gcc/src1.cxx
new file mode 100644
index 0000000..cea6696
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src1.cxx
@@ -0,0 +1,7 @@
+export module M1;
+
+import M2;
+
+export int func1() {
+ return func2();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src2.cxx b/test cases/unit/85 cpp modules/gcc/src2.cxx
new file mode 100644
index 0000000..415714c
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src2.cxx
@@ -0,0 +1,7 @@
+export module M2;
+
+import M3;
+
+export int func2() {
+ return func3();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src3.cxx b/test cases/unit/85 cpp modules/gcc/src3.cxx
new file mode 100644
index 0000000..96f135c
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src3.cxx
@@ -0,0 +1,7 @@
+export module M3;
+
+import M4;
+
+export int func3() {
+ return func4();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src4.cxx b/test cases/unit/85 cpp modules/gcc/src4.cxx
new file mode 100644
index 0000000..1ac1a6a
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src4.cxx
@@ -0,0 +1,7 @@
+export module M4;
+
+import M5;
+
+export int func4() {
+ return func5();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src5.cxx b/test cases/unit/85 cpp modules/gcc/src5.cxx
new file mode 100644
index 0000000..96cf707
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src5.cxx
@@ -0,0 +1,7 @@
+export module M5;
+
+import M6;
+
+export int func5() {
+ return func6();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src6.cxx b/test cases/unit/85 cpp modules/gcc/src6.cxx
new file mode 100644
index 0000000..760b71c
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src6.cxx
@@ -0,0 +1,7 @@
+export module M6;
+
+import M7;
+
+export int func6() {
+ return func7();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src7.cxx b/test cases/unit/85 cpp modules/gcc/src7.cxx
new file mode 100644
index 0000000..8ce6608
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src7.cxx
@@ -0,0 +1,7 @@
+export module M7;
+
+import M8;
+
+export int func7() {
+ return func8();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src8.cxx b/test cases/unit/85 cpp modules/gcc/src8.cxx
new file mode 100644
index 0000000..6a3ef96
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src8.cxx
@@ -0,0 +1,7 @@
+export module M8;
+
+import M9;
+
+export int func8() {
+ return func9();
+}
diff --git a/test cases/unit/85 cpp modules/gcc/src9.cxx b/test cases/unit/85 cpp modules/gcc/src9.cxx
new file mode 100644
index 0000000..3ecb3be
--- /dev/null
+++ b/test cases/unit/85 cpp modules/gcc/src9.cxx
@@ -0,0 +1,5 @@
+export module M9;
+
+export int func9() {
+ return 42;
+}
diff --git a/test cases/unit/85 cpp modules/meson.build b/test cases/unit/85 cpp modules/meson.build
new file mode 100644
index 0000000..579ea9b
--- /dev/null
+++ b/test cases/unit/85 cpp modules/meson.build
@@ -0,0 +1,11 @@
+project('cppmodules', 'cpp', default_options: ['cpp_std=c++latest'])
+
+cpp = meson.get_compiler('cpp')
+
+if cpp.get_id() == 'msvc'
+ subdir('vs')
+elif cpp.get_id() == 'gcc'
+ subdir('gcc')
+else
+ error('Unknown compiler')
+endif
diff --git a/test cases/unit/85 cpp modules/vs/main.cpp b/test cases/unit/85 cpp modules/vs/main.cpp
new file mode 100644
index 0000000..d825c7d
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/main.cpp
@@ -0,0 +1,7 @@
+import M0;
+#include<cstdio>
+
+int main() {
+ printf("The value is %d", func0());
+ return 0;
+}
diff --git a/test cases/unit/85 cpp modules/vs/meson.build b/test cases/unit/85 cpp modules/vs/meson.build
new file mode 100644
index 0000000..e3f6b83
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/meson.build
@@ -0,0 +1,15 @@
+e = executable('modtest',
+ 'main.cpp',
+ 'src0.ixx',
+ 'src1.ixx',
+ 'src2.ixx',
+ 'src3.ixx',
+ 'src4.ixx',
+ 'src5.ixx',
+ 'src6.ixx',
+ 'src7.ixx',
+ 'src8.ixx',
+ 'src9.ixx',
+ )
+
+test('modtest', e)
diff --git a/test cases/unit/85 cpp modules/vs/src0.ixx b/test cases/unit/85 cpp modules/vs/src0.ixx
new file mode 100644
index 0000000..3ca4d14
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src0.ixx
@@ -0,0 +1,7 @@
+export module M0;
+
+import M1;
+
+export int func0() {
+ return func1();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src1.ixx b/test cases/unit/85 cpp modules/vs/src1.ixx
new file mode 100644
index 0000000..cea6696
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src1.ixx
@@ -0,0 +1,7 @@
+export module M1;
+
+import M2;
+
+export int func1() {
+ return func2();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src2.ixx b/test cases/unit/85 cpp modules/vs/src2.ixx
new file mode 100644
index 0000000..415714c
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src2.ixx
@@ -0,0 +1,7 @@
+export module M2;
+
+import M3;
+
+export int func2() {
+ return func3();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src3.ixx b/test cases/unit/85 cpp modules/vs/src3.ixx
new file mode 100644
index 0000000..96f135c
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src3.ixx
@@ -0,0 +1,7 @@
+export module M3;
+
+import M4;
+
+export int func3() {
+ return func4();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src4.ixx b/test cases/unit/85 cpp modules/vs/src4.ixx
new file mode 100644
index 0000000..1ac1a6a
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src4.ixx
@@ -0,0 +1,7 @@
+export module M4;
+
+import M5;
+
+export int func4() {
+ return func5();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src5.ixx b/test cases/unit/85 cpp modules/vs/src5.ixx
new file mode 100644
index 0000000..96cf707
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src5.ixx
@@ -0,0 +1,7 @@
+export module M5;
+
+import M6;
+
+export int func5() {
+ return func6();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src6.ixx b/test cases/unit/85 cpp modules/vs/src6.ixx
new file mode 100644
index 0000000..760b71c
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src6.ixx
@@ -0,0 +1,7 @@
+export module M6;
+
+import M7;
+
+export int func6() {
+ return func7();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src7.ixx b/test cases/unit/85 cpp modules/vs/src7.ixx
new file mode 100644
index 0000000..8ce6608
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src7.ixx
@@ -0,0 +1,7 @@
+export module M7;
+
+import M8;
+
+export int func7() {
+ return func8();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src8.ixx b/test cases/unit/85 cpp modules/vs/src8.ixx
new file mode 100644
index 0000000..6a3ef96
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src8.ixx
@@ -0,0 +1,7 @@
+export module M8;
+
+import M9;
+
+export int func8() {
+ return func9();
+}
diff --git a/test cases/unit/85 cpp modules/vs/src9.ixx b/test cases/unit/85 cpp modules/vs/src9.ixx
new file mode 100644
index 0000000..3ecb3be
--- /dev/null
+++ b/test cases/unit/85 cpp modules/vs/src9.ixx
@@ -0,0 +1,5 @@
+export module M9;
+
+export int func9() {
+ return 42;
+}
diff --git a/test cases/unit/86 prelinking/file1.c b/test cases/unit/86 prelinking/file1.c
new file mode 100644
index 0000000..9f0e265
--- /dev/null
+++ b/test cases/unit/86 prelinking/file1.c
@@ -0,0 +1,14 @@
+#include<public_header.h>
+#include<private_header.h>
+
+int public_func() {
+ return round1_a();
+}
+
+int round1_a() {
+ return round1_b();
+}
+
+int round2_a() {
+ return round2_b();
+}
diff --git a/test cases/unit/86 prelinking/file2.c b/test cases/unit/86 prelinking/file2.c
new file mode 100644
index 0000000..ce3b115
--- /dev/null
+++ b/test cases/unit/86 prelinking/file2.c
@@ -0,0 +1,9 @@
+#include<private_header.h>
+
+int round1_b() {
+ return round1_c();
+}
+
+int round2_b() {
+ return round2_c();
+}
diff --git a/test cases/unit/86 prelinking/file3.c b/test cases/unit/86 prelinking/file3.c
new file mode 100644
index 0000000..85052be
--- /dev/null
+++ b/test cases/unit/86 prelinking/file3.c
@@ -0,0 +1,9 @@
+#include<private_header.h>
+
+int round1_c() {
+ return round1_d();
+}
+
+int round2_c() {
+ return round2_d();
+}
diff --git a/test cases/unit/86 prelinking/file4.c b/test cases/unit/86 prelinking/file4.c
new file mode 100644
index 0000000..622364e
--- /dev/null
+++ b/test cases/unit/86 prelinking/file4.c
@@ -0,0 +1,9 @@
+#include<private_header.h>
+
+int round1_d() {
+ return round2_a();
+}
+
+int round2_d() {
+ return 42;
+}
diff --git a/test cases/unit/86 prelinking/main.c b/test cases/unit/86 prelinking/main.c
new file mode 100644
index 0000000..09a2e5c
--- /dev/null
+++ b/test cases/unit/86 prelinking/main.c
@@ -0,0 +1,10 @@
+#include<public_header.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ if(public_func() != 42) {
+ printf("Something failed.\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/unit/86 prelinking/meson.build b/test cases/unit/86 prelinking/meson.build
new file mode 100644
index 0000000..baa9008
--- /dev/null
+++ b/test cases/unit/86 prelinking/meson.build
@@ -0,0 +1,7 @@
+project('prelinking', 'c')
+
+liba = static_library('prelinked', 'file1.c', 'file2.c', 'file3.c', 'file4.c',
+ prelink: true)
+exe = executable('testprog', 'main.c',
+ link_with: liba)
+test('prelinked', exe)
diff --git a/test cases/unit/86 prelinking/private_header.h b/test cases/unit/86 prelinking/private_header.h
new file mode 100644
index 0000000..f24b621
--- /dev/null
+++ b/test cases/unit/86 prelinking/private_header.h
@@ -0,0 +1,11 @@
+#pragma once
+
+int round1_a();
+int round1_b();
+int round1_c();
+int round1_d();
+
+int round2_a();
+int round2_b();
+int round2_c();
+int round2_d();
diff --git a/test cases/unit/86 prelinking/public_header.h b/test cases/unit/86 prelinking/public_header.h
new file mode 100644
index 0000000..0cd6786
--- /dev/null
+++ b/test cases/unit/86 prelinking/public_header.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int public_func();
diff --git a/test cases/unit/87 run native test/main.c b/test cases/unit/87 run native test/main.c
new file mode 100644
index 0000000..3213780
--- /dev/null
+++ b/test cases/unit/87 run native test/main.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main (int argc, char * argv[])
+{
+ const char *out = "SUCCESS!";
+
+ if (argc != 2) {
+ printf ("%s\n", out);
+ } else {
+ int ret;
+ FILE *f = fopen (argv[1], "w");
+ ret = fwrite (out, sizeof (out), 1, f);
+ if (ret != 1)
+ return -1;
+ }
+ return 0;
+}
diff --git a/test cases/unit/87 run native test/meson.build b/test cases/unit/87 run native test/meson.build
new file mode 100644
index 0000000..3bf419c
--- /dev/null
+++ b/test cases/unit/87 run native test/meson.build
@@ -0,0 +1,6 @@
+project('run native test', ['c'])
+
+executable('terget_exe', 'main.c')
+
+native_exe = executable('native_exe', 'main.c', native: true)
+test('native_exe', native_exe, args: ['native_test_has_run.stamp'])
diff --git a/test cases/unit/88 multiple envvars/meson.build b/test cases/unit/88 multiple envvars/meson.build
new file mode 100644
index 0000000..ac57611
--- /dev/null
+++ b/test cases/unit/88 multiple envvars/meson.build
@@ -0,0 +1,4 @@
+project('multienv', 'c', 'cpp')
+
+executable('cexe', 'prog.c')
+executable('cppexe', 'prog.cpp')
diff --git a/test cases/unit/88 multiple envvars/prog.c b/test cases/unit/88 multiple envvars/prog.c
new file mode 100644
index 0000000..38d3c12
--- /dev/null
+++ b/test cases/unit/88 multiple envvars/prog.c
@@ -0,0 +1,18 @@
+#include<stdio.h>
+
+#ifndef CPPFLAG
+#error CPPFLAG not set
+#endif
+
+#ifndef CFLAG
+#error CFLAGS not set
+#endif
+
+#ifdef CXXFLAG
+#error CXXFLAG is set
+#endif
+
+int main(int argc, char **argv) {
+ printf("%d %s\n", argc, argv[0]);
+ return 0;
+}
diff --git a/test cases/unit/88 multiple envvars/prog.cpp b/test cases/unit/88 multiple envvars/prog.cpp
new file mode 100644
index 0000000..61ccf3a
--- /dev/null
+++ b/test cases/unit/88 multiple envvars/prog.cpp
@@ -0,0 +1,18 @@
+#include<cstdio>
+
+#ifndef CPPFLAG
+#error CPPFLAG not set
+#endif
+
+#ifdef CFLAG
+#error CFLAG is set
+#endif
+
+#ifndef CXXFLAG
+#error CXXFLAG not set
+#endif
+
+int main(int argc, char **argv) {
+ printf("%d %s\n", argc, argv[0]);
+ return 0;
+}
diff --git a/test cases/unit/89 pkgconfig build rpath order/dummy.pc b/test cases/unit/89 pkgconfig build rpath order/dummy.pc
new file mode 100644
index 0000000..9e3048b
--- /dev/null
+++ b/test cases/unit/89 pkgconfig build rpath order/dummy.pc
@@ -0,0 +1,7 @@
+prefix=/foo
+libdir=${prefix}/dummy
+
+Name: dummy
+Description: Nonexisting lib but add an rpath
+Version: 1.0.0
+Libs: -Wl,-rpath,${libdir}
diff --git a/test cases/unit/89 pkgconfig build rpath order/meson.build b/test cases/unit/89 pkgconfig build rpath order/meson.build
new file mode 100644
index 0000000..76ed8de
--- /dev/null
+++ b/test cases/unit/89 pkgconfig build rpath order/meson.build
@@ -0,0 +1,20 @@
+project('build rpath', 'c', 'cpp')
+
+subdir('sub')
+pkgconf_dep = dependency('dummy')
+
+executable('prog', 'prog.c',
+ dependencies : pkgconf_dep,
+ link_with : l,
+ build_rpath : '/foo/bar',
+ install_rpath : '/baz',
+ install : true,
+ )
+
+executable('progcxx', 'prog.cc',
+ dependencies : pkgconf_dep,
+ link_with : l,
+ build_rpath : '/foo/bar',
+ install_rpath : 'baz',
+ install : true,
+ )
diff --git a/test cases/unit/89 pkgconfig build rpath order/prog.c b/test cases/unit/89 pkgconfig build rpath order/prog.c
new file mode 100644
index 0000000..45b2fa3
--- /dev/null
+++ b/test cases/unit/89 pkgconfig build rpath order/prog.c
@@ -0,0 +1,5 @@
+int get_stuff();
+
+int main(int argc, char **argv) {
+ return get_stuff();
+}
diff --git a/test cases/unit/89 pkgconfig build rpath order/prog.cc b/test cases/unit/89 pkgconfig build rpath order/prog.cc
new file mode 100644
index 0000000..c7c2123
--- /dev/null
+++ b/test cases/unit/89 pkgconfig build rpath order/prog.cc
@@ -0,0 +1,8 @@
+#include <string>
+#include <iostream>
+
+int main(int argc, char **argv) {
+ std::string* s = new std::string("Hello");
+ delete s;
+ return 0;
+}
diff --git a/test cases/unit/89 pkgconfig build rpath order/sub/meson.build b/test cases/unit/89 pkgconfig build rpath order/sub/meson.build
new file mode 100644
index 0000000..6879ec6
--- /dev/null
+++ b/test cases/unit/89 pkgconfig build rpath order/sub/meson.build
@@ -0,0 +1 @@
+l = shared_library('stuff', 'stuff.c')
diff --git a/test cases/unit/89 pkgconfig build rpath order/sub/stuff.c b/test cases/unit/89 pkgconfig build rpath order/sub/stuff.c
new file mode 100644
index 0000000..d56d8b0
--- /dev/null
+++ b/test cases/unit/89 pkgconfig build rpath order/sub/stuff.c
@@ -0,0 +1,3 @@
+int get_stuff() {
+ return 0;
+}
diff --git a/test cases/unit/9 d dedup/meson.build b/test cases/unit/9 d dedup/meson.build
new file mode 100644
index 0000000..a7b6a82
--- /dev/null
+++ b/test cases/unit/9 d dedup/meson.build
@@ -0,0 +1,5 @@
+project('d dedup', 'c')
+
+add_project_arguments('-D', 'FOO', '-D', 'BAR', language : 'c')
+
+executable('prog', 'prog.c')
diff --git a/test cases/unit/9 d dedup/prog.c b/test cases/unit/9 d dedup/prog.c
new file mode 100644
index 0000000..505f122
--- /dev/null
+++ b/test cases/unit/9 d dedup/prog.c
@@ -0,0 +1,14 @@
+#include<stdio.h>
+
+#ifndef FOO
+#error FOO is not defined.
+#endif
+
+#ifndef BAR
+#error BAR is not defined.
+#endif
+
+int main(int argc, char **argv) {
+ printf("All is well.\n");
+ return 0;
+}
diff --git a/test cases/unit/90 devenv/main.c b/test cases/unit/90 devenv/main.c
new file mode 100644
index 0000000..2710593
--- /dev/null
+++ b/test cases/unit/90 devenv/main.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#ifdef _WIN32
+ #define DO_IMPORT __declspec(dllimport)
+#else
+ #define DO_IMPORT
+#endif
+
+DO_IMPORT int foo(void);
+
+int main(void) {
+ printf("This is text.\n");
+ return foo();
+}
diff --git a/test cases/unit/90 devenv/meson.build b/test cases/unit/90 devenv/meson.build
new file mode 100644
index 0000000..3b0bb6a
--- /dev/null
+++ b/test cases/unit/90 devenv/meson.build
@@ -0,0 +1,17 @@
+project('devenv', 'c')
+
+meson.add_devenv('TEST_A=1')
+foo_dep = dependency('foo', fallback: 'sub')
+
+env = environment()
+env.append('TEST_B', ['2', '3'], separator: '+')
+meson.add_devenv(env)
+
+meson.add_devenv({'TEST_B': '0'}, separator: '+', method: 'prepend')
+
+env = environment({'TEST_B': ['4']}, separator: '+', method: 'append')
+meson.add_devenv(env)
+
+# This exe links on a library built in another directory. On Windows this means
+# PATH must contain builddir/subprojects/sub to be able to run it.
+executable('app', 'main.c', dependencies: foo_dep, install: true)
diff --git a/test cases/unit/90 devenv/subprojects/sub/foo.c b/test cases/unit/90 devenv/subprojects/sub/foo.c
new file mode 100644
index 0000000..46cb845
--- /dev/null
+++ b/test cases/unit/90 devenv/subprojects/sub/foo.c
@@ -0,0 +1,10 @@
+#ifdef _WIN32
+ #define DO_EXPORT __declspec(dllexport)
+#else
+ #define DO_EXPORT
+#endif
+
+DO_EXPORT int foo(void)
+{
+ return 0;
+}
diff --git a/test cases/unit/90 devenv/subprojects/sub/meson.build b/test cases/unit/90 devenv/subprojects/sub/meson.build
new file mode 100644
index 0000000..5cb1232
--- /dev/null
+++ b/test cases/unit/90 devenv/subprojects/sub/meson.build
@@ -0,0 +1,6 @@
+project('sub', 'c')
+
+meson.add_devenv({'TEST_B': '1'})
+
+libfoo = shared_library('foo', 'foo.c')
+meson.override_dependency('foo', declare_dependency(link_with: libfoo))
diff --git a/test cases/unit/90 devenv/test-devenv.py b/test cases/unit/90 devenv/test-devenv.py
new file mode 100755
index 0000000..75497ff
--- /dev/null
+++ b/test cases/unit/90 devenv/test-devenv.py
@@ -0,0 +1,8 @@
+#! /usr/bin/python
+
+import os
+
+assert os.environ['MESON_DEVENV'] == '1'
+assert os.environ['MESON_PROJECT_NAME'] == 'devenv'
+assert os.environ['TEST_A'] == '1'
+assert os.environ['TEST_B'] == '0+1+2+3+4'
diff --git a/test cases/unit/91 install skip subprojects/foo.c b/test cases/unit/91 install skip subprojects/foo.c
new file mode 100644
index 0000000..25927f5
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/foo.c
@@ -0,0 +1,4 @@
+int main(int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/test cases/unit/91 install skip subprojects/foo.dat b/test cases/unit/91 install skip subprojects/foo.dat
new file mode 100644
index 0000000..421376d
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/foo.dat
@@ -0,0 +1 @@
+dummy
diff --git a/test cases/unit/91 install skip subprojects/foo.h b/test cases/unit/91 install skip subprojects/foo.h
new file mode 100644
index 0000000..a7e26ac
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/foo.h
@@ -0,0 +1 @@
+#define FOO
diff --git a/test cases/unit/91 install skip subprojects/foo/foofile b/test cases/unit/91 install skip subprojects/foo/foofile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/foo/foofile
diff --git a/test cases/unit/91 install skip subprojects/meson.build b/test cases/unit/91 install skip subprojects/meson.build
new file mode 100644
index 0000000..cfbae94
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/meson.build
@@ -0,0 +1,8 @@
+project('foo', 'c')
+
+install_data('foo.dat')
+install_headers('foo.h')
+install_subdir('foo', install_dir: '')
+executable('foo', 'foo.c', install: true)
+
+subproject('bar')
diff --git a/test cases/unit/91 install skip subprojects/subprojects/bar/bar.c b/test cases/unit/91 install skip subprojects/subprojects/bar/bar.c
new file mode 100644
index 0000000..25927f5
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/subprojects/bar/bar.c
@@ -0,0 +1,4 @@
+int main(int argc, char *argv[])
+{
+ return 0;
+}
diff --git a/test cases/unit/91 install skip subprojects/subprojects/bar/bar.dat b/test cases/unit/91 install skip subprojects/subprojects/bar/bar.dat
new file mode 100644
index 0000000..421376d
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/subprojects/bar/bar.dat
@@ -0,0 +1 @@
+dummy
diff --git a/test cases/unit/91 install skip subprojects/subprojects/bar/bar.h b/test cases/unit/91 install skip subprojects/subprojects/bar/bar.h
new file mode 100644
index 0000000..a7e26ac
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/subprojects/bar/bar.h
@@ -0,0 +1 @@
+#define FOO
diff --git a/test cases/unit/91 install skip subprojects/subprojects/bar/bar/barfile b/test cases/unit/91 install skip subprojects/subprojects/bar/bar/barfile
new file mode 100644
index 0000000..421376d
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/subprojects/bar/bar/barfile
@@ -0,0 +1 @@
+dummy
diff --git a/test cases/unit/91 install skip subprojects/subprojects/bar/meson.build b/test cases/unit/91 install skip subprojects/subprojects/bar/meson.build
new file mode 100644
index 0000000..b5b0734
--- /dev/null
+++ b/test cases/unit/91 install skip subprojects/subprojects/bar/meson.build
@@ -0,0 +1,6 @@
+project('bar', 'c')
+
+install_data('bar.dat')
+install_headers('bar.h')
+install_subdir('bar', install_dir: '')
+executable('bar', 'bar.c', install: true)
diff --git a/test cases/unit/92 new subproject in configured project/meson.build b/test cases/unit/92 new subproject in configured project/meson.build
new file mode 100644
index 0000000..b82aa41
--- /dev/null
+++ b/test cases/unit/92 new subproject in configured project/meson.build
@@ -0,0 +1,7 @@
+# SPDX-license-identifier: Apache-2.0
+# Copyright © 2021 Intel Corporation
+project('existing project with new subproject', 'c')
+
+if get_option('use-sub')
+ dep = subproject('sub')
+endif
diff --git a/test cases/unit/92 new subproject in configured project/meson_options.txt b/test cases/unit/92 new subproject in configured project/meson_options.txt
new file mode 100644
index 0000000..12d8395
--- /dev/null
+++ b/test cases/unit/92 new subproject in configured project/meson_options.txt
@@ -0,0 +1,3 @@
+# SPDX-license-identifier: Apache-2.0
+# Copyright © 2021 Intel Corporation
+option('use-sub', type : 'boolean', value : false)
diff --git a/test cases/unit/92 new subproject in configured project/subprojects/sub/foo.c b/test cases/unit/92 new subproject in configured project/subprojects/sub/foo.c
new file mode 100644
index 0000000..9713d9f
--- /dev/null
+++ b/test cases/unit/92 new subproject in configured project/subprojects/sub/foo.c
@@ -0,0 +1,6 @@
+/* SPDX-license-identifier: Apache-2.0 */
+/* Copyright © 2021 Intel Corporation */
+
+int func(void) {
+ return 1;
+}
diff --git a/test cases/unit/92 new subproject in configured project/subprojects/sub/meson.build b/test cases/unit/92 new subproject in configured project/subprojects/sub/meson.build
new file mode 100644
index 0000000..a833b0c
--- /dev/null
+++ b/test cases/unit/92 new subproject in configured project/subprojects/sub/meson.build
@@ -0,0 +1,7 @@
+# SPDX-license-identifier: Apache-2.0
+# Copyright © 2021 Intel Corporation
+project('new subproject', 'c')
+
+l = library('foo', 'foo.c')
+
+dep = declare_dependency(link_with : l)
diff --git a/test cases/unit/93 clangformat/.clang-format b/test cases/unit/93 clangformat/.clang-format
new file mode 100644
index 0000000..689bc60
--- /dev/null
+++ b/test cases/unit/93 clangformat/.clang-format
@@ -0,0 +1,4 @@
+---
+BasedOnStyle: Google
+
+...
diff --git a/test cases/unit/93 clangformat/.clang-format-ignore b/test cases/unit/93 clangformat/.clang-format-ignore
new file mode 100644
index 0000000..7fc4d5a
--- /dev/null
+++ b/test cases/unit/93 clangformat/.clang-format-ignore
@@ -0,0 +1,3 @@
+
+# Ignore C files
+*.c
diff --git a/test cases/unit/93 clangformat/.clang-format-include b/test cases/unit/93 clangformat/.clang-format-include
new file mode 100644
index 0000000..f057c00
--- /dev/null
+++ b/test cases/unit/93 clangformat/.clang-format-include
@@ -0,0 +1,3 @@
+
+# Only reformat in src/
+src/**/*
diff --git a/test cases/unit/93 clangformat/meson.build b/test cases/unit/93 clangformat/meson.build
new file mode 100644
index 0000000..8f4af98
--- /dev/null
+++ b/test cases/unit/93 clangformat/meson.build
@@ -0,0 +1 @@
+project('dummy', 'c', 'cpp')
diff --git a/test cases/unit/93 clangformat/not-included/badformat.cpp b/test cases/unit/93 clangformat/not-included/badformat.cpp
new file mode 100644
index 0000000..99a0ea6
--- /dev/null
+++ b/test cases/unit/93 clangformat/not-included/badformat.cpp
@@ -0,0 +1,2 @@
+class {
+};
diff --git a/test cases/unit/93 clangformat/src/badformat.c b/test cases/unit/93 clangformat/src/badformat.c
new file mode 100644
index 0000000..f1d18b7
--- /dev/null
+++ b/test cases/unit/93 clangformat/src/badformat.c
@@ -0,0 +1,2 @@
+struct {
+};
diff --git a/test cases/unit/93 clangformat/src/badformat.cpp b/test cases/unit/93 clangformat/src/badformat.cpp
new file mode 100644
index 0000000..99a0ea6
--- /dev/null
+++ b/test cases/unit/93 clangformat/src/badformat.cpp
@@ -0,0 +1,2 @@
+class {
+};
diff --git a/test cases/unit/94 custominc/easytogrepfor/genh.py b/test cases/unit/94 custominc/easytogrepfor/genh.py
new file mode 100644
index 0000000..48e033a
--- /dev/null
+++ b/test cases/unit/94 custominc/easytogrepfor/genh.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys
+
+f = open(sys.argv[1], 'w')
+f.write('#define RETURN_VALUE 0')
+f.close()
diff --git a/test cases/unit/94 custominc/easytogrepfor/meson.build b/test cases/unit/94 custominc/easytogrepfor/meson.build
new file mode 100644
index 0000000..e749753
--- /dev/null
+++ b/test cases/unit/94 custominc/easytogrepfor/meson.build
@@ -0,0 +1,3 @@
+genh = custom_target('header',
+ output: 'generated.h',
+ command: [find_program('genh.py'), '@OUTPUT@'])
diff --git a/test cases/unit/94 custominc/helper.c b/test cases/unit/94 custominc/helper.c
new file mode 100644
index 0000000..3237441
--- /dev/null
+++ b/test cases/unit/94 custominc/helper.c
@@ -0,0 +1,5 @@
+#include<generated.h>
+
+int func(void) {
+ return RETURN_VALUE;
+}
diff --git a/test cases/unit/94 custominc/meson.build b/test cases/unit/94 custominc/meson.build
new file mode 100644
index 0000000..bab1139
--- /dev/null
+++ b/test cases/unit/94 custominc/meson.build
@@ -0,0 +1,9 @@
+project('implicit custom dirs', 'c')
+
+subdir('easytogrepfor')
+
+l = static_library('helper', 'helper.c', genh)
+d = declare_dependency(link_with: l, sources: genh)
+executable('prog', 'prog.c', dependencies: d, implicit_include_directories: false)
+
+executable('prog2', 'prog2.c', dependencies: d)
diff --git a/test cases/unit/94 custominc/prog.c b/test cases/unit/94 custominc/prog.c
new file mode 100644
index 0000000..db9df9d
--- /dev/null
+++ b/test cases/unit/94 custominc/prog.c
@@ -0,0 +1,9 @@
+#include<stdlib.h>
+
+int func(void);
+
+int main(int argc, char **argv) {
+ (void)argc;
+ (void)(argv);
+ return func();
+}
diff --git a/test cases/unit/94 custominc/prog2.c b/test cases/unit/94 custominc/prog2.c
new file mode 100644
index 0000000..e64b229
--- /dev/null
+++ b/test cases/unit/94 custominc/prog2.c
@@ -0,0 +1,10 @@
+#include<stdlib.h>
+#include<generated.h>
+
+int func(void);
+
+int main(int argc, char **argv) {
+ (void)argc;
+ (void)(argv);
+ return func() + RETURN_VALUE;
+}
diff --git a/test cases/unit/95 implicit force fallback/meson.build b/test cases/unit/95 implicit force fallback/meson.build
new file mode 100644
index 0000000..623a338
--- /dev/null
+++ b/test cases/unit/95 implicit force fallback/meson.build
@@ -0,0 +1,8 @@
+project('implicit force fallback')
+
+# The dependency 'something' is provided by a subproject. Normally this won't
+# use the fallback subproject because required is false. However this unit test
+# is configured with wrap_mode=forcefallback and force_fallback_for=something
+# in which case we are expecting the fallback to be done.
+d = dependency('something', required: false)
+assert(d.found())
diff --git a/test cases/unit/95 implicit force fallback/subprojects/something/meson.build b/test cases/unit/95 implicit force fallback/subprojects/something/meson.build
new file mode 100644
index 0000000..89a4727
--- /dev/null
+++ b/test cases/unit/95 implicit force fallback/subprojects/something/meson.build
@@ -0,0 +1,3 @@
+project('something')
+
+meson.override_dependency('something', declare_dependency())
diff --git a/test cases/unit/96 compiler.links file arg/meson.build b/test cases/unit/96 compiler.links file arg/meson.build
new file mode 100644
index 0000000..c409dcb
--- /dev/null
+++ b/test cases/unit/96 compiler.links file arg/meson.build
@@ -0,0 +1,11 @@
+project('test', ['c', 'cpp'])
+
+cc = meson.get_compiler('c')
+cxx = meson.get_compiler('cpp')
+
+# used by run_unittests.py to grab the path to the C and C++ compilers
+assert(cc.compiles(files('test.c')))
+assert(cxx.compiles(files('test.c')))
+
+assert(cc.links(files('test.c')))
+assert(cxx.links(files('test.c')))
diff --git a/test cases/unit/96 compiler.links file arg/test.c b/test cases/unit/96 compiler.links file arg/test.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/test cases/unit/96 compiler.links file arg/test.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/test cases/unit/97 link full name/.gitignore b/test cases/unit/97 link full name/.gitignore
new file mode 100644
index 0000000..8129601
--- /dev/null
+++ b/test cases/unit/97 link full name/.gitignore
@@ -0,0 +1,5 @@
+*.a
+*.o
+a.out
+libtestprovider.a
+build
diff --git a/test cases/unit/97 link full name/libtestprovider/meson.build b/test cases/unit/97 link full name/libtestprovider/meson.build
new file mode 100644
index 0000000..128c213
--- /dev/null
+++ b/test cases/unit/97 link full name/libtestprovider/meson.build
@@ -0,0 +1,20 @@
+project('libtestprovider','c')
+
+libtestprovider=static_library('testprovider',
+ files('./provider.c'),
+ install:true,
+ c_args:['-Wall','-Werror'],
+)
+
+pkg = import('pkgconfig')
+
+
+pkg.generate(
+ name:'testprovider',
+ filebase:'libtestprovider',
+ description: 'fortest',
+ requires: [],
+ libraries_private: ['-Wl,--whole-archive'] +
+ ['-L${libdir}','-l:libtestprovider.a']+
+ ['-Wl,--no-whole-archive']
+)
diff --git a/test cases/unit/97 link full name/libtestprovider/provider.c b/test cases/unit/97 link full name/libtestprovider/provider.c
new file mode 100644
index 0000000..5e79966
--- /dev/null
+++ b/test cases/unit/97 link full name/libtestprovider/provider.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+static int g_checked = 0;
+
+static void __attribute__((constructor(101), used)) init_checked(void) {
+ g_checked=100;
+ fprintf(stdout, "inited\n");
+}
+
+
+int get_checked(void) {
+ return g_checked;
+}
diff --git a/test cases/unit/97 link full name/proguser/meson.build b/test cases/unit/97 link full name/proguser/meson.build
new file mode 100644
index 0000000..5be5bc9
--- /dev/null
+++ b/test cases/unit/97 link full name/proguser/meson.build
@@ -0,0 +1,11 @@
+project('testprovider','c')
+
+deplib = dependency('libtestprovider', static:true)
+
+dprovidertest = executable('dprovidertest',
+ files('./receiver.c'),
+ dependencies:[deplib],
+ c_args:['-Wall','-Werror'],
+)
+
+test('testprovider',dprovidertest)
diff --git a/test cases/unit/97 link full name/proguser/receiver.c b/test cases/unit/97 link full name/proguser/receiver.c
new file mode 100644
index 0000000..65e9d8e
--- /dev/null
+++ b/test cases/unit/97 link full name/proguser/receiver.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+int __attribute__((weak)) get_checked(void) {
+ return -1;
+}
+
+
+#define CHECK_VALUE (100)
+#define TEST_SUCCESS (0)
+#define TEST_FAILTURE (-1)
+
+int main(void) {
+ if (get_checked() == CHECK_VALUE) {
+ fprintf(stdout,"good\n");
+ return TEST_SUCCESS;
+ }
+ fprintf(stdout,"bad\n");
+ return TEST_FAILTURE;
+}
diff --git a/test cases/unit/98 install all targets/bar-custom.txt b/test cases/unit/98 install all targets/bar-custom.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/bar-custom.txt
diff --git a/test cases/unit/98 install all targets/bar-devel.h b/test cases/unit/98 install all targets/bar-devel.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/bar-devel.h
diff --git a/test cases/unit/98 install all targets/bar-notag.txt b/test cases/unit/98 install all targets/bar-notag.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/bar-notag.txt
diff --git a/test cases/unit/98 install all targets/custom_files/data.txt b/test cases/unit/98 install all targets/custom_files/data.txt
new file mode 100644
index 0000000..557db03
--- /dev/null
+++ b/test cases/unit/98 install all targets/custom_files/data.txt
@@ -0,0 +1 @@
+Hello World
diff --git a/test cases/unit/98 install all targets/foo.in b/test cases/unit/98 install all targets/foo.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/foo.in
diff --git a/test cases/unit/98 install all targets/foo1-devel.h b/test cases/unit/98 install all targets/foo1-devel.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/foo1-devel.h
diff --git a/test cases/unit/98 install all targets/lib.c b/test cases/unit/98 install all targets/lib.c
new file mode 100644
index 0000000..2ea9c7d
--- /dev/null
+++ b/test cases/unit/98 install all targets/lib.c
@@ -0,0 +1,9 @@
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+#define DLL_PUBLIC
+#endif
+
+int DLL_PUBLIC foo(void) {
+ return 0;
+}
diff --git a/test cases/unit/98 install all targets/main.c b/test cases/unit/98 install all targets/main.c
new file mode 100644
index 0000000..0fb4389
--- /dev/null
+++ b/test cases/unit/98 install all targets/main.c
@@ -0,0 +1,3 @@
+int main(int argc, char *argv[]) {
+ return 0;
+}
diff --git a/test cases/unit/98 install all targets/meson.build b/test cases/unit/98 install all targets/meson.build
new file mode 100644
index 0000000..3065b5f
--- /dev/null
+++ b/test cases/unit/98 install all targets/meson.build
@@ -0,0 +1,108 @@
+project('install tag', 'c')
+
+subdir('subdir')
+
+# Those files should not be tagged
+configure_file(input: 'foo.in', output: 'foo-notag.h',
+ configuration: {'foo': 'bar'},
+ install_dir: get_option('datadir'),
+ install: true,
+)
+install_data('bar-notag.txt',
+ install_dir: get_option('datadir')
+)
+custom_target('ct1',
+ output: ['out1-notag.txt', 'out2-notag.txt'],
+ command: ['script.py', '@OUTPUT@'],
+ install_dir: get_option('datadir'),
+ install: true,
+)
+
+# Those files should be tagged as devel
+install_headers('foo1-devel.h')
+install_data('bar-devel.h',
+ install_dir: get_option('includedir'),
+)
+configure_file(input: 'foo.in', output: 'foo2-devel.h',
+ configuration: {'foo': 'bar'},
+ install_dir: get_option('includedir'),
+ install: true,
+)
+static_library('static', 'lib.c',
+ install: true,
+)
+custom_target('ct-header1',
+ output: ['ct-header1.h'],
+ command: ['script.py', '@OUTPUT@'],
+ install_dir: get_option('includedir'),
+ install: true,
+)
+custom_target('ct-header2',
+ output: ['ct-header2.h', 'ct-header3.h'],
+ command: ['script.py', '@OUTPUT@'],
+ install_dir: [false, get_option('includedir')],
+ install: true,
+)
+install_emptydir(get_option('includedir') / 'subdir-devel')
+install_subdir('custom_files',
+ install_dir: get_option('includedir'),
+)
+
+# Those files should have 'runtime' tag
+executable('app', 'main.c',
+ install: true,
+)
+executable('app-otherdir', 'main.c',
+ install: true,
+ install_dir: 'otherbin',
+)
+shared_library('shared', 'lib.c',
+ install: true,
+)
+both_libraries('both', 'lib.c',
+ install: true,
+)
+
+# Unversioned .so file should have 'devel' tag, others should have 'runtime' tag
+shared_library('versioned_shared', 'lib.c',
+ install: true,
+ version: '1.2.3',
+)
+
+# Those files should have custom tag
+install_data('bar-custom.txt',
+ install_dir: get_option('datadir'),
+ install_tag: 'custom')
+configure_file(input: 'foo.in', output: 'foo-custom.h',
+ configuration: {'foo': 'bar'},
+ install_dir: get_option('datadir'),
+ install_tag: 'custom',
+ install: true,
+)
+both_libraries('bothcustom', 'lib.c',
+ install_tag: 'custom',
+ install: true,
+)
+custom_target('ct2',
+ output: ['out1-custom.txt', 'out2-custom.txt'],
+ command: ['script.py', '@OUTPUT@'],
+ install_dir: get_option('datadir'),
+ install_tag: 'custom',
+ install: true,
+)
+install_subdir('custom_files',
+ install_dir: get_option('datadir'),
+ install_tag: 'custom',
+)
+
+# First is custom, 2nd is devel, 3rd has no tag
+custom_target('ct3',
+ output: ['out3-custom.txt', 'out-devel.h', 'out3-notag.txt'],
+ command: ['script.py', '@OUTPUT@'],
+ install_dir: [get_option('datadir'), get_option('includedir'), get_option('datadir')],
+ install_tag: ['custom', 'devel', false],
+ install: true,
+)
+
+meson.add_install_script('script.py', install_tag: 'custom')
+meson.add_install_script('script.py')
diff --git a/test cases/unit/98 install all targets/script.py b/test cases/unit/98 install all targets/script.py
new file mode 100644
index 0000000..c5f3be9
--- /dev/null
+++ b/test cases/unit/98 install all targets/script.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys
+
+for f in sys.argv[1:]:
+ with open(f, 'w') as f:
+ pass
diff --git a/test cases/unit/98 install all targets/subdir/bar2-devel.h b/test cases/unit/98 install all targets/subdir/bar2-devel.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/subdir/bar2-devel.h
diff --git a/test cases/unit/98 install all targets/subdir/foo2.in b/test cases/unit/98 install all targets/subdir/foo2.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/subdir/foo2.in
diff --git a/test cases/unit/98 install all targets/subdir/foo3-devel.h b/test cases/unit/98 install all targets/subdir/foo3-devel.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/98 install all targets/subdir/foo3-devel.h
diff --git a/test cases/unit/98 install all targets/subdir/lib.c b/test cases/unit/98 install all targets/subdir/lib.c
new file mode 100644
index 0000000..2ea9c7d
--- /dev/null
+++ b/test cases/unit/98 install all targets/subdir/lib.c
@@ -0,0 +1,9 @@
+#if defined _WIN32 || defined __CYGWIN__
+#define DLL_PUBLIC __declspec(dllexport)
+#else
+#define DLL_PUBLIC
+#endif
+
+int DLL_PUBLIC foo(void) {
+ return 0;
+}
diff --git a/test cases/unit/98 install all targets/subdir/main.c b/test cases/unit/98 install all targets/subdir/main.c
new file mode 100644
index 0000000..0fb4389
--- /dev/null
+++ b/test cases/unit/98 install all targets/subdir/main.c
@@ -0,0 +1,3 @@
+int main(int argc, char *argv[]) {
+ return 0;
+}
diff --git a/test cases/unit/98 install all targets/subdir/meson.build b/test cases/unit/98 install all targets/subdir/meson.build
new file mode 100644
index 0000000..53c796a
--- /dev/null
+++ b/test cases/unit/98 install all targets/subdir/meson.build
@@ -0,0 +1,21 @@
+configure_file(input: 'foo2.in', output: 'foo2.h',
+ configuration: {'foo': 'bar'},
+ install_dir: get_option('datadir'),
+ install: true,
+)
+custom_target('ct4',
+ output: ['out1.txt', 'out2.txt'],
+ command: ['script.py', '@OUTPUT@'],
+ install_dir: get_option('datadir'),
+ install: true,
+)
+install_headers('foo3-devel.h')
+install_data('bar2-devel.h',
+ install_dir: get_option('includedir'),
+)
+executable('app2', 'main.c',
+ install: true,
+)
+both_libraries('both2', 'lib.c',
+ install: true,
+)
diff --git a/test cases/unit/98 install all targets/subdir/script.py b/test cases/unit/98 install all targets/subdir/script.py
new file mode 100644
index 0000000..c5f3be9
--- /dev/null
+++ b/test cases/unit/98 install all targets/subdir/script.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys
+
+for f in sys.argv[1:]:
+ with open(f, 'w') as f:
+ pass
diff --git a/test cases/unit/99 custom target name/file.txt.in b/test cases/unit/99 custom target name/file.txt.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/unit/99 custom target name/file.txt.in
diff --git a/test cases/unit/99 custom target name/meson.build b/test cases/unit/99 custom target name/meson.build
new file mode 100644
index 0000000..8d148a8
--- /dev/null
+++ b/test cases/unit/99 custom target name/meson.build
@@ -0,0 +1,14 @@
+project('custom target name', 'c')
+
+python = import('python').find_installation()
+
+# Name argument is optional and should default to 'file.txt'
+custom_target(
+ input: 'file.txt.in',
+ output: '@BASENAME@',
+ command: [python, '--version'],
+ build_by_default: true,
+ capture: true,
+)
+
+subdir('subdir')
diff --git a/test cases/unit/99 custom target name/subdir/meson.build b/test cases/unit/99 custom target name/subdir/meson.build
new file mode 100644
index 0000000..785a7b3
--- /dev/null
+++ b/test cases/unit/99 custom target name/subdir/meson.build
@@ -0,0 +1,9 @@
+# Name argument is optional and should default to 'file.txt', but should be
+# displayed as 'subdir/file.txt' by ninja.
+custom_target(
+ input: '../file.txt.in',
+ output: ['@BASENAME@'],
+ command: [python, '--version'],
+ build_by_default: true,
+ capture: true,
+)
diff --git a/test cases/vala/1 basic/meson.build b/test cases/vala/1 basic/meson.build
new file mode 100644
index 0000000..d1bfabd
--- /dev/null
+++ b/test cases/vala/1 basic/meson.build
@@ -0,0 +1,7 @@
+# Language are case unsensitive, check here that capital C works too.
+project('valatest', 'vala', 'C')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+e = executable('valaprog', 'prog.vala', dependencies : valadeps)
+test('valatest', e)
diff --git a/test cases/vala/1 basic/prog.vala b/test cases/vala/1 basic/prog.vala
new file mode 100644
index 0000000..638e776
--- /dev/null
+++ b/test cases/vala/1 basic/prog.vala
@@ -0,0 +1,7 @@
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ stdout.printf("Vala is working.\n");
+ return 0;
+ }
+}
diff --git a/test cases/vala/10 mixed sources/c/foo.c b/test cases/vala/10 mixed sources/c/foo.c
new file mode 100644
index 0000000..f3c6fb8
--- /dev/null
+++ b/test cases/vala/10 mixed sources/c/foo.c
@@ -0,0 +1,5 @@
+int retval (void);
+
+int test (void) {
+ return retval ();
+}
diff --git a/test cases/vala/10 mixed sources/c/meson.build b/test cases/vala/10 mixed sources/c/meson.build
new file mode 100644
index 0000000..ead0575
--- /dev/null
+++ b/test cases/vala/10 mixed sources/c/meson.build
@@ -0,0 +1,5 @@
+writec = find_program('writec.py')
+
+retval = custom_target('writec',
+ output : 'retval.c',
+ command : [writec, '@OUTPUT@'])
diff --git a/test cases/vala/10 mixed sources/c/writec.py b/test cases/vala/10 mixed sources/c/writec.py
new file mode 100644
index 0000000..2cc822b
--- /dev/null
+++ b/test cases/vala/10 mixed sources/c/writec.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import sys
+
+c = '''int
+retval(void) {
+ return 0;
+}
+'''
+
+with open(sys.argv[1], 'w') as f:
+ f.write(c)
diff --git a/test cases/vala/10 mixed sources/meson.build b/test cases/vala/10 mixed sources/meson.build
new file mode 100644
index 0000000..75b8ecd
--- /dev/null
+++ b/test cases/vala/10 mixed sources/meson.build
@@ -0,0 +1,7 @@
+project('foo', 'c', 'vala')
+
+glib = dependency('glib-2.0')
+
+subdir('c')
+e = executable('foo', 'c/foo.c', retval, 'vala/bar.vala', dependencies: [glib])
+test('test foo', e)
diff --git a/test cases/vala/10 mixed sources/vala/bar.vala b/test cases/vala/10 mixed sources/vala/bar.vala
new file mode 100644
index 0000000..0772f3e
--- /dev/null
+++ b/test cases/vala/10 mixed sources/vala/bar.vala
@@ -0,0 +1,5 @@
+extern int test ();
+
+public int main (string[] args) {
+ return test ();
+}
diff --git a/test cases/vala/11 generated vapi/libbar/bar.c b/test cases/vala/11 generated vapi/libbar/bar.c
new file mode 100644
index 0000000..3037141
--- /dev/null
+++ b/test cases/vala/11 generated vapi/libbar/bar.c
@@ -0,0 +1,29 @@
+#include "bar.h"
+#include "foo.h"
+
+struct _BarBar
+{
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (BarBar, bar_bar, G_TYPE_OBJECT)
+
+static void
+bar_bar_class_init (BarBarClass *klass)
+{
+}
+
+static void
+bar_bar_init (BarBar *self)
+{
+}
+
+/**
+ * bar_bar_return_success:
+ *
+ * Returns 0
+ */
+int bar_bar_return_success(void)
+{
+ return foo_foo_return_success();
+}
diff --git a/test cases/vala/11 generated vapi/libbar/bar.h b/test cases/vala/11 generated vapi/libbar/bar.h
new file mode 100644
index 0000000..4ca7270
--- /dev/null
+++ b/test cases/vala/11 generated vapi/libbar/bar.h
@@ -0,0 +1,9 @@
+#include <glib-object.h>
+
+#pragma once
+
+#define BAR_TYPE_BAR (bar_bar_get_type())
+
+G_DECLARE_FINAL_TYPE (BarBar, bar_bar, BAR, BAR, GObject)
+
+int bar_bar_return_success(void);
diff --git a/test cases/vala/11 generated vapi/libbar/meson.build b/test cases/vala/11 generated vapi/libbar/meson.build
new file mode 100644
index 0000000..0bf7d5c
--- /dev/null
+++ b/test cases/vala/11 generated vapi/libbar/meson.build
@@ -0,0 +1,32 @@
+libbar_sources = [
+ 'bar.c',
+ 'bar.h',
+]
+
+libbar_deps = [
+ dependency('gobject-2.0'),
+ libfoo_dep,
+]
+
+libbar = shared_library('bar', libbar_sources,
+ dependencies: libbar_deps,
+ install: true,
+)
+
+libbar_api_ver = '1.0'
+
+libbar_gir = gnome.generate_gir(libbar,
+ sources: libbar_sources,
+ namespace: 'Bar',
+ nsversion: libbar_api_ver,
+ symbol_prefix: 'bar',
+ extra_args: [
+ '--c-include=bar.h',
+ ],
+)
+
+libbar_vapi = gnome.generate_vapi('bar-' + libbar_api_ver,
+ sources: libbar_gir[0],
+ packages: libfoo_vapi,
+ install: true,
+)
diff --git a/test cases/vala/11 generated vapi/libfoo/foo.c b/test cases/vala/11 generated vapi/libfoo/foo.c
new file mode 100644
index 0000000..dd2b891
--- /dev/null
+++ b/test cases/vala/11 generated vapi/libfoo/foo.c
@@ -0,0 +1,28 @@
+#include "foo.h"
+
+struct _FooFoo
+{
+ GObject parent_instance;
+};
+
+G_DEFINE_TYPE (FooFoo, foo_foo, G_TYPE_OBJECT)
+
+static void
+foo_foo_class_init (FooFooClass *klass)
+{
+}
+
+static void
+foo_foo_init (FooFoo *self)
+{
+}
+
+/**
+ * foo_foo_return_success:
+ *
+ * Returns 0
+ */
+int foo_foo_return_success(void)
+{
+ return 0;
+}
diff --git a/test cases/vala/11 generated vapi/libfoo/foo.h b/test cases/vala/11 generated vapi/libfoo/foo.h
new file mode 100644
index 0000000..e1887d8
--- /dev/null
+++ b/test cases/vala/11 generated vapi/libfoo/foo.h
@@ -0,0 +1,9 @@
+#include <glib-object.h>
+
+#pragma once
+
+#define FOO_TYPE_FOO (foo_foo_get_type())
+
+G_DECLARE_FINAL_TYPE (FooFoo, foo_foo, Foo, FOO, GObject)
+
+int foo_foo_return_success(void);
diff --git a/test cases/vala/11 generated vapi/libfoo/foo.metadata b/test cases/vala/11 generated vapi/libfoo/foo.metadata
new file mode 100644
index 0000000..e208fe3
--- /dev/null
+++ b/test cases/vala/11 generated vapi/libfoo/foo.metadata
@@ -0,0 +1 @@
+Foo.bar nullable
diff --git a/test cases/vala/11 generated vapi/libfoo/meson.build b/test cases/vala/11 generated vapi/libfoo/meson.build
new file mode 100644
index 0000000..ee425f2
--- /dev/null
+++ b/test cases/vala/11 generated vapi/libfoo/meson.build
@@ -0,0 +1,42 @@
+libfoo_sources = [
+ 'foo.c',
+ 'foo.h',
+]
+
+libfoo_deps = [
+ dependency('gobject-2.0')
+]
+
+libfoo = shared_library('foo', libfoo_sources,
+ dependencies: libfoo_deps,
+ install: true,
+)
+
+libfoo_api_ver = '1.0'
+
+libfoo_gir = gnome.generate_gir(libfoo,
+ sources: libfoo_sources,
+ namespace: 'Foo',
+ nsversion: libfoo_api_ver,
+ symbol_prefix: 'foo',
+ extra_args: [
+ '--c-include=foo.h',
+ ],
+)
+
+configure_file(
+ input: 'foo.metadata',
+ output: 'Foo-@0@.metadata'.format(libfoo_api_ver),
+ copy: true
+)
+
+libfoo_vapi = gnome.generate_vapi('foo-' + libfoo_api_ver,
+ metadata_dirs: meson.current_build_dir(),
+ sources: libfoo_gir[0],
+ install: true,
+)
+
+libfoo_dep = declare_dependency(
+ link_with: libfoo,
+ include_directories: include_directories('.'),
+)
diff --git a/test cases/vala/11 generated vapi/main.vala b/test cases/vala/11 generated vapi/main.vala
new file mode 100644
index 0000000..d61fba0
--- /dev/null
+++ b/test cases/vala/11 generated vapi/main.vala
@@ -0,0 +1,9 @@
+using Foo;
+using Bar;
+
+class Main : GLib.Object {
+ public static int main(string[] args) {
+ var ignore = Foo.Foo.return_success();
+ return Bar.Bar.return_success();
+ }
+}
diff --git a/test cases/vala/11 generated vapi/meson.build b/test cases/vala/11 generated vapi/meson.build
new file mode 100644
index 0000000..d5f38ca
--- /dev/null
+++ b/test cases/vala/11 generated vapi/meson.build
@@ -0,0 +1,13 @@
+project('vapi-test', ['c', 'vala'])
+
+gnome = import('gnome')
+subdir('libfoo')
+subdir('libbar')
+
+vapiexe = executable('vapigen-test',
+ 'main.vala',
+ dependencies: [dependency('gobject-2.0'), libfoo_vapi, libbar_vapi],
+ install: true,
+)
+
+test('vapigen-test', vapiexe)
diff --git a/test cases/vala/11 generated vapi/test.json b/test cases/vala/11 generated vapi/test.json
new file mode 100644
index 0000000..1a742aa
--- /dev/null
+++ b/test cases/vala/11 generated vapi/test.json
@@ -0,0 +1,13 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/vapigen-test"},
+ {"type": "expr", "file": "usr/lib/?libfoo.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libfoo.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libbar.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libbar.dll.a"},
+ {"type": "file", "file": "usr/share/vala/vapi/foo-1.0.vapi"},
+ {"type": "file", "file": "usr/share/vala/vapi/foo-1.0.deps"},
+ {"type": "file", "file": "usr/share/vala/vapi/bar-1.0.vapi"},
+ {"type": "file", "file": "usr/share/vala/vapi/bar-1.0.deps"}
+ ]
+}
diff --git a/test cases/vala/12 custom output/bar.vala b/test cases/vala/12 custom output/bar.vala
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/vala/12 custom output/bar.vala
diff --git a/test cases/vala/12 custom output/foo.vala b/test cases/vala/12 custom output/foo.vala
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/vala/12 custom output/foo.vala
diff --git a/test cases/vala/12 custom output/meson.build b/test cases/vala/12 custom output/meson.build
new file mode 100644
index 0000000..c328959
--- /dev/null
+++ b/test cases/vala/12 custom output/meson.build
@@ -0,0 +1,13 @@
+project('valatest', 'c', 'vala')
+
+glib = dependency('glib-2.0')
+gobject = dependency('gobject-2.0')
+
+foo_lib = library('foo-1.0', 'foo.vala',
+ vala_header: 'foo.h',
+ vala_vapi: 'foo.vapi',
+ dependencies: [glib, gobject])
+
+library('bar', 'bar.vala',
+ link_with: [foo_lib],
+ dependencies: [glib, gobject])
diff --git a/test cases/vala/13 find library/meson.build b/test cases/vala/13 find library/meson.build
new file mode 100644
index 0000000..03054d2
--- /dev/null
+++ b/test cases/vala/13 find library/meson.build
@@ -0,0 +1,9 @@
+project('find vala library', 'vala', 'c')
+
+valac = meson.get_compiler('vala')
+
+gobject = dependency('gobject-2.0')
+zlib = valac.find_library('zlib')
+
+e = executable('zlibtest', 'test.vala', dependencies : [gobject, zlib])
+test('testzlib', e)
diff --git a/test cases/vala/13 find library/test.vala b/test cases/vala/13 find library/test.vala
new file mode 100644
index 0000000..b087cfb
--- /dev/null
+++ b/test cases/vala/13 find library/test.vala
@@ -0,0 +1,6 @@
+using ZLib;
+
+public static int main(string[] args) {
+ stdout.printf("ZLIB_VERSION is: %s\n", ZLib.VERSION.STRING);
+ return 0;
+}
diff --git a/test cases/vala/14 target glib version and gresources/gres/meson.build b/test cases/vala/14 target glib version and gresources/gres/meson.build
new file mode 100644
index 0000000..f222a00
--- /dev/null
+++ b/test cases/vala/14 target glib version and gresources/gres/meson.build
@@ -0,0 +1,3 @@
+res = gnome.compile_resources('testui',
+ 'test-resources.xml',
+ source_dir : '.')
diff --git a/test cases/vala/14 target glib version and gresources/gres/test-resources.xml b/test cases/vala/14 target glib version and gresources/gres/test-resources.xml
new file mode 100644
index 0000000..4e8a73f
--- /dev/null
+++ b/test cases/vala/14 target glib version and gresources/gres/test-resources.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/Meson">
+ <file compressed="true" preprocess="xml-stripblanks">test.ui</file>
+ </gresource>
+</gresources>
diff --git a/test cases/vala/14 target glib version and gresources/gres/test.ui b/test cases/vala/14 target glib version and gresources/gres/test.ui
new file mode 100644
index 0000000..f90d941
--- /dev/null
+++ b/test cases/vala/14 target glib version and gresources/gres/test.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.8 -->
+ <template class="TestWidget" parent="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkEntry" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </template>
+</interface>
diff --git a/test cases/vala/14 target glib version and gresources/meson.build b/test cases/vala/14 target glib version and gresources/meson.build
new file mode 100644
index 0000000..dee2627
--- /dev/null
+++ b/test cases/vala/14 target glib version and gresources/meson.build
@@ -0,0 +1,12 @@
+project('test glib target version and gresources', 'c', 'vala')
+
+gnome = import('gnome')
+
+glib = dependency('glib-2.0', version : '>=2.38')
+gtk = dependency('gtk+-3.0')
+
+subdir('gres')
+
+e = executable('gtktemplate', 'test.vala', res, dependencies : [glib, gtk])
+# No X on the CI, so disable this for now
+#test('test-target-glib', e)
diff --git a/test cases/vala/14 target glib version and gresources/test.vala b/test cases/vala/14 target glib version and gresources/test.vala
new file mode 100644
index 0000000..f10bbe4
--- /dev/null
+++ b/test cases/vala/14 target glib version and gresources/test.vala
@@ -0,0 +1,37 @@
+using Gtk;
+using GLib;
+
+[GtkTemplate (ui = "/org/Meson/test.ui")]
+public class TestWidget : Box {
+ public string text {
+ get { return entry.text; }
+ set { entry.text = value; }
+ }
+
+ [GtkChild]
+ private unowned Entry entry;
+
+ public TestWidget (string text) {
+ this.text = text;
+ }
+}
+
+void main(string[] args) {
+ Gtk.init (ref args);
+ var win = new Window();
+ win.destroy.connect (Gtk.main_quit);
+
+ var widget = new TestWidget ("SOME TEXT HERE");
+
+ win.add (widget);
+ win.show_all ();
+
+ /* Exit immediately */
+ Timeout.add_full (Priority.DEFAULT_IDLE, 1, () =>
+ {
+ Gtk.main_quit();
+ return false;
+ });
+
+ Gtk.main ();
+}
diff --git a/test cases/vala/15 static vapi in source tree/meson.build b/test cases/vala/15 static vapi in source tree/meson.build
new file mode 100644
index 0000000..44bea48
--- /dev/null
+++ b/test cases/vala/15 static vapi in source tree/meson.build
@@ -0,0 +1,13 @@
+project('static vapi', 'c', 'vala')
+
+glib = dependency('glib-2.0')
+
+conf = configuration_data()
+conf.set_quoted('VERSION', '1.0.0')
+config_h = configure_file(output : 'config.h',
+ configuration : conf)
+
+e = executable('static-vapi', 'vapi/config.vapi', 'test.vala',
+ dependencies : glib)
+
+test('test-config', e)
diff --git a/test cases/vala/15 static vapi in source tree/test.vala b/test cases/vala/15 static vapi in source tree/test.vala
new file mode 100644
index 0000000..06f2d59
--- /dev/null
+++ b/test cases/vala/15 static vapi in source tree/test.vala
@@ -0,0 +1,6 @@
+using GLib;
+using Config;
+
+public int main (string[] args) {
+ return GLib.strcmp(VERSION, "1.0.0");
+}
diff --git a/test cases/vala/15 static vapi in source tree/vapi/config.vapi b/test cases/vala/15 static vapi in source tree/vapi/config.vapi
new file mode 100644
index 0000000..71bcc6e
--- /dev/null
+++ b/test cases/vala/15 static vapi in source tree/vapi/config.vapi
@@ -0,0 +1,4 @@
+[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")]
+namespace Config {
+ public const string VERSION;
+}
diff --git a/test cases/vala/16 mixed dependence/app.vala b/test cases/vala/16 mixed dependence/app.vala
new file mode 100644
index 0000000..5b54543
--- /dev/null
+++ b/test cases/vala/16 mixed dependence/app.vala
@@ -0,0 +1,7 @@
+namespace App {
+ public static int main(string[] args) {
+ var mixer = new Mixer();
+ print("Current volume is %u\n", mixer.get_volume());
+ return 0;
+ }
+}
diff --git a/test cases/vala/16 mixed dependence/meson.build b/test cases/vala/16 mixed dependence/meson.build
new file mode 100644
index 0000000..b44b47b
--- /dev/null
+++ b/test cases/vala/16 mixed dependence/meson.build
@@ -0,0 +1,16 @@
+project('mixed dependence', 'vala', 'c')
+
+cc = meson.get_compiler('c')
+
+deps = [dependency('glib-2.0'), dependency('gobject-2.0'),
+ # Should be ignored, see https://github.com/mesonbuild/meson/issues/1939
+ cc.find_library('z')]
+
+mixer = static_library('mixer', 'mixer.vala', 'mixer-glue.c',
+ dependencies : deps)
+
+app = executable('app', 'app.vala',
+ link_with : mixer,
+ dependencies : deps)
+
+test('valamixeddependencetest', app)
diff --git a/test cases/vala/16 mixed dependence/mixer-glue.c b/test cases/vala/16 mixed dependence/mixer-glue.c
new file mode 100644
index 0000000..d6c0c37
--- /dev/null
+++ b/test cases/vala/16 mixed dependence/mixer-glue.c
@@ -0,0 +1,5 @@
+#include "mixer.h"
+
+guint mixer_get_volume(Mixer *mixer) {
+ return 11;
+}
diff --git a/test cases/vala/16 mixed dependence/mixer.vala b/test cases/vala/16 mixed dependence/mixer.vala
new file mode 100644
index 0000000..f207132
--- /dev/null
+++ b/test cases/vala/16 mixed dependence/mixer.vala
@@ -0,0 +1,3 @@
+public class Mixer : Object {
+ public extern uint get_volume();
+}
diff --git a/test cases/vala/17 plain consumer/app.c b/test cases/vala/17 plain consumer/app.c
new file mode 100644
index 0000000..c8d0010
--- /dev/null
+++ b/test cases/vala/17 plain consumer/app.c
@@ -0,0 +1,11 @@
+#include "badger.h"
+
+int main(int argc, char *argv[]) {
+ Badger *badger;
+
+ badger = g_object_new(TYPE_BADGER, NULL);
+ g_print("Badger whose name is '%s'\n", badger_get_name(badger));
+ g_object_unref(badger);
+
+ return 0;
+}
diff --git a/test cases/vala/17 plain consumer/badger.vala b/test cases/vala/17 plain consumer/badger.vala
new file mode 100644
index 0000000..1aaeda6
--- /dev/null
+++ b/test cases/vala/17 plain consumer/badger.vala
@@ -0,0 +1,10 @@
+public class Badger : Object {
+ public string name {
+ get;
+ construct;
+ }
+
+ Badger() {
+ Object(name: "Joe");
+ }
+}
diff --git a/test cases/vala/17 plain consumer/meson.build b/test cases/vala/17 plain consumer/meson.build
new file mode 100644
index 0000000..e98bca1
--- /dev/null
+++ b/test cases/vala/17 plain consumer/meson.build
@@ -0,0 +1,12 @@
+project('plain consumer', 'vala', 'c')
+
+deps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+badger = static_library('badger', 'badger.vala',
+ dependencies : deps)
+
+app = executable('app', 'app.c',
+ link_with : badger,
+ dependencies : deps)
+
+test('valaplainconsumertest', app)
diff --git a/test cases/vala/18 vapi consumed twice/app.vala b/test cases/vala/18 vapi consumed twice/app.vala
new file mode 100644
index 0000000..cd94a42
--- /dev/null
+++ b/test cases/vala/18 vapi consumed twice/app.vala
@@ -0,0 +1,11 @@
+namespace App {
+ public static int main(string[] args) {
+ var person = new Person();
+ print("Favorite beer of \"%s\" is %s\n", person.name, person.favorite_beer.flavor);
+
+ var beer = new Beer("tasty");
+ print("This beer is %s\n", beer.flavor);
+
+ return 0;
+ }
+}
diff --git a/test cases/vala/18 vapi consumed twice/beer.vala b/test cases/vala/18 vapi consumed twice/beer.vala
new file mode 100644
index 0000000..cee38ad
--- /dev/null
+++ b/test cases/vala/18 vapi consumed twice/beer.vala
@@ -0,0 +1,10 @@
+public class Beer : Object {
+ public string flavor {
+ get;
+ construct;
+ }
+
+ public Beer(string flavor) {
+ Object(flavor: flavor);
+ }
+}
diff --git a/test cases/vala/18 vapi consumed twice/meson.build b/test cases/vala/18 vapi consumed twice/meson.build
new file mode 100644
index 0000000..6a7f5eb
--- /dev/null
+++ b/test cases/vala/18 vapi consumed twice/meson.build
@@ -0,0 +1,15 @@
+project('vapi consumed twice', 'vala', 'c')
+
+base_deps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+beer = library('beer', 'beer.vala', dependencies : base_deps)
+beer_dep = declare_dependency(link_with : beer)
+
+person = library('person', 'person.vala', link_with : beer,
+ dependencies : base_deps)
+person_dep = declare_dependency(link_with : person, dependencies : [beer_dep])
+
+app = executable('app', 'app.vala',
+ dependencies : base_deps + [person_dep, beer_dep])
+
+test('valavapiconsumedtwicetest', app)
diff --git a/test cases/vala/18 vapi consumed twice/person.vala b/test cases/vala/18 vapi consumed twice/person.vala
new file mode 100644
index 0000000..36b0025
--- /dev/null
+++ b/test cases/vala/18 vapi consumed twice/person.vala
@@ -0,0 +1,16 @@
+public class Person : Object {
+ public string name {
+ get {
+ return "Joe Badger";
+ }
+ }
+
+ public Beer favorite_beer {
+ get;
+ construct;
+ }
+
+ public Person() {
+ Object(favorite_beer: new Beer("smooth"));
+ }
+}
diff --git a/test cases/vala/19 genie/meson.build b/test cases/vala/19 genie/meson.build
new file mode 100644
index 0000000..2bdb185
--- /dev/null
+++ b/test cases/vala/19 genie/meson.build
@@ -0,0 +1,6 @@
+project('genietest', 'vala', 'c')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+e = executable('genieprog', 'prog.gs', dependencies : valadeps)
+test('genietest', e)
diff --git a/test cases/vala/19 genie/prog.gs b/test cases/vala/19 genie/prog.gs
new file mode 100644
index 0000000..f206b09
--- /dev/null
+++ b/test cases/vala/19 genie/prog.gs
@@ -0,0 +1,2 @@
+init
+ print ("Genie is working.")
diff --git a/test cases/vala/2 multiple files/class1.vala b/test cases/vala/2 multiple files/class1.vala
new file mode 100644
index 0000000..7072101
--- /dev/null
+++ b/test cases/vala/2 multiple files/class1.vala
@@ -0,0 +1,7 @@
+class Class1 : GLib.Object {
+
+ public void hello() {
+ var c2 = new Class2();
+ c2.hello();
+ }
+}
diff --git a/test cases/vala/2 multiple files/class2.vala b/test cases/vala/2 multiple files/class2.vala
new file mode 100644
index 0000000..ad76cc1
--- /dev/null
+++ b/test cases/vala/2 multiple files/class2.vala
@@ -0,0 +1,6 @@
+class Class2 : GLib.Object {
+
+ public void hello() {
+ stdout.printf("Multiple file Vala project is working.\n");
+ }
+}
diff --git a/test cases/vala/2 multiple files/main.vala b/test cases/vala/2 multiple files/main.vala
new file mode 100644
index 0000000..6de0fa3
--- /dev/null
+++ b/test cases/vala/2 multiple files/main.vala
@@ -0,0 +1,8 @@
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ var c1 = new Class1();
+ c1.hello();
+ return 0;
+ }
+}
diff --git a/test cases/vala/2 multiple files/meson.build b/test cases/vala/2 multiple files/meson.build
new file mode 100644
index 0000000..dc36073
--- /dev/null
+++ b/test cases/vala/2 multiple files/meson.build
@@ -0,0 +1,10 @@
+# adding 'c' shouldn't be required
+project('multiple files')
+add_languages('vala')
+
+glib = dependency('glib-2.0')
+gobject = dependency('gobject-2.0')
+
+e = executable('prog', 'main.vala', 'class1.vala', 'class2.vala',
+dependencies : [glib, gobject])
+test('multiple file test', e)
diff --git a/test cases/vala/20 genie multiple mixed sources/c_test_one.c b/test cases/vala/20 genie multiple mixed sources/c_test_one.c
new file mode 100644
index 0000000..d0b7e05
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/c_test_one.c
@@ -0,0 +1,5 @@
+#include <glib.h>
+
+gboolean c_test_one_is_true (void) {
+ return TRUE;
+}
diff --git a/test cases/vala/20 genie multiple mixed sources/c_test_two.c b/test cases/vala/20 genie multiple mixed sources/c_test_two.c
new file mode 100644
index 0000000..596928b
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/c_test_two.c
@@ -0,0 +1,5 @@
+#include <glib.h>
+
+gboolean c_test_two_is_true (void) {
+ return TRUE;
+}
diff --git a/test cases/vala/20 genie multiple mixed sources/init.gs b/test cases/vala/20 genie multiple mixed sources/init.gs
new file mode 100644
index 0000000..1564403
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/init.gs
@@ -0,0 +1,10 @@
+def extern c_test_one_is_true():bool
+def extern c_test_two_is_true():bool
+
+init
+ assert( new Genie.TestOne().is_true() )
+ assert( new Genie.TestTwo().is_true() )
+ assert( new Vala.TestOne().is_true() )
+ assert( new Vala.TestTwo().is_true() )
+ assert( c_test_one_is_true() )
+ assert( c_test_two_is_true() )
diff --git a/test cases/vala/20 genie multiple mixed sources/meson.build b/test cases/vala/20 genie multiple mixed sources/meson.build
new file mode 100644
index 0000000..148ce0e
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/meson.build
@@ -0,0 +1,19 @@
+project( 'Genie multiple and mixed sources', 'vala', 'c' )
+
+genie_deps = [
+ dependency( 'glib-2.0' ),
+ dependency( 'gobject-2.0' ),
+]
+
+sources = [
+ 'init.gs',
+ 'test_one.gs',
+ 'test_two.gs',
+ 'vala_test_one.vala',
+ 'vala_test_two.vala',
+ 'c_test_one.c',
+ 'c_test_two.c',
+]
+
+prog = executable( 'genie_prog', sources, dependencies: genie_deps )
+test( 'Given a Genie program when it is compiled from multiple mixed sources then it should work', prog )
diff --git a/test cases/vala/20 genie multiple mixed sources/test_one.gs b/test cases/vala/20 genie multiple mixed sources/test_one.gs
new file mode 100644
index 0000000..af3b1ec
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/test_one.gs
@@ -0,0 +1,5 @@
+namespace Genie
+
+ class TestOne
+ def is_true():bool
+ return true
diff --git a/test cases/vala/20 genie multiple mixed sources/test_two.gs b/test cases/vala/20 genie multiple mixed sources/test_two.gs
new file mode 100644
index 0000000..0a0e03c
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/test_two.gs
@@ -0,0 +1,5 @@
+namespace Genie
+
+ class TestTwo
+ def is_true():bool
+ return true
diff --git a/test cases/vala/20 genie multiple mixed sources/vala_test_one.vala b/test cases/vala/20 genie multiple mixed sources/vala_test_one.vala
new file mode 100644
index 0000000..7044bc8
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/vala_test_one.vala
@@ -0,0 +1,7 @@
+namespace Vala {
+ public class TestOne {
+ public bool is_true() {
+ return true;
+ }
+ }
+}
diff --git a/test cases/vala/20 genie multiple mixed sources/vala_test_two.vala b/test cases/vala/20 genie multiple mixed sources/vala_test_two.vala
new file mode 100644
index 0000000..b530efb
--- /dev/null
+++ b/test cases/vala/20 genie multiple mixed sources/vala_test_two.vala
@@ -0,0 +1,7 @@
+namespace Vala {
+ public class TestTwo {
+ public bool is_true() {
+ return true;
+ }
+ }
+}
diff --git a/test cases/vala/21 type module/foo.vala b/test cases/vala/21 type module/foo.vala
new file mode 100644
index 0000000..0a63225
--- /dev/null
+++ b/test cases/vala/21 type module/foo.vala
@@ -0,0 +1,17 @@
+public extern const string FOO_PLUGIN_PATH;
+
+Foo.PluginModule plugin_module;
+
+public int main () {
+ plugin_module = new Foo.PluginModule (FOO_PLUGIN_PATH, "bar");
+
+ if (!plugin_module.load ()) {
+ return 1;
+ }
+
+ var plugin = Object.new (plugin_module.plugin_type) as Foo.Plugin;
+
+ assert ("bar" == plugin.bar ());
+
+ return 0;
+}
diff --git a/test cases/vala/21 type module/meson.build b/test cases/vala/21 type module/meson.build
new file mode 100644
index 0000000..9bd26e3
--- /dev/null
+++ b/test cases/vala/21 type module/meson.build
@@ -0,0 +1,20 @@
+project('valatest', 'c', 'vala')
+
+glib_dep = dependency('glib-2.0')
+gobject_dep = dependency('gobject-2.0')
+gmodule_dep = dependency('gmodule-2.0')
+
+foo_sources = ['plugin.vala', 'plugin-module.vala']
+foo_lib = shared_library('foo', foo_sources,
+ dependencies: [glib_dep, gobject_dep, gmodule_dep])
+
+shared_module('bar', 'plugin-bar.vala',
+ dependencies: [glib_dep, gobject_dep],
+ link_with: foo_lib)
+
+foo_bin = executable('foo', 'foo.vala',
+ c_args: ['-DFOO_PLUGIN_PATH="@0@"'.format(meson.current_build_dir())],
+ dependencies: [glib_dep, gobject_dep],
+ link_with: foo_lib)
+
+test('shared module', foo_bin)
diff --git a/test cases/vala/21 type module/plugin-bar.vala b/test cases/vala/21 type module/plugin-bar.vala
new file mode 100644
index 0000000..ff6e334
--- /dev/null
+++ b/test cases/vala/21 type module/plugin-bar.vala
@@ -0,0 +1,11 @@
+[ModuleInit]
+public GLib.Type plugin_init (GLib.TypeModule tm) {
+ return typeof (Bar.Plugin);
+}
+
+public class Bar.Plugin : Foo.Plugin, GLib.Object {
+
+ public string bar () {
+ return "bar";
+ }
+}
diff --git a/test cases/vala/21 type module/plugin-module.vala b/test cases/vala/21 type module/plugin-module.vala
new file mode 100644
index 0000000..1c3aeca
--- /dev/null
+++ b/test cases/vala/21 type module/plugin-module.vala
@@ -0,0 +1,54 @@
+public class Foo.PluginModule : TypeModule {
+
+ [CCode (has_target = false)]
+ private delegate Type PluginInit (TypeModule type_module);
+
+ public string? directory { get; construct; default = null; }
+
+ public string name { get; construct; }
+
+ public string path { get; construct; }
+
+ public Type plugin_type { get; private set; }
+
+ private Module? module = null;
+
+ public PluginModule (string? directory, string name) {
+ Object (directory: directory, name: name);
+ }
+
+ construct {
+ path = Module.build_path (directory, name);
+ }
+
+ public override bool load () {
+ module = Module.open (path, ModuleFlags.BIND_LAZY);
+
+ if (module == null) {
+ critical (Module.error ());
+ return false;
+ }
+
+ void* plugin_init;
+ if (!module.symbol ("plugin_init", out plugin_init)){
+ critical (Module.error ());
+ return false;
+ }
+
+ if (plugin_init == null) {
+ return false;
+ }
+
+ plugin_type = ((PluginInit) plugin_init) (this);
+
+ if (!plugin_type.is_a (typeof (Plugin))) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public override void unload () {
+ module = null;
+ }
+}
diff --git a/test cases/vala/21 type module/plugin.vala b/test cases/vala/21 type module/plugin.vala
new file mode 100644
index 0000000..3d0ea4c
--- /dev/null
+++ b/test cases/vala/21 type module/plugin.vala
@@ -0,0 +1,4 @@
+public interface Foo.Plugin : GLib.Object {
+
+ public abstract string bar ();
+}
diff --git a/test cases/vala/22 same target in directories/Subdir/Subdir2/Test.vala b/test cases/vala/22 same target in directories/Subdir/Subdir2/Test.vala
new file mode 100644
index 0000000..94e5cbc
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Subdir/Subdir2/Test.vala
@@ -0,0 +1,5 @@
+public class Subdir.Subdir2.Test : GLib.Object {
+ construct {
+ stdout.printf("Test from Subdir/Subdir2/\n");
+ }
+}
diff --git a/test cases/vala/22 same target in directories/Subdir/Test.vala b/test cases/vala/22 same target in directories/Subdir/Test.vala
new file mode 100644
index 0000000..02143c4
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Subdir/Test.vala
@@ -0,0 +1,5 @@
+public class Subdir.Test : GLib.Object {
+ construct {
+ stdout.printf("Test from Subdir/\n");
+ }
+}
diff --git a/test cases/vala/22 same target in directories/Subdir2/Test.vala b/test cases/vala/22 same target in directories/Subdir2/Test.vala
new file mode 100644
index 0000000..4a2d61f
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Subdir2/Test.vala
@@ -0,0 +1,5 @@
+public class Subdir2.Test : GLib.Object {
+ construct {
+ stdout.printf("Test from Subdir2/\n");
+ }
+}
diff --git a/test cases/vala/22 same target in directories/Test.vala b/test cases/vala/22 same target in directories/Test.vala
new file mode 100644
index 0000000..9154e22
--- /dev/null
+++ b/test cases/vala/22 same target in directories/Test.vala
@@ -0,0 +1,5 @@
+public class Test : GLib.Object {
+ construct {
+ stdout.printf("Test from main directory\n");
+ }
+}
diff --git a/test cases/vala/22 same target in directories/meson.build b/test cases/vala/22 same target in directories/meson.build
new file mode 100644
index 0000000..6785f73
--- /dev/null
+++ b/test cases/vala/22 same target in directories/meson.build
@@ -0,0 +1,13 @@
+project('valatest', 'vala', 'c')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+valafiles = files(
+ 'prog.vala',
+ 'Test.vala',
+ 'Subdir/Test.vala',
+ 'Subdir/Subdir2/Test.vala',
+ 'Subdir2/Test.vala',
+)
+
+e = executable('multidir_prog', valafiles, dependencies : valadeps)
+test('valatest', e)
diff --git a/test cases/vala/22 same target in directories/prog.vala b/test cases/vala/22 same target in directories/prog.vala
new file mode 100644
index 0000000..37cbf7a
--- /dev/null
+++ b/test cases/vala/22 same target in directories/prog.vala
@@ -0,0 +1,8 @@
+int main() {
+ var test1 = new Test ();
+ var test2 = new Subdir.Test ();
+ var test3 = new Subdir2.Test ();
+ var test4 = new Subdir.Subdir2.Test ();
+ stdout.printf("Vala is working.\n");
+ return 0;
+}
diff --git a/test cases/vala/23 thread flags/meson.build b/test cases/vala/23 thread flags/meson.build
new file mode 100644
index 0000000..3b385df
--- /dev/null
+++ b/test cases/vala/23 thread flags/meson.build
@@ -0,0 +1,7 @@
+project('thread flags', 'c', 'vala')
+
+glib = dependency('glib-2.0')
+gobject = dependency('gobject-2.0')
+threads = dependency('threads')
+
+e = executable('valaprog', 'prog.vala', dependencies: [glib, gobject, threads])
diff --git a/test cases/vala/23 thread flags/prog.vala b/test cases/vala/23 thread flags/prog.vala
new file mode 100644
index 0000000..0b2c54c
--- /dev/null
+++ b/test cases/vala/23 thread flags/prog.vala
@@ -0,0 +1,2 @@
+void main () {
+}
diff --git a/test cases/vala/24 export dynamic shared module/app.vala b/test cases/vala/24 export dynamic shared module/app.vala
new file mode 100644
index 0000000..e016ecd
--- /dev/null
+++ b/test cases/vala/24 export dynamic shared module/app.vala
@@ -0,0 +1,21 @@
+const string MODULE_LIB = "libapp_module.so";
+
+delegate int ModuleFunc ();
+
+public int app_func () {
+ return 41;
+}
+
+int main () {
+ Module module;
+ void *func;
+ unowned ModuleFunc mfunc;
+
+ module = Module.open (MODULE_LIB, ModuleFlags.BIND_LAZY);
+ module.symbol ("module_func", out func);
+ mfunc = (ModuleFunc) func;
+
+ print ("%d\n", mfunc ());
+
+ return 0;
+}
diff --git a/test cases/vala/24 export dynamic shared module/meson.build b/test cases/vala/24 export dynamic shared module/meson.build
new file mode 100644
index 0000000..9aa9fd9
--- /dev/null
+++ b/test cases/vala/24 export dynamic shared module/meson.build
@@ -0,0 +1,20 @@
+project ('test', ['c', 'vala'], version: '0.1')
+
+deps = [
+ dependency ('glib-2.0'),
+ dependency ('gmodule-2.0'),
+]
+
+app = executable (
+ 'app',
+ ['app.vala'],
+ dependencies: deps,
+ export_dynamic: true
+)
+
+shared_module (
+ 'app_module',
+ ['module.vala'],
+ link_with: app,
+ dependencies : deps,
+)
diff --git a/test cases/vala/24 export dynamic shared module/module.vala b/test cases/vala/24 export dynamic shared module/module.vala
new file mode 100644
index 0000000..5553727
--- /dev/null
+++ b/test cases/vala/24 export dynamic shared module/module.vala
@@ -0,0 +1,3 @@
+public int module_func () {
+ return app_func() + 1;
+}
diff --git a/test cases/vala/25 extract_all_objects/meson.build b/test cases/vala/25 extract_all_objects/meson.build
new file mode 100644
index 0000000..a1a4ebc
--- /dev/null
+++ b/test cases/vala/25 extract_all_objects/meson.build
@@ -0,0 +1,11 @@
+project('valatest', 'vala', 'c')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+# A dummy target, just so that we can check that extract_all_objects() works
+# properly for Vala sources. Due to a bug, Vala's .c.o files weren't included
+# which would cause the "e" executable below to have no "main" and fail to link.
+dummy = executable('valaprog_dummy', 'prog.vala', dependencies : valadeps, build_by_default: false)
+
+objs = dummy.extract_all_objects()
+e = executable('valaprog', objects: objs, dependencies : valadeps)
diff --git a/test cases/vala/25 extract_all_objects/prog.vala b/test cases/vala/25 extract_all_objects/prog.vala
new file mode 100644
index 0000000..638e776
--- /dev/null
+++ b/test cases/vala/25 extract_all_objects/prog.vala
@@ -0,0 +1,7 @@
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ stdout.printf("Vala is working.\n");
+ return 0;
+ }
+}
diff --git a/test cases/vala/26 vala and asm/meson.build b/test cases/vala/26 vala and asm/meson.build
new file mode 100644
index 0000000..4e662e7
--- /dev/null
+++ b/test cases/vala/26 vala and asm/meson.build
@@ -0,0 +1,23 @@
+project('vala and asm', 'vala', 'c')
+
+cpu = host_machine.cpu_family()
+cc = meson.get_compiler('c')
+
+supported_cpus = ['arm', 'x86', 'x86_64']
+
+if not supported_cpus.contains(cpu)
+ error('MESON_SKIP_TEST unsupported cpu:' + cpu)
+endif
+
+if meson.get_compiler('c').get_id() == 'msvc'
+ error('MESON_SKIP_TEST MSVC can\'t compile assembly')
+endif
+
+if cc.symbols_have_underscore_prefix()
+ add_project_arguments('-DMESON_TEST__UNDERSCORE_SYMBOL', language: 'c')
+endif
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+e = executable('vala-asm', ['prog.vala', 'retval-' + cpu + '.S'],
+ dependencies: valadeps)
+test('test-vala-asm', e)
diff --git a/test cases/vala/26 vala and asm/prog.vala b/test cases/vala/26 vala and asm/prog.vala
new file mode 100644
index 0000000..d5f89a4
--- /dev/null
+++ b/test cases/vala/26 vala and asm/prog.vala
@@ -0,0 +1,9 @@
+extern int get_retval();
+
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ stdout.printf("Vala is working.\n");
+ return get_retval();
+ }
+}
diff --git a/test cases/vala/26 vala and asm/retval-arm.S b/test cases/vala/26 vala and asm/retval-arm.S
new file mode 100644
index 0000000..a892362
--- /dev/null
+++ b/test cases/vala/26 vala and asm/retval-arm.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ mov r0, #0
+ mov pc, lr
diff --git a/test cases/vala/26 vala and asm/retval-x86.S b/test cases/vala/26 vala and asm/retval-x86.S
new file mode 100644
index 0000000..3cb0237
--- /dev/null
+++ b/test cases/vala/26 vala and asm/retval-x86.S
@@ -0,0 +1,12 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+/* Only supported on Linux with GAS */
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retl
diff --git a/test cases/vala/26 vala and asm/retval-x86_64.S b/test cases/vala/26 vala and asm/retval-x86_64.S
new file mode 100644
index 0000000..1a5f3eb
--- /dev/null
+++ b/test cases/vala/26 vala and asm/retval-x86_64.S
@@ -0,0 +1,11 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+# ifdef __linux__
+.type get_retval, %function
+#endif
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retq
diff --git a/test cases/vala/26 vala and asm/symbol-underscore.h b/test cases/vala/26 vala and asm/symbol-underscore.h
new file mode 100644
index 0000000..d0f3ef9
--- /dev/null
+++ b/test cases/vala/26 vala and asm/symbol-underscore.h
@@ -0,0 +1,5 @@
+#if defined(MESON_TEST__UNDERSCORE_SYMBOL)
+# define SYMBOL_NAME(name) _##name
+#else
+# define SYMBOL_NAME(name) name
+#endif
diff --git a/test cases/vala/3 dep/gioprog.vala b/test cases/vala/3 dep/gioprog.vala
new file mode 100644
index 0000000..969aa97
--- /dev/null
+++ b/test cases/vala/3 dep/gioprog.vala
@@ -0,0 +1,8 @@
+class GioProg {
+
+ public static int main(string[] args) {
+ var homedir = File.new_for_path(Environment.get_home_dir());
+ stdout.printf("Home directory as told by gio is " + homedir.get_path() + "\n");
+ return 0;
+ }
+}
diff --git a/test cases/vala/3 dep/meson.build b/test cases/vala/3 dep/meson.build
new file mode 100644
index 0000000..c3563b1
--- /dev/null
+++ b/test cases/vala/3 dep/meson.build
@@ -0,0 +1,12 @@
+project('giotest', 'vala', 'c')
+
+glib = dependency('glib-2.0')
+gobject = dependency('gobject-2.0')
+gio = [dependency('gio-2.0'),
+ # https://github.com/mesonbuild/meson/issues/1484
+ dependency('gio-unix-2.0', required : false),
+ dependency('gio-windows-2.0', required : false)]
+
+e = executable('gioprog', 'gioprog.vala',
+dependencies : [glib, gobject, gio])
+test('giotest', e)
diff --git a/test cases/vala/4 config/config.vapi b/test cases/vala/4 config/config.vapi
new file mode 100644
index 0000000..6845417
--- /dev/null
+++ b/test cases/vala/4 config/config.vapi
@@ -0,0 +1 @@
+public const string DATA_DIRECTORY;
diff --git a/test cases/vala/4 config/meson-something-else.vapi b/test cases/vala/4 config/meson-something-else.vapi
new file mode 100644
index 0000000..ce2b83a
--- /dev/null
+++ b/test cases/vala/4 config/meson-something-else.vapi
@@ -0,0 +1 @@
+public const string SOMETHING_ELSE;
diff --git a/test cases/vala/4 config/meson.build b/test cases/vala/4 config/meson.build
new file mode 100644
index 0000000..7cb93cf
--- /dev/null
+++ b/test cases/vala/4 config/meson.build
@@ -0,0 +1,15 @@
+project('valatest', 'vala', 'c')
+
+valac = meson.get_compiler('vala')
+# Try to find our library
+valadeps = [valac.find_library('meson-something-else', dirs : meson.current_source_dir())]
+valadeps += [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+e = executable(
+'valaprog',
+sources : ['config.vapi', 'prog.vala'],
+dependencies : valadeps,
+c_args : ['-DDATA_DIRECTORY="@0@"'.format(meson.current_source_dir()),
+ '-DSOMETHING_ELSE="Out of this world!"']
+)
+test('valatest', e)
diff --git a/test cases/vala/4 config/prog.vala b/test cases/vala/4 config/prog.vala
new file mode 100644
index 0000000..2b08dad
--- /dev/null
+++ b/test cases/vala/4 config/prog.vala
@@ -0,0 +1,8 @@
+class MainProg : GLib.Object {
+
+ public static int main(string[] args) {
+ stdout.printf("DATA_DIRECTORY is: %s.\n", DATA_DIRECTORY);
+ stdout.printf("SOMETHING_ELSE is: %s.\n", SOMETHING_ELSE);
+ return 0;
+ }
+}
diff --git a/test cases/vala/5 target glib/GLib.Thread.vala b/test cases/vala/5 target glib/GLib.Thread.vala
new file mode 100644
index 0000000..fc82919
--- /dev/null
+++ b/test cases/vala/5 target glib/GLib.Thread.vala
@@ -0,0 +1,43 @@
+extern void * get_ret_code ();
+
+public class MyThread : Object {
+ public int x_times { get; private set; }
+
+ public MyThread (int times) {
+ this.x_times = times;
+ }
+
+ public int run () {
+ for (int i = 0; i < this.x_times; i++) {
+ stdout.printf ("ping! %d/%d\n", i + 1, this.x_times);
+ Thread.usleep (10000);
+ }
+
+ // return & exit have the same effect
+ Thread.exit (get_ret_code ());
+ return 43;
+ }
+}
+
+public static int main (string[] args) {
+ // Check whether threads are supported:
+ if (Thread.supported () == false) {
+ stderr.printf ("Threads are not supported!\n");
+ return -1;
+ }
+
+ try {
+ // Start a thread:
+ MyThread my_thread = new MyThread (10);
+ Thread<int> thread = new Thread<int>.try ("My fst. thread", my_thread.run);
+
+ // Wait until thread finishes:
+ int result = thread.join ();
+ // Output: `Thread stopped! Return value: 42`
+ stdout.printf ("Thread stopped! Return value: %d\n", result);
+ } catch (Error e) {
+ stdout.printf ("Error: %s\n", e.message);
+ }
+
+ return 0;
+}
diff --git a/test cases/vala/5 target glib/meson.build b/test cases/vala/5 target glib/meson.build
new file mode 100644
index 0000000..f285d9f
--- /dev/null
+++ b/test cases/vala/5 target glib/meson.build
@@ -0,0 +1,10 @@
+project('valatest', 'vala', 'c')
+
+if not meson.is_unity()
+ add_global_arguments('-Werror', language : 'c')
+endif
+
+valadeps = [dependency('glib-2.0', version : '>=2.32'), dependency('gobject-2.0')]
+
+e = executable('valaprog', 'GLib.Thread.vala', 'retcode.c', dependencies : valadeps)
+test('valatest', e)
diff --git a/test cases/vala/5 target glib/retcode.c b/test cases/vala/5 target glib/retcode.c
new file mode 100644
index 0000000..df44de5
--- /dev/null
+++ b/test cases/vala/5 target glib/retcode.c
@@ -0,0 +1,5 @@
+void *
+get_ret_code (void)
+{
+ return (void *) (int) 42;
+}
diff --git a/test cases/vala/6 static library/meson.build b/test cases/vala/6 static library/meson.build
new file mode 100644
index 0000000..c74bdf8
--- /dev/null
+++ b/test cases/vala/6 static library/meson.build
@@ -0,0 +1,17 @@
+project('valastatic', 'vala', 'c')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+l = static_library('valalib', 'mylib.vala', dependencies : valadeps)
+# NOTE: This static library is not usable from Vala because it does not carry
+# forward the .vapi and .h files generated by Valac to the next BuildTarget.
+# Will have to be fixed with https://github.com/mesonbuild/meson/issues/891
+m = static_library('extractedlib',
+ objects : l.extract_all_objects(),
+ install : true)
+
+e = executable('valaprog', 'prog.vala',
+link_with : l,
+dependencies : valadeps)
+
+test('valastatictest', e)
diff --git a/test cases/vala/6 static library/mylib.vala b/test cases/vala/6 static library/mylib.vala
new file mode 100644
index 0000000..5cc903b
--- /dev/null
+++ b/test cases/vala/6 static library/mylib.vala
@@ -0,0 +1,5 @@
+public class LibraryObject : Object {
+ public void func() {
+ stdout.printf("Method in library called.");
+ }
+}
diff --git a/test cases/vala/6 static library/prog.vala b/test cases/vala/6 static library/prog.vala
new file mode 100644
index 0000000..3c4a017
--- /dev/null
+++ b/test cases/vala/6 static library/prog.vala
@@ -0,0 +1,7 @@
+class MainApp : Object {
+ public static int main(string[] args) {
+ var l = new LibraryObject();
+ l.func();
+ return 0;
+ }
+}
diff --git a/test cases/vala/6 static library/test.json b/test cases/vala/6 static library/test.json
new file mode 100644
index 0000000..d85ef6d
--- /dev/null
+++ b/test cases/vala/6 static library/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libextractedlib.a"}
+ ]
+}
diff --git a/test cases/vala/7 shared library/lib/meson.build b/test cases/vala/7 shared library/lib/meson.build
new file mode 100644
index 0000000..edeeb96
--- /dev/null
+++ b/test cases/vala/7 shared library/lib/meson.build
@@ -0,0 +1,35 @@
+args = []
+# https://github.com/mesonbuild/meson/issues/1969
+if get_option('unity') == 'on'
+ vala_args = ['-H', 'mylib.h']
+endif
+
+l = shared_library('valalib', 'mylib.vala',
+ vala_args : args,
+ dependencies : valadeps)
+
+shared_library('installed_vala_lib', 'mylib.vala',
+ dependencies : valadeps,
+ install : true)
+
+shared_library('installed_vala_all', 'mylib.vala',
+ dependencies : valadeps,
+ install : true,
+ install_dir : [true, true, true])
+
+shared_library('installed_vala_all_nolib', 'mylib.vala',
+ dependencies : valadeps,
+ install : true,
+ install_dir : [false,
+ join_paths(get_option('includedir'), 'valah'),
+ join_paths(get_option('datadir'), 'vala-1.0', 'vapi')])
+
+shared_library('installed_vala_onlyh', 'mylib.vala',
+ dependencies : valadeps,
+ install : true,
+ install_dir : [false, get_option('includedir'), false])
+
+shared_library('installed_vala_onlyvapi', 'mylib.vala',
+ dependencies : valadeps,
+ install : true,
+ install_dir : [false, false, join_paths(get_option('datadir'), 'vala', 'vapi')])
diff --git a/test cases/vala/7 shared library/lib/mylib.vala b/test cases/vala/7 shared library/lib/mylib.vala
new file mode 100644
index 0000000..5cc903b
--- /dev/null
+++ b/test cases/vala/7 shared library/lib/mylib.vala
@@ -0,0 +1,5 @@
+public class LibraryObject : Object {
+ public void func() {
+ stdout.printf("Method in library called.");
+ }
+}
diff --git a/test cases/vala/7 shared library/meson.build b/test cases/vala/7 shared library/meson.build
new file mode 100644
index 0000000..9c56f14
--- /dev/null
+++ b/test cases/vala/7 shared library/meson.build
@@ -0,0 +1,10 @@
+project('shared library', 'vala', 'c')
+
+valadeps = [dependency('glib-2.0'), dependency('gobject-2.0')]
+
+libinc = include_directories('lib')
+
+subdir('lib')
+subdir('prog')
+
+test('valasharedtest', e)
diff --git a/test cases/vala/7 shared library/prog/meson.build b/test cases/vala/7 shared library/prog/meson.build
new file mode 100644
index 0000000..2b842ea
--- /dev/null
+++ b/test cases/vala/7 shared library/prog/meson.build
@@ -0,0 +1,4 @@
+e = executable('valaprog', 'prog.vala',
+ link_with : l,
+ include_directories : libinc,
+ dependencies : valadeps)
diff --git a/test cases/vala/7 shared library/prog/prog.vala b/test cases/vala/7 shared library/prog/prog.vala
new file mode 100644
index 0000000..3c4a017
--- /dev/null
+++ b/test cases/vala/7 shared library/prog/prog.vala
@@ -0,0 +1,7 @@
+class MainApp : Object {
+ public static int main(string[] args) {
+ var l = new LibraryObject();
+ l.func();
+ return 0;
+ }
+}
diff --git a/test cases/vala/7 shared library/test.json b/test cases/vala/7 shared library/test.json
new file mode 100644
index 0000000..eee3c3d
--- /dev/null
+++ b/test cases/vala/7 shared library/test.json
@@ -0,0 +1,14 @@
+{
+ "installed": [
+ {"type": "expr", "file": "usr/lib/?libinstalled_vala_lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libinstalled_vala_lib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libinstalled_vala_all.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libinstalled_vala_all.dll.a"},
+ {"type": "file", "file": "usr/include/installed_vala_all.h"},
+ {"type": "file", "file": "usr/include/valah/installed_vala_all_nolib.h"},
+ {"type": "file", "file": "usr/include/installed_vala_onlyh.h"},
+ {"type": "file", "file": "usr/share/vala/vapi/installed_vala_all.vapi"},
+ {"type": "file", "file": "usr/share/vala-1.0/vapi/installed_vala_all_nolib.vapi"},
+ {"type": "file", "file": "usr/share/vala/vapi/installed_vala_onlyvapi.vapi"}
+ ]
+}
diff --git a/test cases/vala/8 generated sources/dependency-generated/enum-types.c.template b/test cases/vala/8 generated sources/dependency-generated/enum-types.c.template
new file mode 100644
index 0000000..9d45a93
--- /dev/null
+++ b/test cases/vala/8 generated sources/dependency-generated/enum-types.c.template
@@ -0,0 +1,43 @@
+/*** BEGIN file-header ***/
+
+#include "enum-types.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+#include "@filename@"
+/*** END file-production ***/
+
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+ static gsize static_g_define_type_id = 0;
+
+ if (g_once_init_enter (&static_g_define_type_id)) {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ GType g_define_type_id =
+ g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+
+ g_once_init_leave (&static_g_define_type_id, g_define_type_id);
+ }
+
+ return static_g_define_type_id;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+
+/*** END file-tail ***/
diff --git a/test cases/vala/8 generated sources/dependency-generated/enum-types.h.template b/test cases/vala/8 generated sources/dependency-generated/enum-types.h.template
new file mode 100644
index 0000000..e5478ab
--- /dev/null
+++ b/test cases/vala/8 generated sources/dependency-generated/enum-types.h.template
@@ -0,0 +1,26 @@
+/*** BEGIN file-header ***/
+
+#ifndef __EXAMPLE_ENUMS_TYPES_H__
+#define __EXAMPLE_ENUMS_TYPES_H__
+
+#include <glib-object.h>
+#include "enums.h"
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define EXAMPLE_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __EXAMPLE_ENUMS_TYPES_H__ */
+/*** END file-tail ***/
diff --git a/test cases/vala/8 generated sources/dependency-generated/enums.h b/test cases/vala/8 generated sources/dependency-generated/enums.h
new file mode 100644
index 0000000..3fb621e
--- /dev/null
+++ b/test cases/vala/8 generated sources/dependency-generated/enums.h
@@ -0,0 +1,15 @@
+#ifndef __EXAMPLE_ENUMS_H__
+#define __EXAMPLE_ENUMS_H__
+
+G_BEGIN_DECLS
+
+typedef enum {
+ EXAMPLE_VERBOSITY_ERRORS,
+ EXAMPLE_VERBOSITY_MINIMAL,
+ EXAMPLE_VERBOSITY_DETAILED,
+ EXAMPLE_VERBOSITY_DEBUG,
+} ExampleVerbosity;
+
+G_END_DECLS
+
+#endif /* __EXAMPLE_ENUMS_H__ */
diff --git a/test cases/vala/8 generated sources/dependency-generated/lib.vala b/test cases/vala/8 generated sources/dependency-generated/lib.vala
new file mode 100644
index 0000000..3fcbb7f
--- /dev/null
+++ b/test cases/vala/8 generated sources/dependency-generated/lib.vala
@@ -0,0 +1,3 @@
+int whatever() {
+ return 0;
+}
diff --git a/test cases/vala/8 generated sources/dependency-generated/main.vala b/test cases/vala/8 generated sources/dependency-generated/main.vala
new file mode 100644
index 0000000..33c14ce
--- /dev/null
+++ b/test cases/vala/8 generated sources/dependency-generated/main.vala
@@ -0,0 +1,3 @@
+int main() {
+ return 0;
+}
diff --git a/test cases/vala/8 generated sources/dependency-generated/meson.build b/test cases/vala/8 generated sources/dependency-generated/meson.build
new file mode 100644
index 0000000..a1895b4
--- /dev/null
+++ b/test cases/vala/8 generated sources/dependency-generated/meson.build
@@ -0,0 +1,44 @@
+# Test that dependencies with their own generated sources don't
+# confuse the Vala build instruction generator.
+
+# Test case for https://github.com/mesonbuild/meson/issues/1084
+
+gnome = import('gnome')
+
+gobject = dependency('gobject-2.0')
+
+enums = gnome.mkenums('enum-types',
+ sources: 'enums.h',
+ c_template: 'enum-types.c.template',
+ h_template: 'enum-types.h.template',
+)
+
+libcommon = library('common',
+ enums[0], enums[1],
+ dependencies: gobject)
+
+common_dep = declare_dependency(
+ # This is required so that whoever depends on this also depends
+ # on the generated header; that won't happen implicitly.
+ # See: https://github.com/mesonbuild/meson/issues/1084
+ sources: enums[1],
+ link_with: libcommon,
+)
+
+libplover_vala = library('plover',
+ 'lib.vala',
+ dependencies: [common_dep, gobject]
+)
+
+plover_dep = declare_dependency(
+ link_with: libplover_vala,
+ dependencies: common_dep
+)
+
+vala_prog = executable('hello',
+ 'main.vala',
+ link_with: libplover_vala,
+ # There's no need to specify common_dep here since plover_dep pulls it
+ # in, but it should be harmless to do so.
+ dependencies: [common_dep, plover_dep, gobject]
+)
diff --git a/test cases/vala/8 generated sources/dependency-generated/null.c b/test cases/vala/8 generated sources/dependency-generated/null.c
new file mode 100644
index 0000000..8337712
--- /dev/null
+++ b/test cases/vala/8 generated sources/dependency-generated/null.c
@@ -0,0 +1 @@
+//
diff --git a/test cases/vala/8 generated sources/meson.build b/test cases/vala/8 generated sources/meson.build
new file mode 100644
index 0000000..711a93a
--- /dev/null
+++ b/test cases/vala/8 generated sources/meson.build
@@ -0,0 +1,14 @@
+project('mytest', 'vala', 'c')
+
+cd = configuration_data()
+cd.set('x', 'y')
+
+subdir('src')
+
+executable('generatedtestparent', [src, config, returncode, wrapper],
+ install : true,
+ dependencies: [dependency('glib-2.0'), dependency('gobject-2.0')])
+
+subdir('tools')
+subdir('onlygen')
+subdir('dependency-generated')
diff --git a/test cases/vala/8 generated sources/onlygen/maingen.in b/test cases/vala/8 generated sources/onlygen/maingen.in
new file mode 100644
index 0000000..33c14ce
--- /dev/null
+++ b/test cases/vala/8 generated sources/onlygen/maingen.in
@@ -0,0 +1,3 @@
+int main() {
+ return 0;
+}
diff --git a/test cases/vala/8 generated sources/onlygen/meson.build b/test cases/vala/8 generated sources/onlygen/meson.build
new file mode 100644
index 0000000..f48e0b8
--- /dev/null
+++ b/test cases/vala/8 generated sources/onlygen/meson.build
@@ -0,0 +1,7 @@
+onlygen = generator(copy,
+ output : '@BASENAME@.vala',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+executable('onlygentest', onlygen.process('maingen.in'),
+ install : true,
+ dependencies: [dependency('glib-2.0'), dependency('gobject-2.0')])
diff --git a/test cases/vala/8 generated sources/src/config.vala.in b/test cases/vala/8 generated sources/src/config.vala.in
new file mode 100644
index 0000000..a5196fd
--- /dev/null
+++ b/test cases/vala/8 generated sources/src/config.vala.in
@@ -0,0 +1,3 @@
+namespace Config {
+ public static const string x = "@x@";
+}
diff --git a/test cases/vala/8 generated sources/src/copy_file.py b/test cases/vala/8 generated sources/src/copy_file.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/vala/8 generated sources/src/copy_file.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/vala/8 generated sources/src/meson.build b/test cases/vala/8 generated sources/src/meson.build
new file mode 100644
index 0000000..06515c1
--- /dev/null
+++ b/test cases/vala/8 generated sources/src/meson.build
@@ -0,0 +1,17 @@
+config = configure_file(input: 'config.vala.in',
+ output: 'config.vala',
+ configuration: cd)
+
+print = find_program('write_wrapper.py')
+wrapper = custom_target('wrapper',
+ output : 'print_wrapper.vala',
+ command : [print, '@OUTPUT@'])
+
+copy = find_program('copy_file.py')
+gen = generator(copy,
+ output : '@BASENAME@.vala',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+returncode = gen.process('returncode.in')
+
+src = files('test.vala')
diff --git a/test cases/vala/8 generated sources/src/returncode.in b/test cases/vala/8 generated sources/src/returncode.in
new file mode 100644
index 0000000..e3d3ea6
--- /dev/null
+++ b/test cases/vala/8 generated sources/src/returncode.in
@@ -0,0 +1,3 @@
+int return_code() {
+ return 0;
+}
diff --git a/test cases/vala/8 generated sources/src/test.vala b/test cases/vala/8 generated sources/src/test.vala
new file mode 100644
index 0000000..ca27676
--- /dev/null
+++ b/test cases/vala/8 generated sources/src/test.vala
@@ -0,0 +1,4 @@
+int main() {
+ print_wrapper (Config.x);
+ return return_code ();
+}
diff --git a/test cases/vala/8 generated sources/src/write_wrapper.py b/test cases/vala/8 generated sources/src/write_wrapper.py
new file mode 100644
index 0000000..b5608f7
--- /dev/null
+++ b/test cases/vala/8 generated sources/src/write_wrapper.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import sys
+
+contents = '''
+void print_wrapper(string arg) {
+ print (arg);
+}
+'''
+
+with open(sys.argv[1], 'w') as f:
+ f.write(contents)
diff --git a/test cases/vala/8 generated sources/test.json b/test cases/vala/8 generated sources/test.json
new file mode 100644
index 0000000..d99a6ce
--- /dev/null
+++ b/test cases/vala/8 generated sources/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/generatedtestparent"},
+ {"type": "exe", "file": "usr/bin/generatedtest"},
+ {"type": "exe", "file": "usr/bin/onlygentest"}
+ ]
+}
diff --git a/test cases/vala/8 generated sources/tools/meson.build b/test cases/vala/8 generated sources/tools/meson.build
new file mode 100644
index 0000000..303468e
--- /dev/null
+++ b/test cases/vala/8 generated sources/tools/meson.build
@@ -0,0 +1,3 @@
+executable('generatedtest', [src, config, returncode, wrapper],
+ install : true,
+ dependencies: [dependency('glib-2.0'), dependency('gobject-2.0')])
diff --git a/test cases/vala/9 gir/foo.vala b/test cases/vala/9 gir/foo.vala
new file mode 100644
index 0000000..bb6da10
--- /dev/null
+++ b/test cases/vala/9 gir/foo.vala
@@ -0,0 +1,7 @@
+namespace Foo
+{
+ public int bar ()
+ {
+ return 0;
+ }
+}
diff --git a/test cases/vala/9 gir/meson.build b/test cases/vala/9 gir/meson.build
new file mode 100644
index 0000000..3320527
--- /dev/null
+++ b/test cases/vala/9 gir/meson.build
@@ -0,0 +1,17 @@
+project('foo', 'c', 'vala')
+
+glib = dependency('glib-2.0')
+gobject = dependency('gobject-2.0')
+g_ir_compiler = find_program('g-ir-compiler')
+
+foo = shared_library('foo', 'foo.vala',
+ install : true,
+ install_dir : [true, false, false, true],
+ vala_gir: 'Foo-1.0.gir',
+ dependencies: [glib, gobject])
+
+custom_target('foo-typelib',
+ command: [g_ir_compiler, '--output', '@OUTPUT@', '@INPUT@'],
+ input: meson.current_build_dir() + '/Foo-1.0.gir',
+ output: 'Foo-1.0.typelib',
+ depends: foo)
diff --git a/test cases/vala/9 gir/test.json b/test cases/vala/9 gir/test.json
new file mode 100644
index 0000000..add1d71
--- /dev/null
+++ b/test cases/vala/9 gir/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "expr", "platform": "gcc", "file": "usr/lib/?libfoo.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libfoo.dll.a"},
+ {"type": "file", "file": "usr/share/gir-1.0/Foo-1.0.gir"}
+ ]
+}
diff --git a/test cases/warning/1 version for string div/a/b.c b/test cases/warning/1 version for string div/a/b.c
new file mode 100644
index 0000000..74de8a8
--- /dev/null
+++ b/test cases/warning/1 version for string div/a/b.c
@@ -0,0 +1,3 @@
+int main(void)
+{
+}
diff --git a/test cases/warning/1 version for string div/meson.build b/test cases/warning/1 version for string div/meson.build
new file mode 100644
index 0000000..54e9708
--- /dev/null
+++ b/test cases/warning/1 version for string div/meson.build
@@ -0,0 +1,3 @@
+project('warn on string division', 'c', meson_version: '>=0.48.0')
+
+executable('prog', 'a' / 'b.c')
diff --git a/test cases/warning/1 version for string div/test.json b/test cases/warning/1 version for string div/test.json
new file mode 100644
index 0000000..e8acb69
--- /dev/null
+++ b/test cases/warning/1 version for string div/test.json
@@ -0,0 +1,8 @@
+{
+ "stdout": [
+ {
+ "comment": "literal '/' appears in output, irrespective of os.path.sep, as that's the operator",
+ "line": "test cases/warning/1 version for string div/meson.build:3: WARNING: Project targets '>=0.48.0' but uses feature introduced in '0.49.0': / with string arguments."
+ }
+ ]
+}
diff --git a/test cases/warning/2 languages missing native/meson.build b/test cases/warning/2 languages missing native/meson.build
new file mode 100644
index 0000000..e204715
--- /dev/null
+++ b/test cases/warning/2 languages missing native/meson.build
@@ -0,0 +1,3 @@
+project('languages missing native',
+ meson_version : '>= 0.54')
+add_languages('c')
diff --git a/test cases/warning/2 languages missing native/test.json b/test cases/warning/2 languages missing native/test.json
new file mode 100644
index 0000000..f929654
--- /dev/null
+++ b/test cases/warning/2 languages missing native/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/warning/2 languages missing native/meson.build:3: WARNING: add_languages is missing native:, assuming languages are wanted for both host and build."
+ }
+ ]
+}
diff --git a/test cases/warning/3 fallback consistency/meson.build b/test cases/warning/3 fallback consistency/meson.build
new file mode 100644
index 0000000..ad2b226
--- /dev/null
+++ b/test cases/warning/3 fallback consistency/meson.build
@@ -0,0 +1,7 @@
+project('proj', 'c')
+
+# The first call succeed and cache the value of 'sub' dependency. The 2nd call
+# should return the cached value, but still verify the fallback variable is
+# consistent.
+dependency('sub', fallback : ['sub', 'dep1'])
+dependency('sub', fallback : ['sub', 'dep2'])
diff --git a/test cases/warning/3 fallback consistency/subprojects/sub/meson.build b/test cases/warning/3 fallback consistency/subprojects/sub/meson.build
new file mode 100644
index 0000000..12a6570
--- /dev/null
+++ b/test cases/warning/3 fallback consistency/subprojects/sub/meson.build
@@ -0,0 +1,5 @@
+project('proj', 'c')
+
+dep1 = declare_dependency()
+dep2 = declare_dependency()
+meson.override_dependency('sub', dep1)
diff --git a/test cases/warning/3 fallback consistency/test.json b/test cases/warning/3 fallback consistency/test.json
new file mode 100644
index 0000000..60e25b4
--- /dev/null
+++ b/test cases/warning/3 fallback consistency/test.json
@@ -0,0 +1,10 @@
+{
+ "stdout": [
+ {
+ "line": "WARNING: Inconsistency: Subproject has overridden the dependency with another variable than 'dep2'"
+ }
+ ],
+ "tools": {
+ "cmake": ">=3.14"
+ }
+}
diff --git a/test cases/warning/4 fallback consistency/meson.build b/test cases/warning/4 fallback consistency/meson.build
new file mode 100644
index 0000000..013b473
--- /dev/null
+++ b/test cases/warning/4 fallback consistency/meson.build
@@ -0,0 +1,4 @@
+project('proj', 'c')
+
+# Subproject overrides 'sub' with another variable than dep2. This should warn.
+dependency('sub', fallback : ['sub', 'dep2'])
diff --git a/test cases/warning/4 fallback consistency/subprojects/sub/meson.build b/test cases/warning/4 fallback consistency/subprojects/sub/meson.build
new file mode 100644
index 0000000..12a6570
--- /dev/null
+++ b/test cases/warning/4 fallback consistency/subprojects/sub/meson.build
@@ -0,0 +1,5 @@
+project('proj', 'c')
+
+dep1 = declare_dependency()
+dep2 = declare_dependency()
+meson.override_dependency('sub', dep1)
diff --git a/test cases/warning/4 fallback consistency/test.json b/test cases/warning/4 fallback consistency/test.json
new file mode 100644
index 0000000..60e25b4
--- /dev/null
+++ b/test cases/warning/4 fallback consistency/test.json
@@ -0,0 +1,10 @@
+{
+ "stdout": [
+ {
+ "line": "WARNING: Inconsistency: Subproject has overridden the dependency with another variable than 'dep2'"
+ }
+ ],
+ "tools": {
+ "cmake": ">=3.14"
+ }
+}
diff --git a/test cases/warning/5 fallback consistency/meson.build b/test cases/warning/5 fallback consistency/meson.build
new file mode 100644
index 0000000..3af6ce8
--- /dev/null
+++ b/test cases/warning/5 fallback consistency/meson.build
@@ -0,0 +1,4 @@
+project('fallback consistency')
+
+# Subproject overrides foo with foo_dep but wrap file says it's bar_dep. This should warn.
+dependency('foo')
diff --git a/test cases/warning/5 fallback consistency/subprojects/foo.wrap b/test cases/warning/5 fallback consistency/subprojects/foo.wrap
new file mode 100644
index 0000000..28055d9
--- /dev/null
+++ b/test cases/warning/5 fallback consistency/subprojects/foo.wrap
@@ -0,0 +1,6 @@
+[wrap-file]
+source_url = http://host.invalid/foo.tar.gz
+source_filename = foo.tar.gz
+
+[provide]
+foo = bar_dep
diff --git a/test cases/warning/5 fallback consistency/subprojects/foo/meson.build b/test cases/warning/5 fallback consistency/subprojects/foo/meson.build
new file mode 100644
index 0000000..fb58a4a
--- /dev/null
+++ b/test cases/warning/5 fallback consistency/subprojects/foo/meson.build
@@ -0,0 +1,6 @@
+project('sub')
+
+foo_dep = declare_dependency()
+meson.override_dependency('foo', foo_dep)
+
+bar_dep = declare_dependency()
diff --git a/test cases/warning/5 fallback consistency/test.json b/test cases/warning/5 fallback consistency/test.json
new file mode 100644
index 0000000..8ab28d1
--- /dev/null
+++ b/test cases/warning/5 fallback consistency/test.json
@@ -0,0 +1,10 @@
+{
+ "stdout": [
+ {
+ "line": "WARNING: Inconsistency: Subproject has overridden the dependency with another variable than 'bar_dep'"
+ }
+ ],
+ "tools": {
+ "cmake": ">=3.14"
+ }
+}
diff --git a/test cases/warning/6 list add/meson.build b/test cases/warning/6 list add/meson.build
new file mode 100644
index 0000000..94b7eab
--- /dev/null
+++ b/test cases/warning/6 list add/meson.build
@@ -0,0 +1,7 @@
+project('test list add', meson_version: '>=0.59.0')
+
+l1 = [1, 2, 3]
+l2 = l1 + 4
+l2 += 5
+
+message(l2)
diff --git a/test cases/warning/6 list add/test.json b/test cases/warning/6 list add/test.json
new file mode 100644
index 0000000..e3ce8d0
--- /dev/null
+++ b/test cases/warning/6 list add/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/warning/6 list add/meson.build:4: WARNING: Project targets '>=0.59.0' but uses feature introduced in '0.60.0': list.<plus>. The right hand operand was not a list."
+ }
+ ]
+}
diff --git a/test cases/warning/7 module without unstable/meson.build b/test cases/warning/7 module without unstable/meson.build
new file mode 100644
index 0000000..409a236
--- /dev/null
+++ b/test cases/warning/7 module without unstable/meson.build
@@ -0,0 +1,3 @@
+project('module import without unstable', meson_version : '>= 0.55')
+
+import('keyval')
diff --git a/test cases/warning/7 module without unstable/test.json b/test cases/warning/7 module without unstable/test.json
new file mode 100644
index 0000000..62b8aa1
--- /dev/null
+++ b/test cases/warning/7 module without unstable/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "test cases/warning/7 module without unstable/meson.build:3: WARNING: Project targets '>= 0.55' but uses feature introduced in '0.56.0': module keyval as stable module. Consider either adding \"unstable-\" to the module name, or updating the meson required version to \">= 0.56.0\""
+ }
+ ]
+}
diff --git a/test cases/warning/8 target with no sources/meson.build b/test cases/warning/8 target with no sources/meson.build
new file mode 100644
index 0000000..2a8ee11
--- /dev/null
+++ b/test cases/warning/8 target with no sources/meson.build
@@ -0,0 +1,3 @@
+project('no sources', 'c')
+
+static_library('no sources')
diff --git a/test cases/warning/8 target with no sources/test.json b/test cases/warning/8 target with no sources/test.json
new file mode 100644
index 0000000..30e5b05
--- /dev/null
+++ b/test cases/warning/8 target with no sources/test.json
@@ -0,0 +1,7 @@
+{
+ "stdout": [
+ {
+ "line": "WARNING: Build target no sources has no sources. This was never supposed to be allowed but did because of a bug, support will be removed in a future release of Meson"
+ }
+ ]
+}
diff --git a/test cases/wasm/1 basic/hello.c b/test cases/wasm/1 basic/hello.c
new file mode 100644
index 0000000..2328803
--- /dev/null
+++ b/test cases/wasm/1 basic/hello.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main() {
+ printf("Hello World\n");
+ return 0;
+}
diff --git a/test cases/wasm/1 basic/hello.cpp b/test cases/wasm/1 basic/hello.cpp
new file mode 100644
index 0000000..44b14ac
--- /dev/null
+++ b/test cases/wasm/1 basic/hello.cpp
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(void) {
+ std::cout << "Hello World" << std::endl;
+ return 0;
+}
diff --git a/test cases/wasm/1 basic/hello.html b/test cases/wasm/1 basic/hello.html
new file mode 100644
index 0000000..637bc20
--- /dev/null
+++ b/test cases/wasm/1 basic/hello.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <script src="hello.js"></script>
+ </body>
+</html>
diff --git a/test cases/wasm/1 basic/meson.build b/test cases/wasm/1 basic/meson.build
new file mode 100644
index 0000000..1092a9b
--- /dev/null
+++ b/test cases/wasm/1 basic/meson.build
@@ -0,0 +1,4 @@
+project('emcctest', 'c', 'cpp')
+
+executable('hello-c', 'hello.c')
+executable('hello', 'hello.cpp')
diff --git a/test cases/wasm/2 threads/meson.build b/test cases/wasm/2 threads/meson.build
new file mode 100644
index 0000000..cb682b8
--- /dev/null
+++ b/test cases/wasm/2 threads/meson.build
@@ -0,0 +1,10 @@
+project(
+ 'threads',
+ 'c', 'cpp',
+ default_options : ['cpp_std=c++11'],
+)
+
+dep_threads = dependency('threads')
+
+executable('threads-c', 'threads.c', dependencies : dep_threads)
+executable('threads-c++', 'threads.cpp', dependencies : dep_threads)
diff --git a/test cases/wasm/2 threads/threads.c b/test cases/wasm/2 threads/threads.c
new file mode 100644
index 0000000..7b1a46e
--- /dev/null
+++ b/test cases/wasm/2 threads/threads.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+
+void inthread(void * args) {
+ sleep(1);
+ printf("In thread\n");
+}
+
+int main() {
+#ifdef __EMSCRIPTEN_PTHREADS__
+ pthread_t thread_id;
+ printf("Before Thread\n");
+ pthread_create(&thread_id, NULL, (void *)*inthread, NULL);
+ pthread_join(thread_id, NULL);
+ printf("After Thread\n");
+ return 0;
+#else
+# error "threads not enabled\n"
+#endif
+}
diff --git a/test cases/wasm/2 threads/threads.cpp b/test cases/wasm/2 threads/threads.cpp
new file mode 100644
index 0000000..1caa73d
--- /dev/null
+++ b/test cases/wasm/2 threads/threads.cpp
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <iostream>
+#include <thread>
+
+int main(void) {
+ std::cout << "Before thread" << std::endl;
+ std::thread t([]() {
+ sleep(1);
+ std::cout << "In a thread." << std::endl;
+ });
+ t.join();
+ std::cout << "After thread" << std::endl;
+}
diff --git a/test cases/wasm/3 jslib/meson.build b/test cases/wasm/3 jslib/meson.build
new file mode 100644
index 0000000..3cc1740
--- /dev/null
+++ b/test cases/wasm/3 jslib/meson.build
@@ -0,0 +1,8 @@
+project('jslib', 'c')
+
+cc = meson.get_compiler('c')
+
+sf_dep = cc.find_library('somefuncs.js', dirs: meson.current_source_dir())
+
+executable('libcallc', 'prog.c',
+ dependencies: sf_dep) \ No newline at end of file
diff --git a/test cases/wasm/3 jslib/prog.c b/test cases/wasm/3 jslib/prog.c
new file mode 100644
index 0000000..780da7c
--- /dev/null
+++ b/test cases/wasm/3 jslib/prog.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <emscripten.h>
+
+extern void sample_function();
+
+int main() {
+ printf("Hello World\n");
+ // sampleFunction(); ????
+ return 0;
+}
diff --git a/test cases/wasm/3 jslib/somefuncs.js b/test cases/wasm/3 jslib/somefuncs.js
new file mode 100644
index 0000000..1c00336
--- /dev/null
+++ b/test cases/wasm/3 jslib/somefuncs.js
@@ -0,0 +1,6 @@
+mergeInto(LibraryManager.library, {
+ sample_function__sig: 'v',
+ sample_function: function() {
+ alert("Something happened!");
+ },
+});
diff --git a/test cases/wayland/1 client/both.c b/test cases/wayland/1 client/both.c
new file mode 100644
index 0000000..b6e1bab
--- /dev/null
+++ b/test cases/wayland/1 client/both.c
@@ -0,0 +1,11 @@
+#include "viewporter-client-protocol.h"
+#include "viewporter-server-protocol.h"
+
+int main() {
+#if defined(VIEWPORTER_CLIENT_PROTOCOL_H) && \
+ defined(VIEWPORTER_SERVER_PROTOCOL_H)
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/test cases/wayland/1 client/client.c b/test cases/wayland/1 client/client.c
new file mode 100644
index 0000000..4966721
--- /dev/null
+++ b/test cases/wayland/1 client/client.c
@@ -0,0 +1,9 @@
+#include "xdg-shell-client-protocol.h"
+
+int main() {
+#ifdef XDG_SHELL_CLIENT_PROTOCOL_H
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/test cases/wayland/1 client/local.c b/test cases/wayland/1 client/local.c
new file mode 100644
index 0000000..97bfa56
--- /dev/null
+++ b/test cases/wayland/1 client/local.c
@@ -0,0 +1,9 @@
+#include "test-client-protocol.h"
+
+int main() {
+#ifdef TEST_CLIENT_PROTOCOL_H
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/test cases/wayland/1 client/meson.build b/test cases/wayland/1 client/meson.build
new file mode 100644
index 0000000..cb13db2
--- /dev/null
+++ b/test cases/wayland/1 client/meson.build
@@ -0,0 +1,48 @@
+project('wayland-test-client', 'c')
+
+wl_protocols_dep = dependency('wayland-protocols', required : false)
+if not wl_protocols_dep.found()
+ error('MESON_SKIP_TEST: wayland-protocols not installed')
+endif
+
+wl_client_dep = dependency('wayland-client')
+wl_server_dep = dependency('wayland-server')
+wl_mod = import('unstable-wayland')
+fs = import('fs')
+
+# Client side only
+xdg_shell_xml = wl_mod.find_protocol('xdg-shell')
+xdg_shell = wl_mod.scan_xml(xdg_shell_xml)
+assert(xdg_shell.length() == 2)
+assert(fs.name(xdg_shell[0].full_path()) == 'xdg-shell-protocol.c')
+assert(fs.name(xdg_shell[1].full_path()) == 'xdg-shell-client-protocol.h')
+exe = executable('client', 'client.c', xdg_shell, dependencies : wl_client_dep)
+test('client', exe)
+
+# Server side only
+presentation_time_xml = wl_mod.find_protocol('presentation-time')
+presentation_time = wl_mod.scan_xml(presentation_time_xml, client : false, server : true)
+assert(presentation_time.length() == 2)
+assert(fs.name(presentation_time[0].full_path()) == 'presentation-time-protocol.c')
+assert(fs.name(presentation_time[1].full_path()) == 'presentation-time-server-protocol.h')
+exe = executable('server', 'server.c', presentation_time, dependencies : wl_server_dep)
+test('server', exe)
+
+# Both sides
+viewporter_xml = wl_mod.find_protocol('viewporter')
+viewporter = wl_mod.scan_xml(viewporter_xml, client : true, server : true)
+assert(viewporter.length() == 3)
+assert(fs.name(viewporter[0].full_path()) == 'viewporter-protocol.c')
+assert(fs.name(viewporter[1].full_path()) == 'viewporter-client-protocol.h')
+assert(fs.name(viewporter[2].full_path()) == 'viewporter-server-protocol.h')
+exe = executable('both', 'both.c', viewporter, dependencies : [wl_client_dep, wl_server_dep])
+test('both', exe)
+
+# Local xml
+xmls = files('test.xml')
+gen = wl_mod.scan_xml(xmls)
+assert(gen.length() == 2)
+assert(fs.name(gen[0].full_path()) == 'test-protocol.c')
+assert(fs.name(gen[1].full_path()) == 'test-client-protocol.h')
+exe = executable('local', 'local.c', gen, dependencies : wl_client_dep)
+test('local', exe)
diff --git a/test cases/wayland/1 client/server.c b/test cases/wayland/1 client/server.c
new file mode 100644
index 0000000..e073a7b
--- /dev/null
+++ b/test cases/wayland/1 client/server.c
@@ -0,0 +1,9 @@
+#include "presentation-time-server-protocol.h"
+
+int main() {
+#ifdef PRESENTATION_TIME_SERVER_PROTOCOL_H
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/test cases/wayland/1 client/test.xml b/test cases/wayland/1 client/test.xml
new file mode 100644
index 0000000..f3c6db1
--- /dev/null
+++ b/test cases/wayland/1 client/test.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="test">
+ <interface name="ext_test" version="1">
+ <request name="destroy" type="destructor"/>
+ </interface>
+</protocol>
diff --git a/test cases/wayland/2 core only/core.c b/test cases/wayland/2 core only/core.c
new file mode 100644
index 0000000..5bb55e5
--- /dev/null
+++ b/test cases/wayland/2 core only/core.c
@@ -0,0 +1,9 @@
+#include <xdg-shell-client-protocol.h>
+
+int main() {
+#if defined(XDG_SHELL_CLIENT_PROTOCOL_H) && !defined(WAYLAND_CLIENT_H) && !defined(WAYLAND_CLIENT_PROTOCOL_H)
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/test cases/wayland/2 core only/meson.build b/test cases/wayland/2 core only/meson.build
new file mode 100644
index 0000000..a35e981
--- /dev/null
+++ b/test cases/wayland/2 core only/meson.build
@@ -0,0 +1,14 @@
+project('wayland-test-core-only', 'c')
+
+wl_protocols_dep = dependency('wayland-protocols', required : false)
+if not wl_protocols_dep.found()
+ error('MESON_SKIP_TEST: wayland-protocols not installed')
+endif
+
+wl_mod = import('unstable-wayland')
+wl_client_dep = dependency('wayland-client')
+
+xdg_shell_xml = wl_mod.find_protocol('xdg-shell')
+xdg_shell = wl_mod.scan_xml(xdg_shell_xml, include_core_only : true)
+exe = executable('core', 'core.c', xdg_shell, dependencies : wl_client_dep)
+test('core', exe)
diff --git a/test cases/windows/1 basic/meson.build b/test cases/windows/1 basic/meson.build
new file mode 100644
index 0000000..03d5436
--- /dev/null
+++ b/test cases/windows/1 basic/meson.build
@@ -0,0 +1,4 @@
+project('wintest', 'c')
+
+prog = executable('prog', 'prog.c', install : true)
+test('wintest', prog)
diff --git a/test cases/windows/1 basic/prog.c b/test cases/windows/1 basic/prog.c
new file mode 100644
index 0000000..f400e12
--- /dev/null
+++ b/test cases/windows/1 basic/prog.c
@@ -0,0 +1,5 @@
+#include <windows.h>
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/windows/1 basic/test.json b/test cases/windows/1 basic/test.json
new file mode 100644
index 0000000..650a6e2
--- /dev/null
+++ b/test cases/windows/1 basic/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/windows/10 vs module defs generated custom target/meson.build b/test cases/windows/10 vs module defs generated custom target/meson.build
new file mode 100644
index 0000000..7728ca7
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated custom target/meson.build
@@ -0,0 +1,5 @@
+project('generated_dll_module_defs', 'c')
+
+subdir('subdir')
+exe = executable('prog', 'prog.c', link_with : shlib)
+test('runtest', exe)
diff --git a/test cases/windows/10 vs module defs generated custom target/prog.c b/test cases/windows/10 vs module defs generated custom target/prog.c
new file mode 100644
index 0000000..066ac22
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated custom target/prog.c
@@ -0,0 +1,5 @@
+int somedllfunc(void);
+
+int main(void) {
+ return somedllfunc() == 42 ? 0 : 1;
+}
diff --git a/test cases/windows/10 vs module defs generated custom target/subdir/make_def.py b/test cases/windows/10 vs module defs generated custom target/subdir/make_def.py
new file mode 100755
index 0000000..50acfb5
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated custom target/subdir/make_def.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ print('EXPORTS', file=f)
+ print(' somedllfunc', file=f)
diff --git a/test cases/windows/10 vs module defs generated custom target/subdir/meson.build b/test cases/windows/10 vs module defs generated custom target/subdir/meson.build
new file mode 100644
index 0000000..c4ae33a
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated custom target/subdir/meson.build
@@ -0,0 +1,7 @@
+make_def = find_program('make_def.py')
+
+def_file = custom_target('gen_def',
+ command: [make_def, '@OUTPUT@'],
+ output: 'somedll.def')
+
+shlib = shared_library('somedll', 'somedll.c', vs_module_defs: def_file)
diff --git a/test cases/windows/10 vs module defs generated custom target/subdir/somedll.c b/test cases/windows/10 vs module defs generated custom target/subdir/somedll.c
new file mode 100644
index 0000000..f095b18
--- /dev/null
+++ b/test cases/windows/10 vs module defs generated custom target/subdir/somedll.c
@@ -0,0 +1,3 @@
+int somedllfunc(void) {
+ return 42;
+}
diff --git a/test cases/windows/11 exe implib/meson.build b/test cases/windows/11 exe implib/meson.build
new file mode 100644
index 0000000..0a38ec1
--- /dev/null
+++ b/test cases/windows/11 exe implib/meson.build
@@ -0,0 +1,7 @@
+project('wintest', 'c')
+
+# Test that we can produce an implib for an executable on Windows, and that it's
+# name can be set, and that it is installed along with the executable
+
+executable('prog', 'prog.c', install: true, implib: true)
+executable('prog2', 'prog.c', install: true, implib: 'burble', install_dir: get_option('bindir'))
diff --git a/test cases/windows/11 exe implib/prog.c b/test cases/windows/11 exe implib/prog.c
new file mode 100644
index 0000000..aa3bc5c
--- /dev/null
+++ b/test cases/windows/11 exe implib/prog.c
@@ -0,0 +1,6 @@
+#include <windows.h>
+
+int __declspec(dllexport)
+main(void) {
+ return 0;
+}
diff --git a/test cases/windows/11 exe implib/test.json b/test cases/windows/11 exe implib/test.json
new file mode 100644
index 0000000..f719568
--- /dev/null
+++ b/test cases/windows/11 exe implib/test.json
@@ -0,0 +1,12 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/bin/prog2.exe"},
+ {"type": "pdb", "file": "usr/bin/prog2"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libprog.exe.a"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libburble.a"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/prog.exe.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/burble.lib"}
+ ]
+}
diff --git a/test cases/windows/12 resources with custom targets/meson.build b/test cases/windows/12 resources with custom targets/meson.build
new file mode 100644
index 0000000..282272d
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/meson.build
@@ -0,0 +1,70 @@
+project('winmain', 'c')
+
+# MinGW windres has a bug due to which it doesn't parse args with space properly:
+# https://github.com/mesonbuild/meson/pull/1346
+# https://sourceware.org/bugzilla/show_bug.cgi?id=4933
+if ['gcc', 'clang'].contains(meson.get_compiler('c').get_id()) and host_machine.system() == 'windows'
+ # Construct build_to_src and skip this test if it has spaces
+ # because then the -I flag to windres will also have spaces
+ # and we know the test will fail
+ src_parts = meson.source_root().split('/')
+ build_parts = meson.build_root().split('/')
+
+ # Get the common path (which might just be '/' or 'C:/')
+ common = []
+ done = false
+ count = 0
+ if src_parts.length() > build_parts.length()
+ parts = build_parts
+ other = src_parts
+ else
+ parts = src_parts
+ other = build_parts
+ endif
+ foreach part : parts
+ if not done and part == other.get(count)
+ common += [part]
+ else
+ done = true
+ endif
+ count += 1
+ endforeach
+
+ # Create path components to go down from the build root to the common path
+ count = 0
+ rel = build_parts
+ foreach build : build_parts
+ if count < build_parts.length() - common.length()
+ rel += ['..']
+ endif
+ count += 1
+ endforeach
+
+ # Create path components to go up from the common path to the build root
+ count = 0
+ foreach src : src_parts
+ if count >= common.length()
+ rel += [src]
+ endif
+ count += 1
+ endforeach
+
+ build_to_src = '/'.join(rel)
+
+ if build_to_src.contains(' ')
+ message('build_to_src is: ' + build_to_src)
+ error('MESON_SKIP_TEST build_to_src has spaces')
+ endif
+ # Welcome to the end of this conditional.
+ # We hope you never have to implement something like this.
+endif
+
+subdir('res')
+
+foreach id : [0, 1, 2]
+ exe = executable('prog_@0@'.format(id), 'prog.c',
+ res[id],
+ gui_app : true)
+
+ test('winmain_@0@'.format(id), exe)
+endforeach
diff --git a/test cases/windows/12 resources with custom targets/prog.c b/test cases/windows/12 resources with custom targets/prog.c
new file mode 100644
index 0000000..cb6892d
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/prog.c
@@ -0,0 +1,19 @@
+#include<windows.h>
+
+#define MY_ICON 1
+
+int APIENTRY
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow) {
+ HICON hIcon;
+ hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MY_ICON));
+ // avoid unused argument error while matching template
+ ((void)hInstance);
+ ((void)hPrevInstance);
+ ((void)lpszCmdLine);
+ ((void)nCmdShow);
+ return hIcon ? 0 : 1;
+}
diff --git a/test cases/windows/12 resources with custom targets/res/gen-res.py b/test cases/windows/12 resources with custom targets/res/gen-res.py
new file mode 100755
index 0000000..e5ef6b1
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/res/gen-res.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+
+with open(sys.argv[1]) as infile, open(sys.argv[2], 'w') as outfile:
+ outfile.write(infile.read().format(icon=sys.argv[3]))
diff --git a/test cases/windows/12 resources with custom targets/res/meson.build b/test cases/windows/12 resources with custom targets/res/meson.build
new file mode 100644
index 0000000..9797637
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/res/meson.build
@@ -0,0 +1,19 @@
+win = import('windows')
+
+rc_writer = find_program('./gen-res.py')
+
+rc_sources = []
+
+foreach id : [1, 2]
+ rc_sources += custom_target('RC source file @0@'.format(id),
+ input : 'myres.rc.in',
+ output : 'myres_@0@.rc'.format(id),
+ command : [rc_writer, '@INPUT@', '@OUTPUT@', files('sample.ico')],
+ install : false,
+ build_always : false)
+endforeach
+
+rc_sources += files('myres_static.rc')
+
+res = win.compile_resources(rc_sources,
+ include_directories: include_directories('.'))
diff --git a/test cases/windows/12 resources with custom targets/res/myres.rc.in b/test cases/windows/12 resources with custom targets/res/myres.rc.in
new file mode 100644
index 0000000..0cff642
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/res/myres.rc.in
@@ -0,0 +1,4 @@
+#include<windows.h>
+#include<resource.h>
+
+1 ICON "{icon}"
diff --git a/test cases/windows/12 resources with custom targets/res/myres_static.rc b/test cases/windows/12 resources with custom targets/res/myres_static.rc
new file mode 100644
index 0000000..12838ae
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/res/myres_static.rc
@@ -0,0 +1,3 @@
+#include<windows.h>
+
+1 ICON "sample.ico"
diff --git a/test cases/windows/12 resources with custom targets/res/resource.h b/test cases/windows/12 resources with custom targets/res/resource.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/res/resource.h
diff --git a/test cases/windows/12 resources with custom targets/res/sample.ico b/test cases/windows/12 resources with custom targets/res/sample.ico
new file mode 100644
index 0000000..24bd3d9
--- /dev/null
+++ b/test cases/windows/12 resources with custom targets/res/sample.ico
Binary files differ
diff --git a/test cases/windows/13 test argument extra paths/exe/main.c b/test cases/windows/13 test argument extra paths/exe/main.c
new file mode 100644
index 0000000..1032ae2
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/exe/main.c
@@ -0,0 +1,5 @@
+#include <foo.h>
+
+int main(void) {
+ return foo_process();
+}
diff --git a/test cases/windows/13 test argument extra paths/exe/meson.build b/test cases/windows/13 test argument extra paths/exe/meson.build
new file mode 100644
index 0000000..138500a
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/exe/meson.build
@@ -0,0 +1,3 @@
+barexe = executable('bar', 'main.c',
+ include_directories: incfoo,
+ link_with: libfoo)
diff --git a/test cases/windows/13 test argument extra paths/lib/foo.c b/test cases/windows/13 test argument extra paths/lib/foo.c
new file mode 100644
index 0000000..86b1a03
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/lib/foo.c
@@ -0,0 +1,6 @@
+#include "foo.h"
+
+int
+foo_process(void) {
+ return 42;
+}
diff --git a/test cases/windows/13 test argument extra paths/lib/foo.h b/test cases/windows/13 test argument extra paths/lib/foo.h
new file mode 100644
index 0000000..5078c58
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/lib/foo.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#if defined _WIN32 || defined __CYGWIN__
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+DLL_PUBLIC int foo_process(void);
diff --git a/test cases/windows/13 test argument extra paths/lib/meson.build b/test cases/windows/13 test argument extra paths/lib/meson.build
new file mode 100644
index 0000000..aa0bf14
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/lib/meson.build
@@ -0,0 +1,3 @@
+incfoo = include_directories('.')
+
+libfoo = library('foo', 'foo.c')
diff --git a/test cases/windows/13 test argument extra paths/meson.build b/test cases/windows/13 test argument extra paths/meson.build
new file mode 100644
index 0000000..f105946
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/meson.build
@@ -0,0 +1,5 @@
+project('test argument extra paths', 'c')
+
+subdir('lib')
+subdir('exe')
+subdir('test')
diff --git a/test cases/windows/13 test argument extra paths/test/meson.build b/test cases/windows/13 test argument extra paths/test/meson.build
new file mode 100644
index 0000000..2e608be
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/test/meson.build
@@ -0,0 +1,3 @@
+python3 = import('python').find_installation('')
+
+test('run_exe', python3, args: [files('test_run_exe.py')[0], barexe])
diff --git a/test cases/windows/13 test argument extra paths/test/test_run_exe.py b/test cases/windows/13 test argument extra paths/test/test_run_exe.py
new file mode 100644
index 0000000..77c7ddc
--- /dev/null
+++ b/test cases/windows/13 test argument extra paths/test/test_run_exe.py
@@ -0,0 +1,12 @@
+import subprocess
+import argparse
+import sys
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('prog')
+ args = parser.parse_args()
+
+ res = subprocess.run(args.prog)
+
+ sys.exit(res.returncode - 42)
diff --git a/test cases/windows/14 resources with custom target depend_files/ico/gen-ico.py b/test cases/windows/14 resources with custom target depend_files/ico/gen-ico.py
new file mode 100755
index 0000000..c49e0dd
--- /dev/null
+++ b/test cases/windows/14 resources with custom target depend_files/ico/gen-ico.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+
+with open(sys.argv[1], 'rb') as infile, open(sys.argv[2], 'wb') as outfile:
+ outfile.write(infile.read())
diff --git a/test cases/windows/14 resources with custom target depend_files/ico/meson.build b/test cases/windows/14 resources with custom target depend_files/ico/meson.build
new file mode 100644
index 0000000..3fae9e8
--- /dev/null
+++ b/test cases/windows/14 resources with custom target depend_files/ico/meson.build
@@ -0,0 +1,8 @@
+ico_writer = find_program('gen-ico.py')
+
+ico = custom_target('makeico',
+ input : 'sample.ico.in',
+ output : 'sample.ico',
+ command : [ico_writer, '@INPUT@', '@OUTPUT@'],
+ install : false,
+ build_always : false)
diff --git a/test cases/windows/14 resources with custom target depend_files/ico/sample.ico.in b/test cases/windows/14 resources with custom target depend_files/ico/sample.ico.in
new file mode 100644
index 0000000..24bd3d9
--- /dev/null
+++ b/test cases/windows/14 resources with custom target depend_files/ico/sample.ico.in
Binary files differ
diff --git a/test cases/windows/14 resources with custom target depend_files/meson.build b/test cases/windows/14 resources with custom target depend_files/meson.build
new file mode 100644
index 0000000..85ba06f
--- /dev/null
+++ b/test cases/windows/14 resources with custom target depend_files/meson.build
@@ -0,0 +1,69 @@
+project('winmain', 'c')
+
+# MinGW windres has a bug due to which it doesn't parse args with space properly:
+# https://github.com/mesonbuild/meson/pull/1346
+# https://sourceware.org/bugzilla/show_bug.cgi?id=4933
+if meson.get_compiler('c').get_id() == 'gcc' and host_machine.system() == 'windows'
+ # Construct build_to_src and skip this test if it has spaces
+ # because then the -I flag to windres will also have spaces
+ # and we know the test will fail
+ src_parts = meson.source_root().split('/')
+ build_parts = meson.build_root().split('/')
+
+ # Get the common path (which might just be '/' or 'C:/')
+ common = []
+ done = false
+ count = 0
+ if src_parts.length() > build_parts.length()
+ parts = build_parts
+ other = src_parts
+ else
+ parts = src_parts
+ other = build_parts
+ endif
+ foreach part : parts
+ if not done and part == other.get(count)
+ common += [part]
+ else
+ done = true
+ endif
+ count += 1
+ endforeach
+
+ # Create path components to go down from the build root to the common path
+ count = 0
+ rel = build_parts
+ foreach build : build_parts
+ if count < build_parts.length() - common.length()
+ rel += ['..']
+ endif
+ count += 1
+ endforeach
+
+ # Create path components to go up from the common path to the build root
+ count = 0
+ foreach src : src_parts
+ if count >= common.length()
+ rel += [src]
+ endif
+ count += 1
+ endforeach
+
+ build_to_src = '/'.join(rel)
+
+ if build_to_src.contains(' ')
+ message('build_to_src is: ' + build_to_src)
+ error('MESON_SKIP_TEST build_to_src has spaces')
+ endif
+ # Welcome to the end of this conditional.
+ # We hope you never have to implement something like this.
+endif
+
+subdir('ico')
+subdir('res')
+
+exe = executable('prog', 'prog.c',
+ res,
+ gui_app : true)
+
+test('winmain', exe)
diff --git a/test cases/windows/14 resources with custom target depend_files/prog.c b/test cases/windows/14 resources with custom target depend_files/prog.c
new file mode 100644
index 0000000..cb6892d
--- /dev/null
+++ b/test cases/windows/14 resources with custom target depend_files/prog.c
@@ -0,0 +1,19 @@
+#include<windows.h>
+
+#define MY_ICON 1
+
+int APIENTRY
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow) {
+ HICON hIcon;
+ hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MY_ICON));
+ // avoid unused argument error while matching template
+ ((void)hInstance);
+ ((void)hPrevInstance);
+ ((void)lpszCmdLine);
+ ((void)nCmdShow);
+ return hIcon ? 0 : 1;
+}
diff --git a/test cases/windows/14 resources with custom target depend_files/res/meson.build b/test cases/windows/14 resources with custom target depend_files/res/meson.build
new file mode 100644
index 0000000..3d43b3f
--- /dev/null
+++ b/test cases/windows/14 resources with custom target depend_files/res/meson.build
@@ -0,0 +1,4 @@
+win = import('windows')
+
+res = win.compile_resources('myres.rc',
+ depends: ico)
diff --git a/test cases/windows/14 resources with custom target depend_files/res/myres.rc b/test cases/windows/14 resources with custom target depend_files/res/myres.rc
new file mode 100644
index 0000000..12838ae
--- /dev/null
+++ b/test cases/windows/14 resources with custom target depend_files/res/myres.rc
@@ -0,0 +1,3 @@
+#include<windows.h>
+
+1 ICON "sample.ico"
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/a/meson.build b/test cases/windows/15 resource scripts with duplicate filenames/a/meson.build
new file mode 100644
index 0000000..73f18c8
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/a/meson.build
@@ -0,0 +1 @@
+a = win.compile_resources('rsrc.rc')
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/a/rsrc.rc b/test cases/windows/15 resource scripts with duplicate filenames/a/rsrc.rc
new file mode 100644
index 0000000..1997b8e
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/a/rsrc.rc
@@ -0,0 +1 @@
+a RCDATA { "a" }
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/b/meson.build b/test cases/windows/15 resource scripts with duplicate filenames/b/meson.build
new file mode 100644
index 0000000..d0b0aab
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/b/meson.build
@@ -0,0 +1,2 @@
+bf = files('rsrc.rc')
+b = win.compile_resources(bf)
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/b/rsrc.rc b/test cases/windows/15 resource scripts with duplicate filenames/b/rsrc.rc
new file mode 100644
index 0000000..a8e3b27
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/b/rsrc.rc
@@ -0,0 +1 @@
+b RCDATA { "b" }
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/c/meson.build b/test cases/windows/15 resource scripts with duplicate filenames/c/meson.build
new file mode 100644
index 0000000..a7b7e30
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/c/meson.build
@@ -0,0 +1,2 @@
+cf = files('rsrc.rc')
+c = win.compile_resources(cf)
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/c/rsrc.rc b/test cases/windows/15 resource scripts with duplicate filenames/c/rsrc.rc
new file mode 100644
index 0000000..1fa2c1c
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/c/rsrc.rc
@@ -0,0 +1 @@
+c RCDATA { "c" }
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe3/meson.build b/test cases/windows/15 resource scripts with duplicate filenames/exe3/meson.build
new file mode 100644
index 0000000..1b97435
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe3/meson.build
@@ -0,0 +1,5 @@
+dll_res = win.compile_resources('src_dll/version.rc')
+shared_library('lib3', 'src_dll/main.c', dll_res)
+
+exe_res = win.compile_resources('src_exe/version.rc')
+executable('exe3', 'src_exe/main.c', exe_res)
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/main.c b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/main.c
new file mode 100644
index 0000000..2bd8cd2
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/main.c
@@ -0,0 +1,10 @@
+#include <windows.h>
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ // avoid unused argument error while matching template
+ ((void)hinstDLL);
+ ((void)fdwReason);
+ ((void)lpvReserved);
+ return TRUE;
+}
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/version.rc b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/version.rc
new file mode 100644
index 0000000..abdbaaa
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_dll/version.rc
@@ -0,0 +1,11 @@
+ #include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+BEGIN
+END
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/main.c b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/version.rc b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/version.rc
new file mode 100644
index 0000000..abdbaaa
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe3/src_exe/version.rc
@@ -0,0 +1,11 @@
+ #include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+BEGIN
+END
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe4/meson.build b/test cases/windows/15 resource scripts with duplicate filenames/exe4/meson.build
new file mode 100644
index 0000000..2ae3a71
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe4/meson.build
@@ -0,0 +1,5 @@
+dll_res = win.compile_resources(files('src_dll/version.rc'))
+shared_library('lib4', 'src_dll/main.c', dll_res)
+
+exe_res = win.compile_resources(files('src_exe/version.rc'))
+executable('exe4', 'src_exe/main.c', exe_res)
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/main.c b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/main.c
new file mode 100644
index 0000000..2bd8cd2
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/main.c
@@ -0,0 +1,10 @@
+#include <windows.h>
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ // avoid unused argument error while matching template
+ ((void)hinstDLL);
+ ((void)fdwReason);
+ ((void)lpvReserved);
+ return TRUE;
+}
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/version.rc b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/version.rc
new file mode 100644
index 0000000..abdbaaa
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_dll/version.rc
@@ -0,0 +1,11 @@
+ #include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+BEGIN
+END
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/main.c b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/main.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/version.rc b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/version.rc
new file mode 100644
index 0000000..abdbaaa
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/exe4/src_exe/version.rc
@@ -0,0 +1,11 @@
+ #include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+BEGIN
+END
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/meson.build b/test cases/windows/15 resource scripts with duplicate filenames/meson.build
new file mode 100644
index 0000000..9fa3525
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/meson.build
@@ -0,0 +1,21 @@
+project('foobar', 'c')
+
+win = import('windows')
+
+subdir('a')
+subdir('b')
+subdir('c')
+subdir('exe3')
+subdir('exe4')
+
+main = win.compile_resources('rsrc.rc')
+
+testa = executable('testa', 'verify.c', a)
+testb = executable('testb', 'verify.c', b)
+testc = executable('testc', 'verify.c', c)
+testmain = executable('testmain', 'verify.c', main)
+
+test('a', testa, args: 'a')
+test('b', testb, args: 'b')
+test('c', testc, args: 'c')
+test('main', testmain, args: 'main')
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/rsrc.rc b/test cases/windows/15 resource scripts with duplicate filenames/rsrc.rc
new file mode 100644
index 0000000..8f6aa1f
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/rsrc.rc
@@ -0,0 +1 @@
+main RCDATA { "main" }
diff --git a/test cases/windows/15 resource scripts with duplicate filenames/verify.c b/test cases/windows/15 resource scripts with duplicate filenames/verify.c
new file mode 100644
index 0000000..8f5b88e
--- /dev/null
+++ b/test cases/windows/15 resource scripts with duplicate filenames/verify.c
@@ -0,0 +1,25 @@
+#include <assert.h>
+#include <windows.h>
+
+int main(int argc, char *argv[])
+{
+ // verify that the expected resource exists and has the expected contents
+ HRSRC hRsrc;
+ unsigned int size;
+ HGLOBAL hGlobal;
+ void* data;
+
+ ((void)argc);
+
+ hRsrc = FindResource(NULL, argv[1], RT_RCDATA);
+ assert(hRsrc);
+
+ size = SizeofResource(NULL, hRsrc);
+ hGlobal = LoadResource(NULL, hRsrc);
+ data = LockResource(hGlobal);
+
+ assert(size == strlen(argv[1]));
+ assert(memcmp(data, argv[1], size) == 0);
+
+ return 0;
+}
diff --git a/test cases/windows/16 gui app/console_prog.c b/test cases/windows/16 gui app/console_prog.c
new file mode 100644
index 0000000..9b6bdc2
--- /dev/null
+++ b/test cases/windows/16 gui app/console_prog.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/test cases/windows/16 gui app/dummy.c b/test cases/windows/16 gui app/dummy.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/windows/16 gui app/dummy.c
diff --git a/test cases/windows/16 gui app/gui_app_tester.py b/test cases/windows/16 gui app/gui_app_tester.py
new file mode 100644
index 0000000..53e7649
--- /dev/null
+++ b/test cases/windows/16 gui app/gui_app_tester.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+try:
+ import pefile
+except ImportError:
+ if 'CI' in os.environ:
+ raise
+ # Skip the test if not on CI
+ sys.exit(77)
+
+executable = sys.argv[1]
+expected = int(sys.argv[2])
+
+actual = pefile.PE(executable).dump_dict()['OPTIONAL_HEADER']['Subsystem']['Value']
+
+print('subsystem expected: %d, actual: %d' % (expected, actual))
+sys.exit(0 if (expected == actual) else 1)
diff --git a/test cases/windows/16 gui app/gui_prog.c b/test cases/windows/16 gui app/gui_prog.c
new file mode 100644
index 0000000..9cdf170
--- /dev/null
+++ b/test cases/windows/16 gui app/gui_prog.c
@@ -0,0 +1,11 @@
+#include <windows.h>
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, int nCmdShow) {
+ // avoid unused argument error while matching template
+ ((void)hInstance);
+ ((void)hPrevInstance);
+ ((void)lpCmdLine);
+ ((void)nCmdShow);
+ return 0;
+}
diff --git a/test cases/windows/16 gui app/meson.build b/test cases/windows/16 gui app/meson.build
new file mode 100644
index 0000000..3021c43
--- /dev/null
+++ b/test cases/windows/16 gui app/meson.build
@@ -0,0 +1,26 @@
+project('gui_app_test', 'c')
+
+#
+# test that linking a Windows console applications with the main function in a
+# library is correctly instructed which entrypoint function to look for
+#
+
+console_lib = static_library('main', 'console_prog.c')
+executable('console', 'dummy.c', link_with: console_lib, win_subsystem: 'console')
+executable('console2', 'dummy.c', link_with: console_lib, gui_app: false)
+
+#
+# also verify that the correct subsystem is set by executable(gui_app:)
+#
+
+gui_prog = executable('gui_prog', 'gui_prog.c', win_subsystem: 'windows,6.0')
+gui_prog2 = executable('gui_prog2', 'gui_prog.c', gui_app: true)
+console_prog = executable('console_prog', 'console_prog.c', win_subsystem: 'console')
+console_prog2 = executable('console_prog2', 'console_prog.c', gui_app: false)
+
+tester = find_program('gui_app_tester.py')
+
+test('is_gui', tester, args: [gui_prog, '2'])
+test('is_gui2', tester, args: [gui_prog2, '2'])
+test('not_gui', tester, args: [console_prog, '3'])
+test('not_gui2', tester, args: [console_prog2, '3'])
diff --git a/test cases/windows/17 msvc ndebug/main.cpp b/test cases/windows/17 msvc ndebug/main.cpp
new file mode 100644
index 0000000..d647d71
--- /dev/null
+++ b/test cases/windows/17 msvc ndebug/main.cpp
@@ -0,0 +1,9 @@
+int main() {
+#ifdef NDEBUG
+ // NDEBUG is defined
+ return 0;
+#else
+ // NDEBUG is not defined
+ return 1;
+#endif
+} \ No newline at end of file
diff --git a/test cases/windows/17 msvc ndebug/meson.build b/test cases/windows/17 msvc ndebug/meson.build
new file mode 100644
index 0000000..78eaf89
--- /dev/null
+++ b/test cases/windows/17 msvc ndebug/meson.build
@@ -0,0 +1,7 @@
+project('msvc_ndebug', 'cpp',
+ default_options : [ 'b_ndebug=true' ]
+)
+
+exe = executable('exe', 'main.cpp')
+
+test('ndebug', exe)
diff --git a/test cases/windows/18 msvc charset/iso-8859-1.c b/test cases/windows/18 msvc charset/iso-8859-1.c
new file mode 100644
index 0000000..66c6a00
--- /dev/null
+++ b/test cases/windows/18 msvc charset/iso-8859-1.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char *argcv[])
+{
+ printf("This is ISO-8859-1 encoded é\n");
+ return 0;
+}
diff --git a/test cases/windows/18 msvc charset/meson.build b/test cases/windows/18 msvc charset/meson.build
new file mode 100644
index 0000000..bb6f667
--- /dev/null
+++ b/test cases/windows/18 msvc charset/meson.build
@@ -0,0 +1,15 @@
+project('charset', 'c')
+
+cc = meson.get_compiler('c')
+
+if cc.get_id() != 'msvc'
+ error('MESON_SKIP_TEST requires MSVC.')
+endif
+
+executable('utf8', 'utf8.c')
+
+if get_option('test-failure')
+ executable('iso-8859-1', 'iso-8859-1.c')
+else
+ executable('iso-8859-1', 'iso-8859-1.c', c_args: '/source-charset:.850')
+endif
diff --git a/test cases/windows/18 msvc charset/meson_options.txt b/test cases/windows/18 msvc charset/meson_options.txt
new file mode 100644
index 0000000..2cfba63
--- /dev/null
+++ b/test cases/windows/18 msvc charset/meson_options.txt
@@ -0,0 +1 @@
+option('test-failure', type: 'boolean', value: false)
diff --git a/test cases/windows/18 msvc charset/utf8.c b/test cases/windows/18 msvc charset/utf8.c
new file mode 100644
index 0000000..d6dc5aa
--- /dev/null
+++ b/test cases/windows/18 msvc charset/utf8.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char *argcv[])
+{
+ printf("This is UTF-8 encoded é\n");
+ return 0;
+}
diff --git a/test cases/windows/19 msvc cplusplus define/main.cpp b/test cases/windows/19 msvc cplusplus define/main.cpp
new file mode 100644
index 0000000..bc0b1fd
--- /dev/null
+++ b/test cases/windows/19 msvc cplusplus define/main.cpp
@@ -0,0 +1,7 @@
+int main() {
+#if __cplusplus == 199711L
+ return 1;
+#else
+ return 0;
+#endif
+}
diff --git a/test cases/windows/19 msvc cplusplus define/meson.build b/test cases/windows/19 msvc cplusplus define/meson.build
new file mode 100644
index 0000000..9b85ff6
--- /dev/null
+++ b/test cases/windows/19 msvc cplusplus define/meson.build
@@ -0,0 +1,14 @@
+project('msvc __cplusplus', 'cpp', default_options : ['cpp_std=c++14'])
+
+cpp = meson.get_compiler('cpp')
+
+if cpp.get_id() != 'msvc'
+ error('MESON_SKIP_TEST: test is only relevant for msvc')
+elif meson.project_version().version_compare('< 15.7')
+ error('MESON_SKIP_TEST: test is only relevant for msvc versions >= 15.7')
+endif
+
+test(
+ 'main',
+ executable('main', 'main.cpp'),
+)
diff --git a/test cases/windows/2 winmain/meson.build b/test cases/windows/2 winmain/meson.build
new file mode 100644
index 0000000..ea0d23b
--- /dev/null
+++ b/test cases/windows/2 winmain/meson.build
@@ -0,0 +1,4 @@
+project('winmain', 'c')
+
+exe = executable('prog', 'prog.c', gui_app : true)
+test('winmain', exe)
diff --git a/test cases/windows/2 winmain/prog.c b/test cases/windows/2 winmain/prog.c
new file mode 100644
index 0000000..3bd4c95
--- /dev/null
+++ b/test cases/windows/2 winmain/prog.c
@@ -0,0 +1,15 @@
+#include<windows.h>
+
+int APIENTRY
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow) {
+// avoid unused argument error while matching template
+ ((void)hInstance);
+ ((void)hPrevInstance);
+ ((void)lpszCmdLine);
+ ((void)nCmdShow);
+ return 0;
+}
diff --git a/test cases/windows/20 vs install static lib with generated obj deps/both_lib_source.c b/test cases/windows/20 vs install static lib with generated obj deps/both_lib_source.c
new file mode 100644
index 0000000..aa926b1
--- /dev/null
+++ b/test cases/windows/20 vs install static lib with generated obj deps/both_lib_source.c
@@ -0,0 +1,7 @@
+extern int static_lib_function(void);
+extern __declspec(dllexport) int both_lib_function(void);
+
+int both_lib_function(void)
+{
+ return static_lib_function();
+}
diff --git a/test cases/windows/20 vs install static lib with generated obj deps/copyfile.py b/test cases/windows/20 vs install static lib with generated obj deps/copyfile.py
new file mode 100644
index 0000000..738e894
--- /dev/null
+++ b/test cases/windows/20 vs install static lib with generated obj deps/copyfile.py
@@ -0,0 +1,4 @@
+from shutil import copyfile
+import sys
+
+copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/windows/20 vs install static lib with generated obj deps/generated_source.c b/test cases/windows/20 vs install static lib with generated obj deps/generated_source.c
new file mode 100644
index 0000000..8671cbf
--- /dev/null
+++ b/test cases/windows/20 vs install static lib with generated obj deps/generated_source.c
@@ -0,0 +1,4 @@
+int generated_function(void)
+{
+ return 42;
+}
diff --git a/test cases/windows/20 vs install static lib with generated obj deps/meson.build b/test cases/windows/20 vs install static lib with generated obj deps/meson.build
new file mode 100644
index 0000000..bc61772
--- /dev/null
+++ b/test cases/windows/20 vs install static lib with generated obj deps/meson.build
@@ -0,0 +1,20 @@
+project('test', 'c')
+
+generated_c = custom_target(
+ 'generated.c',
+ input : files('generated_source.c', 'copyfile.py'),
+ output : 'generated.c',
+ command : ['python', '@INPUT1@', '@INPUT0@', '@OUTPUT@'],
+)
+
+static_lib = static_library(
+ 'static_lib',
+ [files('static_lib_source.c'), generated_c],
+)
+
+both_lib = both_libraries(
+ 'both_lib',
+ [files('both_lib_source.c')],
+ link_with : [static_lib],
+ install : true,
+)
diff --git a/test cases/windows/20 vs install static lib with generated obj deps/static_lib_source.c b/test cases/windows/20 vs install static lib with generated obj deps/static_lib_source.c
new file mode 100644
index 0000000..e86153a
--- /dev/null
+++ b/test cases/windows/20 vs install static lib with generated obj deps/static_lib_source.c
@@ -0,0 +1,6 @@
+extern int generated_function(void);
+
+int static_lib_function(void)
+{
+ return generated_function();
+}
diff --git a/test cases/windows/20 vs install static lib with generated obj deps/test.json b/test cases/windows/20 vs install static lib with generated obj deps/test.json
new file mode 100644
index 0000000..451da1e
--- /dev/null
+++ b/test cases/windows/20 vs install static lib with generated obj deps/test.json
@@ -0,0 +1,13 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libboth_lib.a"},
+
+ {"type": "shared_lib", "platform": "msvc", "file": "usr/bin/both_lib"},
+ {"type": "implib", "platform": "msvc", "file": "usr/lib/both_lib"},
+ {"type": "pdb", "platform": "msvc", "file": "usr/bin/both_lib"},
+
+ {"type": "expr", "platform": "gcc", "file": "usr/lib/?libboth_lib.dll"},
+ {"type": "implib", "platform": "gcc", "file": "usr/lib/libboth_lib"},
+ {"type": "pdb", "platform": "gcc", "file": "usr/bin/libboth_lib"}
+ ]
+}
diff --git a/test cases/windows/21 masm/hello.masm b/test cases/windows/21 masm/hello.masm
new file mode 100644
index 0000000..a47dc96
--- /dev/null
+++ b/test cases/windows/21 masm/hello.masm
@@ -0,0 +1,33 @@
+; ---------------------------------------------
+; Hello World for Win64 Intel x64 Assembly
+;
+; by fruel (https://github.com/fruel)
+; 13 June 2016
+; ---------------------------------------------
+
+GetStdHandle PROTO
+ExitProcess PROTO
+WriteConsoleA PROTO
+
+.data
+msg BYTE "Hello World!",0
+bytesWritten DWORD ?
+
+.code
+mainCRTStartup proc
+ sub rsp, 5 * 8 ; reserve shadow space
+
+ mov rcx, -11 ; nStdHandle (STD_OUTPUT_HANDLE)
+ call GetStdHandle
+
+ mov rcx, rax ; hConsoleOutput
+ lea rdx, msg ; *lpBuffer
+ mov r8, LENGTHOF msg - 1 ; nNumberOfCharsToWrite
+ lea r9, bytesWritten ; lpNumberOfCharsWritten
+ mov QWORD PTR [rsp + 4 * SIZEOF QWORD], 0 ; lpReserved
+ call WriteConsoleA
+
+ mov rcx, 0 ; uExitCode
+ call ExitProcess
+mainCRTStartup endp
+END
diff --git a/test cases/windows/21 masm/meson.build b/test cases/windows/21 masm/meson.build
new file mode 100644
index 0000000..b6b8fbb
--- /dev/null
+++ b/test cases/windows/21 masm/meson.build
@@ -0,0 +1,14 @@
+project('test-masm', 'c')
+
+if get_option('backend').startswith('vs')
+ error('MESON_SKIP_TEST: masm is not supported by vs backend')
+endif
+
+cc = meson.get_compiler('c')
+
+# MASM must be found when using MSVC, otherwise it is optional
+if not add_languages('masm', required: cc.get_argument_syntax() == 'msvc')
+ error('MESON_SKIP_TEST: masm not available')
+endif
+
+executable('app', 'hello.masm')
diff --git a/test cases/windows/3 cpp/meson.build b/test cases/windows/3 cpp/meson.build
new file mode 100644
index 0000000..a9e6569
--- /dev/null
+++ b/test cases/windows/3 cpp/meson.build
@@ -0,0 +1,4 @@
+project('wincpp', 'cpp', default_options : ['cpp_std=c++14'])
+
+exe = executable('prog', 'prog.cpp')
+test('wincpp', exe)
diff --git a/test cases/windows/3 cpp/prog.cpp b/test cases/windows/3 cpp/prog.cpp
new file mode 100644
index 0000000..69092f7
--- /dev/null
+++ b/test cases/windows/3 cpp/prog.cpp
@@ -0,0 +1,7 @@
+#include<windows.h>
+
+class Foo;
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/windows/4 winmaincpp/meson.build b/test cases/windows/4 winmaincpp/meson.build
new file mode 100644
index 0000000..4eda8ca
--- /dev/null
+++ b/test cases/windows/4 winmaincpp/meson.build
@@ -0,0 +1,4 @@
+project('winmaincpp', 'cpp')
+
+exe = executable('prog', 'prog.cpp', gui_app : true)
+test('winmaincpp', exe)
diff --git a/test cases/windows/4 winmaincpp/prog.cpp b/test cases/windows/4 winmaincpp/prog.cpp
new file mode 100644
index 0000000..6182257
--- /dev/null
+++ b/test cases/windows/4 winmaincpp/prog.cpp
@@ -0,0 +1,17 @@
+#include<windows.h>
+
+class Foo;
+
+int APIENTRY
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow) {
+// avoid unused argument error while matching template
+ ((void)hInstance);
+ ((void)hPrevInstance);
+ ((void)lpszCmdLine);
+ ((void)nCmdShow);
+ return 0;
+}
diff --git a/test cases/windows/5 resources/inc/meson.build b/test cases/windows/5 resources/inc/meson.build
new file mode 100644
index 0000000..b8b511a
--- /dev/null
+++ b/test cases/windows/5 resources/inc/meson.build
@@ -0,0 +1 @@
+inc = include_directories('resource')
diff --git a/test cases/windows/5 resources/inc/resource/resource.h b/test cases/windows/5 resources/inc/resource/resource.h
new file mode 100644
index 0000000..dbdd509
--- /dev/null
+++ b/test cases/windows/5 resources/inc/resource/resource.h
@@ -0,0 +1 @@
+#define ICON_ID 1
diff --git a/test cases/windows/5 resources/meson.build b/test cases/windows/5 resources/meson.build
new file mode 100644
index 0000000..27b2fcc
--- /dev/null
+++ b/test cases/windows/5 resources/meson.build
@@ -0,0 +1,69 @@
+project('winmain', 'c')
+
+# MinGW windres has a bug due to which it doesn't parse args with space properly:
+# https://github.com/mesonbuild/meson/pull/1346
+# https://sourceware.org/bugzilla/show_bug.cgi?id=4933
+if ['gcc', 'clang'].contains(meson.get_compiler('c').get_id()) and host_machine.system() == 'windows'
+ # Construct build_to_src and skip this test if it has spaces
+ # because then the -I flag to windres will also have spaces
+ # and we know the test will fail
+ src_parts = meson.source_root().split('/')
+ build_parts = meson.build_root().split('/')
+
+ # Get the common path (which might just be '/' or 'C:/')
+ common = []
+ done = false
+ count = 0
+ if src_parts.length() > build_parts.length()
+ parts = build_parts
+ other = src_parts
+ else
+ parts = src_parts
+ other = build_parts
+ endif
+ foreach part : parts
+ if not done and part == other.get(count)
+ common += [part]
+ else
+ done = true
+ endif
+ count += 1
+ endforeach
+
+ # Create path components to go down from the build root to the common path
+ count = 0
+ rel = build_parts
+ foreach build : build_parts
+ if count < build_parts.length() - common.length()
+ rel += ['..']
+ endif
+ count += 1
+ endforeach
+
+ # Create path components to go up from the common path to the build root
+ count = 0
+ foreach src : src_parts
+ if count >= common.length()
+ rel += [src]
+ endif
+ count += 1
+ endforeach
+
+ build_to_src = '/'.join(rel)
+
+ if build_to_src.contains(' ')
+ message('build_to_src is: ' + build_to_src)
+ error('MESON_SKIP_TEST build_to_src has spaces')
+ endif
+ # Welcome to the end of this conditional.
+ # We hope you never have to implement something like this.
+endif
+
+subdir('inc')
+subdir('res')
+
+exe = executable('prog', 'prog.c',
+ res,
+ gui_app : true)
+
+test('winmain', exe)
diff --git a/test cases/windows/5 resources/prog.c b/test cases/windows/5 resources/prog.c
new file mode 100644
index 0000000..3409c39
--- /dev/null
+++ b/test cases/windows/5 resources/prog.c
@@ -0,0 +1,21 @@
+#include<windows.h>
+
+// deliberately don't get MY_ICON from resource.h so that depfile generation can
+// be exercised in the WindowsTests.test_rc_depends_files unit test
+#define MY_ICON 1
+
+int APIENTRY
+WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow) {
+ HICON hIcon;
+ hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MY_ICON));
+// avoid unused argument error while matching template
+ ((void)hInstance);
+ ((void)hPrevInstance);
+ ((void)lpszCmdLine);
+ ((void)nCmdShow);
+ return hIcon ? 0 : 1;
+}
diff --git a/test cases/windows/5 resources/res/dummy.c b/test cases/windows/5 resources/res/dummy.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/windows/5 resources/res/dummy.c
diff --git a/test cases/windows/5 resources/res/meson.build b/test cases/windows/5 resources/res/meson.build
new file mode 100644
index 0000000..74e0778
--- /dev/null
+++ b/test cases/windows/5 resources/res/meson.build
@@ -0,0 +1,10 @@
+win = import('windows')
+
+res = win.compile_resources('myres.rc',
+ depend_files: 'sample.ico',
+ include_directories : inc,
+ args : [['-DFOO'], '-DBAR'])
+
+# test that with MSVC tools, LIB/LINK invokes CVTRES with correct /MACHINE
+static_library('reslib', res, 'dummy.c')
+shared_library('shreslib', res, 'dummy.c')
diff --git a/test cases/windows/5 resources/res/myres.rc b/test cases/windows/5 resources/res/myres.rc
new file mode 100644
index 0000000..802bc7b
--- /dev/null
+++ b/test cases/windows/5 resources/res/myres.rc
@@ -0,0 +1,4 @@
+#include<windows.h>
+#include"resource.h"
+
+ICON_ID ICON "sample.ico"
diff --git a/test cases/windows/5 resources/res/sample.ico b/test cases/windows/5 resources/res/sample.ico
new file mode 100644
index 0000000..24bd3d9
--- /dev/null
+++ b/test cases/windows/5 resources/res/sample.ico
Binary files differ
diff --git a/test cases/windows/6 vs module defs/meson.build b/test cases/windows/6 vs module defs/meson.build
new file mode 100644
index 0000000..fb59028
--- /dev/null
+++ b/test cases/windows/6 vs module defs/meson.build
@@ -0,0 +1,5 @@
+project('dll_module_defs', 'c')
+
+subdir('subdir')
+exe = executable('prog', 'prog.c', link_with : shlib)
+test('runtest', exe)
diff --git a/test cases/windows/6 vs module defs/prog.c b/test cases/windows/6 vs module defs/prog.c
new file mode 100644
index 0000000..066ac22
--- /dev/null
+++ b/test cases/windows/6 vs module defs/prog.c
@@ -0,0 +1,5 @@
+int somedllfunc(void);
+
+int main(void) {
+ return somedllfunc() == 42 ? 0 : 1;
+}
diff --git a/test cases/windows/6 vs module defs/subdir/meson.build b/test cases/windows/6 vs module defs/subdir/meson.build
new file mode 100644
index 0000000..60633c3
--- /dev/null
+++ b/test cases/windows/6 vs module defs/subdir/meson.build
@@ -0,0 +1 @@
+shlib = shared_library('somedll', 'somedll.c', vs_module_defs : 'somedll.def')
diff --git a/test cases/windows/6 vs module defs/subdir/somedll.c b/test cases/windows/6 vs module defs/subdir/somedll.c
new file mode 100644
index 0000000..f095b18
--- /dev/null
+++ b/test cases/windows/6 vs module defs/subdir/somedll.c
@@ -0,0 +1,3 @@
+int somedllfunc(void) {
+ return 42;
+}
diff --git a/test cases/windows/6 vs module defs/subdir/somedll.def b/test cases/windows/6 vs module defs/subdir/somedll.def
new file mode 100644
index 0000000..60fd1a1
--- /dev/null
+++ b/test cases/windows/6 vs module defs/subdir/somedll.def
@@ -0,0 +1,2 @@
+EXPORTS
+ somedllfunc
diff --git a/test cases/windows/7 dll versioning/copyfile.py b/test cases/windows/7 dll versioning/copyfile.py
new file mode 100644
index 0000000..ff42ac3
--- /dev/null
+++ b/test cases/windows/7 dll versioning/copyfile.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
diff --git a/test cases/windows/7 dll versioning/exe.orig.c b/test cases/windows/7 dll versioning/exe.orig.c
new file mode 100644
index 0000000..1e8e90e
--- /dev/null
+++ b/test cases/windows/7 dll versioning/exe.orig.c
@@ -0,0 +1,8 @@
+int myFunc (void);
+
+int main(void)
+{
+ if (myFunc() == 55)
+ return 0;
+ return 1;
+}
diff --git a/test cases/windows/7 dll versioning/lib.c b/test cases/windows/7 dll versioning/lib.c
new file mode 100644
index 0000000..37e0d1d
--- /dev/null
+++ b/test cases/windows/7 dll versioning/lib.c
@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int myFunc(void) {
+ return 55;
+}
diff --git a/test cases/windows/7 dll versioning/meson.build b/test cases/windows/7 dll versioning/meson.build
new file mode 100644
index 0000000..983c2c4
--- /dev/null
+++ b/test cases/windows/7 dll versioning/meson.build
@@ -0,0 +1,54 @@
+project('msvc dll versioning', 'c')
+
+cc = meson.get_compiler('c')
+
+# Test that we create correctly-named dll and import lib files,
+# and also install them in the right place
+some = shared_library('some', 'lib.c',
+ version : '1.2.3',
+ soversion : '0',
+ install : true)
+
+noversion = shared_library('noversion', 'lib.c',
+ install : true)
+
+onlyversion = shared_library('onlyversion', 'lib.c',
+ version : '1.4.5',
+ install : true)
+
+onlysoversion = shared_library('onlysoversion', 'lib.c',
+ # Also test that int soversion is acceptable
+ soversion : 5,
+ install : true)
+
+# Hack to make the executables below depend on the shared libraries above
+# without actually adding them as `link_with` dependencies since we want to try
+# linking to them with -lfoo linker arguments.
+cp = find_program('copyfile.py')
+out = custom_target('library-dependency-hack',
+ input : 'exe.orig.c',
+ output : 'exe.c',
+ depends : [some, noversion, onlyversion, onlysoversion],
+ command : [cp, '@INPUT@', '@OUTPUT@'])
+
+# Manually test if the linker can find the above libraries
+# i.e., whether they were generated with the right naming scheme
+test('manually linked 1', executable('manuallink1', out,
+ link_args : ['-L.', '-lsome']))
+
+test('manually linked 2', executable('manuallink2', out,
+ link_args : ['-L.', '-lnoversion']))
+
+test('manually linked 3', executable('manuallink3', out,
+ link_args : ['-L.', '-lonlyversion']))
+
+test('manually linked 4', executable('manuallink4', out,
+ link_args : ['-L.', '-lonlysoversion']))
+
+shared_library('customdir', 'lib.c',
+ install : true,
+ install_dir : get_option('libexecdir'))
+
+shared_module('module', 'lib.c',
+ install : true,
+ install_dir: join_paths(get_option('libdir'), 'modules'))
diff --git a/test cases/windows/7 dll versioning/test.json b/test cases/windows/7 dll versioning/test.json
new file mode 100644
index 0000000..1402925
--- /dev/null
+++ b/test cases/windows/7 dll versioning/test.json
@@ -0,0 +1,34 @@
+{
+ "installed": [
+ {"type": "file", "platform": "msvc", "file": "usr/bin/some-0.dll"},
+ {"type": "pdb", "file": "usr/bin/some-0"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/some.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/noversion.dll"},
+ {"type": "pdb", "file": "usr/bin/noversion"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/noversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/onlyversion-1.dll"},
+ {"type": "pdb", "file": "usr/bin/onlyversion-1"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/onlyversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/onlysoversion-5.dll"},
+ {"type": "pdb", "file": "usr/bin/onlysoversion-5"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/onlysoversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/libexec/customdir.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/libexec/customdir.lib"},
+ {"type": "pdb", "file": "usr/libexec/customdir"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/modules/module.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/modules/module.lib"},
+ {"type": "pdb", "file": "usr/lib/modules/module"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libsome-0.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsome.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libnoversion.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libnoversion.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libonlyversion-1.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlyversion.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libonlysoversion-5.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlysoversion.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/libexec/?libcustomdir.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/libexec/libcustomdir.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/lib/modules/?libmodule.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/modules/libmodule.dll.a"}
+ ]
+}
diff --git a/test cases/windows/8 find program/meson.build b/test cases/windows/8 find program/meson.build
new file mode 100644
index 0000000..565fb62
--- /dev/null
+++ b/test cases/windows/8 find program/meson.build
@@ -0,0 +1,12 @@
+project('find program', 'c')
+
+# Test that we can find native windows executables
+find_program('cmd')
+find_program('cmd.exe')
+
+# Test that a script file with an extension can be found
+ext = find_program('test-script-ext.py')
+test('ext', ext)
+# Test that a script file without an extension can be found
+prog = find_program('test-script')
+test('script', prog)
diff --git a/test cases/windows/8 find program/test-script b/test cases/windows/8 find program/test-script
new file mode 100644
index 0000000..e764165
--- /dev/null
+++ b/test cases/windows/8 find program/test-script
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('1')
diff --git a/test cases/windows/8 find program/test-script-ext.py b/test cases/windows/8 find program/test-script-ext.py
new file mode 100644
index 0000000..ae9adfb
--- /dev/null
+++ b/test cases/windows/8 find program/test-script-ext.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python3
+
+print('ext/noext')
diff --git a/test cases/windows/9 vs module defs generated/meson.build b/test cases/windows/9 vs module defs generated/meson.build
new file mode 100644
index 0000000..7728ca7
--- /dev/null
+++ b/test cases/windows/9 vs module defs generated/meson.build
@@ -0,0 +1,5 @@
+project('generated_dll_module_defs', 'c')
+
+subdir('subdir')
+exe = executable('prog', 'prog.c', link_with : shlib)
+test('runtest', exe)
diff --git a/test cases/windows/9 vs module defs generated/prog.c b/test cases/windows/9 vs module defs generated/prog.c
new file mode 100644
index 0000000..066ac22
--- /dev/null
+++ b/test cases/windows/9 vs module defs generated/prog.c
@@ -0,0 +1,5 @@
+int somedllfunc(void);
+
+int main(void) {
+ return somedllfunc() == 42 ? 0 : 1;
+}
diff --git a/test cases/windows/9 vs module defs generated/subdir/meson.build b/test cases/windows/9 vs module defs generated/subdir/meson.build
new file mode 100644
index 0000000..356f83a
--- /dev/null
+++ b/test cases/windows/9 vs module defs generated/subdir/meson.build
@@ -0,0 +1,10 @@
+conf = configuration_data()
+conf.set('func', 'somedllfunc')
+def_file = configure_file(
+ input: 'somedll.def.in',
+ output: 'somedll.def',
+ configuration : conf,
+)
+
+shlib = shared_library('somedll', 'somedll.c', vs_module_defs : def_file)
+shmod = shared_module('somemod', 'somedll.c', vs_module_defs : def_file)
diff --git a/test cases/windows/9 vs module defs generated/subdir/somedll.c b/test cases/windows/9 vs module defs generated/subdir/somedll.c
new file mode 100644
index 0000000..f095b18
--- /dev/null
+++ b/test cases/windows/9 vs module defs generated/subdir/somedll.c
@@ -0,0 +1,3 @@
+int somedllfunc(void) {
+ return 42;
+}
diff --git a/test cases/windows/9 vs module defs generated/subdir/somedll.def.in b/test cases/windows/9 vs module defs generated/subdir/somedll.def.in
new file mode 100644
index 0000000..c29207c
--- /dev/null
+++ b/test cases/windows/9 vs module defs generated/subdir/somedll.def.in
@@ -0,0 +1,2 @@
+EXPORTS
+ @func@