class_docstr: Custom `build_ext` command to include CUDA C source files.
class_docstr_tok: ["Custom","`","build_ext","`","command","to","include","CUDA","C","source","files","."]
code: def build_extensions(self) -> None:
      num_jobs = int(os.environ.get("CUPY_NUM_BUILD_JOBS", "4"))
      if num_jobs > 1:
          self.parallel = num_jobs
          if hasattr(self.compiler, "initialize"):
              # Workarounds a bug in setuptools/distutils on Windows by
              # initializing the compiler before starting a thread.
              # By default, MSVCCompiler performs initialization in the
              # first compilation. However, in parallel compilation mode,
              # the init code runs in each thread and messes up the internal
              # state as the init code is not locked and is not idempotent.
              # https://github.com/pypa/setuptools/blob/v60.0.0/setuptools/_distutils/_msvccompiler.py#L322-L327
              self.compiler.initialize()
  
      # Compile "*.pyx" files into "*.cpp" files.
      print("Cythonizing...")
      self._cythonize(num_jobs)
  
      # Change an extension in each source filenames from "*.pyx" to "*.cpp".
      # c.f. `Cython.Distutils.old_build_ext`
      for ext in self.extensions:
          sources_pyx, sources_others = filter_files_by_extension(
              ext.sources, ".pyx"
          )
          sources_cpp = [
              "{}.cpp".format(os.path.splitext(src)[0])
              for src in sources_pyx
          ]
          ext.sources = sources_cpp + sources_others
          for src in ext.sources:
              if not os.path.isfile(src):
                  raise RuntimeError(
                      f"Fatal error: missing file: {src}"
                  )
  
      print("Building extensions...")
      super().build_extensions()
  
      if sys.platform == "win32":
          print("Generating DLL dependency list...")
  
          # Find "dumpbin.exe" next to "lib.exe".
          dumpbin = os.path.join(
              os.path.dirname(self.compiler.lib), "dumpbin.exe"
          )
  
          # Save list of dependent DLLs for all extension modules.
          depends = sorted(
              set(
                  sum(
                      [
                          dumpbin_dependents(dumpbin, f)
                          for f in self.get_outputs()
                      ],
                      [],
                  )
              )
          )
  
          depends_json = os.path.join(
              self.build_lib, "cupy", ".data", "_depends.json"
          )
          os.makedirs(os.path.dirname(depends_json), exist_ok=True)
          with open(depends_json, "w") as f:
              json.dump({"depends": depends}, f)
  
imports: import json
  import os
  import os.path
  import subprocess
  import sys
  from typing import Any, Dict, List, Tuple
  import setuptools
  import setuptools.command.build_ext
  import cupy_builder
  import cupy_builder.install_build
  from cupy_builder._context import Context
  from cupy_builder._compiler import DeviceCompilerUnix, DeviceCompilerWin32
label_desc: Use image node_id 2 for calling the custom_build_ext obj's underlying member method code with example usage: obj.build_extensions() without return types