def parse_link_command(self, link_command: str, link_txt_path: str) -> None: link_args = link_command.split() output_path = None inputs = [] if self.conf.is_ninja: base_dir = self.conf.build_root else: base_dir = os.path.join(os.path.dirname(link_txt_path), '..', '..') i = 0 compilation = False while i < len(link_args): arg = link_args[i] if arg == '-o': new_output_path = link_args[i + 1] if output_path and new_output_path and output_path != new_output_path: raise RuntimeError( "Multiple output paths for a link command ('{}' and '{}'): {}".format( output_path, new_output_path, link_command)) output_path = new_output_path if self.conf.is_ninja and is_object_file(output_path): compilation = True i += 1 elif arg == '--shared_library_suffix': # Skip the next argument. i += 1 elif not arg.startswith('@rpath/'): if is_object_file(arg): node = self.dep_graph.find_or_create_node( os.path.abspath(os.path.join(base_dir, arg))) inputs.append(node.path) elif is_shared_library(arg): node = self.dep_graph.find_or_create_node( os.path.abspath(os.path.join(base_dir, arg)), source_str=link_txt_path) inputs.append(node.path) i += 1 if self.conf.is_ninja and compilation: # Ignore compilation commands. We are interested in linking commands only at this point. return if not output_path: if self.conf.is_ninja: return raise RuntimeError("Could not find output path for link command: %s" % link_command) if not os.path.isabs(output_path): output_path = os.path.abspath(os.path.join(base_dir, output_path)) output_node = self.dep_graph.find_or_create_node(output_path, source_str=link_txt_path) output_node.validate_existence() for input_node in inputs: dependency_node = self.dep_graph.find_or_create_node(input_node) if output_node is dependency_node: raise RuntimeError( ("Cannot add a dependency from a node to itself: %s. " "Parsed from command: %s") % (output_node, link_command)) output_node.add_dependency(dependency_node) output_node.set_link_command(link_args)
def resolve_dependent_rel_path(self, rel_path: str) -> str: if os.path.isabs(rel_path): return rel_path if is_object_file(rel_path): return os.path.join(self.conf.build_root, rel_path) raise RuntimeError( "Don't know how to resolve relative path of a 'dependent': {}". format(rel_path))