如何使用编译_命令.json用叮当的python绑定?

2024-03-29 02:13:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下脚本,试图打印出给定C++文件中的所有AST节点。当在包含简单include的简单文件(同一目录中的头文件等)上使用它时,它可以很好地工作。在

#!/usr/bin/env python
from argparse import ArgumentParser, FileType
from clang import cindex


def node_info(node):
    return {'kind': node.kind,
            'usr': node.get_usr(),
            'spelling': node.spelling,
            'location': node.location,
            'file': node.location.file.name,
            'extent.start': node.extent.start,
            'extent.end': node.extent.end,
            'is_definition': node.is_definition()
            }


def get_nodes_in_file(node, filename, ls=None):
    ls = ls if ls is not None else []
    for n in node.get_children():
        if n.location.file is not None and n.location.file.name == filename:
            ls.append(n)
            get_nodes_in_file(n, filename, ls)
    return ls


def main():
    arg_parser = ArgumentParser()
    arg_parser.add_argument('source_file', type=FileType('r+'),
                            help='C++ source file to parse.')
    arg_parser.add_argument('compilation_database', type=FileType('r+'),
                            help='The compile_commands.json to use to parse the source file.')
    args = arg_parser.parse_args()
    compilation_database_path = args.compilation_database.name
    source_file_path = args.source_file.name
    clang_args = ['-x', 'c++', '-std=c++11', '-p', compilation_database_path]
    index = cindex.Index.create()
    translation_unit = index.parse(source_file_path, clang_args)
    file_nodes = get_nodes_in_file(translation_unit.cursor, source_file_path)
    print [p.spelling for p in file_nodes]


if __name__ == '__main__':
    main()

但是,当我运行脚本并提供一个具有CixILL的有效C++文件时,我得到了一个^ {CD1>}命令.json父目录中的文件。使用CMake和clang,这段代码运行和构建都很好,但是我似乎不知道如何传递指向编译的参数_命令.json正确地。在

我也很难在clang文档中找到这个选项,并且无法使-ast-dump工作。但是,clang check只需传递文件路径就可以了!在


Tags: 文件pathnameinnodesourcegetis
2条回答

你自己接受的答案是不正确的。libclangdoes support compilation databases和{a2},libclang python绑定。

造成混淆的主要原因可能是libclang知道/使用的编译标志只是可以传递给clang前端的所有参数的子集。支持编译数据库,但不能自动工作:必须手动加载和查询它。这样的方法应该有效:

#!/usr/bin/env python
from argparse import ArgumentParser, FileType
from clang import cindex

compilation_database_path = args.compilation_database.name
source_file_path = args.source_file.name
index = cindex.Index.create()

# Step 1: load the compilation database
compdb = cindex.CompilationDatabase.fromDirectory(compilation_database_path)

# Step 2: query compilation flags
try:
    file_args = compdb.getCompileCommands(source_file_path)
    translation_unit = index.parse(source_file_path, file_args)
    file_nodes = get_nodes_in_file(translation_unit.cursor, source_file_path)
    print [p.spelling for p in file_nodes]
except CompilationDatabaseError:
    print 'Could not load compilation flags for', source_file_path

据我所知,Libclang不支持编译数据库,但Libtooling支持。为了解决这个问题,我选择了compile_commands.json的路径作为参数,最后自己解析它,找到感兴趣的文件和相关的include(-I和{}包含)。

相关问题 更多 >