code: def create_extension(
      extension_name,
      module_dir,
      cpp_files,
      h_files,
      swig_files,
      folders=[],
      include_modules=None,
      extra_compile_args=None,
      swig_opts=None,
  ):
      swig_path = SwigPath(module_dir, extension_name)
      extension_path = swig_path.extension_path
  
      # Add directory to filenames
      def add_dir_name(dir_name, filenames):
          return list(
              os.path.join(dir_name, filename) for filename in filenames
          )
  
      swig_files = add_dir_name(
          "lib/swig/tick/" + module_dir[7:], swig_files
      )
  
      for folder in folders:
          for file in os.listdir(folder):
              file_path = os.path.join(folder, file)
              if os.path.isfile(file_path):
                  _, ext = os.path.splitext(file)
                  if ext == ".cpp":
                      cpp_files += [os.path.join(folder, file)]
                  elif ext == ".txt":
                      pass
                  elif ext == ".inl":
                      pass
                  else:
                      warnings.warn(
                          "Included file %s in folder %s has an "
                          'unknown extension "%s"' % (file, folder, ext)
                      )
  
      min_swig_opts = [
          "-py3",
          "-c++",
          "-Ilib/swig",
          "-Ilib/include",
          "-outdir",
          swig_path.build,
      ]
  
      if swig_opts is None:
          swig_opts = min_swig_opts
      else:
          swig_opts.extend(min_swig_opts)
  
      # Here we set the minimum compile flags.
      min_extra_compile_args = [
          "-D_FILE_OFFSET_BITS=64",
          "-DPYTHON_LINK",
          "-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION",
          "-Ilib/include",
          sparse_indices_flag,
          "-std=c++11",
          "-O2",  # -O3 is sometimes dangerous and has caused segfaults on Travis
          "-DNDEBUG",  # some assertions fail without this (TODO tbh)
      ]
      if TICK_DEBUG == 0 or TICK_DEBUG == "0":
          min_extra_compile_args.append("-g0")
  
      if use_fast_math:
          min_extra_compile_args.append("-ffast-math")
  
      if extra_compile_args is None:
          extra_compile_args = min_extra_compile_args
      else:
          extra_compile_args.extend(min_extra_compile_args)
  
      extra_compile_args.append("-Wall")
  
      if platform.system() == "Windows":
          extra_compile_args.append("-DBUILDING_DLL")
      elif TICK_WERROR == 1 or TICK_WERROR == "1":
          ## Added -Wall to get all warnings and -Werror to treat them as errors
          extra_compile_args.append("-Werror")
  
      libraries = []
      library_dirs = []
      runtime_library_dirs = []
      extra_link_args = []
      define_macros = []
      extra_include_dirs = ["include", "swig"]
  
      # Deal with (optional) BLAS
      extra_compile_args.extend(blas_info.get("extra_compile_args", []))
      extra_link_args.extend(blas_info.get("extra_link_args", []))
      libraries.extend(blas_info.get("libraries", []))
      library_dirs.extend(blas_info.get("library_dirs", []))
      define_macros.extend(blas_info.get("define_macros", []))
  
      if "define_macros" in blas_info and any(
          key == "HAVE_CBLAS" for key, _ in blas_info["define_macros"]
      ):
          define_macros.append(("TICK_USE_CBLAS", None))
      if (
          "libraries" in blas_info
          and "mkl_rt" in blas_info["libraries"]
      ):
          define_macros.append(("TICK_USE_MKL", None))
          extra_include_dirs.extend(blas_info["include_dirs"])
          if platform.system() != "Windows":
              for lib_dir in blas_info["library_dirs"]:
                  extra_link_args.append("-Wl,-rpath," + lib_dir)
              # if not Linux assume MacOS
              if platform.system() != "Linux":
                  rel_path = os.path.relpath(lib_dir, swig_path.build)
                  if os.path.exists(rel_path):
                      extra_link_args.append(
                          "-Wl,-rpath,@loader_path/" + rel_path
                      )
  
      if include_modules is None:
          include_modules = []
  
      # Include all what need for module link
      for mod in include_modules:
          if mod.__class__ != SwigPath:
              raise ValueError("Unhandled class for included module")
  
          for opts in [swig_opts, extra_compile_args]:
              opts.extend(["-I" + mod.swig])
  
          # Because setuptools produces shared object files with non-standard
          # On windows we need to use ".lib" rather than ".pyd"
          # when linking libs to other libs
          if platform.system() == "Windows":
              lib = os.path.join(
                  build_dir, mod.build, "_" + mod.extension_name
              )
              lib += os.path.splitext(
                  sysconfig.get_config_var("EXT_SUFFIX")
              )[0]
              libraries.append(lib)
          elif platform.system() == "Linux":
              lib_dir = os.path.abspath(
                  os.path.join(build_dir, mod.build)
              )
              extra_link_args.append("-L" + lib_dir)
              extra_link_args.append("-Wl,-rpath," + lib_dir)
              extra_link_args.append("-l:" + mod.lib_filename)
          else:
              extra_link_args.append(
                  os.path.abspath(
                      os.path.join(
                          build_dir, mod.build, mod.lib_filename
                      )
                  )
              )
  
          # Make sure that the runtime linker can find shared object
          # dependencies by using the relative path to the dependency library.
          rel_path = os.path.relpath(mod.build, swig_path.build)
          if platform.system() == "Linux":
              # $ORIGIN refers to the location of the current shared object file
              # at runtime
              runtime_library_dirs.append("\$ORIGIN/%s" % rel_path)
          elif platform.system() == "Windows":
              pass
          else:  # Assuming non-Windows builds for now
              # For OSX builds we use @loader_path instead
              extra_link_args.append(
                  "-Wl,-rpath,%s" % "@loader_path/%s" % rel_path
              )
  
      # Setting the SONAME/install_name for the built libraries. It ensures that
      # the runtime linker will have a chance to find the libraries even after
      # they're moved (during install, for example)
      filename = swig_path.lib_filename
      if platform.system() == "Linux":
          extra_link_args.append("-Wl,-soname,%s" % filename)
      elif platform.system() == "Windows":
          pass
      else:
          # For OSX the install_name needs to be prefixed with @rpath
          extra_link_args.append(
              "-Wl,-install_name,@rpath/%s" % filename
          )
  
      for df in debug_flags:
          full_flag = "-D" + df
  
          extra_compile_args.append(full_flag)
  
          if df == "DEBUG_COSTLY_THROW":
              swig_opts.append(full_flag)
  
      # Adding Cereal serialization library
      extra_include_dirs.append("lib/third_party/cereal/include")
  
      # Adding numpy include directory
      if numpy_include:
          extra_include_dirs.append(numpy_include)
  
      # This is to override the use of IMPLIB in distutils
      # which puts the lib/exp files in the wrong directory
      # see: https://github.com/python/cpython/blob/08bb8a41cc976343795bd0e241cd7388e9f44ad5/Lib/distutils/_msvccompiler.py#L467
      if platform.system() == "Windows":
          implib = "/IMPLIB:" + os.path.abspath(
              os.path.join(
                  build_dir, swig_path.build, "_" + extension_name
              )
          )
          implib += os.path.splitext(
              sysconfig.get_config_var("EXT_SUFFIX")
          )[0]
          extra_link_args.append(implib + ".lib")
  
      core_module = SwigExtension(
          extension_path,
          module_ref=swig_path,
          sources=swig_files + cpp_files,
          extra_compile_args=extra_compile_args,
          extra_link_args=extra_link_args,
          define_macros=define_macros,
          swig_opts=swig_opts,
          libraries=libraries,
          include_dirs=extra_include_dirs,
          library_dirs=library_dirs,
          runtime_library_dirs=runtime_library_dirs,
          depends=h_files,
          language="c++",
          ext_name=extension_name,
      )
  
      return core_module
  
imports: import multiprocessing
  import os
  import pathlib
  import platform
  import re
  import shutil
  import subprocess
  import sys
  import sysconfig
  import time
  import unittest
  import warnings
  from abc import ABC
  from setuptools import find_packages, setup, Command
  from setuptools.command.install import install
  from setuptools.extension import Extension
  import distutils
  from distutils.command.build import build
  from distutils.command.clean import clean
  from distutils import sysconfig
  from packaging import version
label_desc: Use image node_id 1 for calling a global function with example usage: create_extension(extension_name, module_dir, cpp_files, h_files, swig_files, folders, include_modules, extra_compile_args, swig_opts) and returns: core_module, list