summaryrefslogtreecommitdiffstats
path: root/test cases/native
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-29 04:41:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-29 04:41:38 +0000
commit7b6e527f440cd7e6f8be2b07cee320ee6ca18786 (patch)
tree4a2738d69fa2814659fdadddf5826282e73d81f4 /test cases/native
parentInitial commit. (diff)
downloadmeson-7b6e527f440cd7e6f8be2b07cee320ee6ca18786.tar.xz
meson-7b6e527f440cd7e6f8be2b07cee320ee6ca18786.zip
Adding upstream version 1.0.1.upstream/1.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test cases/native')
-rw-r--r--test cases/native/1 trivial/meson.build9
-rw-r--r--test cases/native/1 trivial/trivial.c6
-rw-r--r--test cases/native/2 global arg/meson.build14
-rw-r--r--test cases/native/2 global arg/prog.c43
-rw-r--r--test cases/native/2 global arg/prog.cc15
-rwxr-xr-xtest cases/native/3 pipeline/depends/copyrunner.py7
-rw-r--r--test cases/native/3 pipeline/depends/filecopier.c23
-rw-r--r--test cases/native/3 pipeline/depends/libsrc.c.in3
-rw-r--r--test cases/native/3 pipeline/depends/meson.build11
-rw-r--r--test cases/native/3 pipeline/depends/prog.c5
-rw-r--r--test cases/native/3 pipeline/input_src.dat1
-rw-r--r--test cases/native/3 pipeline/meson.build23
-rw-r--r--test cases/native/3 pipeline/prog.c5
-rw-r--r--test cases/native/3 pipeline/src/input_src.dat1
-rw-r--r--test cases/native/3 pipeline/src/meson.build12
-rw-r--r--test cases/native/3 pipeline/src/prog.c9
-rw-r--r--test cases/native/3 pipeline/src/srcgen.c40
-rw-r--r--test cases/native/3 pipeline/srcgen.c69
-rw-r--r--test cases/native/4 tryrun/error.c3
-rw-r--r--test cases/native/4 tryrun/meson.build78
-rw-r--r--test cases/native/4 tryrun/no_compile.c1
-rw-r--r--test cases/native/4 tryrun/ok.c7
-rw-r--r--test cases/native/5 install script/file.txt0
-rw-r--r--test cases/native/5 install script/meson.build12
-rw-r--r--test cases/native/5 install script/src/exe.c27
-rw-r--r--test cases/native/5 install script/src/meson.build1
-rw-r--r--test cases/native/5 install script/test.json8
-rwxr-xr-xtest cases/native/5 install script/wrap.py6
-rw-r--r--test cases/native/6 add language/meson.build3
-rw-r--r--test cases/native/6 add language/prog.cc6
-rw-r--r--test cases/native/7 selfbuilt custom/checkarg.cpp6
-rw-r--r--test cases/native/7 selfbuilt custom/data.dat1
-rw-r--r--test cases/native/7 selfbuilt custom/mainprog.cpp5
-rw-r--r--test cases/native/7 selfbuilt custom/meson.build39
-rw-r--r--test cases/native/7 selfbuilt custom/tool.cpp34
-rw-r--r--test cases/native/8 external program shebang parsing/input.txt1
-rw-r--r--test cases/native/8 external program shebang parsing/main.c72
-rw-r--r--test cases/native/8 external program shebang parsing/meson.build21
-rw-r--r--test cases/native/8 external program shebang parsing/script.int.in2
-rw-r--r--test cases/native/9 override with exe/main2.input0
-rw-r--r--test cases/native/9 override with exe/meson.build21
-rw-r--r--test cases/native/9 override with exe/subprojects/sub/foobar.c13
-rw-r--r--test cases/native/9 override with exe/subprojects/sub/meson.build3
43 files changed, 666 insertions, 0 deletions
diff --git a/test cases/native/1 trivial/meson.build b/test cases/native/1 trivial/meson.build
new file mode 100644
index 0000000..f6c5d4d
--- /dev/null
+++ b/test cases/native/1 trivial/meson.build
@@ -0,0 +1,9 @@
+project('trivial native test', 'c')
+
+sources = 'trivial.c'
+cc = meson.get_compiler('c', native: true)
+
+if meson.is_cross_build()
+ native_exe = executable('native-trivialprog', sources : sources, native : true)
+ test('native exe in cross build', native_exe)
+endif
diff --git a/test cases/native/1 trivial/trivial.c b/test cases/native/1 trivial/trivial.c
new file mode 100644
index 0000000..96612d4
--- /dev/null
+++ b/test cases/native/1 trivial/trivial.c
@@ -0,0 +1,6 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("Trivial test is working.\n");
+ return 0;
+}
diff --git a/test cases/native/2 global arg/meson.build b/test cases/native/2 global arg/meson.build
new file mode 100644
index 0000000..c303a02
--- /dev/null
+++ b/test cases/native/2 global arg/meson.build
@@ -0,0 +1,14 @@
+project('global arg test', 'cpp', 'c')
+
+add_global_arguments('-DMYTHING', language : 'c', native : true)
+add_global_arguments('-DMYCPPTHING', language : 'cpp', native : true)
+add_global_arguments('-DGLOBAL_BUILD', language : 'c', native : true)
+
+build_c_args = ['-DARG_BUILD']
+c_args = ['-DARG_HOST']
+
+add_global_arguments('-DMYCANDCPPTHING', language: ['c', 'cpp'], native: true)
+
+exe1 = executable('prog1', 'prog.c', c_args : build_c_args, native : true)
+
+test('prog1', exe1)
diff --git a/test cases/native/2 global arg/prog.c b/test cases/native/2 global arg/prog.c
new file mode 100644
index 0000000..2a71236
--- /dev/null
+++ b/test cases/native/2 global arg/prog.c
@@ -0,0 +1,43 @@
+#ifndef MYTHING
+ #error "Global argument not set"
+#endif
+
+#ifdef MYCPPTHING
+ #error "Wrong global argument set"
+#endif
+
+#ifndef MYCANDCPPTHING
+ #error "Global argument not set"
+#endif
+
+#if !defined(GLOBAL_HOST) && !defined(GLOBAL_BUILD)
+ #error "Neither global_host nor glogal_build is set."
+#endif
+
+#if defined(GLOBAL_HOST) && defined(GLOBAL_BUILD)
+ #error "Both global build and global host set."
+#endif
+
+#ifdef GLOBAL_BUILD
+ #ifndef ARG_BUILD
+ #error "Global is build but arg_build is not set."
+ #endif
+
+ #ifdef ARG_HOST
+ #error "Global is build but arg host is set."
+ #endif
+#endif
+
+#ifdef GLOBAL_HOST
+ #ifndef ARG_HOST
+ #error "Global is host but arg_host is not set."
+ #endif
+
+ #ifdef ARG_BUILD
+ #error "Global is host but arg_build is set."
+ #endif
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/native/2 global arg/prog.cc b/test cases/native/2 global arg/prog.cc
new file mode 100644
index 0000000..5c32209
--- /dev/null
+++ b/test cases/native/2 global arg/prog.cc
@@ -0,0 +1,15 @@
+#ifdef MYTHING
+#error "Wrong global argument set"
+#endif
+
+#ifndef MYCPPTHING
+#error "Global argument not set"
+#endif
+
+#ifndef MYCANDCPPTHING
+#error "Global argument not set"
+#endif
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/native/3 pipeline/depends/copyrunner.py b/test cases/native/3 pipeline/depends/copyrunner.py
new file mode 100755
index 0000000..0ef6a6d
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/copyrunner.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys, subprocess
+
+prog, infile, outfile = sys.argv[1:]
+
+subprocess.check_call([prog, infile, outfile])
diff --git a/test cases/native/3 pipeline/depends/filecopier.c b/test cases/native/3 pipeline/depends/filecopier.c
new file mode 100644
index 0000000..e10e4e7
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/filecopier.c
@@ -0,0 +1,23 @@
+#include<stdio.h>
+#include<assert.h>
+
+#define BUFSIZE 1024
+
+int main(int argc, char **argv) {
+ char buffer[BUFSIZE];
+ size_t num_read;
+ size_t num_written;
+ FILE *fin = fopen(argv[1], "rb");
+ FILE *fout;
+ assert(argc>0);
+ assert(fin);
+ num_read = fread(buffer, 1, BUFSIZE, fin);
+ assert(num_read > 0);
+ fclose(fin);
+ fout = fopen(argv[2], "wb");
+ assert(fout);
+ num_written = fwrite(buffer, 1, num_read, fout);
+ assert(num_written == num_read);
+ fclose(fout);
+ return 0;
+}
diff --git a/test cases/native/3 pipeline/depends/libsrc.c.in b/test cases/native/3 pipeline/depends/libsrc.c.in
new file mode 100644
index 0000000..8180551
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/libsrc.c.in
@@ -0,0 +1,3 @@
+int func(void) {
+ return 42;
+}
diff --git a/test cases/native/3 pipeline/depends/meson.build b/test cases/native/3 pipeline/depends/meson.build
new file mode 100644
index 0000000..5111fee
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/meson.build
@@ -0,0 +1,11 @@
+runner = find_program('copyrunner.py')
+
+copier = executable('copier', 'filecopier.c', native: true)
+
+cg = generator(runner,
+ output: ['@BASENAME@.c'],
+ arguments: [copier.full_path(), '@INPUT@', '@OUTPUT@'],
+ depends: copier)
+
+test('generatordep',
+ executable('gd', 'prog.c', cg.process('libsrc.c.in')))
diff --git a/test cases/native/3 pipeline/depends/prog.c b/test cases/native/3 pipeline/depends/prog.c
new file mode 100644
index 0000000..54c40e1
--- /dev/null
+++ b/test cases/native/3 pipeline/depends/prog.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func() != 42;
+}
diff --git a/test cases/native/3 pipeline/input_src.dat b/test cases/native/3 pipeline/input_src.dat
new file mode 100644
index 0000000..a324dca
--- /dev/null
+++ b/test cases/native/3 pipeline/input_src.dat
@@ -0,0 +1 @@
+int func(void) { return 0; }
diff --git a/test cases/native/3 pipeline/meson.build b/test cases/native/3 pipeline/meson.build
new file mode 100644
index 0000000..e12cb7b
--- /dev/null
+++ b/test cases/native/3 pipeline/meson.build
@@ -0,0 +1,23 @@
+project('pipeline test', 'c')
+
+# We need to run this executable locally so build it with
+# the host compiler.
+e1 = executable('srcgen', 'srcgen.c', native : true)
+
+# Generate a source file that needs to be included in the build.
+gen = generator(e1, \
+ depfile : '@BASENAME@.d',
+ output : '@BASENAME@.c', # Line continuation inside arguments should work without needing a "\".
+ arguments : ['@INPUT@', '@OUTPUT@', '@DEPFILE@'])
+
+generated = gen.process(['input_src.dat'])
+
+e2 = executable('prog', 'prog.c', generated)
+
+test('pipelined', e2)
+
+# This is in a subdirectory to make sure
+# we write proper subdir paths to output.
+subdir('src')
+
+subdir('depends')
diff --git a/test cases/native/3 pipeline/prog.c b/test cases/native/3 pipeline/prog.c
new file mode 100644
index 0000000..128f2bb
--- /dev/null
+++ b/test cases/native/3 pipeline/prog.c
@@ -0,0 +1,5 @@
+int func(void);
+
+int main(void) {
+ return func();
+}
diff --git a/test cases/native/3 pipeline/src/input_src.dat b/test cases/native/3 pipeline/src/input_src.dat
new file mode 100644
index 0000000..354499a
--- /dev/null
+++ b/test cases/native/3 pipeline/src/input_src.dat
@@ -0,0 +1 @@
+#include<stdio.h>
diff --git a/test cases/native/3 pipeline/src/meson.build b/test cases/native/3 pipeline/src/meson.build
new file mode 100644
index 0000000..4e9ac11
--- /dev/null
+++ b/test cases/native/3 pipeline/src/meson.build
@@ -0,0 +1,12 @@
+e1 = executable('srcgen', 'srcgen.c', native : true)
+
+# Generate a header file that needs to be included.
+gen = generator(e1,
+ output : '@BASENAME@.h',
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+generated = gen.process('input_src.dat')
+
+e2 = executable('prog', 'prog.c', generated)
+
+test('pipelined', e2)
diff --git a/test cases/native/3 pipeline/src/prog.c b/test cases/native/3 pipeline/src/prog.c
new file mode 100644
index 0000000..83121b5
--- /dev/null
+++ b/test cases/native/3 pipeline/src/prog.c
@@ -0,0 +1,9 @@
+#include"input_src.h"
+
+int main(void) {
+ void *foo = printf;
+ if(foo) {
+ return 0;
+ }
+ return 1;
+}
diff --git a/test cases/native/3 pipeline/src/srcgen.c b/test cases/native/3 pipeline/src/srcgen.c
new file mode 100644
index 0000000..26761d2
--- /dev/null
+++ b/test cases/native/3 pipeline/src/srcgen.c
@@ -0,0 +1,40 @@
+#include<stdio.h>
+#include<assert.h>
+
+#define ARRSIZE 80
+
+int main(int argc, char **argv) {
+ char arr[ARRSIZE];
+ char *ifilename;
+ char *ofilename;
+ FILE *ifile;
+ FILE *ofile;
+ size_t bytes;
+
+ if(argc != 3) {
+ fprintf(stderr, "%s <input file> <output file>\n", argv[0]);
+ return 1;
+ }
+ ifilename = argv[1];
+ ofilename = argv[2];
+ printf("%s\n", ifilename);
+ ifile = fopen(ifilename, "r");
+ if(!ifile) {
+ fprintf(stderr, "Could not open source file %s.\n", ifilename);
+ return 1;
+ }
+ ofile = fopen(ofilename, "w");
+ if(!ofile) {
+ fprintf(stderr, "Could not open target file %s\n", ofilename);
+ fclose(ifile);
+ return 1;
+ }
+ bytes = fread(arr, 1, ARRSIZE, ifile);
+ assert(bytes < 80);
+ assert(bytes > 0);
+ fwrite(arr, 1, bytes, ofile);
+
+ fclose(ifile);
+ fclose(ofile);
+ return 0;
+}
diff --git a/test cases/native/3 pipeline/srcgen.c b/test cases/native/3 pipeline/srcgen.c
new file mode 100644
index 0000000..ceb9ecc
--- /dev/null
+++ b/test cases/native/3 pipeline/srcgen.c
@@ -0,0 +1,69 @@
+#include<stdio.h>
+#include<assert.h>
+#include<string.h>
+
+#define ARRSIZE 80
+
+int main(int argc, char **argv) {
+ char arr[ARRSIZE];
+ char *ofilename;
+ char *ifilename;
+ char *dfilename;
+ FILE *ifile;
+ FILE *ofile;
+ FILE *depfile;
+ size_t bytes;
+ int i;
+
+ if(argc != 4) {
+ fprintf(stderr, "%s <input file> <output file> <dependency file>\n", argv[0]);
+ return 1;
+ }
+ ifilename = argv[1];
+ ofilename = argv[2];
+ dfilename = argv[3];
+ ifile = fopen(argv[1], "r");
+ if(!ifile) {
+ fprintf(stderr, "Could not open source file %s.\n", argv[1]);
+ return 1;
+ }
+ ofile = fopen(ofilename, "w");
+ if(!ofile) {
+ fprintf(stderr, "Could not open target file %s\n", ofilename);
+ fclose(ifile);
+ return 1;
+ }
+ bytes = fread(arr, 1, ARRSIZE, ifile);
+ assert(bytes < 80);
+ assert(bytes > 0);
+ fwrite(arr, 1, bytes, ofile);
+
+ depfile = fopen(dfilename, "w");
+ if(!depfile) {
+ fprintf(stderr, "Could not open depfile %s\n", ofilename);
+ fclose(ifile);
+ fclose(ofile);
+ return 1;
+ }
+ for(i=0; i<strlen(ofilename); i++) {
+ if(ofilename[i] == ' ') {
+ fwrite("\\ ", 1, 2, depfile);
+ } else {
+ fwrite(&ofilename[i], 1, 1, depfile);
+ }
+ }
+ fwrite(": ", 1, 2, depfile);
+ for(i=0; i<strlen(ifilename); i++) {
+ if(ifilename[i] == ' ') {
+ fwrite("\\ ", 1, 2, depfile);
+ } else {
+ fwrite(&ifilename[i], 1, 1, depfile);
+ }
+ }
+ fwrite("\n", 1, 1, depfile);
+
+ fclose(ifile);
+ fclose(ofile);
+ fclose(depfile);
+ return 0;
+}
diff --git a/test cases/native/4 tryrun/error.c b/test cases/native/4 tryrun/error.c
new file mode 100644
index 0000000..53ef08e
--- /dev/null
+++ b/test cases/native/4 tryrun/error.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 1;
+}
diff --git a/test cases/native/4 tryrun/meson.build b/test cases/native/4 tryrun/meson.build
new file mode 100644
index 0000000..5580974
--- /dev/null
+++ b/test cases/native/4 tryrun/meson.build
@@ -0,0 +1,78 @@
+project('tryrun', 'c', 'cpp')
+
+# Complex to exercise all code paths.
+if meson.is_cross_build()
+ if meson.can_run_host_binaries()
+ compilers = [meson.get_compiler('c', native : false), meson.get_compiler('cpp', native : false)]
+ else
+ compilers = [meson.get_compiler('c', native : true), meson.get_compiler('cpp', native : true)]
+ endif
+else
+ compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
+endif
+
+ok_code = '''#include<stdio.h>
+int main(void) {
+ printf("%s\n", "stdout");
+ fprintf(stderr, "%s\n", "stderr");
+ return 0;
+}
+'''
+
+error_code = '''int main(void) {
+ return 1;
+}
+'''
+
+no_compile_code = '''int main(void) {
+'''
+
+INPUTS = [
+ ['String', ok_code, error_code, no_compile_code],
+ ['File', files('ok.c'), files('error.c'), files('no_compile.c')],
+]
+
+foreach cc : compilers
+ foreach input : INPUTS
+ type = input[0]
+ ok = cc.run(input[1], name : type + ' should succeed')
+ err = cc.run(input[2], name : type + ' should fail')
+ noc = cc.run(input[3], name : type + ' does not compile')
+
+ if noc.compiled()
+ error(type + ' compilation fail test failed.')
+ else
+ message(type + ' fail detected properly.')
+ endif
+
+ if ok.compiled()
+ message(type + ' compilation worked.')
+ else
+ error(type + ' compilation did not work.')
+ endif
+
+ if ok.returncode() == 0
+ message(type + ' return code ok.')
+ else
+ error(type + ' return code fail')
+ endif
+
+ if err.returncode() == 1
+ message(type + ' bad return code ok.')
+ else
+ error(type + ' bad return code fail.')
+ endif
+
+ if ok.stdout().strip() == 'stdout'
+ message(type + ' stdout ok.')
+ else
+ message(type + ' bad stdout.')
+ endif
+
+ if ok.stderr().strip() == 'stderr'
+ message(type + ' stderr ok.')
+ else
+ message(type + ' bad stderr.')
+ endif
+ endforeach
+endforeach
diff --git a/test cases/native/4 tryrun/no_compile.c b/test cases/native/4 tryrun/no_compile.c
new file mode 100644
index 0000000..496c2e8
--- /dev/null
+++ b/test cases/native/4 tryrun/no_compile.c
@@ -0,0 +1 @@
+int main(void) {
diff --git a/test cases/native/4 tryrun/ok.c b/test cases/native/4 tryrun/ok.c
new file mode 100644
index 0000000..e2a36c8
--- /dev/null
+++ b/test cases/native/4 tryrun/ok.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+
+int main(void) {
+ printf("%s\n", "stdout");
+ fprintf(stderr, "%s\n", "stderr");
+ return 0;
+}
diff --git a/test cases/native/5 install script/file.txt b/test cases/native/5 install script/file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/native/5 install script/file.txt
diff --git a/test cases/native/5 install script/meson.build b/test cases/native/5 install script/meson.build
new file mode 100644
index 0000000..8a69a0d
--- /dev/null
+++ b/test cases/native/5 install script/meson.build
@@ -0,0 +1,12 @@
+project('custom install script', 'c')
+
+# this is just to ensure that the install directory exists before exe is run
+install_data('file.txt', install_dir: '.')
+
+subdir('src')
+
+meson.add_install_script(exe, 'generated.txt')
+wrap = find_program('wrap.py')
+# Yes, these are getting silly
+meson.add_install_script(wrap, exe, 'wrapped.txt')
+meson.add_install_script(wrap, wrap, exe, 'wrapped2.txt')
diff --git a/test cases/native/5 install script/src/exe.c b/test cases/native/5 install script/src/exe.c
new file mode 100644
index 0000000..2df3ee8
--- /dev/null
+++ b/test cases/native/5 install script/src/exe.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char * argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "Takes exactly 2 arguments\n");
+ return 1;
+ }
+
+ char * dirname = getenv("MESON_INSTALL_DESTDIR_PREFIX");
+ char * fullname = malloc(strlen(dirname) + 1 + strlen(argv[1]) + 1);
+ strcpy(fullname, dirname);
+ strcat(fullname, "/");
+ strcat(fullname, argv[1]);
+
+ FILE * fp = fopen(fullname, "w");
+ if (!fp)
+ return 1;
+
+ fputs("Some text\n", fp);
+ fclose(fp);
+
+ free(fullname);
+
+ return 0;
+}
diff --git a/test cases/native/5 install script/src/meson.build b/test cases/native/5 install script/src/meson.build
new file mode 100644
index 0000000..f60c995
--- /dev/null
+++ b/test cases/native/5 install script/src/meson.build
@@ -0,0 +1 @@
+exe = executable('exe', 'exe.c', install : false, native : true)
diff --git a/test cases/native/5 install script/test.json b/test cases/native/5 install script/test.json
new file mode 100644
index 0000000..c41c27c
--- /dev/null
+++ b/test cases/native/5 install script/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/file.txt"},
+ {"type": "file", "file": "usr/generated.txt"},
+ {"type": "file", "file": "usr/wrapped.txt"},
+ {"type": "file", "file": "usr/wrapped2.txt"}
+ ]
+}
diff --git a/test cases/native/5 install script/wrap.py b/test cases/native/5 install script/wrap.py
new file mode 100755
index 0000000..87508e0
--- /dev/null
+++ b/test cases/native/5 install script/wrap.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import subprocess
+import sys
+
+subprocess.run(sys.argv[1:])
diff --git a/test cases/native/6 add language/meson.build b/test cases/native/6 add language/meson.build
new file mode 100644
index 0000000..a7aad73
--- /dev/null
+++ b/test cases/native/6 add language/meson.build
@@ -0,0 +1,3 @@
+project('add language', 'c')
+assert(add_languages('cpp', native: true), 'Add_languages returned false on success')
+test('C++', executable('cppprog', 'prog.cc', native: true))
diff --git a/test cases/native/6 add language/prog.cc b/test cases/native/6 add language/prog.cc
new file mode 100644
index 0000000..03647dd
--- /dev/null
+++ b/test cases/native/6 add language/prog.cc
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int, char**) {
+ std::cout << "I am C++.\n";
+ return 0;
+}
diff --git a/test cases/native/7 selfbuilt custom/checkarg.cpp b/test cases/native/7 selfbuilt custom/checkarg.cpp
new file mode 100644
index 0000000..99092ee
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/checkarg.cpp
@@ -0,0 +1,6 @@
+#include <cassert>
+
+int main(int argc, char *[]) {
+ assert(argc == 2);
+ return 0;
+}
diff --git a/test cases/native/7 selfbuilt custom/data.dat b/test cases/native/7 selfbuilt custom/data.dat
new file mode 100644
index 0000000..83fd1d9
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/data.dat
@@ -0,0 +1 @@
+generated_function
diff --git a/test cases/native/7 selfbuilt custom/mainprog.cpp b/test cases/native/7 selfbuilt custom/mainprog.cpp
new file mode 100644
index 0000000..bb45dca
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/mainprog.cpp
@@ -0,0 +1,5 @@
+#include"data.h"
+
+int main(void) {
+ return generated_function() != 52;
+}
diff --git a/test cases/native/7 selfbuilt custom/meson.build b/test cases/native/7 selfbuilt custom/meson.build
new file mode 100644
index 0000000..b536352
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/meson.build
@@ -0,0 +1,39 @@
+project('selfbuilt custom', 'cpp')
+
+# Build an exe and use it in a custom target
+# whose output is used to build a different exe.
+
+tool = executable('tool', 'tool.cpp', native : true)
+
+hfile = custom_target('datah',
+ output : 'data.h',
+ input : 'data.dat',
+ command : [tool, '@INPUT@', '@OUTPUT@'],
+)
+
+main = executable('mainprog', 'mainprog.cpp', hfile)
+
+test('maintest', main)
+
+lib = library('libtool', 'tool.cpp')
+
+checkarg = executable('checkarg', 'checkarg.cpp', native : true)
+
+ctlib = custom_target('ctlib',
+ output : 'ctlib.out',
+ capture : true,
+ command : [checkarg, lib],
+ build_by_default : true,
+)
+
+if meson.is_cross_build() and meson.can_run_host_binaries()
+ checkarg_host = executable('checkarg_host', 'checkarg.cpp')
+
+ ctlib_host = custom_target(
+ 'ctlib_host',
+ output : 'ctlib.host.out',
+ capture : true,
+ command : [checkarg_host, lib],
+ build_by_default : true,
+ )
+endif
diff --git a/test cases/native/7 selfbuilt custom/tool.cpp b/test cases/native/7 selfbuilt custom/tool.cpp
new file mode 100644
index 0000000..6a28dd8
--- /dev/null
+++ b/test cases/native/7 selfbuilt custom/tool.cpp
@@ -0,0 +1,34 @@
+#include<iostream>
+#include<fstream>
+#include<string>
+
+using namespace std;
+
+const char prefix[] = "int ";
+const char suffix[] = " () {\n return 52;}\n";
+
+int main(int argc, char **argv) {
+ if(argc != 3) {
+ cout << "You is fail.\n";
+ return 1;
+ }
+ ifstream is(argv[1], ifstream::binary);
+ if(!is) {
+ cout << "Opening input file failed.\n";
+ return 1;
+ }
+ string funcname;
+ is >> funcname;
+ ofstream os(argv[2], ofstream::binary);
+ if(!os) {
+ cout << "Opening output file failed.\n";
+ return 1;
+ }
+ os << prefix << funcname << suffix;
+ os.close();
+ if(!os.good()) {
+ cout << "Writing data out failed.\n";
+ return 1;
+ }
+ return 0;
+}
diff --git a/test cases/native/8 external program shebang parsing/input.txt b/test cases/native/8 external program shebang parsing/input.txt
new file mode 100644
index 0000000..40e30d4
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/input.txt
@@ -0,0 +1 @@
+some stuff here
diff --git a/test cases/native/8 external program shebang parsing/main.c b/test cases/native/8 external program shebang parsing/main.c
new file mode 100644
index 0000000..48b080e
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/main.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#ifdef _WIN32
+ #include <io.h>
+ #include <windows.h>
+#else
+ #include <unistd.h>
+#endif
+
+/* Who cares about stack sizes in test programs anyway */
+#define LINE_LENGTH 4096
+
+static int
+intrp_copyfile (char * src, char * dest)
+{
+#ifdef _WIN32
+ if (!CopyFile (src, dest, FALSE))
+ return 1;
+ return 0;
+#else
+ return execlp ("cp", "cp", src, dest, NULL);
+#endif
+}
+
+static void
+parser_get_line (FILE * f, char line[LINE_LENGTH])
+{
+ if (!fgets (line, LINE_LENGTH, f))
+ fprintf (stderr, "%s\n", strerror (errno));
+}
+
+int
+main (int argc, char * argv[])
+{
+ FILE *f = NULL;
+ char line[LINE_LENGTH];
+
+ if (argc != 4) {
+ fprintf (stderr, "Invalid number of arguments: %i\n", argc);
+ goto err;
+ }
+
+ if ((f = fopen (argv[1], "r")) == NULL) {
+ fprintf (stderr, "%s\n", strerror (errno));
+ goto err;
+ }
+
+ parser_get_line (f, line);
+
+ if (!line || line[0] != '#' || line[1] != '!') {
+ fprintf (stderr, "Invalid script\n");
+ goto err;
+ }
+
+ parser_get_line (f, line);
+
+ if (!line || strncmp (line, "copy", 4) != 0) {
+ fprintf (stderr, "Syntax error: %s\n", line);
+ goto err;
+ }
+
+ return intrp_copyfile (argv[2], argv[3]);
+
+err:
+ fclose (f);
+ return 1;
+}
diff --git a/test cases/native/8 external program shebang parsing/meson.build b/test cases/native/8 external program shebang parsing/meson.build
new file mode 100644
index 0000000..c1cc5af
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/meson.build
@@ -0,0 +1,21 @@
+project('shebang parsing', 'c')
+
+interpreter = executable('aninterp', 'main.c', native : true)
+
+cdata = configuration_data()
+cdata.set('INTRP', interpreter.full_path())
+
+f = configure_file(input : 'script.int.in',
+ output : 'script.int',
+ configuration : cdata)
+
+# Test that parsing a shebang with spaces works properly. See `man execve`,
+# specifically the section on "Interpreter scripts" and the one under "NOTES".
+script = find_program(f)
+
+custom_target('interpthis',
+ input : 'input.txt',
+ output : 'output.txt',
+ depends : interpreter,
+ command : [script, '@INPUT@', '@OUTPUT@'],
+ build_by_default : true)
diff --git a/test cases/native/8 external program shebang parsing/script.int.in b/test cases/native/8 external program shebang parsing/script.int.in
new file mode 100644
index 0000000..77ff909
--- /dev/null
+++ b/test cases/native/8 external program shebang parsing/script.int.in
@@ -0,0 +1,2 @@
+#!/usr/bin/env @INTRP@
+copy
diff --git a/test cases/native/9 override with exe/main2.input b/test cases/native/9 override with exe/main2.input
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/native/9 override with exe/main2.input
diff --git a/test cases/native/9 override with exe/meson.build b/test cases/native/9 override with exe/meson.build
new file mode 100644
index 0000000..5275532
--- /dev/null
+++ b/test cases/native/9 override with exe/meson.build
@@ -0,0 +1,21 @@
+project('myexe', 'c', version: '0.1')
+sub = subproject('sub')
+
+prog = find_program('foobar', version : '>= 2.0', required : false)
+assert(not prog.found())
+
+prog = find_program('foobar', version : '>= 1.0')
+custom1 = custom_target('custom1',
+ build_by_default : true,
+ input : [],
+ output : 'main1.c',
+ command : [prog, '@OUTPUT@'])
+gen = generator(prog,
+ output : '@BASENAME@.c',
+ arguments : ['@OUTPUT@'])
+custom2 = gen.process('main2.input')
+
+message(prog.full_path())
+
+executable('e1', custom1)
+executable('e2', custom2)
diff --git a/test cases/native/9 override with exe/subprojects/sub/foobar.c b/test cases/native/9 override with exe/subprojects/sub/foobar.c
new file mode 100644
index 0000000..c21d450
--- /dev/null
+++ b/test cases/native/9 override with exe/subprojects/sub/foobar.c
@@ -0,0 +1,13 @@
+#include <assert.h>
+#include <stdio.h>
+
+int main(int argc, char* argv[]) {
+ assert(argc == 2);
+ FILE *f = fopen(argv[1], "w");
+ const char msg[] = "int main(void) {return 0;}\n";
+ size_t w = fwrite(msg, 1, sizeof(msg) - 1, f);
+ assert(w == sizeof(msg) - 1);
+ int r = fclose(f);
+ assert(r == 0);
+ return 0;
+}
diff --git a/test cases/native/9 override with exe/subprojects/sub/meson.build b/test cases/native/9 override with exe/subprojects/sub/meson.build
new file mode 100644
index 0000000..f0343b2
--- /dev/null
+++ b/test cases/native/9 override with exe/subprojects/sub/meson.build
@@ -0,0 +1,3 @@
+project('sub', 'c', version : '1.0')
+foobar = executable('foobar', 'foobar.c', native : true)
+meson.override_find_program('foobar', foobar)