class_docstr: CompilerRunner base class.
  
  Parameters
  ==========
  
  sources : list of str
      Paths to sources.
  out : str
  flags : iterable of str
      Compiler flags.
  run_linker : bool
  compiler_name_exe : (str, str) tuple
      Tuple of compiler name &  command to call.
  cwd : str
      Path of root of relative paths.
  include_dirs : list of str
      Include directories.
  libraries : list of str
      Libraries to link against.
  library_dirs : list of str
      Paths to search for shared libraries.
  std : str
      Standard string, e.g. ``'c++11'``, ``'c99'``, ``'f2003'``.
  define: iterable of strings
      macros to define
  undef : iterable of strings
      macros to undefine
  preferred_vendor : string
      name of preferred vendor e.g. 'gnu' or 'intel'
  
  Methods
  =======
  
  run():
      Invoke compilation as a subprocess.
class_docstr_tok: ["CompilerRunner","base","class",".","Parameters","==========","sources",":","list","of","str","Paths","to","sources",".","out",":","str","flags",":","iterable","of","str","Compiler","flags",".","run_linker",":","bool","compiler_name_exe",":","(","str",",","str",")","tuple","Tuple","of","compiler","name","&","command","to","call",".","cwd",":","str","Path","of","root","of","relative","paths",".","include_dirs",":","list","of","str","Include","directories",".","libraries",":","list","of","str","Libraries","to","link","against",".","library_dirs",":","list","of","str","Paths","to","search","for","shared","libraries",".","std",":","str","Standard","string",",","e.g",".","``","'","c++11","'","``",",","``","'c99","'","``",",","``","'f2003","'","``",".","define",":","iterable","of","strings","macros","to","define","undef",":","iterable","of","strings","macros","to","undefine","preferred_vendor",":","string","name","of","preferred","vendor","e.g",".","'gnu","'","or","'intel'","Methods","=======","run","(",")",":","Invoke","compilation","as","a","subprocess","."]
code: def __init__(
      self,
      sources,
      out,
      flags=None,
      run_linker=True,
      compiler=None,
      cwd=".",
      include_dirs=None,
      libraries=None,
      library_dirs=None,
      std=None,
      define=None,
      undef=None,
      strict_aliasing=None,
      preferred_vendor=None,
      linkline=None,
      **kwargs,
  ):
      if isinstance(sources, str):
          raise ValueError(
              "Expected argument sources to be a list of strings."
          )
      self.sources = list(sources)
      self.out = out
      self.flags = flags or []
      if os.environ.get(self.environ_key_flags):
          self.flags += os.environ[self.environ_key_flags].split()
      self.cwd = cwd
      if compiler:
          self.compiler_name, self.compiler_binary = compiler
      elif os.environ.get(self.environ_key_compiler):
          self.compiler_binary = os.environ[self.environ_key_compiler]
          for k, v in self.compiler_dict.items():
              if k in self.compiler_binary:
                  self.compiler_vendor = k
                  self.compiler_name = v
                  break
          else:
              self.compiler_vendor, self.compiler_name = list(
                  self.compiler_dict.items()
              )[0]
              warnings.warn(
                  "failed to determine what kind of compiler %s is, assuming %s"
                  % (self.compiler_binary, self.compiler_name)
              )
      else:
          # Find a compiler
          if preferred_vendor is None:
              preferred_vendor = os.environ.get(
                  "SYMPY_COMPILER_VENDOR", None
              )
          (
              self.compiler_name,
              self.compiler_binary,
              self.compiler_vendor,
          ) = self.find_compiler(preferred_vendor)
          if self.compiler_binary is None:
              raise ValueError(
                  "No compiler found (searched: {})".format(
                      ", ".join(self.compiler_dict.values())
                  )
              )
      self.define = define or []
      self.undef = undef or []
      self.include_dirs = include_dirs or []
      self.libraries = libraries or []
      self.library_dirs = library_dirs or []
      self.std = std or self.standards[0]
      self.run_linker = run_linker
      if self.run_linker:
          # both gnu and intel compilers use '-c' for disabling linker
          self.flags = list(filter(lambda x: x != "-c", self.flags))
      else:
          if "-c" not in self.flags:
              self.flags.append("-c")
  
      if self.std:
          self.flags.append(
              self.std_formater[self.compiler_name](self.std)
          )
  
      self.linkline = (linkline or []) + [
          lf
          for lf in map(
              str.strip,
              os.environ.get(self.environ_key_ldflags, "").split(),
          )
          if lf != ""
      ]
  
      if strict_aliasing is not None:
          nsa_re = re.compile("no-strict-aliasing$")
          sa_re = re.compile("strict-aliasing$")
          if strict_aliasing is True:
              if any(map(nsa_re.match, flags)):
                  raise CompileError(
                      "Strict aliasing cannot be both enforced and disabled"
                  )
              elif any(map(sa_re.match, flags)):
                  pass  # already enforced
              else:
                  flags.append("-fstrict-aliasing")
          elif strict_aliasing is False:
              if any(map(nsa_re.match, flags)):
                  pass  # already disabled
              else:
                  if any(map(sa_re.match, flags)):
                      raise CompileError(
                          "Strict aliasing cannot be both enforced and disabled"
                      )
                  else:
                      flags.append("-fno-strict-aliasing")
          else:
              msg = "Expected argument strict_aliasing to be True/False, got {}"
              raise ValueError(msg.format(strict_aliasing))
  
imports: from __future__ import annotations
  from typing import Callable, Optional
  from collections import OrderedDict
  import os
  import re
  import subprocess
  import warnings
  from .util import find_binary_of_command, unique_list, CompileError
label_desc: Use image node_id 1 to create a new CompilerRunner object  with example: obj = CompilerRunner(sources, out, flags, run_linker, compiler, cwd, include_dirs, libraries, library_dirs, std, define, undef, strict_aliasing, preferred_vendor, linkline)