diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-29 04:41:38 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-29 04:41:38 +0000 |
commit | 7b6e527f440cd7e6f8be2b07cee320ee6ca18786 (patch) | |
tree | 4a2738d69fa2814659fdadddf5826282e73d81f4 /test cases/common | |
parent | Initial commit. (diff) | |
download | meson-upstream.tar.xz meson-upstream.zip |
Adding upstream version 1.0.1.upstream/1.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
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 Binary files differnew file mode 100644 index 0000000..98e9ed9 --- /dev/null +++ b/test cases/common/14 configure file/invalid-utf8.bin.in 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew file mode 100644 index 0000000..ed1fefe --- /dev/null +++ b/test cases/common/234 get_file_contents/utf-16-text 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 Binary files differnew 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 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 |