code: def __init__(self, args):
      argparser = argparse.ArgumentParser(allow_abbrev=False)
      argparser.add_argument("--cmake-binary-dir", required=True)
      argparser.add_argument("--cmake-ar", required=True)
      argparser.add_argument("--cmake-ranlib", required=True)
      argparser.add_argument("--cmake-host-system-name", required=True)
      argparser.add_argument("--cmake-cxx-standard-libraries")
      argparser.add_argument("--global-part-suffix", required=True)
      self.parsed_args, other_args = argparser.parse_known_args(
          args=args
      )
  
      if len(other_args) < 2:
          # must contain at least '--linking-cmdline' and orginal linking tool name
          raise Exception("not enough arguments")
      if other_args[0] != "--linking-cmdline":
          raise Exception(
              "expected '--linking-cmdline' arg, got {}".format(
                  other_args[0]
              )
          )
  
      self.is_msvc_compatible_linker = other_args[1].endswith(
          "\\link.exe"
      ) or other_args[1].endswith("\\lld-link.exe")
  
      is_host_system_windows = (
          self.parsed_args.cmake_host_system_name == "Windows"
      )
      std_libraries_to_exclude_from_input = (
          set(self.parsed_args.cmake_cxx_standard_libraries.split())
          if self.parsed_args.cmake_cxx_standard_libraries is not None
          else set()
      )
      msvc_preserved_option_prefixes = [
          "machine:",
          "nodefaultlib",
          "nologo",
      ]
  
      self.preserved_options = []
  
      # these variables can contain paths absolute or relative to CMAKE_BINARY_DIR
      self.global_libs_and_objects_input = []
      self.non_global_libs_input = []
      self.output = None
  
      def is_external_library(path):
          """
          Check whether this library has been built in this CMake project or came from Conan-provided dependencies
          (these use absolute paths).
          If it is a library that is added from some other path (like CUDA) return True
          """
          return not (
              os.path.exists(path)
              or os.path.exists(
                  os.path.join(self.parsed_args.cmake_binary_dir, path)
              )
          )
  
      def process_input(args):
          i = 0
          is_in_whole_archive = False
  
          while i < len(args):
              arg = args[i]
              if is_host_system_windows and (
                  (arg[0] == "/") or (arg[0] == "-")
              ):
                  arg_wo_specifier_lower = arg[1:].lower()
                  if arg_wo_specifier_lower.startswith("out:"):
                      self.output = arg[len("/out:") :]
                  elif arg_wo_specifier_lower.startswith(
                      "wholearchive:"
                  ):
                      lib_path = arg[len("/wholearchive:") :]
                      if not is_external_library(lib_path):
                          self.global_libs_and_objects_input.append(
                              lib_path
                          )
                  else:
                      for (
                          preserved_option_prefix
                      ) in msvc_preserved_option_prefixes:
                          if arg_wo_specifier_lower.startswith(
                              preserved_option_prefix
                          ):
                              self.preserved_options.append(arg)
                              break
                  # other flags are non-linking related and just ignored
              elif arg[0] == "-":
                  if arg == "-o":
                      if (i + 1) >= len(args):
                          raise Exception("-o flag without an argument")
                      self.output = args[i + 1]
                      i += 1
                  elif arg == "-Wl,--whole-archive":
                      is_in_whole_archive = True
                  elif arg == "-Wl,--no-whole-archive":
                      is_in_whole_archive = False
                  elif arg.startswith("-Wl,-force_load,"):
                      lib_path = arg[len("-Wl,-force_load,") :]
                      if not is_external_library(lib_path):
                          self.global_libs_and_objects_input.append(
                              lib_path
                          )
                  elif arg == "-isysroot":
                      i += 1
                  # other flags are non-linking related and just ignored
              elif arg[0] == "@":
                  # response file with args
                  with open(arg[1:]) as response_file:
                      parsed_args = shlex.shlex(
                          response_file,
                          posix=False,
                          punctuation_chars=False,
                      )
                      parsed_args.whitespace_split = True
                      args_in_response_file = list(
                          arg.strip('"') for arg in parsed_args
                      )
                      process_input(args_in_response_file)
              elif not is_external_library(arg):
                  if (
                      is_in_whole_archive
                      or arg.endswith(".o")
                      or arg.endswith(".obj")
                  ):
                      self.global_libs_and_objects_input.append(arg)
                  elif arg not in std_libraries_to_exclude_from_input:
                      self.non_global_libs_input.append(arg)
              i += 1
  
      process_input(other_args[2:])
  
      if self.output is None:
          raise Exception("No output specified")
  
      if (len(self.global_libs_and_objects_input) == 0) and (
          len(self.non_global_libs_input) == 0
      ):
          raise Exception(
              "List of input objects and libraries is empty"
          )
  
file_path: catboost/build/scripts/create_recursive_library_for_cmake.py
imports: import argparse
  import os
  import shlex
  import subprocess
  import sys
  import tempfile
label_desc: Use image node_id 1 to create a new Opts object from inherited base classes: object with example: obj = Opts(args)