code: def build(
      opts=None,
      cross_build_final_stage=False,
      cmake_platform_to_root_path: Dict[str, str] = None,
      cmake_platform_to_python_dev_paths: Dict[
          str, PythonDevPaths
      ] = None,
      **kwargs,
  ):
      """
      cmake_platform_to_root_path is dict: platform_name -> cmake_find_root_path
      cmake_platform_to_python_dev_paths is dict: platform_name -> PythonDevPaths
      used only for macOS universal builds because in other cases it is sufficient
      to add Python3_INCLUDE_DIR, Python3_LIBRARY, CMAKE_FIND_ROOT_PATH to cmake_extra_args
      """
  
      if opts is None:
          opts = Opts(**kwargs)
  
      if opts.native_built_tools_root_dir is not None:
          opts.native_built_tools_root_dir = os.path.abspath(
              opts.native_built_tools_root_dir
          )
  
      cmd_runner = CmdRunner(opts.dry_run)
  
      if opts.macos_universal_binaries:
          if opts.target_platform is not None:
              raise RuntimeError(
                  "macos_universal_binaries and target_platform options are incompatible"
              )
          build_macos_universal_binaries(
              opts,
              cmake_platform_to_root_path,
              cmake_platform_to_python_dev_paths,
              cmd_runner,
          )
          return
      elif opts.target_platform is not None:
          if (
              opts.target_platform != get_host_platform()
          ) and not cross_build_final_stage:
              cross_build(opts, cmd_runner)
              return
          target_platform = opts.target_platform
      else:
          target_platform = get_host_platform()
  
      require_pic = get_require_pic(opts.targets)
  
      logging.info(
          f'target_platform={target_platform}. Building targets {" ".join(opts.targets)} {"with" if require_pic else "without"} PIC'
      )
  
      source_root_dir = get_source_root_dir()
  
      if opts.cmake_target_toolchain is None:
          cmake_target_toolchain = get_default_build_platform_toolchain(
              source_root_dir
          )
      else:
          cmake_target_toolchain = opts.cmake_target_toolchain
  
      if platform.system().lower() == "windows":
          # Need vcvars set up for Ninja generator
          build_environ = get_msvc_environ(
              opts.msvs_installation_path,
              opts.msvs_version,
              opts.msvc_toolset,
              cmd_runner,
              opts.dry_run,
          )
      else:
          build_environ = os.environ
  
      # can be empty if called for tools build
      catboost_components = get_catboost_components(opts.targets)
  
      cmake_cmd = [
          "cmake",
          source_root_dir,
          "-B",
          opts.build_root_dir,
          "-G",
          "Ninja",
          f"-DCMAKE_BUILD_TYPE={opts.build_type}",
          f"-DCMAKE_TOOLCHAIN_FILE={cmake_target_toolchain}",
      ]
      if opts.verbose:
          cmake_cmd += ["--log-level=VERBOSE"]
      if require_pic:
          cmake_cmd += ["-DCMAKE_POSITION_INDEPENDENT_CODE=On"]
      cmake_cmd += [
          f'-DCATBOOST_COMPONENTS={";".join(sorted(catboost_components)) if catboost_components else "none"}'
      ]
      if platform.system().lower() == "darwin":
          cmake_cmd += [
              f"-DCMAKE_OSX_DEPLOYMENT_TARGET={opts.macosx_version_min}"
          ]
  
      cmake_cmd += [f'-DHAVE_CUDA={"yes" if opts.have_cuda else "no"}']
      if opts.have_cuda:
          cuda_root_dir = get_cuda_root_dir(opts.cuda_root_dir)
          # CMake requires nvcc to be available in $PATH
          add_cuda_bin_path_to_system_path(build_environ, cuda_root_dir)
          cmake_cmd += [
              f"-DCUDAToolkit_ROOT={cuda_root_dir}",
              f"-DCMAKE_CUDA_RUNTIME_LIBRARY={opts.cuda_runtime_library}",
          ]
  
      if opts.native_built_tools_root_dir:
          cmake_cmd += [
              f"-DTOOLS_ROOT={opts.native_built_tools_root_dir}"
          ]
  
      if opts.cmake_extra_args is not None:
          cmake_cmd += opts.cmake_extra_args
  
      cmd_runner.run(cmake_cmd, env=build_environ)
  
      if opts.rebuild:
          ninja_clean_cmd = [
              "ninja",
              "-C",
              opts.build_root_dir,
              "clean",
          ]
          if opts.verbose:
              ninja_cmd += ["-v"]
          ninja_clean_cmd += opts.targets
          cmd_runner.run(ninja_clean_cmd, env=build_environ)
  
      ninja_cmd = [
          "ninja",
          "-C",
          opts.build_root_dir,
      ]
      if opts.verbose:
          ninja_cmd += ["-v"]
      if opts.parallel_build_jobs is not None:
          ninja_cmd += ["-j", str(opts.parallel_build_jobs)]
      ninja_cmd += opts.targets
      cmd_runner.run(ninja_cmd, env=build_environ)
  
imports: import argparse
  import copy
  import logging
  import os
  import platform
  import subprocess
  import sys
  import tempfile
  from typing import Dict
label_desc: Use image node_id 15 for calling a global function with example usage: build(opts, cross_build_final_stage, cmake_platform_to_root_path, cmake_platform_to_python_dev_paths) without return types