首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在基于libtooling的工具中获取编译命令

如何在基于libtooling的工具中获取编译命令
EN

Stack Overflow用户
提问于 2020-02-11 10:11:17
回答 1查看 546关注 0票数 2

我已经构建了一个自定义工具(基于libtooling)来转换源代码。我使用了clang自己的教程,并设法运行了自己的自定义FrontendAction。现在,我需要解析提供给工具的编译标志(在命令行上),以自定义转换。然而,不管我做什么,CompilationDatabase似乎总是返回一个空的编译命令列表。

这是示例代码:

代码语言:javascript
运行
复制
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"

static cl::OptionCategory MyToolCategory("CustomTool");
static cl::extrahelp MoreHelp("\nMore help text...");

int main(int argc, const char **argv)
{
    CommonOptionsParser op(argc, argv, MyToolCategory);                     // Parse the command-line arguments
    CompilationDatabase &Compilations = op.getCompilations();

    for (const auto &cmd: Compilations.getAllCompileCommands()) { //<---- this list is always empty!!!
        std::cout << "filename: " << cmd.Filename;
        // Do stuff with compile flags
    }

    ClangTool Tool(Compilations, op.getSourcePathList());           // Create a new Clang Tool instance (a LibTooling environment)
    return Tool.run(newFrontendActionFactory<MyASTFrontendAction>().get()); // Run custom Frontendaction
}

我就是这样调用这个工具的:

代码语言:javascript
运行
复制
./custom-tool sample.c -- -I/some/include/path -std=gnu11

我希望能够获得命令行标志-I/some/include/path-std=gnu11

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-13 09:11:52

编译数据库

您的编译数据库(compile_commands.json)要么为空,要么不存在。从技术上讲,所有编译命令都是数据库中的所有命令,因此是空的。

然后clang如何使用我提供的选项?

Clang在CompilationDatabase对象周围创建一个临时包装器,将这些选项添加到CompilationDatabase询问过的任何文件中,即使该文件不在数据库中,甚至在不存在时也是如此。

那么,我怎样才能获得这些信息呢?

不需要迭代编译命令,您可以在源列表上进行迭代,并要求(也称为getCompileCommands)数据库为该特定文件提供命令。

工作演示

代码语言:javascript
运行
复制
#include "clang/Tooling/CommonOptionsParser.h"

using namespace clang;
using namespace tooling;
using namespace llvm;

static cl::OptionCategory MyToolCategory("CustomTool");
static cl::extrahelp MoreHelp("\nMore help text...");

void print(const std::vector<CompileCommand> &Commands) {
  if (Commands.empty()) {
    return;
  }
  for (auto opt : Commands[0].CommandLine) {
    llvm::errs() << "\t" << opt << "\n";
  }
}

int main(int argc, const char **argv) {
  CommonOptionsParser OP(argc, argv,
                         MyToolCategory);
  CompilationDatabase &Compilations = OP.getCompilations();

  for (const auto &File :
       OP.getSourcePathList()) {
    llvm::errs() << "filename: " << File << "\n";
    llvm::errs() << "opts:\n";
    auto Commands = Compilations.getCompileCommands(File);
    print(Commands);
  }

  auto CommandsForFakeFile = Compilations.getCompileCommands("baloney.c");
  llvm::errs() << "fake filename: baloney.c\n";
  print(CommandsForFakeFile);

  return 0;
}

上面的代码生成以下输出:

代码语言:javascript
运行
复制
> ./myTool test.cpp -- -I/some/include/path -std=gnu11
filename: test.cpp
opts:
    $PATH_TO_MYTOOL_EXEC/clang-tool
    -I/some/include/path
    -std=gnu11
    test.cpp
fake filename: baloney.c
    $PATH_TO_MYTOOL_EXEC/clang-tool
    -I/some/include/path
    -std=gnu11
    baloney.c

我希望这些信息会有帮助!和Clang的黑客合作愉快!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60166458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档