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