python (3.11.7)
       1  import distutils.command.build_clib as orig
       2  from distutils.errors import DistutilsSetupError
       3  from distutils import log
       4  from setuptools.dep_util import newer_pairwise_group
       5  
       6  
       7  class ESC[4;38;5;81mbuild_clib(ESC[4;38;5;149morigESC[4;38;5;149m.ESC[4;38;5;149mbuild_clib):
       8      """
       9      Override the default build_clib behaviour to do the following:
      10  
      11      1. Implement a rudimentary timestamp-based dependency system
      12         so 'compile()' doesn't run every time.
      13      2. Add more keys to the 'build_info' dictionary:
      14          * obj_deps - specify dependencies for each object compiled.
      15                       this should be a dictionary mapping a key
      16                       with the source filename to a list of
      17                       dependencies. Use an empty string for global
      18                       dependencies.
      19          * cflags   - specify a list of additional flags to pass to
      20                       the compiler.
      21      """
      22  
      23      def build_libraries(self, libraries):
      24          for (lib_name, build_info) in libraries:
      25              sources = build_info.get('sources')
      26              if sources is None or not isinstance(sources, (list, tuple)):
      27                  raise DistutilsSetupError(
      28                      "in 'libraries' option (library '%s'), "
      29                      "'sources' must be present and must be "
      30                      "a list of source filenames" % lib_name)
      31              sources = list(sources)
      32  
      33              log.info("building '%s' library", lib_name)
      34  
      35              # Make sure everything is the correct type.
      36              # obj_deps should be a dictionary of keys as sources
      37              # and a list/tuple of files that are its dependencies.
      38              obj_deps = build_info.get('obj_deps', dict())
      39              if not isinstance(obj_deps, dict):
      40                  raise DistutilsSetupError(
      41                      "in 'libraries' option (library '%s'), "
      42                      "'obj_deps' must be a dictionary of "
      43                      "type 'source: list'" % lib_name)
      44              dependencies = []
      45  
      46              # Get the global dependencies that are specified by the '' key.
      47              # These will go into every source's dependency list.
      48              global_deps = obj_deps.get('', list())
      49              if not isinstance(global_deps, (list, tuple)):
      50                  raise DistutilsSetupError(
      51                      "in 'libraries' option (library '%s'), "
      52                      "'obj_deps' must be a dictionary of "
      53                      "type 'source: list'" % lib_name)
      54  
      55              # Build the list to be used by newer_pairwise_group
      56              # each source will be auto-added to its dependencies.
      57              for source in sources:
      58                  src_deps = [source]
      59                  src_deps.extend(global_deps)
      60                  extra_deps = obj_deps.get(source, list())
      61                  if not isinstance(extra_deps, (list, tuple)):
      62                      raise DistutilsSetupError(
      63                          "in 'libraries' option (library '%s'), "
      64                          "'obj_deps' must be a dictionary of "
      65                          "type 'source: list'" % lib_name)
      66                  src_deps.extend(extra_deps)
      67                  dependencies.append(src_deps)
      68  
      69              expected_objects = self.compiler.object_filenames(
      70                  sources,
      71                  output_dir=self.build_temp,
      72              )
      73  
      74              if (
      75                  newer_pairwise_group(dependencies, expected_objects)
      76                  != ([], [])
      77              ):
      78                  # First, compile the source code to object files in the library
      79                  # directory.  (This should probably change to putting object
      80                  # files in a temporary build directory.)
      81                  macros = build_info.get('macros')
      82                  include_dirs = build_info.get('include_dirs')
      83                  cflags = build_info.get('cflags')
      84                  self.compiler.compile(
      85                      sources,
      86                      output_dir=self.build_temp,
      87                      macros=macros,
      88                      include_dirs=include_dirs,
      89                      extra_postargs=cflags,
      90                      debug=self.debug
      91                  )
      92  
      93              # Now "link" the object files together into a static library.
      94              # (On Unix at least, this isn't really linking -- it just
      95              # builds an archive.  Whatever.)
      96              self.compiler.create_static_lib(
      97                  expected_objects,
      98                  lib_name,
      99                  output_dir=self.build_clib,
     100                  debug=self.debug
     101              )