Пример #1
0
    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)
Пример #2
0
 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))