From b6296fbde37c677654bfeb7c64515870d54457fb Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Mon, 9 Jan 2017 14:52:54 -0500 Subject: [compdb] Expand response files inline based on a switch. References to response files in a clang compile_commands.json file can be tricky to deal with when tooling expects all the command flags to be present in the 'command' field. This change introduces a '-x' option to '-t compdb' that will expand @rspfile style response file invocations inline. E.g. ```sh $ ninja -t compdb cc [ { "directory": "/src/foo", "command": "cc -foo -bar @foo.obj.rsp", "file": "foo.cc" } ] $ ninja -t compdb -x cc [ { "directory": "/src/foo", "command": "cc -foo -bar foo.cc", "file": "foo.cc" } ] ``` --- src/ninja.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/ninja.cc b/src/ninja.cc index 245cac1..bc86456 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -662,10 +662,68 @@ void EncodeJSONString(const char *str) { } } -int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, char* argv[]) { +enum EvaluateCommandMode { + ECM_NORMAL, + ECM_EXPAND_RSPFILE +}; +string EvaluateCommandWithRspfile(Edge* edge, EvaluateCommandMode mode) { + string command = edge->EvaluateCommand(); + if (mode == ECM_NORMAL) + return command; + + string rspfile = edge->GetUnescapedRspfile(); + if (rspfile.empty()) + return command; + + size_t index = command.find(rspfile); + if (index == 0 || index == string::npos || command[index - 1] != '@') + return command; + + string rspfile_content = edge->GetBinding("rspfile_content"); + size_t newline_index = 0; + while ((newline_index = rspfile_content.find('\n', newline_index)) != + string::npos) { + rspfile_content.replace(newline_index, 1, 1, ' '); + ++newline_index; + } + command.replace(index - 1, rspfile.length() + 1, rspfile_content); + return command; +} + +int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, + char* argv[]) { + // The compdb tool uses getopt, and expects argv[0] to contain the name of + // the tool, i.e. "compdb". + argc++; + argv--; + bool first = true; vector cwd; + EvaluateCommandMode eval_mode = ECM_NORMAL; + + optind = 1; + int opt; + while ((opt = getopt(argc, argv, const_cast("hx"))) != -1) { + switch(opt) { + case 'x': + eval_mode = ECM_EXPAND_RSPFILE; + break; + + case 'h': + default: + printf( + "usage: ninja -t compdb [options] [rules]\n" + "\n" + "options:\n" + " -x expand @rspfile style response file invocations\n" + ); + return 1; + } + } + argv += optind; + argc -= optind; + do { cwd.resize(cwd.size() + 1024); errno = 0; @@ -688,7 +746,7 @@ int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, char* a printf("\n {\n \"directory\": \""); EncodeJSONString(&cwd[0]); printf("\",\n \"command\": \""); - EncodeJSONString((*e)->EvaluateCommand().c_str()); + EncodeJSONString(EvaluateCommandWithRspfile(*e, eval_mode).c_str()); printf("\",\n \"file\": \""); EncodeJSONString((*e)->inputs_[0]->path().c_str()); printf("\",\n \"output\": \""); -- cgit v0.12 From e71bcceefb942f8355aab83ab447d702354ba272 Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Thu, 5 Apr 2018 11:18:09 -0400 Subject: [compdb] Move declarations closer to their use. --- src/ninja.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ninja.cc b/src/ninja.cc index bc86456..f4246d6 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -697,9 +697,6 @@ int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, argc++; argv--; - bool first = true; - vector cwd; - EvaluateCommandMode eval_mode = ECM_NORMAL; optind = 1; @@ -724,6 +721,9 @@ int NinjaMain::ToolCompilationDatabase(const Options* options, int argc, argv += optind; argc -= optind; + bool first = true; + vector cwd; + do { cwd.resize(cwd.size() + 1024); errno = 0; -- cgit v0.12