|
| 1 | +from pathlib import Path |
| 2 | + |
| 3 | +from clang_bind.cmake_frontend import CMakeFileAPI, CompilationDatabase |
| 4 | +from clang_bind.parse import Parse |
| 5 | + |
| 6 | + |
| 7 | +class Bind: |
| 8 | + """Class to bind cpp modules. |
| 9 | +
|
| 10 | + :param source_dir: Source dir of cpp library. |
| 11 | + :type source_dir: str |
| 12 | + :param build_dir: CMake build dir of cpp library, containing .cmake dir or compile_commands.json |
| 13 | + :type build_dir: str |
| 14 | + :param output_dir: Output dir |
| 15 | + :type output_dir: str |
| 16 | + :param output_module_name: Module name in python |
| 17 | + :type output_module_name: str |
| 18 | + :param cpp_modules: List of cpp modules to bind, defaults to []: bind all. |
| 19 | + :type cpp_modules: list, optional |
| 20 | + :param allow_inclusions_from_other_modules: Allow inclusions from other modules, which are not specified in cpp_modules, defaults to True |
| 21 | + :type allow_inclusions_from_other_modules: bool, optional |
| 22 | + """ |
| 23 | + |
| 24 | + def __init__( |
| 25 | + self, |
| 26 | + source_dir, |
| 27 | + build_dir, |
| 28 | + output_dir, |
| 29 | + output_module_name, |
| 30 | + cpp_modules=[], |
| 31 | + allow_inclusions_from_other_modules=True, |
| 32 | + ): |
| 33 | + all_cpp_modules = CMakeFileAPI(build_dir).get_library_targets() |
| 34 | + if not cpp_modules: |
| 35 | + cpp_modules = all_cpp_modules # bind all cpp modules |
| 36 | + |
| 37 | + all_inclusion_sources = [] |
| 38 | + for module in all_cpp_modules: # for all cpp modules, populate the variable |
| 39 | + sources = CMakeFileAPI(build_dir).get_sources(module) # module's sources |
| 40 | + cpp_sources = list( |
| 41 | + filter(lambda source: source.endswith(".cpp"), sources) |
| 42 | + ) # sources ending with .cpp |
| 43 | + all_inclusion_sources += list( |
| 44 | + set(sources) - set(cpp_sources) |
| 45 | + ) # other sources like .h and .hpp files |
| 46 | + |
| 47 | + self.binding_db = {} # binding database |
| 48 | + for module in cpp_modules: |
| 49 | + sources = CMakeFileAPI(build_dir).get_sources(module) # module's sources |
| 50 | + cpp_sources = list( |
| 51 | + filter(lambda source: source.endswith(".cpp"), sources) |
| 52 | + ) # sources ending with .cpp |
| 53 | + inclusion_sources = ( |
| 54 | + all_inclusion_sources |
| 55 | + if allow_inclusions_from_other_modules |
| 56 | + else list(set(sources) - set(cpp_sources)) |
| 57 | + ) # other sources like .h and .hpp files |
| 58 | + |
| 59 | + self.binding_db[module] = { |
| 60 | + "inclusion_sources": inclusion_sources, # inclusions for the module |
| 61 | + "files": [ # list of files' information |
| 62 | + { |
| 63 | + "source_path": Path(source_dir, cpp_source), |
| 64 | + "output_path": Path(output_dir, cpp_source), |
| 65 | + "compiler_arguments": CompilationDatabase( |
| 66 | + build_dir |
| 67 | + ).get_compilation_arguments(cpp_source), |
| 68 | + } |
| 69 | + for cpp_source in cpp_sources |
| 70 | + ], |
| 71 | + } |
| 72 | + |
| 73 | + def _parse(self): |
| 74 | + """For all input files, get the parsed tree and update the db.""" |
| 75 | + for module in self.binding_db.values(): |
| 76 | + for file in module.get("files"): |
| 77 | + # for each file, update the db with the parsed tree |
| 78 | + file.update( |
| 79 | + { |
| 80 | + "parsed_tree": Parse( |
| 81 | + file.get("source_path"), |
| 82 | + module.get("inclusion_sources"), |
| 83 | + file.get("compiler_arguments"), |
| 84 | + ).get_tree() |
| 85 | + } |
| 86 | + ) |
| 87 | + |
| 88 | + def bind(self): |
| 89 | + """Function to bind the input files.""" |
| 90 | + self._parse() |
0 commit comments