summaryrefslogtreecommitdiffstats
path: root/test cases/common
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-29 04:41:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-29 04:41:38 +0000
commit7b6e527f440cd7e6f8be2b07cee320ee6ca18786 (patch)
tree4a2738d69fa2814659fdadddf5826282e73d81f4 /test cases/common
parentInitial commit. (diff)
downloadmeson-7b6e527f440cd7e6f8be2b07cee320ee6ca18786.tar.xz
meson-7b6e527f440cd7e6f8be2b07cee320ee6ca18786.zip
Adding upstream version 1.0.1.upstream/1.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-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
1352 files changed, 17032 insertions, 0 deletions
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