files: # Copyright 2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  # Public symbols for compilers sub-package when using 'from . import compilers'
  __all__ = [
      'CompilerType',
  
      'all_languages',
      'base_options',
      'clib_langs',
      'clink_langs',
      'c_suffixes',
      'cpp_suffixes',
      'get_macos_dylib_install_name',
      'get_base_compile_args',
      'get_base_link_args',
      'is_assembly',
      'is_header',
      'is_library',
      'is_llvm_ir',
      'is_object',
      'is_source',
      'lang_suffixes',
      'sanitizer_compile_args',
      'sort_clink',
  
      'ArmCCompiler',
      'ArmCPPCompiler',
      'ArmclangCCompiler',
      'ArmclangCPPCompiler',
      'CCompiler',
      'ClangCCompiler',
      'ClangCompiler',
      'ClangCPPCompiler',
      'ClangObjCCompiler',
      'ClangObjCPPCompiler',
      'CompilerArgs',
      'CPPCompiler',
      'DCompiler',
      'DmdDCompiler',
      'FortranCompiler',
      'G95FortranCompiler',
      'GnuCCompiler',
      'ElbrusCCompiler',
      'GnuCompiler',
      'GnuCPPCompiler',
      'ElbrusCPPCompiler',
      'GnuDCompiler',
      'GnuFortranCompiler',
      'ElbrusFortranCompiler',
      'GnuObjCCompiler',
      'GnuObjCPPCompiler',
      'IntelCompiler',
      'IntelCCompiler',
      'IntelCPPCompiler',
      'IntelFortranCompiler',
      'JavaCompiler',
      'LLVMDCompiler',
      'MonoCompiler',
      'VisualStudioCsCompiler',
      'NAGFortranCompiler',
      'ObjCCompiler',
      'ObjCPPCompiler',
      'Open64FortranCompiler',
      'PathScaleFortranCompiler',
      'PGIFortranCompiler',
      'RustCompiler',
      'SunFortranCompiler',
      'SwiftCompiler',
      'ValaCompiler',
      'VisualStudioCCompiler',
      'VisualStudioCPPCompiler',
  ]
  
  # Bring symbols from each module into compilers sub-package namespace
  from .compilers import (
      CompilerType,
      all_languages,
      base_options,
      clib_langs,
      clink_langs,
      c_suffixes,
      cpp_suffixes,
      get_macos_dylib_install_name,
      get_base_compile_args,
      get_base_link_args,
      is_header,
      is_source,
      is_assembly,
      is_llvm_ir,
      is_object,
      is_library,
      lang_suffixes,
      sanitizer_compile_args,
      sort_clink,
      ClangCompiler,
      CompilerArgs,
      GnuCompiler,
      IntelCompiler,
  )
  from .c import (
      CCompiler,
      ArmCCompiler,
      ArmclangCCompiler,
      ClangCCompiler,
      GnuCCompiler,
      ElbrusCCompiler,
      IntelCCompiler,
      VisualStudioCCompiler,
  )
  from .cpp import (
      CPPCompiler,
      ArmCPPCompiler,
      ArmclangCPPCompiler,
      ClangCPPCompiler,
      GnuCPPCompiler,
      ElbrusCPPCompiler,
      IntelCPPCompiler,
      VisualStudioCPPCompiler,
  )
  from .cs import MonoCompiler, VisualStudioCsCompiler
  from .d import (
      DCompiler,
      DmdDCompiler,
      GnuDCompiler,
      LLVMDCompiler,
  )
  from .fortran import (
      FortranCompiler,
      G95FortranCompiler,
      GnuFortranCompiler,
      ElbrusFortranCompiler,
      IntelFortranCompiler,
      NAGFortranCompiler,
      Open64FortranCompiler,
      PathScaleFortranCompiler,
      PGIFortranCompiler,
      SunFortranCompiler,
  )
  from .java import JavaCompiler
  from .objc import (
      ObjCCompiler,
      ClangObjCCompiler,
      GnuObjCCompiler,
  )
  from .objcpp import (
      ObjCPPCompiler,
      ClangObjCPPCompiler,
      GnuObjCPPCompiler,
  )
  from .rust import RustCompiler
  from .swift import SwiftCompiler
  from .vala import ValaCompiler
  
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/__init__.py
files: # Copyright 2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  # Public symbols for compilers sub-package when using 'from . import compilers'
  __all__ = [
      'CLANG_OSX',
      'CLANG_STANDARD',
      'CLANG_WIN',
      'GCC_CYGWIN',
      'GCC_MINGW',
      'GCC_OSX',
      'GCC_STANDARD',
      'ICC_OSX',
      'ICC_STANDARD',
      'ICC_WIN',
  
      'all_languages',
      'base_options',
      'clib_langs',
      'clink_langs',
      'c_suffixes',
      'cpp_suffixes',
      'get_macos_dylib_install_name',
      'get_base_compile_args',
      'get_base_link_args',
      'is_assembly',
      'is_header',
      'is_library',
      'is_llvm_ir',
      'is_object',
      'is_source',
      'lang_suffixes',
      'sanitizer_compile_args',
      'sort_clink',
  
      'ArmCCompiler',
      'ArmCPPCompiler',
      'ArmclangCCompiler',
      'ArmclangCPPCompiler',
      'CCompiler',
      'ClangCCompiler',
      'ClangCompiler',
      'ClangCPPCompiler',
      'ClangObjCCompiler',
      'ClangObjCPPCompiler',
      'CompilerArgs',
      'CPPCompiler',
      'DCompiler',
      'DmdDCompiler',
      'FortranCompiler',
      'G95FortranCompiler',
      'GnuCCompiler',
      'ElbrusCCompiler',
      'GnuCompiler',
      'GnuCPPCompiler',
      'ElbrusCPPCompiler',
      'GnuDCompiler',
      'GnuFortranCompiler',
      'ElbrusFortranCompiler',
      'GnuObjCCompiler',
      'GnuObjCPPCompiler',
      'IntelCompiler',
      'IntelCCompiler',
      'IntelCPPCompiler',
      'IntelFortranCompiler',
      'JavaCompiler',
      'LLVMDCompiler',
      'MonoCompiler',
      'VisualStudioCsCompiler',
      'NAGFortranCompiler',
      'ObjCCompiler',
      'ObjCPPCompiler',
      'Open64FortranCompiler',
      'PathScaleFortranCompiler',
      'PGIFortranCompiler',
      'RustCompiler',
      'SunFortranCompiler',
      'SwiftCompiler',
      'ValaCompiler',
      'VisualStudioCCompiler',
      'VisualStudioCPPCompiler',
  ]
  
  # Bring symbols from each module into compilers sub-package namespace
  from .compilers import (
      GCC_OSX,
      GCC_MINGW,
      GCC_CYGWIN,
      GCC_STANDARD,
      CLANG_OSX,
      CLANG_WIN,
      CLANG_STANDARD,
      ICC_OSX,
      ICC_WIN,
      ICC_STANDARD,
      all_languages,
      base_options,
      clib_langs,
      clink_langs,
      c_suffixes,
      cpp_suffixes,
      get_macos_dylib_install_name,
      get_base_compile_args,
      get_base_link_args,
      is_header,
      is_source,
      is_assembly,
      is_llvm_ir,
      is_object,
      is_library,
      lang_suffixes,
      sanitizer_compile_args,
      sort_clink,
      ClangCompiler,
      CompilerArgs,
      GnuCompiler,
      IntelCompiler,
  )
  from .c import (
      CCompiler,
      ArmCCompiler,
      ArmclangCCompiler,
      ClangCCompiler,
      GnuCCompiler,
      ElbrusCCompiler,
      IntelCCompiler,
      VisualStudioCCompiler,
  )
  from .cpp import (
      CPPCompiler,
      ArmCPPCompiler,
      ArmclangCPPCompiler,
      ClangCPPCompiler,
      GnuCPPCompiler,
      ElbrusCPPCompiler,
      IntelCPPCompiler,
      VisualStudioCPPCompiler,
  )
  from .cs import MonoCompiler, VisualStudioCsCompiler
  from .d import (
      DCompiler,
      DmdDCompiler,
      GnuDCompiler,
      LLVMDCompiler,
  )
  from .fortran import (
      FortranCompiler,
      G95FortranCompiler,
      GnuFortranCompiler,
      ElbrusFortranCompiler,
      IntelFortranCompiler,
      NAGFortranCompiler,
      Open64FortranCompiler,
      PathScaleFortranCompiler,
      PGIFortranCompiler,
      SunFortranCompiler,
  )
  from .java import JavaCompiler
  from .objc import (
      ObjCCompiler,
      ClangObjCCompiler,
      GnuObjCCompiler,
  )
  from .objcpp import (
      ObjCPPCompiler,
      ClangObjCPPCompiler,
      GnuObjCPPCompiler,
  )
  from .rust import RustCompiler
  from .swift import SwiftCompiler
  from .vala import ValaCompiler
  
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/__init__.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import re
  import glob
  import os.path
  import subprocess
  import functools
  import itertools
  from pathlib import Path
  
  from .. import mlog
  from .. import coredata
  from . import compilers
  from ..mesonlib import (
      EnvironmentException, MesonException, version_compare, Popen_safe, listify,
      for_windows, for_darwin, for_cygwin, for_haiku, for_openbsd,
  )
  from .c_function_attributes import C_FUNC_ATTRIBUTES
  
  from .compilers import (
      CompilerType,
      get_largefile_args,
      gnu_winlibs,
      msvc_winlibs,
      vs32_instruction_set_args,
      vs64_instruction_set_args,
      ArmCompiler,
      ArmclangCompiler,
      ClangCompiler,
      Compiler,
      CompilerArgs,
      CrossNoRunException,
      GnuCompiler,
      ElbrusCompiler,
      IntelCompiler,
      RunResult,
  )
  
  gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt')
  
  
  class CCompiler(Compiler):
      # TODO: Replace this manual cache with functools.lru_cache
      library_dirs_cache = {}
      program_dirs_cache = {}
      find_library_cache = {}
      internal_libs = gnu_compiler_internal_libs
  
      @staticmethod
      def attribute_check_func(name):
          try:
              return C_FUNC_ATTRIBUTES[name]
          except KeyError:
              raise MesonException('Unknown function attribute "{}"'.format(name))
  
      def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
          # If a child ObjC or CPP class has already set it, don't set it ourselves
          if not hasattr(self, 'language'):
              self.language = 'c'
          super().__init__(exelist, version, **kwargs)
          self.id = 'unknown'
          self.is_cross = is_cross
          self.can_compile_suffixes.add('h')
          # If the exe wrapper was not found, pretend it wasn't set so that the
          # sanity check is skipped and compiler checks use fallbacks.
          if not exe_wrapper or not exe_wrapper.found():
              self.exe_wrapper = None
          else:
              self.exe_wrapper = exe_wrapper.get_command()
  
          # Set to None until we actually need to check this
          self.has_fatal_warnings_link_arg = None
  
      def needs_static_linker(self):
          return True # When compiling static libraries, so yes.
  
      def get_always_args(self):
          '''
          Args that are always-on for all C compilers other than MSVC
          '''
          return ['-pipe'] + get_largefile_args(self)
  
      def get_linker_debug_crt_args(self):
          """
          Arguments needed to select a debug crt for the linker
          This is only needed for MSVC
          """
          return []
  
      def get_no_stdinc_args(self):
          return ['-nostdinc']
  
      def get_no_stdlib_link_args(self):
          return ['-nostdlib']
  
      def get_warn_args(self, level):
          return self.warn_args[level]
  
      def get_no_warn_args(self):
          # Almost every compiler uses this for disabling warnings
          return ['-w']
  
      def get_soname_args(self, *args):
          return []
  
      def split_shlib_to_parts(self, fname):
          return None, fname
  
      # The default behavior is this, override in MSVC
      @functools.lru_cache(maxsize=None)
      def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
          if self.id == 'clang' and self.compiler_type == CompilerType.CLANG_OSX:
              return self.build_osx_rpath_args(build_dir, rpath_paths, build_rpath)
          return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
  
      def get_dependency_gen_args(self, outtarget, outfile):
          return ['-MD', '-MQ', outtarget, '-MF', outfile]
  
      def depfile_for_object(self, objfile):
          return objfile + '.' + self.get_depfile_suffix()
  
      def get_depfile_suffix(self):
          return 'd'
  
      def get_exelist(self):
          return self.exelist[:]
  
      def get_linker_exelist(self):
          return self.exelist[:]
  
      def get_preprocess_only_args(self):
          return ['-E', '-P']
  
      def get_compile_only_args(self):
          return ['-c']
  
      def get_no_optimization_args(self):
          return ['-O0']
  
      def get_compiler_check_args(self):
          '''
          Get arguments useful for compiler checks such as being permissive in
          the code quality and not doing any optimization.
          '''
          return self.get_no_optimization_args()
  
      def get_allow_undefined_link_args(self):
          '''
          Get args for allowing undefined symbols when linking to a shared library
          '''
          if self.id in ('clang', 'gcc'):
              if self.compiler_type.is_osx_compiler:
                  # Apple ld
                  return ['-Wl,-undefined,dynamic_lookup']
              else:
                  # GNU ld and LLVM lld
                  return ['-Wl,--allow-shlib-undefined']
          elif self.id == 'msvc':
              # link.exe
              return ['/FORCE:UNRESOLVED']
          # FIXME: implement other linkers
          return []
  
      def get_output_args(self, target):
          return ['-o', target]
  
      def get_linker_output_args(self, outputname):
          return ['-o', outputname]
  
      def get_coverage_args(self):
          return ['--coverage']
  
      def get_coverage_link_args(self):
          return ['--coverage']
  
      def get_werror_args(self):
          return ['-Werror']
  
      def get_std_exe_link_args(self):
          return []
  
      def get_include_args(self, path, is_system):
          if path == '':
              path = '.'
          if is_system:
              return ['-isystem', path]
          return ['-I' + path]
  
      def get_std_shared_lib_link_args(self):
          return ['-shared']
  
      @functools.lru_cache()
      def _get_search_dirs(self, env):
          extra_args = ['--print-search-dirs']
          stdo = None
          with self._build_wrapper('', env, extra_args, None, '
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/c.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import re
  import glob
  import os.path
  import subprocess
  import functools
  import itertools
  from pathlib import Path
  
  from .. import mlog
  from .. import coredata
  from . import compilers
  from ..mesonlib import (
      EnvironmentException, MesonException, version_compare, Popen_safe, listify,
      for_windows, for_darwin, for_cygwin, for_haiku, for_openbsd,
  )
  from .c_function_attributes import C_FUNC_ATTRIBUTES
  
  from .compilers import (
      GCC_MINGW,
      get_largefile_args,
      gnu_winlibs,
      msvc_winlibs,
      vs32_instruction_set_args,
      vs64_instruction_set_args,
      ArmCompiler,
      ArmclangCompiler,
      ClangCompiler,
      Compiler,
      CompilerArgs,
      CrossNoRunException,
      GnuCompiler,
      ElbrusCompiler,
      IntelCompiler,
      RunResult,
  )
  
  gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt')
  
  
  class CCompiler(Compiler):
      # TODO: Replace this manual cache with functools.lru_cache
      library_dirs_cache = {}
      program_dirs_cache = {}
      find_library_cache = {}
      internal_libs = gnu_compiler_internal_libs
  
      @staticmethod
      def attribute_check_func(name):
          try:
              return C_FUNC_ATTRIBUTES[name]
          except KeyError:
              raise MesonException('Unknown function attribute "{}"'.format(name))
  
      def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
          # If a child ObjC or CPP class has already set it, don't set it ourselves
          if not hasattr(self, 'language'):
              self.language = 'c'
          super().__init__(exelist, version, **kwargs)
          self.id = 'unknown'
          self.is_cross = is_cross
          self.can_compile_suffixes.add('h')
          # If the exe wrapper was not found, pretend it wasn't set so that the
          # sanity check is skipped and compiler checks use fallbacks.
          if not exe_wrapper or not exe_wrapper.found():
              self.exe_wrapper = None
          else:
              self.exe_wrapper = exe_wrapper.get_command()
  
          # Set to None until we actually need to check this
          self.has_fatal_warnings_link_arg = None
  
      def needs_static_linker(self):
          return True # When compiling static libraries, so yes.
  
      def get_always_args(self):
          '''
          Args that are always-on for all C compilers other than MSVC
          '''
          return ['-pipe'] + get_largefile_args(self)
  
      def get_linker_debug_crt_args(self):
          """
          Arguments needed to select a debug crt for the linker
          This is only needed for MSVC
          """
          return []
  
      def get_no_stdinc_args(self):
          return ['-nostdinc']
  
      def get_no_stdlib_link_args(self):
          return ['-nostdlib']
  
      def get_warn_args(self, level):
          return self.warn_args[level]
  
      def get_no_warn_args(self):
          # Almost every compiler uses this for disabling warnings
          return ['-w']
  
      def get_soname_args(self, *args):
          return []
  
      def split_shlib_to_parts(self, fname):
          return None, fname
  
      # The default behavior is this, override in MSVC
      @functools.lru_cache(maxsize=None)
      def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
          if self.id == 'clang' and self.clang_type == compilers.CLANG_OSX:
              return self.build_osx_rpath_args(build_dir, rpath_paths, build_rpath)
          return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
  
      def get_dependency_gen_args(self, outtarget, outfile):
          return ['-MD', '-MQ', outtarget, '-MF', outfile]
  
      def depfile_for_object(self, objfile):
          return objfile + '.' + self.get_depfile_suffix()
  
      def get_depfile_suffix(self):
          return 'd'
  
      def get_exelist(self):
          return self.exelist[:]
  
      def get_linker_exelist(self):
          return self.exelist[:]
  
      def get_preprocess_only_args(self):
          return ['-E', '-P']
  
      def get_compile_only_args(self):
          return ['-c']
  
      def get_no_optimization_args(self):
          return ['-O0']
  
      def get_compiler_check_args(self):
          '''
          Get arguments useful for compiler checks such as being permissive in
          the code quality and not doing any optimization.
          '''
          return self.get_no_optimization_args()
  
      def get_allow_undefined_link_args(self):
          '''
          Get args for allowing undefined symbols when linking to a shared library
          '''
          if self.id == 'clang':
              if self.clang_type == compilers.CLANG_OSX:
                  # Apple ld
                  return ['-Wl,-undefined,dynamic_lookup']
              else:
                  # GNU ld and LLVM lld
                  return ['-Wl,--allow-shlib-undefined']
          elif self.id == 'gcc':
              if self.gcc_type == compilers.GCC_OSX:
                  # Apple ld
                  return ['-Wl,-undefined,dynamic_lookup']
              else:
                  # GNU ld and LLVM lld
                  return ['-Wl,--allow-shlib-undefined']
          elif self.id == 'msvc':
              # link.exe
              return ['/FORCE:UNRESOLVED']
          # FIXME: implement other linkers
          return []
  
      def get_output_args(self, target):
          return ['-o', target]
  
      def get_linker_output_args(self, outputname):
          return ['-o', outputname]
  
      def get_coverage_args(self):
          return ['--coverage']
  
      def get_coverage_link_args(self):
          return ['--coverage']
  
      def get_werror_args(self):
          return ['-Werror']
  
      def get_std_exe_link_args(self):
          return []
  
      def get_include_args(self, path, is_system):
          if path == '':
              path = '.'
          if is_system:
              return ['-isystem', path]
          return ['-I' + path]
  
      def get_std_shared
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/c.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import contextlib, enum, os.path, re, tempfile, shlex
  import subprocess
  
  from ..linkers import StaticLinker
  from .. import coredata
  from .. import mlog
  from .. import mesonlib
  from ..mesonlib import EnvironmentException, MesonException, OrderedSet, version_compare, Popen_safe
  
  """This file contains the data files of all compilers Meson knows
  about. To support a new compiler, add its information below.
  Also add corresponding autodetection code in environment.py."""
  
  header_suffixes = ('h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di')
  obj_suffixes = ('o', 'obj', 'res')
  lib_suffixes = ('a', 'lib', 'dll', 'dylib', 'so')
  # Mapping of language to suffixes of files that should always be in that language
  # This means we can't include .h headers here since they could be C, C++, ObjC, etc.
  lang_suffixes = {
      'c': ('c',),
      'cpp': ('cpp', 'cc', 'cxx', 'c++', 'hh', 'hpp', 'ipp', 'hxx'),
      # f90, f95, f03, f08 are for free-form fortran ('f90' recommended)
      # f, for, ftn, fpp are for fixed-form fortran ('f' or 'for' recommended)
      'fortran': ('f90', 'f95', 'f03', 'f08', 'f', 'for', 'ftn', 'fpp'),
      'd': ('d', 'di'),
      'objc': ('m',),
      'objcpp': ('mm',),
      'rust': ('rs',),
      'vala': ('vala', 'vapi', 'gs'),
      'cs': ('cs',),
      'swift': ('swift',),
      'java': ('java',),
  }
  all_languages = lang_suffixes.keys()
  cpp_suffixes = lang_suffixes['cpp'] + ('h',)
  c_suffixes = lang_suffixes['c'] + ('h',)
  # List of languages that by default consume and output libraries following the
  # C ABI; these can generally be used interchangebly
  clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'fortran',)
  # List of languages that can be linked with C code directly by the linker
  # used in build.py:process_compilers() and build.py:get_dynamic_linker()
  # XXX: Add Rust to this?
  clink_langs = ('d',) + clib_langs
  clink_suffixes = ()
  for _l in clink_langs + ('vala',):
      clink_suffixes += lang_suffixes[_l]
  clink_suffixes += ('h', 'll', 's')
  
  soregex = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
  
  # Environment variables that each lang uses.
  cflags_mapping = {'c': 'CFLAGS',
                    'cpp': 'CXXFLAGS',
                    'objc': 'OBJCFLAGS',
                    'objcpp': 'OBJCXXFLAGS',
                    'fortran': 'FFLAGS',
                    'd': 'DFLAGS',
                    'vala': 'VALAFLAGS',
                    'rust': 'RUSTFLAGS'}
  
  # All these are only for C-linkable languages; see `clink_langs` above.
  
  def sort_clink(lang):
      '''
      Sorting function to sort the list of languages according to
      reversed(compilers.clink_langs) and append the unknown langs in the end.
      The purpose is to prefer C over C++ for files that can be compiled by
      both such as assembly, C, etc. Also applies to ObjC, ObjC++, etc.
      '''
      if lang not in clink_langs:
          return 1
      return -clink_langs.index(lang)
  
  def is_header(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      suffix = fname.split('.')[-1]
      return suffix in header_suffixes
  
  def is_source(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      suffix = fname.split('.')[-1].lower()
      return suffix in clink_suffixes
  
  def is_assembly(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      return fname.split('.')[-1].lower() == 's'
  
  def is_llvm_ir(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      return fname.split('.')[-1] == 'll'
  
  def is_object(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      suffix = fname.split('.')[-1]
      return suffix in obj_suffixes
  
  def is_library(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
  
      if soregex.match(fname):
          return True
  
      suffix = fname.split('.')[-1]
      return suffix in lib_suffixes
  
  gnulike_buildtype_args = {'plain': [],
                            'debug': [],
                            'debugoptimized': [],
                            'release': [],
                            'minsize': []}
  
  armclang_buildtype_args = {'plain': [],
                             'debug': ['-O0', '-g'],
                             'debugoptimized': ['-O1', '-g'],
                             'release': ['-Os'],
                             'minsize': ['-Oz']}
  
  arm_buildtype_args = {'plain': [],
                        'debug': ['-O0', '--debug'],
                        'debugoptimized': ['-O1', '--debug'],
                        'release': ['-O3', '-Otime'],
                        'minsize': ['-O3', '-Ospace'],
                        }
  
  msvc_buildtype_args = {'plain': [],
                         'debug': ["/ZI", "/Ob0", "/Od", "/RTC1"],
                         'debugoptimized': ["/Zi", "/Ob1"],
                         'release': ["/Ob2", "/Gw"],
                         'minsize': ["/Zi", "/Gw"],
                         }
  
  apple_buildtype_linker_args = {'plain': [],
                                 'debug': [],
                                 'debugoptimized': [],
                                 'release': [],
                                 'minsize': [],
                                 }
  
  gnulike_buildtype_linker_args =
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/compilers.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import contextlib, os.path, re, tempfile, shlex
  import subprocess
  
  from ..linkers import StaticLinker
  from .. import coredata
  from .. import mlog
  from .. import mesonlib
  from ..mesonlib import EnvironmentException, MesonException, OrderedSet, version_compare, Popen_safe
  
  """This file contains the data files of all compilers Meson knows
  about. To support a new compiler, add its information below.
  Also add corresponding autodetection code in environment.py."""
  
  header_suffixes = ('h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di')
  obj_suffixes = ('o', 'obj', 'res')
  lib_suffixes = ('a', 'lib', 'dll', 'dylib', 'so')
  # Mapping of language to suffixes of files that should always be in that language
  # This means we can't include .h headers here since they could be C, C++, ObjC, etc.
  lang_suffixes = {
      'c': ('c',),
      'cpp': ('cpp', 'cc', 'cxx', 'c++', 'hh', 'hpp', 'ipp', 'hxx'),
      # f90, f95, f03, f08 are for free-form fortran ('f90' recommended)
      # f, for, ftn, fpp are for fixed-form fortran ('f' or 'for' recommended)
      'fortran': ('f90', 'f95', 'f03', 'f08', 'f', 'for', 'ftn', 'fpp'),
      'd': ('d', 'di'),
      'objc': ('m',),
      'objcpp': ('mm',),
      'rust': ('rs',),
      'vala': ('vala', 'vapi', 'gs'),
      'cs': ('cs',),
      'swift': ('swift',),
      'java': ('java',),
  }
  all_languages = lang_suffixes.keys()
  cpp_suffixes = lang_suffixes['cpp'] + ('h',)
  c_suffixes = lang_suffixes['c'] + ('h',)
  # List of languages that by default consume and output libraries following the
  # C ABI; these can generally be used interchangebly
  clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'fortran',)
  # List of languages that can be linked with C code directly by the linker
  # used in build.py:process_compilers() and build.py:get_dynamic_linker()
  # XXX: Add Rust to this?
  clink_langs = ('d',) + clib_langs
  clink_suffixes = ()
  for _l in clink_langs + ('vala',):
      clink_suffixes += lang_suffixes[_l]
  clink_suffixes += ('h', 'll', 's')
  
  soregex = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
  
  # Environment variables that each lang uses.
  cflags_mapping = {'c': 'CFLAGS',
                    'cpp': 'CXXFLAGS',
                    'objc': 'OBJCFLAGS',
                    'objcpp': 'OBJCXXFLAGS',
                    'fortran': 'FFLAGS',
                    'd': 'DFLAGS',
                    'vala': 'VALAFLAGS',
                    'rust': 'RUSTFLAGS'}
  
  # All these are only for C-linkable languages; see `clink_langs` above.
  
  def sort_clink(lang):
      '''
      Sorting function to sort the list of languages according to
      reversed(compilers.clink_langs) and append the unknown langs in the end.
      The purpose is to prefer C over C++ for files that can be compiled by
      both such as assembly, C, etc. Also applies to ObjC, ObjC++, etc.
      '''
      if lang not in clink_langs:
          return 1
      return -clink_langs.index(lang)
  
  def is_header(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      suffix = fname.split('.')[-1]
      return suffix in header_suffixes
  
  def is_source(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      suffix = fname.split('.')[-1].lower()
      return suffix in clink_suffixes
  
  def is_assembly(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      return fname.split('.')[-1].lower() == 's'
  
  def is_llvm_ir(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      return fname.split('.')[-1] == 'll'
  
  def is_object(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
      suffix = fname.split('.')[-1]
      return suffix in obj_suffixes
  
  def is_library(fname):
      if hasattr(fname, 'fname'):
          fname = fname.fname
  
      if soregex.match(fname):
          return True
  
      suffix = fname.split('.')[-1]
      return suffix in lib_suffixes
  
  gnulike_buildtype_args = {'plain': [],
                            'debug': [],
                            'debugoptimized': [],
                            'release': [],
                            'minsize': []}
  
  armclang_buildtype_args = {'plain': [],
                             'debug': ['-O0', '-g'],
                             'debugoptimized': ['-O1', '-g'],
                             'release': ['-Os'],
                             'minsize': ['-Oz']}
  
  arm_buildtype_args = {'plain': [],
                        'debug': ['-O0', '--debug'],
                        'debugoptimized': ['-O1', '--debug'],
                        'release': ['-O3', '-Otime'],
                        'minsize': ['-O3', '-Ospace'],
                        }
  
  msvc_buildtype_args = {'plain': [],
                         'debug': ["/ZI", "/Ob0", "/Od", "/RTC1"],
                         'debugoptimized': ["/Zi", "/Ob1"],
                         'release': ["/Ob2", "/Gw"],
                         'minsize': ["/Zi", "/Gw"],
                         }
  
  apple_buildtype_linker_args = {'plain': [],
                                 'debug': [],
                                 'debugoptimized': [],
                                 'release': [],
                                 'minsize': [],
                                 }
  
  gnulike_buildtype_linker_args = {'plain
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/compilers.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import functools
  import os.path
  
  from .. import coredata
  from .. import mlog
  from ..mesonlib import MesonException, version_compare
  
  from .c import CCompiler, VisualStudioCCompiler
  from .compilers import (
      CompilerType,
      gnu_winlibs,
      msvc_winlibs,
      ClangCompiler,
      GnuCompiler,
      ElbrusCompiler,
      IntelCompiler,
      ArmCompiler,
      ArmclangCompiler,
  )
  from .c_function_attributes import CXX_FUNC_ATTRIBUTES
  
  class CPPCompiler(CCompiler):
  
      @classmethod
      def attribute_check_func(cls, name):
          return CXX_FUNC_ATTRIBUTES.get(name, super().attribute_check_func(name))
  
      def __init__(self, exelist, version, is_cross, exe_wrap, **kwargs):
          # If a child ObjCPP class has already set it, don't set it ourselves
          if not hasattr(self, 'language'):
              self.language = 'cpp'
          CCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs)
  
      def get_display_language(self):
          return 'C++'
  
      def get_no_stdinc_args(self):
          return ['-nostdinc++']
  
      def sanity_check(self, work_dir, environment):
          code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
          return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code)
  
      def get_compiler_check_args(self):
          # -fpermissive allows non-conforming code to compile which is necessary
          # for many C++ checks. Particularly, the has_header_symbol check is
          # too strict without this and always fails.
          return super().get_compiler_check_args() + ['-fpermissive']
  
      def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
          # Check if it's a C-like symbol
          if super().has_header_symbol(hname, symbol, prefix, env, extra_args, dependencies):
              return True
          # Check if it's a class or a template
          if extra_args is None:
              extra_args = []
          fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol}
          t = '''{prefix}
          #include <{header}>
          using {symbol};
          int main () {{ return 0; }}'''
          return self.compiles(t.format(**fargs), env, extra_args, dependencies)
  
      def _test_cpp_std_arg(self, cpp_std_value):
          # Test whether the compiler understands a -std=XY argument
          assert(cpp_std_value.startswith('-std='))
  
          # This test does not use has_multi_arguments() for two reasons:
          # 1. has_multi_arguments() requires an env argument, which the compiler
          #    object does not have at this point.
          # 2. even if it did have an env object, that might contain another more
          #    recent -std= argument, which might lead to a cascaded failure.
          CPP_TEST = 'int i = static_cast<int>(0);'
          with self.compile(code=CPP_TEST, extra_args=[cpp_std_value], mode='compile') as p:
              if p.returncode == 0:
                  mlog.debug('Compiler accepts {}:'.format(cpp_std_value), 'YES')
                  return True
              else:
                  mlog.debug('Compiler accepts {}:'.format(cpp_std_value), 'NO')
                  return False
  
      @functools.lru_cache()
      def _find_best_cpp_std(self, cpp_std):
          # The initial version mapping approach to make falling back
          # from '-std=c++14' to '-std=c++1y' was too brittle. For instance,
          # Apple's Clang uses a different versioning scheme to upstream LLVM,
          # making the whole detection logic awfully brittle. Instead, let's
          # just see if feeding GCC or Clang our '-std=' setting works, and
          # if not, try the fallback argument.
          CPP_FALLBACKS = {
              'c++11': 'c++0x',
              'gnu++11': 'gnu++0x',
              'c++14': 'c++1y',
              'gnu++14': 'gnu++1y',
              'c++17': 'c++1z',
              'gnu++17': 'gnu++1z'
          }
  
          # Currently, remapping is only supported for Clang and GCC
          assert(self.id in frozenset(['clang', 'gcc']))
  
          if cpp_std not in CPP_FALLBACKS:
              # 'c++03' and 'c++98' don't have fallback types
              return '-std=' + cpp_std
  
          for i in (cpp_std, CPP_FALLBACKS[cpp_std]):
              cpp_std_value = '-std=' + i
              if self._test_cpp_std_arg(cpp_std_value):
                  return cpp_std_value
  
          raise MesonException('C++ Compiler does not support -std={}'.format(cpp_std))
  
  
  class ClangCPPCompiler(ClangCompiler, CPPCompiler):
      def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
          CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
          ClangCompiler.__init__(self, compiler_type)
          default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  
      def get_options(self):
          opts = CPPCompiler.get_options(self)
          opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
                                                           ['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a',
                                                            'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'],
                                                           'none')})
          return opts
  
      def get_option_compile_args(self, options):
          args = []
  
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/cpp.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import functools
  import os.path
  
  from .. import coredata
  from .. import mlog
  from ..mesonlib import MesonException, version_compare
  
  from .c import CCompiler, VisualStudioCCompiler
  from .compilers import (
      GCC_MINGW,
      gnu_winlibs,
      msvc_winlibs,
      ClangCompiler,
      GnuCompiler,
      ElbrusCompiler,
      IntelCompiler,
      ArmCompiler,
      ArmclangCompiler,
  )
  from .c_function_attributes import CXX_FUNC_ATTRIBUTES
  
  class CPPCompiler(CCompiler):
  
      @classmethod
      def attribute_check_func(cls, name):
          return CXX_FUNC_ATTRIBUTES.get(name, super().attribute_check_func(name))
  
      def __init__(self, exelist, version, is_cross, exe_wrap, **kwargs):
          # If a child ObjCPP class has already set it, don't set it ourselves
          if not hasattr(self, 'language'):
              self.language = 'cpp'
          CCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs)
  
      def get_display_language(self):
          return 'C++'
  
      def get_no_stdinc_args(self):
          return ['-nostdinc++']
  
      def sanity_check(self, work_dir, environment):
          code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
          return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code)
  
      def get_compiler_check_args(self):
          # -fpermissive allows non-conforming code to compile which is necessary
          # for many C++ checks. Particularly, the has_header_symbol check is
          # too strict without this and always fails.
          return super().get_compiler_check_args() + ['-fpermissive']
  
      def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
          # Check if it's a C-like symbol
          if super().has_header_symbol(hname, symbol, prefix, env, extra_args, dependencies):
              return True
          # Check if it's a class or a template
          if extra_args is None:
              extra_args = []
          fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol}
          t = '''{prefix}
          #include <{header}>
          using {symbol};
          int main () {{ return 0; }}'''
          return self.compiles(t.format(**fargs), env, extra_args, dependencies)
  
      def _test_cpp_std_arg(self, cpp_std_value):
          # Test whether the compiler understands a -std=XY argument
          assert(cpp_std_value.startswith('-std='))
  
          # This test does not use has_multi_arguments() for two reasons:
          # 1. has_multi_arguments() requires an env argument, which the compiler
          #    object does not have at this point.
          # 2. even if it did have an env object, that might contain another more
          #    recent -std= argument, which might lead to a cascaded failure.
          CPP_TEST = 'int i = static_cast<int>(0);'
          with self.compile(code=CPP_TEST, extra_args=[cpp_std_value], mode='compile') as p:
              if p.returncode == 0:
                  mlog.debug('Compiler accepts {}:'.format(cpp_std_value), 'YES')
                  return True
              else:
                  mlog.debug('Compiler accepts {}:'.format(cpp_std_value), 'NO')
                  return False
  
      @functools.lru_cache()
      def _find_best_cpp_std(self, cpp_std):
          # The initial version mapping approach to make falling back
          # from '-std=c++14' to '-std=c++1y' was too brittle. For instance,
          # Apple's Clang uses a different versioning scheme to upstream LLVM,
          # making the whole detection logic awfully brittle. Instead, let's
          # just see if feeding GCC or Clang our '-std=' setting works, and
          # if not, try the fallback argument.
          CPP_FALLBACKS = {
              'c++11': 'c++0x',
              'gnu++11': 'gnu++0x',
              'c++14': 'c++1y',
              'gnu++14': 'gnu++1y',
              'c++17': 'c++1z',
              'gnu++17': 'gnu++1z'
          }
  
          # Currently, remapping is only supported for Clang and GCC
          assert(self.id in frozenset(['clang', 'gcc']))
  
          if cpp_std not in CPP_FALLBACKS:
              # 'c++03' and 'c++98' don't have fallback types
              return '-std=' + cpp_std
  
          for i in (cpp_std, CPP_FALLBACKS[cpp_std]):
              cpp_std_value = '-std=' + i
              if self._test_cpp_std_arg(cpp_std_value):
                  return cpp_std_value
  
          raise MesonException('C++ Compiler does not support -std={}'.format(cpp_std))
  
  
  class ClangCPPCompiler(ClangCompiler, CPPCompiler):
      def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None, **kwargs):
          CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
          ClangCompiler.__init__(self, cltype)
          default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  
      def get_options(self):
          opts = CPPCompiler.get_options(self)
          opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
                                                           ['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a',
                                                            'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'],
                                                           'none')})
          return opts
  
      def get_option_compile_args(self, options):
          args =
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/cpp.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os.path, subprocess
  
  from ..mesonlib import EnvironmentException, version_compare, is_windows, is_osx
  
  from .compilers import (
      CompilerType,
      d_dmd_buildtype_args,
      d_gdc_buildtype_args,
      d_ldc_buildtype_args,
      get_gcc_soname_args,
      gnu_color_args,
      gnu_optimization_args,
      clike_debug_args,
      Compiler,
      CompilerArgs,
  )
  
  d_feature_args = {'gcc':  {'unittest': '-funittest',
                             'version': '-fversion',
                             'import_dir': '-J'
                             },
                    'llvm': {'unittest': '-unittest',
                             'version': '-d-version',
                             'import_dir': '-J'
                             },
                    'dmd':  {'unittest': '-unittest',
                             'version': '-version',
                             'import_dir': '-J'
                             }
                    }
  
  ldc_optimization_args = {'0': [],
                           'g': [],
                           '1': ['-O1'],
                           '2': ['-O2'],
                           '3': ['-O3'],
                           's': ['-Os'],
                           }
  
  dmd_optimization_args = {'0': [],
                           'g': [],
                           '1': ['-O'],
                           '2': ['-O'],
                           '3': ['-O'],
                           's': ['-O'],
                           }
  
  class DCompiler(Compiler):
      mscrt_args = {
          'none': ['-mscrtlib='],
          'md': ['-mscrtlib=msvcrt'],
          'mdd': ['-mscrtlib=msvcrtd'],
          'mt': ['-mscrtlib=libcmt'],
          'mtd': ['-mscrtlib=libcmtd'],
      }
  
      def __init__(self, exelist, version, is_cross, is_64, **kwargs):
          self.language = 'd'
          super().__init__(exelist, version, **kwargs)
          self.id = 'unknown'
          self.is_cross = is_cross
          self.is_64 = is_64
  
      def sanity_check(self, work_dir, environment):
          source_name = os.path.join(work_dir, 'sanity.d')
          output_name = os.path.join(work_dir, 'dtest')
          with open(source_name, 'w') as ofile:
              ofile.write('''void main() { }''')
          pc = subprocess.Popen(self.exelist + self.get_output_args(output_name) + self.get_target_arch_args() + [source_name], cwd=work_dir)
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('D compiler %s can not compile programs.' % self.name_string())
          if subprocess.call(output_name) != 0:
              raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string())
  
      def needs_static_linker(self):
          return True
  
      def name_string(self):
          return ' '.join(self.exelist)
  
      def get_exelist(self):
          return self.exelist
  
      def get_linker_exelist(self):
          return self.exelist[:]
  
      def get_output_args(self, target):
          return ['-of=' + target]
  
      def get_linker_output_args(self, target):
          return ['-of=' + target]
  
      def get_include_args(self, path, is_system):
          return ['-I=' + path]
  
      def get_warn_args(self, level):
          return ['-wi']
  
      def get_werror_args(self):
          return ['-w']
  
      def get_dependency_gen_args(self, outtarget, outfile):
          # DMD and LDC does not currently return Makefile-compatible dependency info.
          return []
  
      def get_linker_search_args(self, dirname):
          # -L is recognized as "add this to the search path" by the linker,
          # while the compiler recognizes it as "pass to linker".
          return ['-Wl,-L' + dirname]
  
      def get_coverage_args(self):
          return ['-cov']
  
      def get_preprocess_only_args(self):
          return ['-E']
  
      def get_compile_only_args(self):
          return ['-c']
  
      def depfile_for_object(self, objfile):
          return objfile + '.' + self.get_depfile_suffix()
  
      def get_depfile_suffix(self):
          return 'deps'
  
      def get_pic_args(self):
          if is_windows():
              return []
          return ['-fPIC']
  
      def get_std_shared_lib_link_args(self):
          return ['-shared']
  
      def get_soname_args(self, *args):
          # FIXME: Make this work for cross-compiling
          if is_windows():
              return []
          elif is_osx():
              soname_args = get_gcc_soname_args(CompilerType.GCC_OSX, *args)
              if soname_args:
                  return ['-Wl,' + ','.join(soname_args)]
              return []
  
          return get_gcc_soname_args(CompilerType.GCC_STANDARD, *args)
  
      def get_feature_args(self, kwargs, build_to_src):
          res = []
          if 'unittest' in kwargs:
              unittest = kwargs.pop('unittest')
              unittest_arg = d_feature_args[self.id]['unittest']
              if not unittest_arg:
                  raise EnvironmentException('D compiler %s does not support the "unittest" feature.' % self.name_string())
              if unittest:
                  res.append(unittest_arg)
  
          if 'versions' in kwargs:
              versions = kwargs.pop('versions')
              if not isinstance(versions, list):
                  versions = [versions]
  
              version_arg = d_feature_args[self.id]['version']
              if not version_arg:
                  raise EnvironmentException('D compiler %s does not support the "feature versions" feature.' % self.name_string())
              for v in versions:
                  res.append('{0}={1}'.format(version_arg, v))
  
          if 'import_dirs' in kwargs:
              import_dirs = kwargs.pop('import_dirs')
              if not isinstance(import_dirs, list):
                  import_dirs = [import_dirs]
  
              import_dir_arg = d_feature_args[self.id]['import_dir']
              if not import_dir_arg:
                  raise EnvironmentException('D compiler %s does not support the "string import directories" feature.' % self.name_string())
              for idir_obj in import_dirs:
                  basedir = idir_obj.get_curdir()
                  for idir in idir_obj.get_incdirs():
                      # Avoid superfluous '/.' at the end of paths when
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/d.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os.path, subprocess
  
  from ..mesonlib import EnvironmentException, version_compare, is_windows, is_osx
  
  from .compilers import (
      GCC_STANDARD,
      GCC_OSX,
      d_dmd_buildtype_args,
      d_gdc_buildtype_args,
      d_ldc_buildtype_args,
      get_gcc_soname_args,
      gnu_color_args,
      gnu_optimization_args,
      clike_debug_args,
      Compiler,
      CompilerArgs,
  )
  
  d_feature_args = {'gcc':  {'unittest': '-funittest',
                             'version': '-fversion',
                             'import_dir': '-J'
                             },
                    'llvm': {'unittest': '-unittest',
                             'version': '-d-version',
                             'import_dir': '-J'
                             },
                    'dmd':  {'unittest': '-unittest',
                             'version': '-version',
                             'import_dir': '-J'
                             }
                    }
  
  ldc_optimization_args = {'0': [],
                           'g': [],
                           '1': ['-O1'],
                           '2': ['-O2'],
                           '3': ['-O3'],
                           's': ['-Os'],
                           }
  
  dmd_optimization_args = {'0': [],
                           'g': [],
                           '1': ['-O'],
                           '2': ['-O'],
                           '3': ['-O'],
                           's': ['-O'],
                           }
  
  class DCompiler(Compiler):
      mscrt_args = {
          'none': ['-mscrtlib='],
          'md': ['-mscrtlib=msvcrt'],
          'mdd': ['-mscrtlib=msvcrtd'],
          'mt': ['-mscrtlib=libcmt'],
          'mtd': ['-mscrtlib=libcmtd'],
      }
  
      def __init__(self, exelist, version, is_cross, is_64, **kwargs):
          self.language = 'd'
          super().__init__(exelist, version, **kwargs)
          self.id = 'unknown'
          self.is_cross = is_cross
          self.is_64 = is_64
  
      def sanity_check(self, work_dir, environment):
          source_name = os.path.join(work_dir, 'sanity.d')
          output_name = os.path.join(work_dir, 'dtest')
          with open(source_name, 'w') as ofile:
              ofile.write('''void main() { }''')
          pc = subprocess.Popen(self.exelist + self.get_output_args(output_name) + self.get_target_arch_args() + [source_name], cwd=work_dir)
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('D compiler %s can not compile programs.' % self.name_string())
          if subprocess.call(output_name) != 0:
              raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string())
  
      def needs_static_linker(self):
          return True
  
      def name_string(self):
          return ' '.join(self.exelist)
  
      def get_exelist(self):
          return self.exelist
  
      def get_linker_exelist(self):
          return self.exelist[:]
  
      def get_output_args(self, target):
          return ['-of=' + target]
  
      def get_linker_output_args(self, target):
          return ['-of=' + target]
  
      def get_include_args(self, path, is_system):
          return ['-I=' + path]
  
      def get_warn_args(self, level):
          return ['-wi']
  
      def get_werror_args(self):
          return ['-w']
  
      def get_dependency_gen_args(self, outtarget, outfile):
          # DMD and LDC does not currently return Makefile-compatible dependency info.
          return []
  
      def get_linker_search_args(self, dirname):
          # -L is recognized as "add this to the search path" by the linker,
          # while the compiler recognizes it as "pass to linker".
          return ['-Wl,-L' + dirname]
  
      def get_coverage_args(self):
          return ['-cov']
  
      def get_preprocess_only_args(self):
          return ['-E']
  
      def get_compile_only_args(self):
          return ['-c']
  
      def depfile_for_object(self, objfile):
          return objfile + '.' + self.get_depfile_suffix()
  
      def get_depfile_suffix(self):
          return 'deps'
  
      def get_pic_args(self):
          if is_windows():
              return []
          return ['-fPIC']
  
      def get_std_shared_lib_link_args(self):
          return ['-shared']
  
      def get_soname_args(self, *args):
          # FIXME: Make this work for cross-compiling
          if is_windows():
              return []
          elif is_osx():
              soname_args = get_gcc_soname_args(GCC_OSX, *args)
              if soname_args:
                  return ['-Wl,' + ','.join(soname_args)]
              return []
  
          return get_gcc_soname_args(GCC_STANDARD, *args)
  
      def get_feature_args(self, kwargs, build_to_src):
          res = []
          if 'unittest' in kwargs:
              unittest = kwargs.pop('unittest')
              unittest_arg = d_feature_args[self.id]['unittest']
              if not unittest_arg:
                  raise EnvironmentException('D compiler %s does not support the "unittest" feature.' % self.name_string())
              if unittest:
                  res.append(unittest_arg)
  
          if 'versions' in kwargs:
              versions = kwargs.pop('versions')
              if not isinstance(versions, list):
                  versions = [versions]
  
              version_arg = d_feature_args[self.id]['version']
              if not version_arg:
                  raise EnvironmentException('D compiler %s does not support the "feature versions" feature.' % self.name_string())
              for v in versions:
                  res.append('{0}={1}'.format(version_arg, v))
  
          if 'import_dirs' in kwargs:
              import_dirs = kwargs.pop('import_dirs')
              if not isinstance(import_dirs, list):
                  import_dirs = [import_dirs]
  
              import_dir_arg = d_feature_args[self.id]['import_dir']
              if not import_dir_arg:
                  raise EnvironmentException('D compiler %s does not support the "string import directories" feature.' % self.name_string())
              for idir_obj in import_dirs:
                  basedir = idir_obj.get_curdir()
                  for idir in idir_obj.get_incdirs():
                      # Avoid superfluous '/.' at the end of paths
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/d.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from .c import CCompiler
  from .compilers import (
      CompilerType,
      apple_buildtype_linker_args,
      gnulike_buildtype_args,
      gnulike_buildtype_linker_args,
      gnu_optimization_args,
      clike_debug_args,
      Compiler,
      GnuCompiler,
      ElbrusCompiler,
      IntelCompiler,
  )
  
  from mesonbuild.mesonlib import EnvironmentException, is_osx
  import subprocess, os
  
  class FortranCompiler(Compiler):
      library_dirs_cache = CCompiler.library_dirs_cache
      program_dirs_cache = CCompiler.library_dirs_cache
      find_library_cache = CCompiler.library_dirs_cache
  
      def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
          self.language = 'fortran'
          Compiler.__init__(self, exelist, version, **kwargs)
          cc = CCompiler(exelist, version, is_cross, exe_wrapper, **kwargs)
          self.id = 'unknown'
          self.is_cross = cc.is_cross
          self.exe_wrapper = cc.exe_wrapper
  
      def get_display_language(self):
          return 'Fortran'
  
      def needs_static_linker(self):
          return CCompiler.needs_static_linker(self)
  
      def get_always_args(self):
          return CCompiler.get_always_args(self)
  
      def get_linker_debug_crt_args(self):
          return CCompiler.get_linker_debug_crt_args(self)
  
      def get_no_stdinc_args(self):
          return CCompiler.get_no_stdinc_args(self)
  
      def get_no_stdlib_link_args(self):
          return CCompiler.get_no_stdlib_link_args(self)
  
      def get_warn_args(self, level):
          return CCompiler.get_warn_args(self, level)
  
      def get_no_warn_args(self):
          return CCompiler.get_no_warn_args(self)
  
      def get_soname_args(self, *args):
          return CCompiler.get_soname_args(self, *args)
  
      def sanity_check(self, work_dir, environment):
          source_name = os.path.join(work_dir, 'sanitycheckf.f90')
          binary_name = os.path.join(work_dir, 'sanitycheckf')
          with open(source_name, 'w') as ofile:
              ofile.write('''program prog
       print *, "Fortran compilation is working."
  end program prog
  ''')
          extra_flags = self.get_cross_extra_flags(environment, link=True)
          pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('Compiler %s can not compile programs.' % self.name_string())
          if self.is_cross:
              if self.exe_wrapper is None:
                  # Can't check if the binaries run so we have to assume they do
                  return
              cmdlist = self.exe_wrapper + [binary_name]
          else:
              cmdlist = [binary_name]
          pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
          pe.wait()
          if pe.returncode != 0:
              raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
  
      def get_std_warn_args(self, level):
          return FortranCompiler.std_warn_args
  
      def get_buildtype_args(self, buildtype):
          return gnulike_buildtype_args[buildtype]
  
      def get_optimization_args(self, optimization_level):
          return gnu_optimization_args[optimization_level]
  
      def get_debug_args(self, is_debug):
          return clike_debug_args[is_debug]
  
      def get_buildtype_linker_args(self, buildtype):
          if is_osx():
              return apple_buildtype_linker_args[buildtype]
          return gnulike_buildtype_linker_args[buildtype]
  
      def split_shlib_to_parts(self, fname):
          return CCompiler.split_shlib_to_parts(self, fname)
  
      def build_rpath_args(self, *args):
          return CCompiler.build_rpath_args(self, *args)
  
      def get_dependency_gen_args(self, outtarget, outfile):
          return []
  
      def depfile_for_object(self, objfile):
          return CCompiler.depfile_for_object(self, objfile)
  
      def get_depfile_suffix(self):
          return CCompiler.get_depfile_suffix(self)
  
      def get_exelist(self):
          return CCompiler.get_exelist(self)
  
      def get_linker_exelist(self):
          return CCompiler.get_linker_exelist(self)
  
      def get_preprocess_only_args(self):
          return ['-cpp'] + CCompiler.get_preprocess_only_args(self)
  
      def get_compile_only_args(self):
          return CCompiler.get_compile_only_args(self)
  
      def get_no_optimization_args(self):
          return CCompiler.get_no_optimization_args(self)
  
      def get_compiler_check_args(self):
          return CCompiler.get_compiler_check_args(self)
  
      def get_allow_undefined_link_args(self):
          return CCompiler.get_allow_undefined_link_args(self)
  
      def get_output_args(self, target):
          return CCompiler.get_output_args(self, target)
  
      def get_linker_output_args(self, outputname):
          return CCompiler.get_linker_output_args(self, outputname)
  
      def get_coverage_args(self):
          return CCompiler.get_coverage_args(self)
  
      def get_coverage_link_args(self):
          return CCompiler.get_coverage_link_args(self)
  
      def get_werror_args(self):
          return CCompiler.get_werror_args(self)
  
      def get_std_exe_link_args(self):
          return CCompiler.get_std_exe_link_args(self)
  
      def get_include_args(self, path, is_system):
          return CCompiler.get_include_args(self, path, is_system)
  
      def get_module_incdir_args(self):
          return ('-I', )
  
      def get_module_outdir_args(self, path):
          return ['-module' + path]
  
      def module_name_to_filename(self, module_name):
          return module_name.lower() + '.mod'
  
      def get_std_shared_lib_link_args(self):
          return CCompiler.get_std_shared_lib_link_args(self)
  
      def _get_search_dirs(self, *args, **kwargs):
          return CCompiler._get_search_dirs(self, *args, **kwargs)
  
      def get_compiler_dirs(self, *args, **kwargs):
          return CCompiler.get_compiler_dirs(self, *args, **kwargs)
  
      def get_l
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/fortran.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from .c import CCompiler
  from .compilers import (
      ICC_STANDARD,
      apple_buildtype_linker_args,
      gnulike_buildtype_args,
      gnulike_buildtype_linker_args,
      gnu_optimization_args,
      clike_debug_args,
      Compiler,
      GnuCompiler,
      ElbrusCompiler,
      IntelCompiler,
  )
  
  from mesonbuild.mesonlib import EnvironmentException, is_osx
  import subprocess, os
  
  class FortranCompiler(Compiler):
      library_dirs_cache = CCompiler.library_dirs_cache
      program_dirs_cache = CCompiler.library_dirs_cache
      find_library_cache = CCompiler.library_dirs_cache
  
      def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
          self.language = 'fortran'
          Compiler.__init__(self, exelist, version, **kwargs)
          cc = CCompiler(exelist, version, is_cross, exe_wrapper, **kwargs)
          self.id = 'unknown'
          self.is_cross = cc.is_cross
          self.exe_wrapper = cc.exe_wrapper
  
      def get_display_language(self):
          return 'Fortran'
  
      def needs_static_linker(self):
          return CCompiler.needs_static_linker(self)
  
      def get_always_args(self):
          return CCompiler.get_always_args(self)
  
      def get_linker_debug_crt_args(self):
          return CCompiler.get_linker_debug_crt_args(self)
  
      def get_no_stdinc_args(self):
          return CCompiler.get_no_stdinc_args(self)
  
      def get_no_stdlib_link_args(self):
          return CCompiler.get_no_stdlib_link_args(self)
  
      def get_warn_args(self, level):
          return CCompiler.get_warn_args(self, level)
  
      def get_no_warn_args(self):
          return CCompiler.get_no_warn_args(self)
  
      def get_soname_args(self, *args):
          return CCompiler.get_soname_args(self, *args)
  
      def sanity_check(self, work_dir, environment):
          source_name = os.path.join(work_dir, 'sanitycheckf.f90')
          binary_name = os.path.join(work_dir, 'sanitycheckf')
          with open(source_name, 'w') as ofile:
              ofile.write('''program prog
       print *, "Fortran compilation is working."
  end program prog
  ''')
          extra_flags = self.get_cross_extra_flags(environment, link=True)
          pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('Compiler %s can not compile programs.' % self.name_string())
          if self.is_cross:
              if self.exe_wrapper is None:
                  # Can't check if the binaries run so we have to assume they do
                  return
              cmdlist = self.exe_wrapper + [binary_name]
          else:
              cmdlist = [binary_name]
          pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
          pe.wait()
          if pe.returncode != 0:
              raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
  
      def get_std_warn_args(self, level):
          return FortranCompiler.std_warn_args
  
      def get_buildtype_args(self, buildtype):
          return gnulike_buildtype_args[buildtype]
  
      def get_optimization_args(self, optimization_level):
          return gnu_optimization_args[optimization_level]
  
      def get_debug_args(self, is_debug):
          return clike_debug_args[is_debug]
  
      def get_buildtype_linker_args(self, buildtype):
          if is_osx():
              return apple_buildtype_linker_args[buildtype]
          return gnulike_buildtype_linker_args[buildtype]
  
      def split_shlib_to_parts(self, fname):
          return CCompiler.split_shlib_to_parts(self, fname)
  
      def build_rpath_args(self, *args):
          return CCompiler.build_rpath_args(self, *args)
  
      def get_dependency_gen_args(self, outtarget, outfile):
          return []
  
      def depfile_for_object(self, objfile):
          return CCompiler.depfile_for_object(self, objfile)
  
      def get_depfile_suffix(self):
          return CCompiler.get_depfile_suffix(self)
  
      def get_exelist(self):
          return CCompiler.get_exelist(self)
  
      def get_linker_exelist(self):
          return CCompiler.get_linker_exelist(self)
  
      def get_preprocess_only_args(self):
          return ['-cpp'] + CCompiler.get_preprocess_only_args(self)
  
      def get_compile_only_args(self):
          return CCompiler.get_compile_only_args(self)
  
      def get_no_optimization_args(self):
          return CCompiler.get_no_optimization_args(self)
  
      def get_compiler_check_args(self):
          return CCompiler.get_compiler_check_args(self)
  
      def get_allow_undefined_link_args(self):
          return CCompiler.get_allow_undefined_link_args(self)
  
      def get_output_args(self, target):
          return CCompiler.get_output_args(self, target)
  
      def get_linker_output_args(self, outputname):
          return CCompiler.get_linker_output_args(self, outputname)
  
      def get_coverage_args(self):
          return CCompiler.get_coverage_args(self)
  
      def get_coverage_link_args(self):
          return CCompiler.get_coverage_link_args(self)
  
      def get_werror_args(self):
          return CCompiler.get_werror_args(self)
  
      def get_std_exe_link_args(self):
          return CCompiler.get_std_exe_link_args(self)
  
      def get_include_args(self, path, is_system):
          return CCompiler.get_include_args(self, path, is_system)
  
      def get_module_incdir_args(self):
          return ('-I', )
  
      def get_module_outdir_args(self, path):
          return ['-module' + path]
  
      def module_name_to_filename(self, module_name):
          return module_name.lower() + '.mod'
  
      def get_std_shared_lib_link_args(self):
          return CCompiler.get_std_shared_lib_link_args(self)
  
      def _get_search_dirs(self, *args, **kwargs):
          return CCompiler._get_search_dirs(self, *args, **kwargs)
  
      def get_compiler_dirs(self, *args, **kwargs):
          return CCompiler.get_compiler_dirs(self, *args, **kwargs)
  
      def get
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/fortran.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os.path, subprocess
  
  from ..mesonlib import EnvironmentException
  
  from .c import CCompiler
  from .compilers import ClangCompiler, GnuCompiler
  
  class ObjCCompiler(CCompiler):
      def __init__(self, exelist, version, is_cross, exe_wrap):
          self.language = 'objc'
          CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  
      def get_display_language(self):
          return 'Objective-C'
  
      def sanity_check(self, work_dir, environment):
          # TODO try to use sanity_check_impl instead of duplicated code
          source_name = os.path.join(work_dir, 'sanitycheckobjc.m')
          binary_name = os.path.join(work_dir, 'sanitycheckobjc')
          extra_flags = self.get_cross_extra_flags(environment, link=False)
          if self.is_cross:
              extra_flags += self.get_compile_only_args()
          with open(source_name, 'w') as ofile:
              ofile.write('#import<stdio.h>\n'
                          'int main(int argc, char **argv) { return 0; }\n')
          pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('ObjC compiler %s can not compile programs.' % self.name_string())
          if self.is_cross:
              # Can't check if the binaries run so we have to assume they do
              return
          pe = subprocess.Popen(binary_name)
          pe.wait()
          if pe.returncode != 0:
              raise EnvironmentException('Executables created by ObjC compiler %s are not runnable.' % self.name_string())
  
  
  class GnuObjCCompiler(GnuCompiler, ObjCCompiler):
      def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None):
          ObjCCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
          GnuCompiler.__init__(self, compiler_type, defines)
          default_warn_args = ['-Wall', '-Winvalid-pch']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  
  
  class ClangObjCCompiler(ClangCompiler, ObjCCompiler):
      def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None):
          ObjCCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
          ClangCompiler.__init__(self, compiler_type)
          default_warn_args = ['-Wall', '-Winvalid-pch']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
          self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']
  
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/objc.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os.path, subprocess
  
  from ..mesonlib import EnvironmentException
  
  from .c import CCompiler
  from .compilers import ClangCompiler, GnuCompiler
  
  class ObjCCompiler(CCompiler):
      def __init__(self, exelist, version, is_cross, exe_wrap):
          self.language = 'objc'
          CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  
      def get_display_language(self):
          return 'Objective-C'
  
      def sanity_check(self, work_dir, environment):
          # TODO try to use sanity_check_impl instead of duplicated code
          source_name = os.path.join(work_dir, 'sanitycheckobjc.m')
          binary_name = os.path.join(work_dir, 'sanitycheckobjc')
          extra_flags = self.get_cross_extra_flags(environment, link=False)
          if self.is_cross:
              extra_flags += self.get_compile_only_args()
          with open(source_name, 'w') as ofile:
              ofile.write('#import<stdio.h>\n'
                          'int main(int argc, char **argv) { return 0; }\n')
          pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('ObjC compiler %s can not compile programs.' % self.name_string())
          if self.is_cross:
              # Can't check if the binaries run so we have to assume they do
              return
          pe = subprocess.Popen(binary_name)
          pe.wait()
          if pe.returncode != 0:
              raise EnvironmentException('Executables created by ObjC compiler %s are not runnable.' % self.name_string())
  
  
  class GnuObjCCompiler(GnuCompiler, ObjCCompiler):
      def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
          ObjCCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
          GnuCompiler.__init__(self, gcc_type, defines)
          default_warn_args = ['-Wall', '-Winvalid-pch']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  
  
  class ClangObjCCompiler(ClangCompiler, GnuObjCCompiler):
      def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
          GnuObjCCompiler.__init__(self, exelist, version, cltype, is_cross, exe_wrapper)
          ClangCompiler.__init__(self, cltype)
          self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']
  
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/objc.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os.path, subprocess
  
  from ..mesonlib import EnvironmentException
  
  from .cpp import CPPCompiler
  from .compilers import ClangCompiler, GnuCompiler
  
  class ObjCPPCompiler(CPPCompiler):
      def __init__(self, exelist, version, is_cross, exe_wrap):
          self.language = 'objcpp'
          CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  
      def get_display_language(self):
          return 'Objective-C++'
  
      def sanity_check(self, work_dir, environment):
          # TODO try to use sanity_check_impl instead of duplicated code
          source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm')
          binary_name = os.path.join(work_dir, 'sanitycheckobjcpp')
          extra_flags = self.get_cross_extra_flags(environment, link=False)
          if self.is_cross:
              extra_flags += self.get_compile_only_args()
          with open(source_name, 'w') as ofile:
              ofile.write('#import<stdio.h>\n'
                          'class MyClass;'
                          'int main(int argc, char **argv) { return 0; }\n')
          pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('ObjC++ compiler %s can not compile programs.' % self.name_string())
          if self.is_cross:
              # Can't check if the binaries run so we have to assume they do
              return
          pe = subprocess.Popen(binary_name)
          pe.wait()
          if pe.returncode != 0:
              raise EnvironmentException('Executables created by ObjC++ compiler %s are not runnable.' % self.name_string())
  
  
  class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
      def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None):
          ObjCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
          GnuCompiler.__init__(self, compiler_type, defines)
          default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  
  
  class ClangObjCPPCompiler(ClangCompiler, ObjCPPCompiler):
      def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None):
          ObjCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
          ClangCompiler.__init__(self, compiler_type)
          default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
          self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']
  
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/objcpp.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os.path, subprocess
  
  from ..mesonlib import EnvironmentException
  
  from .cpp import CPPCompiler
  from .compilers import ClangCompiler, GnuCompiler
  
  class ObjCPPCompiler(CPPCompiler):
      def __init__(self, exelist, version, is_cross, exe_wrap):
          self.language = 'objcpp'
          CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  
      def get_display_language(self):
          return 'Objective-C++'
  
      def sanity_check(self, work_dir, environment):
          # TODO try to use sanity_check_impl instead of duplicated code
          source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm')
          binary_name = os.path.join(work_dir, 'sanitycheckobjcpp')
          extra_flags = self.get_cross_extra_flags(environment, link=False)
          if self.is_cross:
              extra_flags += self.get_compile_only_args()
          with open(source_name, 'w') as ofile:
              ofile.write('#import<stdio.h>\n'
                          'class MyClass;'
                          'int main(int argc, char **argv) { return 0; }\n')
          pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
          pc.wait()
          if pc.returncode != 0:
              raise EnvironmentException('ObjC++ compiler %s can not compile programs.' % self.name_string())
          if self.is_cross:
              # Can't check if the binaries run so we have to assume they do
              return
          pe = subprocess.Popen(binary_name)
          pe.wait()
          if pe.returncode != 0:
              raise EnvironmentException('Executables created by ObjC++ compiler %s are not runnable.' % self.name_string())
  
  
  class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
      def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
          ObjCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
          GnuCompiler.__init__(self, gcc_type, defines)
          default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
          self.warn_args = {'1': default_warn_args,
                            '2': default_warn_args + ['-Wextra'],
                            '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  
  
  class ClangObjCPPCompiler(ClangCompiler, GnuObjCPPCompiler):
      def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
          GnuObjCPPCompiler.__init__(self, exelist, version, cltype, is_cross, exe_wrapper)
          ClangCompiler.__init__(self, cltype)
          self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage']
  
  
  [... the rest is omitted ...]
files: mesonbuild/compilers/objcpp.py
files: # Copyright 2012-2016 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import configparser, os, platform, re, shlex, shutil, subprocess
  
  from . import coredata
  from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker
  from . import mesonlib
  from .mesonlib import EnvironmentException, Popen_safe
  from . import mlog
  
  from . import compilers
  from .compilers import (
      CompilerType,
      is_assembly,
      is_header,
      is_library,
      is_llvm_ir,
      is_object,
      is_source,
  )
  from .compilers import (
      ArmCCompiler,
      ArmCPPCompiler,
      ArmclangCCompiler,
      ArmclangCPPCompiler,
      ClangCCompiler,
      ClangCPPCompiler,
      ClangObjCCompiler,
      ClangObjCPPCompiler,
      G95FortranCompiler,
      GnuCCompiler,
      GnuCPPCompiler,
      GnuFortranCompiler,
      GnuObjCCompiler,
      GnuObjCPPCompiler,
      ElbrusCCompiler,
      ElbrusCPPCompiler,
      ElbrusFortranCompiler,
      IntelCCompiler,
      IntelCPPCompiler,
      IntelFortranCompiler,
      JavaCompiler,
      MonoCompiler,
      VisualStudioCsCompiler,
      NAGFortranCompiler,
      Open64FortranCompiler,
      PathScaleFortranCompiler,
      PGIFortranCompiler,
      RustCompiler,
      SunFortranCompiler,
      ValaCompiler,
      VisualStudioCCompiler,
      VisualStudioCPPCompiler,
  )
  
  build_filename = 'meson.build'
  
  known_cpu_families = (
      'aarch64',
      'arm',
      'e2k',
      'ia64',
      'mips',
      'mips64',
      'parisc',
      'ppc',
      'ppc64',
      'riscv32',
      'riscv64',
      's390x',
      'sparc',
      'sparc64',
      'x86',
      'x86_64'
  )
  
  def detect_gcovr(version='3.1', log=False):
      gcovr_exe = 'gcovr'
      try:
          p, found = Popen_safe([gcovr_exe, '--version'])[0:2]
      except (FileNotFoundError, PermissionError):
          # Doesn't exist in PATH or isn't executable
          return None, None
      found = search_version(found)
      if p.returncode == 0:
          if log:
              mlog.log('Found gcovr-{} at {}'.format(found, shlex.quote(shutil.which(gcovr_exe))))
          return gcovr_exe, mesonlib.version_compare(found, '>=' + version)
      return None, None
  
  def find_coverage_tools():
      gcovr_exe, gcovr_new_rootdir = detect_gcovr()
  
      lcov_exe = 'lcov'
      genhtml_exe = 'genhtml'
  
      if not mesonlib.exe_exists([lcov_exe, '--version']):
          lcov_exe = None
      if not mesonlib.exe_exists([genhtml_exe, '--version']):
          genhtml_exe = None
  
      return gcovr_exe, gcovr_new_rootdir, lcov_exe, genhtml_exe
  
  def detect_ninja(version='1.5', log=False):
      for n in ['ninja', 'ninja-build']:
          try:
              p, found = Popen_safe([n, '--version'])[0:2]
          except (FileNotFoundError, PermissionError):
              # Doesn't exist in PATH or isn't executable
              continue
          found = found.strip()
          # Perhaps we should add a way for the caller to know the failure mode
          # (not found or too old)
          if p.returncode == 0 and mesonlib.version_compare(found, '>=' + version):
              if log:
                  mlog.log('Found ninja-{} at {}'.format(found, shlex.quote(shutil.which(n))))
              return n
  
  def detect_native_windows_arch():
      """
      The architecture of Windows itself: x86 or amd64
      """
      # These env variables are always available. See:
      # https://msdn.microsoft.com/en-us/library/aa384274(VS.85).aspx
      # https://blogs.msdn.microsoft.com/david.wang/2006/03/27/howto-detect-process-bitness/
      arch = os.environ.get('PROCESSOR_ARCHITEW6432', '').lower()
      if not arch:
          try:
              # If this doesn't exist, something is messing with the environment
              arch = os.environ['PROCESSOR_ARCHITECTURE'].lower()
          except KeyError:
              raise EnvironmentException('Unable to detect native OS architecture')
      return arch
  
  def detect_windows_arch(compilers):
      """
      Detecting the 'native' architecture of Windows is not a trivial task. We
      cannot trust that the architecture that Python is built for is the 'native'
      one because you can run 32-bit apps on 64-bit Windows using WOW64 and
      people sometimes install 32-bit Python on 64-bit Windows.
  
      We also can't rely on the architecture of the OS itself, since it's
      perfectly normal to compile and run 32-bit applications on Windows as if
      they were native applications. It's a terrible experience to require the
      user to supply a cross-info file to compile 32-bit applications on 64-bit
      Windows. Thankfully, the only way to compile things with Visual Studio on
      Windows is by entering the 'msvc toolchain' environment, which can be
      easily detected.
  
      In the end, the sanest method is as follows:
      1. Check if we're in an MSVC toolchain environment, and if so, return the
         MSVC toolchain architecture as our 'native' architecture.
      2. If not, check environment variables that are set by Windows and WOW64 to
         find out the architecture that Windows is built for, and use that as our
         'native' architecture.
      """
      os_arch = detect_native_windows_arch()
      if os_arch != 'amd64':
          return os_arch
      # If we're on 64-bit Windows, 32-bit apps can be compiled without
      # cross-compilation. So if we're doing that, just set the native arch as
      # 32-bit and pretend like we're running under WOW64. Else, return the
      # actual Windows architecture that we deduced above.
      for compiler in compilers.values():
  
  
  [... the rest is omitted ...]
files: mesonbuild/environment.py
files: # Copyright 2012-2016 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import configparser, os, platform, re, shlex, shutil, subprocess
  
  from . import coredata
  from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker
  from . import mesonlib
  from .mesonlib import EnvironmentException, Popen_safe
  from . import mlog
  
  from . import compilers
  from .compilers import (
      CLANG_OSX,
      CLANG_STANDARD,
      CLANG_WIN,
      GCC_CYGWIN,
      GCC_MINGW,
      GCC_OSX,
      GCC_STANDARD,
      ICC_STANDARD,
      is_assembly,
      is_header,
      is_library,
      is_llvm_ir,
      is_object,
      is_source,
  )
  from .compilers import (
      ArmCCompiler,
      ArmCPPCompiler,
      ArmclangCCompiler,
      ArmclangCPPCompiler,
      ClangCCompiler,
      ClangCPPCompiler,
      ClangObjCCompiler,
      ClangObjCPPCompiler,
      G95FortranCompiler,
      GnuCCompiler,
      GnuCPPCompiler,
      GnuFortranCompiler,
      GnuObjCCompiler,
      GnuObjCPPCompiler,
      ElbrusCCompiler,
      ElbrusCPPCompiler,
      ElbrusFortranCompiler,
      IntelCCompiler,
      IntelCPPCompiler,
      IntelFortranCompiler,
      JavaCompiler,
      MonoCompiler,
      VisualStudioCsCompiler,
      NAGFortranCompiler,
      Open64FortranCompiler,
      PathScaleFortranCompiler,
      PGIFortranCompiler,
      RustCompiler,
      SunFortranCompiler,
      ValaCompiler,
      VisualStudioCCompiler,
      VisualStudioCPPCompiler,
  )
  
  build_filename = 'meson.build'
  
  known_cpu_families = (
      'aarch64',
      'arm',
      'e2k',
      'ia64',
      'mips',
      'mips64',
      'parisc',
      'ppc',
      'ppc64',
      'riscv32',
      'riscv64',
      's390x',
      'sparc',
      'sparc64',
      'x86',
      'x86_64'
  )
  
  def detect_gcovr(version='3.1', log=False):
      gcovr_exe = 'gcovr'
      try:
          p, found = Popen_safe([gcovr_exe, '--version'])[0:2]
      except (FileNotFoundError, PermissionError):
          # Doesn't exist in PATH or isn't executable
          return None, None
      found = search_version(found)
      if p.returncode == 0:
          if log:
              mlog.log('Found gcovr-{} at {}'.format(found, shlex.quote(shutil.which(gcovr_exe))))
          return gcovr_exe, mesonlib.version_compare(found, '>=' + version)
      return None, None
  
  def find_coverage_tools():
      gcovr_exe, gcovr_new_rootdir = detect_gcovr()
  
      lcov_exe = 'lcov'
      genhtml_exe = 'genhtml'
  
      if not mesonlib.exe_exists([lcov_exe, '--version']):
          lcov_exe = None
      if not mesonlib.exe_exists([genhtml_exe, '--version']):
          genhtml_exe = None
  
      return gcovr_exe, gcovr_new_rootdir, lcov_exe, genhtml_exe
  
  def detect_ninja(version='1.5', log=False):
      for n in ['ninja', 'ninja-build']:
          try:
              p, found = Popen_safe([n, '--version'])[0:2]
          except (FileNotFoundError, PermissionError):
              # Doesn't exist in PATH or isn't executable
              continue
          found = found.strip()
          # Perhaps we should add a way for the caller to know the failure mode
          # (not found or too old)
          if p.returncode == 0 and mesonlib.version_compare(found, '>=' + version):
              if log:
                  mlog.log('Found ninja-{} at {}'.format(found, shlex.quote(shutil.which(n))))
              return n
  
  def detect_native_windows_arch():
      """
      The architecture of Windows itself: x86 or amd64
      """
      # These env variables are always available. See:
      # https://msdn.microsoft.com/en-us/library/aa384274(VS.85).aspx
      # https://blogs.msdn.microsoft.com/david.wang/2006/03/27/howto-detect-process-bitness/
      arch = os.environ.get('PROCESSOR_ARCHITEW6432', '').lower()
      if not arch:
          try:
              # If this doesn't exist, something is messing with the environment
              arch = os.environ['PROCESSOR_ARCHITECTURE'].lower()
          except KeyError:
              raise EnvironmentException('Unable to detect native OS architecture')
      return arch
  
  def detect_windows_arch(compilers):
      """
      Detecting the 'native' architecture of Windows is not a trivial task. We
      cannot trust that the architecture that Python is built for is the 'native'
      one because you can run 32-bit apps on 64-bit Windows using WOW64 and
      people sometimes install 32-bit Python on 64-bit Windows.
  
      We also can't rely on the architecture of the OS itself, since it's
      perfectly normal to compile and run 32-bit applications on Windows as if
      they were native applications. It's a terrible experience to require the
      user to supply a cross-info file to compile 32-bit applications on 64-bit
      Windows. Thankfully, the only way to compile things with Visual Studio on
      Windows is by entering the 'msvc toolchain' environment, which can be
      easily detected.
  
      In the end, the sanest method is as follows:
      1. Check if we're in an MSVC toolchain environment, and if so, return the
         MSVC toolchain architecture as our 'native' architecture.
      2. If not, check environment variables that are set by Windows and WOW64 to
         find out the architecture that Windows is built for, and use that as our
         'native' architecture.
      """
      os_arch = detect_native_windows_arch()
      if os_arch != 'amd64':
          return os_arch
      # If we're on 64-bit Windows, 32-bit apps can be compiled without
      # cross-compilation. So if we're doing that,
  
  [... the rest is omitted ...]
files: mesonbuild/environment.py
files: #!/usr/bin/env python3
  # Copyright 2016-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import stat
  import shlex
  import subprocess
  import re, json
  import tempfile
  import textwrap
  import os
  import shutil
  import unittest
  import platform
  from itertools import chain
  from unittest import mock
  from configparser import ConfigParser
  from glob import glob
  from pathlib import (PurePath, Path)
  
  import mesonbuild.mlog
  import mesonbuild.compilers
  import mesonbuild.environment
  import mesonbuild.mesonlib
  import mesonbuild.coredata
  import mesonbuild.modules.gnome
  from mesonbuild.interpreter import Interpreter, ObjectHolder
  from mesonbuild.mesonlib import (
      is_windows, is_osx, is_cygwin, is_dragonflybsd, is_openbsd,
      windows_proof_rmtree, python_command, version_compare,
      BuildDirLock, Version
  )
  from mesonbuild.environment import detect_ninja
  from mesonbuild.mesonlib import MesonException, EnvironmentException
  from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
  import mesonbuild.modules.pkgconfig
  
  from run_tests import exe_suffix, get_fake_env, get_meson_script
  from run_tests import get_builddir_target_args, get_backend_commands, Backend
  from run_tests import ensure_backend_detects_changes, run_configure_inprocess
  from run_tests import run_mtest_inprocess
  from run_tests import FakeBuild, FakeCompilerOptions
  
  def get_dynamic_section_entry(fname, entry):
      if is_cygwin() or is_osx():
              raise unittest.SkipTest('Test only applicable to ELF platforms')
  
      try:
          raw_out = subprocess.check_output(['readelf', '-d', fname],
                                            universal_newlines=True)
      except FileNotFoundError:
          # FIXME: Try using depfixer.py:Elf() as a fallback
          raise unittest.SkipTest('readelf not found')
      pattern = re.compile(entry + r': \[(.*?)\]')
      for line in raw_out.split('\n'):
          m = pattern.search(line)
          if m is not None:
              return m.group(1)
      return None # The file did not contain the specified entry.
  
  def get_soname(fname):
      return get_dynamic_section_entry(fname, 'soname')
  
  def get_rpath(fname):
      return get_dynamic_section_entry(fname, r'(?:rpath|runpath)')
  
  def is_tarball():
      if not os.path.isdir('docs'):
          return True
      return False
  
  def is_ci():
      if 'TRAVIS' in os.environ or 'APPVEYOR' in os.environ:
          return True
      return False
  
  def _git_init(project_dir):
      subprocess.check_call(['git', 'init'], cwd=project_dir, stdout=subprocess.DEVNULL)
      subprocess.check_call(['git', 'config',
                             'user.name', 'Author Person'], cwd=project_dir)
      subprocess.check_call(['git', 'config',
                             'user.email', 'teh_coderz@example.com'], cwd=project_dir)
      subprocess.check_call('git add *', cwd=project_dir, shell=True,
                            stdout=subprocess.DEVNULL)
      subprocess.check_call(['git', 'commit', '-a', '-m', 'I am a project'], cwd=project_dir,
                            stdout=subprocess.DEVNULL)
  
  def skipIfNoPkgconfig(f):
      '''
      Skip this test if no pkg-config is found, unless we're on Travis or
      Appveyor CI.  This allows users to run our test suite without having
      pkg-config installed on, f.ex., macOS, while ensuring that our CI does not
      silently skip the test because of misconfiguration.
  
      Note: Yes, we provide pkg-config even while running Windows CI
      '''
      def wrapped(*args, **kwargs):
          if not is_ci() and shutil.which('pkg-config') is None:
              raise unittest.SkipTest('pkg-config not found')
          return f(*args, **kwargs)
      return wrapped
  
  class PatchModule:
      '''
      Fancy monkey-patching! Whee! Can't use mock.patch because it only
      patches in the local namespace.
      '''
      def __init__(self, func, name, impl):
          self.func = func
          assert(isinstance(name, str))
          self.func_name = name
          self.old_impl = None
          self.new_impl = impl
  
      def __enter__(self):
          self.old_impl = self.func
          exec('{} = self.new_impl'.format(self.func_name))
  
      def __exit__(self, *args):
          exec('{} = self.old_impl'.format(self.func_name))
  
  
  class InternalTests(unittest.TestCase):
  
      def test_version_number(self):
          searchfunc = mesonbuild.environment.search_version
          self.assertEqual(searchfunc('foobar 1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('foobar 2016.10.28 1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('2016.10.28 1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('foobar 2016.10.128'), 'unknown version')
          self.assertEqual(searchfunc('2016.10.128'), 'unknown version')
  
      def test_mode_symbolic_to_bits(self):
          modefunc = mesonbuild.mesonlib.FileMode.perms_s_to_bits
          self.assertEqual(modefunc('---------'), 0)
          self.assertEqual(modefunc('r--------'), stat.S_IRUSR)
          self.assertEqual(modefunc('---r-----'), stat.S_IRGRP)
          self.assertEqual(modefunc('------r--'), stat.S_IROTH)
          self.assertEqual(modefunc('-w-------'), stat.S_IWUSR)
          self.assertEqual(modefunc('----w----'), stat.S_IWGRP)
          self.assertEqual(modefunc('-------w-'), stat.S_IWOTH)
          self.assertEqual(modefunc('--x------'), stat.S_IXUSR)
          self.assertEqual(modefunc('-----x---'), stat.S_IXGRP)
          self.assertEqual(modefunc('--------x'), stat.S_IXOTH)
          self.assertEqual(modefunc('--S------'), stat.S_ISUID)
          self.assertEqual(modefunc('-----S---'), stat.S_ISGID)
          self.assertEqual(modefunc('--------T'), stat
  
  [... the rest is omitted ...]
files: run_unittests.py
files: #!/usr/bin/env python3
  # Copyright 2016-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import stat
  import shlex
  import subprocess
  import re, json
  import tempfile
  import textwrap
  import os
  import shutil
  import unittest
  import platform
  from itertools import chain
  from unittest import mock
  from configparser import ConfigParser
  from glob import glob
  from pathlib import (PurePath, Path)
  
  import mesonbuild.mlog
  import mesonbuild.compilers
  import mesonbuild.environment
  import mesonbuild.mesonlib
  import mesonbuild.coredata
  import mesonbuild.modules.gnome
  from mesonbuild.interpreter import Interpreter, ObjectHolder
  from mesonbuild.mesonlib import (
      is_windows, is_osx, is_cygwin, is_dragonflybsd, is_openbsd,
      windows_proof_rmtree, python_command, version_compare,
      BuildDirLock, Version
  )
  from mesonbuild.environment import detect_ninja
  from mesonbuild.mesonlib import MesonException, EnvironmentException
  from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
  import mesonbuild.modules.pkgconfig
  
  from run_tests import exe_suffix, get_fake_env, get_meson_script
  from run_tests import get_builddir_target_args, get_backend_commands, Backend
  from run_tests import ensure_backend_detects_changes, run_configure_inprocess
  from run_tests import run_mtest_inprocess
  from run_tests import FakeBuild, FakeCompilerOptions
  
  def get_dynamic_section_entry(fname, entry):
      if is_cygwin() or is_osx():
              raise unittest.SkipTest('Test only applicable to ELF platforms')
  
      try:
          raw_out = subprocess.check_output(['readelf', '-d', fname],
                                            universal_newlines=True)
      except FileNotFoundError:
          # FIXME: Try using depfixer.py:Elf() as a fallback
          raise unittest.SkipTest('readelf not found')
      pattern = re.compile(entry + r': \[(.*?)\]')
      for line in raw_out.split('\n'):
          m = pattern.search(line)
          if m is not None:
              return m.group(1)
      return None # The file did not contain the specified entry.
  
  def get_soname(fname):
      return get_dynamic_section_entry(fname, 'soname')
  
  def get_rpath(fname):
      return get_dynamic_section_entry(fname, r'(?:rpath|runpath)')
  
  def is_tarball():
      if not os.path.isdir('docs'):
          return True
      return False
  
  def is_ci():
      if 'TRAVIS' in os.environ or 'APPVEYOR' in os.environ:
          return True
      return False
  
  def _git_init(project_dir):
      subprocess.check_call(['git', 'init'], cwd=project_dir, stdout=subprocess.DEVNULL)
      subprocess.check_call(['git', 'config',
                             'user.name', 'Author Person'], cwd=project_dir)
      subprocess.check_call(['git', 'config',
                             'user.email', 'teh_coderz@example.com'], cwd=project_dir)
      subprocess.check_call('git add *', cwd=project_dir, shell=True,
                            stdout=subprocess.DEVNULL)
      subprocess.check_call(['git', 'commit', '-a', '-m', 'I am a project'], cwd=project_dir,
                            stdout=subprocess.DEVNULL)
  
  def skipIfNoPkgconfig(f):
      '''
      Skip this test if no pkg-config is found, unless we're on Travis or
      Appveyor CI.  This allows users to run our test suite without having
      pkg-config installed on, f.ex., macOS, while ensuring that our CI does not
      silently skip the test because of misconfiguration.
  
      Note: Yes, we provide pkg-config even while running Windows CI
      '''
      def wrapped(*args, **kwargs):
          if not is_ci() and shutil.which('pkg-config') is None:
              raise unittest.SkipTest('pkg-config not found')
          return f(*args, **kwargs)
      return wrapped
  
  class PatchModule:
      '''
      Fancy monkey-patching! Whee! Can't use mock.patch because it only
      patches in the local namespace.
      '''
      def __init__(self, func, name, impl):
          self.func = func
          assert(isinstance(name, str))
          self.func_name = name
          self.old_impl = None
          self.new_impl = impl
  
      def __enter__(self):
          self.old_impl = self.func
          exec('{} = self.new_impl'.format(self.func_name))
  
      def __exit__(self, *args):
          exec('{} = self.old_impl'.format(self.func_name))
  
  
  class InternalTests(unittest.TestCase):
  
      def test_version_number(self):
          searchfunc = mesonbuild.environment.search_version
          self.assertEqual(searchfunc('foobar 1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('foobar 2016.10.28 1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('2016.10.28 1.2.3'), '1.2.3')
          self.assertEqual(searchfunc('foobar 2016.10.128'), 'unknown version')
          self.assertEqual(searchfunc('2016.10.128'), 'unknown version')
  
      def test_mode_symbolic_to_bits(self):
          modefunc = mesonbuild.mesonlib.FileMode.perms_s_to_bits
          self.assertEqual(modefunc('---------'), 0)
          self.assertEqual(modefunc('r--------'), stat.S_IRUSR)
          self.assertEqual(modefunc('---r-----'), stat.S_IRGRP)
          self.assertEqual(modefunc('------r--'), stat.S_IROTH)
          self.assertEqual(modefunc('-w-------'), stat.S_IWUSR)
          self.assertEqual(modefunc('----w----'), stat.S_IWGRP)
          self.assertEqual(modefunc('-------w-'), stat.S_IWOTH)
          self.assertEqual(modefunc('--x------'), stat.S_IXUSR)
          self.assertEqual(modefunc('-----x---'), stat.S_IXGRP)
          self.assertEqual(modefunc('--------x'), stat.S_IXOTH)
          self.assertEqual(modefunc('--S------'), stat.S_ISUID)
          self.assertEqual(modefunc('-----S---'), stat.S_ISGID)
          self.assertEqual(modefunc('--------T'), stat
  
  [... the rest is omitted ...]
files: run_unittests.py