code: def run(self):
      if not self.extensions:
          return
  
      # Make sure that extension sources are complete.
      self.run_command("build_src")
  
      if self.distribution.has_c_libraries():
          if self.inplace:
              if self.distribution.have_run.get("build_clib"):
                  log.warn(
                      "build_clib already run, it is too late to "
                      "ensure in-place build of build_clib"
                  )
                  build_clib = self.distribution.get_command_obj(
                      "build_clib"
                  )
              else:
                  build_clib = self.distribution.get_command_obj(
                      "build_clib"
                  )
                  build_clib.inplace = 1
                  build_clib.ensure_finalized()
                  build_clib.run()
                  self.distribution.have_run["build_clib"] = 1
  
          else:
              self.run_command("build_clib")
              build_clib = self.get_finalized_command("build_clib")
          self.library_dirs.append(build_clib.build_clib)
      else:
          build_clib = None
  
      # Not including C libraries to the list of
      # extension libraries automatically to prevent
      # bogus linking commands. Extensions must
      # explicitly specify the C libraries that they use.
  
      from distutils.ccompiler import new_compiler
      from numpy.distutils.fcompiler import new_fcompiler
  
      compiler_type = self.compiler
      # Initialize C compiler:
      self.compiler = new_compiler(
          compiler=compiler_type,
          verbose=self.verbose,
          dry_run=self.dry_run,
          force=self.force,
      )
      self.compiler.customize(self.distribution)
      self.compiler.customize_cmd(self)
  
      if self.warn_error:
          self.compiler.compiler.append("-Werror")
          self.compiler.compiler_so.append("-Werror")
  
      self.compiler.show_customization()
  
      if not self.disable_optimization:
          dispatch_hpath = os.path.join(
              "numpy",
              "distutils",
              "include",
              "npy_cpu_dispatch_config.h",
          )
          dispatch_hpath = os.path.join(
              self.get_finalized_command("build_src").build_src,
              dispatch_hpath,
          )
          opt_cache_path = os.path.abspath(
              os.path.join(
                  self.build_temp, "ccompiler_opt_cache_ext.py"
              )
          )
          if hasattr(self, "compiler_opt"):
              # By default `CCompilerOpt` update the cache at the exit of
              # the process, which may lead to duplicate building
              # (see build_extension()/force_rebuild) if run() called
              # multiple times within the same os process/thread without
              # giving the chance the previous instances of `CCompilerOpt`
              # to update the cache.
              self.compiler_opt.cache_flush()
  
          self.compiler_opt = new_ccompiler_opt(
              compiler=self.compiler,
              dispatch_hpath=dispatch_hpath,
              cpu_baseline=self.cpu_baseline,
              cpu_dispatch=self.cpu_dispatch,
              cache_path=opt_cache_path,
          )
  
          def report(copt):
              log.info(
                  "\n########### EXT COMPILER OPTIMIZATION ###########"
              )
              log.info(copt.report(full=True))
  
          import atexit
  
          atexit.register(report, self.compiler_opt)
  
      # Setup directory for storing generated extra DLL files on Windows
      self.extra_dll_dir = os.path.join(self.build_temp, ".libs")
      if not os.path.isdir(self.extra_dll_dir):
          os.makedirs(self.extra_dll_dir)
  
      # Create mapping of libraries built by build_clib:
      clibs = {}
      if build_clib is not None:
          for libname, build_info in build_clib.libraries or []:
              if libname in clibs and clibs[libname] != build_info:
                  log.warn(
                      "library %r defined more than once,"
                      " overwriting build_info\n%s... \nwith\n%s..."
                      % (
                          libname,
                          repr(clibs[libname])[:300],
                          repr(build_info)[:300],
                      )
                  )
              clibs[libname] = build_info
      # .. and distribution libraries:
      for libname, build_info in self.distribution.libraries or []:
          if libname in clibs:
              # build_clib libraries have a precedence before distribution ones
              continue
          clibs[libname] = build_info
  
      # Determine if C++/Fortran 77/Fortran 90 compilers are needed.
      # Update extension libraries, library_dirs, and macros.
      all_languages = set()
      for ext in self.extensions:
          ext_languages = set()
          c_libs = []
          c_lib_dirs = []
          macros = []
          for libname in ext.libraries:
              if libname in clibs:
                  binfo = clibs[libname]
                  c_libs += binfo.get("libraries", [])
                  c_lib_dirs += binfo.get("library_dirs", [])
                  for m in binfo.get("macros", []):
                      if m not in macros:
                          macros.append(m)
  
              for l in clibs.get(libname, {}).get(
                  "source_languages", []
              ):
                  ext_languages.add(l)
          if c_libs:
              new_c_libs = ext.libraries + c_libs
              log.info(
                  "updating extension %r libraries from %r to %r"
                  % (ext.name, ext.libraries, new_c_libs)
              )
              ext.libraries = new_c_libs
              ext.library_dirs = ext.library_dirs + c_lib_dirs
          if macros:
              log.info(
                  "extending extension %r defined_macros with %r"
                  % (ext.name, macros)
              )
              ext.define_macros = ext.define_macros + macros
  
          # determine extension languages
          if has_f_sources(ext.sources):
              ext_languages.add("f77")
          if has_cxx_sources(ext.sources):
              ext_languages.add("c++")
          l = ext.language or self.compiler.detect_language(ext.sources)
          if l:
              ext_languages.add(l)
  
          # reset language attribute for choosing proper linker
          #
          # When we build extensions with multiple languages, we have to
          # choose a linker. The rules here are:
          #   1. if there is Fortran code, always prefer the Fortran linker,
          #   2. otherwise prefer C++ over C,
          #   3. Users can force a particular linker by using
          #          `language='c'`  # or 'c++', 'f90', 'f77'
          #      in their config.add_extension() calls.
          if "c++" in ext_languages:
              ext_language = "c++"
          else:
              ext_language = "c"  # default
  
          has_fortran = False
          if "f90" in ext_languages:
              ext_language = "f90"
              has_fortran = True
          elif "f77" in ext_languages:
              ext_language = "f77"
              has_fortran = True
  
          if not ext.language or has_fortran:
              if l and l != ext_language and ext.language:
                  log.warn(
                      "resetting extension %r language from %r to %r."
                      % (ext.name, l, ext_language)
                  )
  
          ext.language = ext_language
  
          # global language
          all_languages.update(ext_languages)
  
      need_f90_compiler = "f90" in all_languages
      need_f77_compiler = "f77" in all_languages
      need_cxx_compiler = "c++" in all_languages
  
      # Initialize C++ compiler:
      if need_cxx_compiler:
          self._cxx_compiler = new_compiler(
              compiler=compiler_type,
              verbose=self.verbose,
              dry_run=self.dry_run,
              force=self.force,
          )
          compiler = self._cxx_compiler
          compiler.customize(
              self.distribution, need_cxx=need_cxx_compiler
          )
          compiler.customize_cmd(self)
          compiler.show_customization()
          self._cxx_compiler = compiler.cxx_compiler()
      else:
          self._cxx_compiler = None
  
      # Initialize Fortran 77 compiler:
      if need_f77_compiler:
          ctype = self.fcompiler
          self._f77_compiler = new_fcompiler(
              compiler=self.fcompiler,
              verbose=self.verbose,
              dry_run=self.dry_run,
              force=self.force,
              requiref90=False,
              c_compiler=self.compiler,
          )
          fcompiler = self._f77_compiler
          if fcompiler:
              ctype = fcompiler.compiler_type
              fcompiler.customize(self.distribution)
          if fcompiler and fcompiler.get_version():
              fcompiler.customize_cmd(self)
              fcompiler.show_customization()
          else:
              self.warn("f77_compiler=%s is not available." % (ctype))
              self._f77_compiler = None
      else:
          self._f77_compiler = None
  
      # Initialize Fortran 90 compiler:
      if need_f90_compiler:
          ctype = self.fcompiler
          self._f90_compiler = new_fcompiler(
              compiler=self.fcompiler,
              verbose=self.verbose,
              dry_run=self.dry_run,
              force=self.force,
              requiref90=True,
              c_compiler=self.compiler,
          )
          fcompiler = self._f90_compiler
          if fcompiler:
              ctype = fcompiler.compiler_type
              fcompiler.customize(self.distribution)
          if fcompiler and fcompiler.get_version():
              fcompiler.customize_cmd(self)
              fcompiler.show_customization()
          else:
              self.warn("f90_compiler=%s is not available." % (ctype))
              self._f90_compiler = None
      else:
          self._f90_compiler = None
  
      # Build extensions
      self.build_extensions()
  
      # Copy over any extra DLL files
      # FIXME: In the case where there are more than two packages,
      # we blindly assume that both packages need all of the libraries,
      # resulting in a larger wheel than is required. This should be fixed,
      # but it's so rare that I won't bother to handle it.
      pkg_roots = {
          self.get_ext_fullname(ext.name).split(".")[0]
          for ext in self.extensions
      }
      for pkg_root in pkg_roots:
          shared_lib_dir = os.path.join(pkg_root, ".libs")
          if not self.inplace:
              shared_lib_dir = os.path.join(
                  self.build_lib, shared_lib_dir
              )
          for fn in os.listdir(self.extra_dll_dir):
              if not os.path.isdir(shared_lib_dir):
                  os.makedirs(shared_lib_dir)
              if not fn.lower().endswith(".dll"):
                  continue
              runtime_lib = os.path.join(self.extra_dll_dir, fn)
              copy_file(runtime_lib, shared_lib_dir)
  
imports: import os
  import subprocess
  from glob import glob
  from distutils.dep_util import newer_group
  from distutils.command.build_ext import build_ext
  from distutils.errors import DistutilsFileError, DistutilsSetupError, DistutilsError
  from distutils.file_util import copy_file
  from numpy.distutils import log
  from numpy.distutils.exec_command import filepath_from_subprocess_output
  from numpy.distutils.system_info import combine_paths
  from numpy.distutils.misc_util import filter_sources, get_ext_source_files, get_numpy_include_dirs, has_cxx_sources, has_f_sources, is_sequence
  from numpy.distutils.command.config_compiler import show_fortran_compilers
  from numpy.distutils.ccompiler_opt import new_ccompiler_opt, CCompilerOpt
label_desc: Use image node_id 3 for calling the build_ext obj's underlying member method code with example usage: obj.run() without return types