code: def build_extension(self, ext):
      lit_dir = shutil.which("lit")
      ninja_dir = shutil.which("ninja")
      user_home = (
          os.getenv("HOME")
          or os.getenv("USERPROFILE")
          or os.getenv("HOMEPATH")
          or None
      )
      if not user_home:
          raise RuntimeError("Could not find user home directory")
      triton_cache_path = os.path.join(user_home, ".triton")
      # lit is used by the test suite
      thirdparty_cmake_args = get_thirdparty_packages(triton_cache_path)
      extdir = os.path.abspath(
          os.path.dirname(self.get_ext_fullpath(ext.path))
      )
      # create build directories
      if not os.path.exists(self.build_temp):
          os.makedirs(self.build_temp)
      # python directories
      python_include_dir = sysconfig.get_path("platinclude")
      cmake_args = [
          "-G",
          "Ninja",  # Ninja is much faster than make
          "-DCMAKE_MAKE_PROGRAM="
          + ninja_dir,  # Pass explicit path to ninja otherwise cmake may cache a temporary path
          "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
          "-DLLVM_ENABLE_WERROR=ON",
          "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=" + extdir,
          "-DTRITON_BUILD_TUTORIALS=OFF",
          "-DTRITON_BUILD_PYTHON_MODULE=ON",
          "-DPython3_EXECUTABLE:FILEPATH=" + sys.executable,
          "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON",
          "-DPYTHON_INCLUDE_DIRS=" + python_include_dir,
          "-DTRITON_CODEGEN_BACKENDS="
          + ";".join([b.name for b in backends]),
      ]
      if lit_dir is not None:
          cmake_args.append("-DLLVM_EXTERNAL_LIT=" + lit_dir)
      cmake_args.extend(thirdparty_cmake_args)
  
      # configuration
      cfg = get_build_type()
      build_args = ["--config", cfg]
  
      # third-party backend
  
      # codegen_backends = get_codegen_backends()
      # if len(codegen_backends) > 0:
      #     all_codegen_backends = ';'.join(codegen_backends)
      #     cmake_args += ["-DTRITON_CODEGEN_BACKENDS=" + all_codegen_backends]
  
      if platform.system() == "Windows":
          cmake_args += [
              f"-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_{cfg.upper()}={extdir}"
          ]
          if sys.maxsize > 2**32:
              cmake_args += ["-A", "x64"]
      else:
          cmake_args += ["-DCMAKE_BUILD_TYPE=" + cfg]
          max_jobs = os.getenv("MAX_JOBS", str(2 * os.cpu_count()))
          build_args += ["-j" + max_jobs]
  
      if check_env_flag("TRITON_BUILD_WITH_CLANG_LLD"):
          cmake_args += [
              "-DCMAKE_C_COMPILER=clang",
              "-DCMAKE_CXX_COMPILER=clang++",
              "-DCMAKE_LINKER=lld",
              "-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld",
              "-DCMAKE_MODULE_LINKER_FLAGS=-fuse-ld=lld",
              "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld",
          ]
  
      # Note that asan doesn't work with binaries that use the GPU, so this is
      # only useful for tools like triton-opt that don't run code on the GPU.
      #
      # I tried and gave up getting msan to work.  It seems that libstdc++'s
      # std::string does not play nicely with clang's msan (I didn't try
      # gcc's).  I was unable to configure clang to ignore the error, and I
      # also wasn't able to get libc++ to work, but that doesn't mean it's
      # impossible. :)
      if check_env_flag("TRITON_BUILD_WITH_ASAN"):
          cmake_args += [
              "-DCMAKE_C_FLAGS=-fsanitize=address",
              "-DCMAKE_CXX_FLAGS=-fsanitize=address",
          ]
  
      if check_env_flag("TRITON_BUILD_WITH_CCACHE"):
          cmake_args += [
              "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
          ]
  
      env = os.environ.copy()
      cmake_dir = get_cmake_dir()
      subprocess.check_call(
          ["cmake", self.base_dir] + cmake_args, cwd=cmake_dir, env=env
      )
      subprocess.check_call(
          ["cmake", "--build", "."] + build_args, cwd=cmake_dir
      )
      subprocess.check_call(
          ["cmake", "--build", ".", "--target", "mlir-doc"],
          cwd=cmake_dir,
      )
  
imports: import os
  import platform
  import re
  import shutil
  import subprocess
  import sys
  import sysconfig
  import tarfile
  import tempfile
  import urllib.request
  from distutils.command.clean import clean
  from pathlib import Path
  from typing import NamedTuple
  from setuptools import Extension, setup
  from setuptools.command.build_ext import build_ext
  from setuptools.command.build_py import build_py
  from dataclasses import dataclass
label_desc: Use image node_id 4 for calling the CMakeBuild obj's underlying member method code with example usage: obj.build_extension(ext) without return types