# SPDX-License-Identifier: Apache-2.0
# Copyright 2016-2021 The Meson development team

from __future__ import annotations

import subprocess
import tempfile
import textwrap
import os
import shutil
import functools
import threading
import sys
from itertools import chain
from unittest import mock, skipIf, SkipTest, TestCase
from pathlib import Path
import typing as T

import mesonbuild.mlog
import mesonbuild.depfile
import mesonbuild.dependencies.factory
import mesonbuild.envconfig
import mesonbuild.environment
import mesonbuild.coredata
import mesonbuild.modules.gnome

from mesonbuild import machinefile

from mesonbuild.mesonlib import (
    MachineChoice, is_windows, is_osx, is_cygwin, is_haiku, is_sunos
)
from mesonbuild.compilers import (
    detect_swift_compiler, compiler_from_language
)
import mesonbuild.modules.pkgconfig


from run_tests import (
    Backend,
    get_fake_env
)

from .baseplatformtests import BasePlatformTests
from .helpers import *

@functools.lru_cache()
def is_real_gnu_compiler(path):
    '''
    Check if the gcc we have is a real gcc and not a macOS wrapper around clang
    '''
    if not path:
        return False
    out = subprocess.check_output([path, '--version'], encoding='utf-8', universal_newlines=True, stderr=subprocess.STDOUT)
    return 'Free Software Foundation' in out

cross_dir = Path(__file__).parent.parent / 'cross'

class MachineFileStoreTests(TestCase):

    def test_loading(self):
        store = machinefile.MachineFileStore([cross_dir / 'ubuntu-armhf.txt'], [], str(cross_dir))
        self.assertIsNotNone(store)

class NativeFileTests(BasePlatformTests):

    def setUp(self):
        super().setUp()
        self.testcase = os.path.join(self.unit_test_dir, '46 native file binary')
        self.current_config = 0
        self.current_wrapper = 0

    def helper_create_native_file(self, values: T.Dict[str, T.Dict[str, T.Union[str, int, float, bool, T.Sequence[T.Union[str, int, float, bool]]]]]) -> str:
        """Create a config file as a temporary file.

        values should be a nested dictionary structure of {section: {key:
        value}}
        """
        filename = os.path.join(self.builddir, f'generated{self.current_config}.config')
        self.current_config += 1
        with open(filename, 'wt', encoding='utf-8') as f:
            for section, entries in values.items():
                f.write(f'[{section}]\n')
                for k, v in entries.items():
                    if isinstance(v, (bool, int, float)):
                        f.write(f"{k}={v}\n")
                    elif isinstance(v, str):
                        f.write(f"{k}='{v}'\n")
                    else:
                        f.write("{}=[{}]\n".format(k, ', '.join([f"'{w}'" for w in v])))
        return filename

    def helper_create_binary_wrapper(self, binary, dir_=None, extra_args=None, **kwargs):
        """Creates a wrapper around a binary that overrides specific values."""
        filename = os.path.join(dir_ or self.builddir, f'binary_wrapper{self.current_wrapper}.py')
        extra_args = extra_args or {}
        self.current_wrapper += 1
        if is_haiku():
            chbang = '#!/bin/env python3'
        else:
            chbang = '#!/usr/bin/env python3'

        with open(filename, 'wt', encoding='utf-8') as f:
            f.write(textwrap.dedent('''\
                {}
                import argparse
                import subprocess
                import sys

                def main():
                    parser = argparse.ArgumentParser()
                '''.format(chbang)))
            for name in chain(extra_args, kwargs):
                f.write('    parser.add_argument("-{0}", "--{0}", action="store_true")\n'.format(name))
            f.write('    args, extra_args = parser.parse_known_args()\n')
            for name, value in chain(extra_args.items(), kwargs.items()):
                f.write(f'    if args.{name}:\n')
                f.write('        print("{}", file=sys.{})\n'.format(value, kwargs.get('outfile', 'stdout')))
                f.write('        sys.exit(0)\n')
            f.write(textwrap.dedent('''
                    ret = subprocess.run(
                        ["{}"] + extra_args,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)
                    print(ret.stdout.decode('utf-8'))
                    print(ret.stderr.decode('utf-8'), file=sys.stderr)
                    sys.exit(ret.returncode)

                if __name__ == '__main__':
                    main()
                '''.format(binary)))

        if not is_windows():
            os.chmod(filename, 0o755)
            return filename

        # On windows we need yet another level of indirection, as cmd cannot
        # invoke python files itself, so instead we generate a .bat file, which
        # invokes our python wrapper
        batfile = os.path.join(self.builddir, f'binary_wrapper{self.current_wrapper}.bat')
        with open(batfile, 'wt', encoding='utf-8') as f:
            f.write(fr'@{sys.executable} {filename} %*')
        return batfile

    def helper_for_compiler(self, lang, cb, for_machine = MachineChoice.HOST):
        """Helper for generating tests for overriding compilers for languages
        with more than one implementation, such as C, C++, ObjC, ObjC++, and D.
        """
        env = get_fake_env()
        getter = lambda: compiler_from_language(env, lang, for_machine)
        cc = getter()
        binary, newid = cb(cc)
        env.binaries[for_machine].binaries[lang] = binary
        compiler = getter()
        self.assertEqual(compiler.id, newid)

    def test_multiple_native_files_override(self):
        wrapper = self.helper_create_binary_wrapper('bash', version='foo')
        config = self.helper_create_native_file({'binaries': {'bash': wrapper}})
        wrapper = self.helper_create_binary_wrapper('bash', version='12345')
        config2 = self.helper_create_native_file({'binaries': {'bash': wrapper}})
        self.init(self.testcase, extra_args=[
            '--native-file', config, '--native-file', config2,
            '-Dcase=find_program'])

    # This test hangs on cygwin.
    @skipIf(os.name != 'posix' or is_cygwin(), 'Uses fifos, which are not available on non Unix OSes.')
    def test_native_file_is_pipe(self):
        fifo = os.path.join(self.builddir, 'native.file')
        os.mkfifo(fifo)
        with tempfile.TemporaryDirectory() as d:
            wrapper = self.helper_create_binary_wrapper('bash', d, version='12345')

            def filler():
                with open(fifo, 'w', encoding='utf-8') as f:
                    f.write('[binaries]\n')
                    f.write(f"bash = '{wrapper}'\n")

            thread = threading.Thread(target=filler)
            thread.start()

            self.init(self.testcase, extra_args=['--native-file', fifo, '-Dcase=find_program'])

            thread.join()
            os.unlink(fifo)

            self.init(self.testcase, extra_args=['--wipe'])

    def test_multiple_native_files(self):
        wrapper = self.helper_create_binary_wrapper('bash', version='12345')
        config = self.helper_create_native_file({'binaries': {'bash': wrapper}})
        wrapper = self.helper_create_binary_wrapper('python')
        config2 = self.helper_create_native_file({'binaries': {'python': wrapper}})
        self.init(self.testcase, extra_args=[
            '--native-file', config, '--native-file', config2,
            '-Dcase=find_program'])

    def _simple_test(self, case, binary, entry=None):
        wrapper = self.helper_create_binary_wrapper(binary, version='12345')
        config = self.helper_create_native_file({'binaries': {entry or binary: wrapper}})
        self.init(self.testcase, extra_args=['--native-file', config, f'-Dcase={case}'])

    def test_find_program(self):
        self._simple_test('find_program', 'bash')

    def test_config_tool_dep(self):
        # Do the skip at this level to avoid screwing up the cache
        if mesonbuild.environment.detect_msys2_arch():
            raise SkipTest('Skipped due to problems with LLVM on MSYS2')
        if not shutil.which('llvm-config'):
            raise SkipTest('No llvm-installed, cannot test')
        self._simple_test('config_dep', 'llvm-config')

    def test_python3_module(self):
        self._simple_test('python3', 'python3')

    def test_python_module(self):
        if is_windows():
            # Bat adds extra crap to stdout, so the version check logic in the
            # python module breaks. This is fine on other OSes because they
            # don't need the extra indirection.
            raise SkipTest('bat indirection breaks internal sanity checks.')
        elif is_osx():
            binary = 'python'
        else:
            binary = 'python2'

            # We not have python2, check for it
            for v in ['2', '2.7', '-2.7']:
                try:
                    rc = subprocess.call(['pkg-config', '--cflags', f'python{v}'],
                                         stdout=subprocess.DEVNULL,
                                         stderr=subprocess.DEVNULL)
                except FileNotFoundError:
                    raise SkipTest('Not running Python 2 tests because pkg-config not found.')
                if rc == 0:
                    break
            else:
                raise SkipTest('Not running Python 2 tests because dev packages not installed.')
        self._simple_test('python', binary, entry='python')

    @skipIf(is_windows(), 'Setting up multiple compilers on windows is hard')
    @skip_if_env_set('CC')
    def test_c_compiler(self):
        def cb(comp):
            if comp.id == 'gcc':
                if not shutil.which('clang'):
                    raise SkipTest('Only one compiler found, cannot test.')
                return 'clang', 'clang'
            if not is_real_gnu_compiler(shutil.which('gcc')):
                raise SkipTest('Only one compiler found, cannot test.')
            return 'gcc', 'gcc'
        self.helper_for_compiler('c', cb)

    @skipIf(is_windows(), 'Setting up multiple compilers on windows is hard')
    @skip_if_env_set('CXX')
    def test_cpp_compiler(self):
        def cb(comp):
            if comp.id == 'gcc':
                if not shutil.which('clang++'):
                    raise SkipTest('Only one compiler found, cannot test.')
                return 'clang++', 'clang'
            if not is_real_gnu_compiler(shutil.which('g++')):
                raise SkipTest('Only one compiler found, cannot test.')
            return 'g++', 'gcc'
        self.helper_for_compiler('cpp', cb)

    @skip_if_not_language('objc')
    @skip_if_env_set('OBJC')
    def test_objc_compiler(self):
        def cb(comp):
            if comp.id == 'gcc':
                if not shutil.which('clang'):
                    raise SkipTest('Only one compiler found, cannot test.')
                return 'clang', 'clang'
            if not is_real_gnu_compiler(shutil.which('gcc')):
                raise SkipTest('Only one compiler found, cannot test.')
            return 'gcc', 'gcc'
        self.helper_for_compiler('objc', cb)

    @skip_if_not_language('objcpp')
    @skip_if_env_set('OBJCXX')
    def test_objcpp_compiler(self):
        def cb(comp):
            if comp.id == 'gcc':
                if not shutil.which('clang++'):
                    raise SkipTest('Only one compiler found, cannot test.')
                return 'clang++', 'clang'
            if not is_real_gnu_compiler(shutil.which('g++')):
                raise SkipTest('Only one compiler found, cannot test.')
            return 'g++', 'gcc'
        self.helper_for_compiler('objcpp', cb)

    @skip_if_not_language('d')
    @skip_if_env_set('DC')
    def test_d_compiler(self):
        def cb(comp):
            if comp.id == 'dmd':
                if shutil.which('ldc'):
                    return 'ldc', 'ldc'
                elif shutil.which('gdc'):
                    return 'gdc', 'gdc'
                else:
                    raise SkipTest('No alternative dlang compiler found.')
            if shutil.which('dmd'):
                return 'dmd', 'dmd'
            raise SkipTest('No alternative dlang compiler found.')
        self.helper_for_compiler('d', cb)

    @skip_if_not_language('cs')
    @skip_if_env_set('CSC')
    def test_cs_compiler(self):
        def cb(comp):
            if comp.id == 'csc':
                if not shutil.which('mcs'):
                    raise SkipTest('No alternate C# implementation.')
                return 'mcs', 'mcs'
            if not shutil.which('csc'):
                raise SkipTest('No alternate C# implementation.')
            return 'csc', 'csc'
        self.helper_for_compiler('cs', cb)

    @skip_if_not_language('fortran')
    @skip_if_env_set('FC')
    def test_fortran_compiler(self):
        def cb(comp):
            if comp.id == 'lcc':
                if shutil.which('lfortran'):
                    return 'lfortran', 'lcc'
                raise SkipTest('No alternate Fortran implementation.')
            elif comp.id == 'gcc':
                if shutil.which('ifort'):
                    # There is an ICC for windows (windows build, linux host),
                    # but we don't support that ATM so let's not worry about it.
                    if is_windows():
                        return 'ifort', 'intel-cl'
                    return 'ifort', 'intel'
                elif shutil.which('flang'):
                    return 'flang', 'flang'
                elif shutil.which('pgfortran'):
                    return 'pgfortran', 'pgi'
                # XXX: there are several other fortran compilers meson
                # supports, but I don't have any of them to test with
                raise SkipTest('No alternate Fortran implementation.')
            if not shutil.which('gfortran'):
                raise SkipTest('No alternate Fortran implementation.')
            return 'gfortran', 'gcc'
        self.helper_for_compiler('fortran', cb)

    def _single_implementation_compiler(self, lang: str, binary: str, version_str: str, version: str) -> None:
        """Helper for languages with a single (supported) implementation.

        Builds a wrapper around the compiler to override the version.
        """
        wrapper = self.helper_create_binary_wrapper(binary, version=version_str)
        env = get_fake_env()
        env.binaries.host.binaries[lang] = [wrapper]
        compiler = compiler_from_language(env, lang, MachineChoice.HOST)
        self.assertEqual(compiler.version, version)

    @skip_if_not_language('vala')
    @skip_if_env_set('VALAC')
    def test_vala_compiler(self):
        self._single_implementation_compiler(
            'vala', 'valac', 'Vala 1.2345', '1.2345')

    @skip_if_not_language('rust')
    @skip_if_env_set('RUSTC')
    def test_rust_compiler(self):
        self._single_implementation_compiler(
            'rust', 'rustc', 'rustc 1.2345', '1.2345')

    @skip_if_not_language('java')
    def test_java_compiler(self):
        self._single_implementation_compiler(
            'java', 'javac', 'javac 9.99.77', '9.99.77')

    @skip_if_not_language('java')
    def test_java_classpath(self):
        if self.backend is not Backend.ninja:
            raise SkipTest('Jar is only supported with Ninja')
        testdir = os.path.join(self.unit_test_dir, '112 classpath')
        self.init(testdir)
        self.build()
        one_build_path = get_classpath(os.path.join(self.builddir, 'one.jar'))
        self.assertIsNone(one_build_path)
        two_build_path = get_classpath(os.path.join(self.builddir, 'two.jar'))
        self.assertEqual(two_build_path, 'one.jar')
        self.install()
        one_install_path = get_classpath(os.path.join(self.installdir, 'usr/bin/one.jar'))
        self.assertIsNone(one_install_path)
        two_install_path = get_classpath(os.path.join(self.installdir, 'usr/bin/two.jar'))
        self.assertIsNone(two_install_path)

    @skip_if_not_language('swift')
    def test_swift_compiler(self):
        wrapper = self.helper_create_binary_wrapper(
            'swiftc', version='Swift 1.2345', outfile='stderr',
            extra_args={'Xlinker': 'macosx_version. PROJECT:ld - 1.2.3'})
        env = get_fake_env()
        env.binaries.host.binaries['swift'] = [wrapper]
        compiler = detect_swift_compiler(env, MachineChoice.HOST)
        self.assertEqual(compiler.version, '1.2345')

    def test_native_file_dirs(self):
        testcase = os.path.join(self.unit_test_dir, '59 native file override')
        self.init(testcase, default_args=False,
                  extra_args=['--native-file', os.path.join(testcase, 'nativefile')])

    def test_native_file_dirs_overridden(self):
        testcase = os.path.join(self.unit_test_dir, '59 native file override')
        self.init(testcase, default_args=False,
                  extra_args=['--native-file', os.path.join(testcase, 'nativefile'),
                              '-Ddef_libdir=liblib', '-Dlibdir=liblib'])

    def test_compile_sys_path(self):
        """Compiling with a native file stored in a system path works.

        There was a bug which caused the paths to be stored incorrectly and
        would result in ninja invoking meson in an infinite loop. This tests
        for that by actually invoking ninja.
        """
        testcase = os.path.join(self.common_test_dir, '1 trivial')

        # It really doesn't matter what's in the native file, just that it exists
        config = self.helper_create_native_file({'binaries': {'bash': 'false'}})

        self.init(testcase, extra_args=['--native-file', config])
        self.build()

    def test_user_options(self):
        testcase = os.path.join(self.common_test_dir, '40 options')
        for opt, value in [('testoption', 'some other val'), ('other_one', True),
                           ('combo_opt', 'one'), ('array_opt', ['two']),
                           ('integer_opt', 0),
                           ('CaseSenSiTivE', 'SOME other Value'),
                           ('CASESENSITIVE', 'some other Value')]:
            config = self.helper_create_native_file({'project options': {opt: value}})
            with self.assertRaises(subprocess.CalledProcessError) as cm:
                self.init(testcase, extra_args=['--native-file', config])
                self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option')

    def test_user_options_command_line_overrides(self):
        testcase = os.path.join(self.common_test_dir, '40 options')
        config = self.helper_create_native_file({'project options': {'other_one': True}})
        self.init(testcase, extra_args=['--native-file', config, '-Dother_one=false'])

    def test_user_options_subproject(self):
        testcase = os.path.join(self.unit_test_dir, '78 user options for subproject')

        s = os.path.join(testcase, 'subprojects')
        if not os.path.exists(s):
            os.mkdir(s)
        s = os.path.join(s, 'sub')
        if not os.path.exists(s):
            sub = os.path.join(self.common_test_dir, '40 options')
            shutil.copytree(sub, s)

        for opt, value in [('testoption', 'some other val'), ('other_one', True),
                           ('combo_opt', 'one'), ('array_opt', ['two']),
                           ('integer_opt', 0)]:
            config = self.helper_create_native_file({'sub:project options': {opt: value}})
            with self.assertRaises(subprocess.CalledProcessError) as cm:
                self.init(testcase, extra_args=['--native-file', config])
                self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option')

    def test_option_bool(self):
        # Bools are allowed to be unquoted
        testcase = os.path.join(self.common_test_dir, '1 trivial')
        config = self.helper_create_native_file({'built-in options': {'werror': True}})
        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            # Test that no-per subproject options are inherited from the parent
            if 'werror' in each['name']:
                self.assertEqual(each['value'], True)
                break
        else:
            self.fail('Did not find werror in build options?')

    def test_option_integer(self):
        # Bools are allowed to be unquoted
        testcase = os.path.join(self.common_test_dir, '1 trivial')
        config = self.helper_create_native_file({'built-in options': {'unity_size': 100}})
        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            # Test that no-per subproject options are inherited from the parent
            if 'unity_size' in each['name']:
                self.assertEqual(each['value'], 100)
                break
        else:
            self.fail('Did not find unity_size in build options?')

    def test_builtin_options(self):
        testcase = os.path.join(self.common_test_dir, '2 cpp')
        config = self.helper_create_native_file({'built-in options': {'cpp_std': 'c++14'}})

        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'cpp_std':
                self.assertEqual(each['value'], 'c++14')
                break
        else:
            self.fail('Did not find werror in build options?')

    def test_builtin_options_conf_overrides_env(self):
        testcase = os.path.join(self.common_test_dir, '2 cpp')
        config = self.helper_create_native_file({'built-in options': {'pkg_config_path': '/foo'}})

        self.init(testcase, extra_args=['--native-file', config], override_envvars={'PKG_CONFIG_PATH': '/bar'})
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'pkg_config_path':
                self.assertEqual(each['value'], ['/foo'])
                break
        else:
            self.fail('Did not find pkg_config_path in build options?')

    def test_builtin_options_subprojects(self):
        testcase = os.path.join(self.common_test_dir, '98 subproject subdir')
        config = self.helper_create_native_file({'built-in options': {'default_library': 'both', 'c_args': ['-Dfoo']}, 'sub:built-in options': {'default_library': 'static'}})

        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        found = 0
        for each in configuration:
            # Test that no-per subproject options are inherited from the parent
            if 'c_args' in each['name']:
                # This path will be hit twice, once for build and once for host,
                self.assertEqual(each['value'], ['-Dfoo'])
                found += 1
            elif each['name'] == 'default_library':
                self.assertEqual(each['value'], 'both')
                found += 1
            elif each['name'] == 'sub:default_library':
                self.assertEqual(each['value'], 'static')
                found += 1
        self.assertEqual(found, 4, 'Did not find all three sections')

    def test_builtin_options_subprojects_overrides_buildfiles(self):
        # If the buildfile says subproject(... default_library: shared), ensure that's overwritten
        testcase = os.path.join(self.common_test_dir, '223 persubproject options')
        config = self.helper_create_native_file({'sub2:built-in options': {'default_library': 'shared'}})

        with self.assertRaises((RuntimeError, subprocess.CalledProcessError)) as cm:
            self.init(testcase, extra_args=['--native-file', config])
            if isinstance(cm, RuntimeError):
                check = str(cm.exception)
            else:
                check = cm.exception.stdout
            self.assertIn(check, 'Parent should override default_library')

    def test_builtin_options_subprojects_dont_inherits_parent_override(self):
        # If the buildfile says subproject(... default_library: shared), ensure that's overwritten
        testcase = os.path.join(self.common_test_dir, '223 persubproject options')
        config = self.helper_create_native_file({'built-in options': {'default_library': 'both'}})
        self.init(testcase, extra_args=['--native-file', config])

    def test_builtin_options_compiler_properties(self):
        # the properties section can have lang_args, and those need to be
        # overwritten by the built-in options
        testcase = os.path.join(self.common_test_dir, '1 trivial')
        config = self.helper_create_native_file({
            'built-in options': {'c_args': ['-DFOO']},
            'properties': {'c_args': ['-DBAR']},
        })

        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'c_args':
                self.assertEqual(each['value'], ['-DFOO'])
                break
        else:
            self.fail('Did not find c_args in build options?')

    def test_builtin_options_compiler_properties_legacy(self):
        # The legacy placement in properties is still valid if a 'built-in
        # options' setting is present, but doesn't have the lang_args
        testcase = os.path.join(self.common_test_dir, '1 trivial')
        config = self.helper_create_native_file({
            'built-in options': {'default_library': 'static'},
            'properties': {'c_args': ['-DBAR']},
        })

        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'c_args':
                self.assertEqual(each['value'], ['-DBAR'])
                break
        else:
            self.fail('Did not find c_args in build options?')

    def test_builtin_options_paths(self):
        # the properties section can have lang_args, and those need to be
        # overwritten by the built-in options
        testcase = os.path.join(self.common_test_dir, '1 trivial')
        config = self.helper_create_native_file({
            'built-in options': {'bindir': 'foo'},
            'paths': {'bindir': 'bar'},
        })

        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'bindir':
                self.assertEqual(each['value'], 'foo')
                break
        else:
            self.fail('Did not find bindir in build options?')

    def test_builtin_options_paths_legacy(self):
        testcase = os.path.join(self.common_test_dir, '1 trivial')
        config = self.helper_create_native_file({
            'built-in options': {'default_library': 'static'},
            'paths': {'bindir': 'bar'},
        })

        self.init(testcase, extra_args=['--native-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'bindir':
                self.assertEqual(each['value'], 'bar')
                break
        else:
            self.fail('Did not find bindir in build options?')

    @skip_if_not_language('rust')
    def test_bindgen_clang_arguments(self) -> None:
        if self.backend is not Backend.ninja:
            raise SkipTest('Rust is only supported with Ninja')

        testcase = os.path.join(self.rust_test_dir, '12 bindgen')
        config = self.helper_create_native_file({
            'properties': {'bindgen_clang_arguments': 'sentinel'}
        })

        self.init(testcase, extra_args=['--native-file', config])
        targets: T.List[T.Dict[str, T.Any]] = self.introspect('--targets')
        for t in targets:
            if t['id'].startswith('rustmod-bindgen'):
                args: T.List[str] = t['target_sources'][0]['compiler']
                self.assertIn('sentinel', args, msg="Did not find machine file value")
                cargs_start = args.index('--')
                sent_arg = args.index('sentinel')
                self.assertLess(cargs_start, sent_arg, msg='sentinel argument does not come after "--"')
                break
        else:
            self.fail('Did not find a bindgen target')


class CrossFileTests(BasePlatformTests):

    """Tests for cross file functionality not directly related to
    cross compiling.

    This is mainly aimed to testing overrides from cross files.
    """

    def setUp(self):
        super().setUp()
        self.current_config = 0
        self.current_wrapper = 0

    def _cross_file_generator(self, *, needs_exe_wrapper: bool = False,
                              exe_wrapper: T.Optional[T.List[str]] = None) -> str:
        if is_windows():
            raise SkipTest('Cannot run this test on non-mingw/non-cygwin windows')

        return textwrap.dedent(f"""\
            [binaries]
            c = '{shutil.which('gcc' if is_sunos() else 'cc')}'
            ar = '{shutil.which('ar')}'
            strip = '{shutil.which('strip')}'
            exe_wrapper = {str(exe_wrapper) if exe_wrapper is not None else '[]'}

            [properties]
            needs_exe_wrapper = {needs_exe_wrapper}

            [host_machine]
            system = 'linux'
            cpu_family = 'x86'
            cpu = 'i686'
            endian = 'little'
            """)

    def _stub_exe_wrapper(self) -> str:
        return textwrap.dedent('''\
            #!/usr/bin/env python3
            import subprocess
            import sys

            sys.exit(subprocess.run(sys.argv[1:]).returncode)
            ''')

    def test_needs_exe_wrapper_true(self):
        testdir = os.path.join(self.unit_test_dir, '70 cross test passed')
        with tempfile.TemporaryDirectory() as d:
            p = Path(d) / 'crossfile'
            with p.open('wt', encoding='utf-8') as f:
                f.write(self._cross_file_generator(needs_exe_wrapper=True))
            self.init(testdir, extra_args=['--cross-file=' + str(p)])
            out = self.run_target('test')
            self.assertRegex(out, r'Skipped:\s*1\s*\n')

    def test_needs_exe_wrapper_false(self):
        testdir = os.path.join(self.unit_test_dir, '70 cross test passed')
        with tempfile.TemporaryDirectory() as d:
            p = Path(d) / 'crossfile'
            with p.open('wt', encoding='utf-8') as f:
                f.write(self._cross_file_generator(needs_exe_wrapper=False))
            self.init(testdir, extra_args=['--cross-file=' + str(p)])
            out = self.run_target('test')
            self.assertNotRegex(out, r'Skipped:\s*1\n')

    def test_needs_exe_wrapper_true_wrapper(self):
        testdir = os.path.join(self.unit_test_dir, '70 cross test passed')
        with tempfile.TemporaryDirectory() as d:
            s = Path(d) / 'wrapper.py'
            with s.open('wt', encoding='utf-8') as f:
                f.write(self._stub_exe_wrapper())
            s.chmod(0o774)
            p = Path(d) / 'crossfile'
            with p.open('wt', encoding='utf-8') as f:
                f.write(self._cross_file_generator(
                    needs_exe_wrapper=True,
                    exe_wrapper=[str(s)]))

            self.init(testdir, extra_args=['--cross-file=' + str(p), '-Dexpect=true'])
            out = self.run_target('test')
            self.assertRegex(out, r'Ok:\s*3\s*\n')

    def test_cross_exe_passed_no_wrapper(self):
        testdir = os.path.join(self.unit_test_dir, '70 cross test passed')
        with tempfile.TemporaryDirectory() as d:
            p = Path(d) / 'crossfile'
            with p.open('wt', encoding='utf-8') as f:
                f.write(self._cross_file_generator(needs_exe_wrapper=True))

            self.init(testdir, extra_args=['--cross-file=' + str(p)])
            self.build()
            out = self.run_target('test')
            self.assertRegex(out, r'Skipped:\s*1\s*\n')

    # The test uses mocking and thus requires that the current process is the
    # one to run the Meson steps. If we are using an external test executable
    # (most commonly in Debian autopkgtests) then the mocking won't work.
    @skipIf('MESON_EXE' in os.environ, 'MESON_EXE is defined, cannot use mocking.')
    def test_cross_file_system_paths(self):
        if is_windows():
            raise SkipTest('system crossfile paths not defined for Windows (yet)')

        testdir = os.path.join(self.common_test_dir, '1 trivial')
        cross_content = self._cross_file_generator()
        with tempfile.TemporaryDirectory() as d:
            dir_ = os.path.join(d, 'meson', 'cross')
            os.makedirs(dir_)
            with tempfile.NamedTemporaryFile('w', dir=dir_, delete=False, encoding='utf-8') as f:
                f.write(cross_content)
            name = os.path.basename(f.name)

            with mock.patch.dict(os.environ, {'XDG_DATA_HOME': d}):
                self.init(testdir, extra_args=['--cross-file=' + name], inprocess=True)
                self.wipe()

            with mock.patch.dict(os.environ, {'XDG_DATA_DIRS': d}):
                os.environ.pop('XDG_DATA_HOME', None)
                self.init(testdir, extra_args=['--cross-file=' + name], inprocess=True)
                self.wipe()

        with tempfile.TemporaryDirectory() as d:
            dir_ = os.path.join(d, '.local', 'share', 'meson', 'cross')
            os.makedirs(dir_)
            with tempfile.NamedTemporaryFile('w', dir=dir_, delete=False, encoding='utf-8') as f:
                f.write(cross_content)
            name = os.path.basename(f.name)

            # If XDG_DATA_HOME is set in the environment running the
            # tests this test will fail, os mock the environment, pop
            # it, then test
            with mock.patch.dict(os.environ):
                os.environ.pop('XDG_DATA_HOME', None)
                with mock.patch('mesonbuild.coredata.os.path.expanduser', lambda x: x.replace('~', d)):
                    self.init(testdir, extra_args=['--cross-file=' + name], inprocess=True)
                    self.wipe()

    def helper_create_cross_file(self, values):
        """Create a config file as a temporary file.

        values should be a nested dictionary structure of {section: {key:
        value}}
        """
        filename = os.path.join(self.builddir, f'generated{self.current_config}.config')
        self.current_config += 1
        with open(filename, 'wt', encoding='utf-8') as f:
            for section, entries in values.items():
                f.write(f'[{section}]\n')
                for k, v in entries.items():
                    f.write(f"{k}={v!r}\n")
        return filename

    def test_cross_file_dirs(self):
        testcase = os.path.join(self.unit_test_dir, '59 native file override')
        self.init(testcase, default_args=False,
                  extra_args=['--native-file', os.path.join(testcase, 'nativefile'),
                              '--cross-file', os.path.join(testcase, 'crossfile'),
                              '-Ddef_bindir=binbar',
                              '-Ddef_datadir=databar',
                              '-Ddef_includedir=includebar',
                              '-Ddef_infodir=infobar',
                              '-Ddef_libdir=libbar',
                              '-Ddef_libexecdir=libexecbar',
                              '-Ddef_localedir=localebar',
                              '-Ddef_localstatedir=localstatebar',
                              '-Ddef_mandir=manbar',
                              '-Ddef_sbindir=sbinbar',
                              '-Ddef_sharedstatedir=sharedstatebar',
                              '-Ddef_sysconfdir=sysconfbar'])

    def test_cross_file_dirs_overridden(self):
        testcase = os.path.join(self.unit_test_dir, '59 native file override')
        self.init(testcase, default_args=False,
                  extra_args=['--native-file', os.path.join(testcase, 'nativefile'),
                              '--cross-file', os.path.join(testcase, 'crossfile'),
                              '-Ddef_libdir=liblib', '-Dlibdir=liblib',
                              '-Ddef_bindir=binbar',
                              '-Ddef_datadir=databar',
                              '-Ddef_includedir=includebar',
                              '-Ddef_infodir=infobar',
                              '-Ddef_libexecdir=libexecbar',
                              '-Ddef_localedir=localebar',
                              '-Ddef_localstatedir=localstatebar',
                              '-Ddef_mandir=manbar',
                              '-Ddef_sbindir=sbinbar',
                              '-Ddef_sharedstatedir=sharedstatebar',
                              '-Ddef_sysconfdir=sysconfbar'])

    def test_cross_file_dirs_chain(self):
        # crossfile2 overrides crossfile overrides nativefile
        testcase = os.path.join(self.unit_test_dir, '59 native file override')
        self.init(testcase, default_args=False,
                  extra_args=['--native-file', os.path.join(testcase, 'nativefile'),
                              '--cross-file', os.path.join(testcase, 'crossfile'),
                              '--cross-file', os.path.join(testcase, 'crossfile2'),
                              '-Ddef_bindir=binbar2',
                              '-Ddef_datadir=databar',
                              '-Ddef_includedir=includebar',
                              '-Ddef_infodir=infobar',
                              '-Ddef_libdir=libbar',
                              '-Ddef_libexecdir=libexecbar',
                              '-Ddef_localedir=localebar',
                              '-Ddef_localstatedir=localstatebar',
                              '-Ddef_mandir=manbar',
                              '-Ddef_sbindir=sbinbar',
                              '-Ddef_sharedstatedir=sharedstatebar',
                              '-Ddef_sysconfdir=sysconfbar'])

    def test_user_options(self):
        # This is just a touch test for cross file, since the implementation
        # shares code after loading from the files
        testcase = os.path.join(self.common_test_dir, '40 options')
        config = self.helper_create_cross_file({'project options': {'testoption': 'some other value'}})
        with self.assertRaises(subprocess.CalledProcessError) as cm:
            self.init(testcase, extra_args=['--cross-file', config])
            self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option')

    def test_builtin_options(self):
        testcase = os.path.join(self.common_test_dir, '2 cpp')
        config = self.helper_create_cross_file({'built-in options': {'cpp_std': 'c++14'}})

        self.init(testcase, extra_args=['--cross-file', config])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'cpp_std':
                self.assertEqual(each['value'], 'c++14')
                break
        else:
            self.fail('No c++ standard set?')

    def test_builtin_options_per_machine(self):
        """Test options that are allowed to be set on a per-machine basis.

        Such options could be passed twice, once for the build machine, and
        once for the host machine. I've picked pkg-config path, but any would
        do that can be set for both.
        """
        testcase = os.path.join(self.common_test_dir, '2 cpp')
        cross = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/cross/path', 'cpp_std': 'c++17'}})
        native = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/native/path', 'cpp_std': 'c++14'}})

        # Ensure that PKG_CONFIG_PATH is not set in the environment
        with mock.patch.dict('os.environ'):
            for k in ['PKG_CONFIG_PATH', 'PKG_CONFIG_PATH_FOR_BUILD']:
                try:
                    del os.environ[k]
                except KeyError:
                    pass
            self.init(testcase, extra_args=['--cross-file', cross, '--native-file', native])

        configuration = self.introspect('--buildoptions')
        found = 0
        for each in configuration:
            if each['name'] == 'pkg_config_path':
                self.assertEqual(each['value'], ['/cross/path'])
                found += 1
            elif each['name'] == 'cpp_std':
                self.assertEqual(each['value'], 'c++17')
                found += 1
            elif each['name'] == 'build.pkg_config_path':
                self.assertEqual(each['value'], ['/native/path'])
                found += 1
            elif each['name'] == 'build.cpp_std':
                self.assertEqual(each['value'], 'c++14')
                found += 1

            if found == 4:
                break
        self.assertEqual(found, 4, 'Did not find all sections.')

    def test_builtin_options_conf_overrides_env(self):
        testcase = os.path.join(self.common_test_dir, '2 cpp')
        config = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/native', 'cpp_args': '-DFILE'}})
        cross = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/cross', 'cpp_args': '-DFILE'}})

        self.init(testcase, extra_args=['--native-file', config, '--cross-file', cross],
                  override_envvars={'PKG_CONFIG_PATH': '/bar', 'PKG_CONFIG_PATH_FOR_BUILD': '/dir',
                                    'CXXFLAGS': '-DENV', 'CXXFLAGS_FOR_BUILD': '-DENV'})
        configuration = self.introspect('--buildoptions')
        found = 0
        expected = 4
        for each in configuration:
            if each['name'] == 'pkg_config_path':
                self.assertEqual(each['value'], ['/cross'])
                found += 1
            elif each['name'] == 'build.pkg_config_path':
                self.assertEqual(each['value'], ['/native'])
                found += 1
            elif each['name'].endswith('cpp_args'):
                self.assertEqual(each['value'], ['-DFILE'])
                found += 1
            if found == expected:
                break
        self.assertEqual(found, expected, 'Did not find all sections.')

    def test_for_build_env_vars(self) -> None:
        testcase = os.path.join(self.common_test_dir, '2 cpp')
        config = self.helper_create_cross_file({'built-in options': {}})
        cross = self.helper_create_cross_file({'built-in options': {}})

        self.init(testcase, extra_args=['--native-file', config, '--cross-file', cross],
                  override_envvars={'PKG_CONFIG_PATH': '/bar', 'PKG_CONFIG_PATH_FOR_BUILD': '/dir'})
        configuration = self.introspect('--buildoptions')
        found = 0
        for each in configuration:
            if each['name'] == 'pkg_config_path':
                self.assertEqual(each['value'], ['/bar'])
                found += 1
            elif each['name'] == 'build.pkg_config_path':
                self.assertEqual(each['value'], ['/dir'])
                found += 1
            if found == 2:
                break
        self.assertEqual(found, 2, 'Did not find all sections.')

    def test_project_options_native_only(self) -> None:
        # Do not load project options from a native file when doing a cross
        # build
        testcase = os.path.join(self.unit_test_dir, '19 array option')
        config = self.helper_create_cross_file({'project options': {'list': ['bar', 'foo']}})
        cross = self.helper_create_cross_file({'binaries': {}})

        self.init(testcase, extra_args=['--native-file', config, '--cross-file', cross])
        configuration = self.introspect('--buildoptions')
        for each in configuration:
            if each['name'] == 'list':
                self.assertEqual(each['value'], ['foo', 'bar'])
                break
        else:
            self.fail('Did not find expected option.')
