]> git.tdb.fi Git - builder.git/blob - source/compilecommandsgenerator.cpp
Add support for generating compile_commands.json
[builder.git] / source / compilecommandsgenerator.cpp
1 #include <msp/io/file.h>
2 #include <msp/io/print.h>
3 #include <msp/strings/utils.h>
4 #include "builder.h"
5 #include "compilecommandsgenerator.h"
6 #include "compilecommandsjson.h"
7 #include "objectfile.h"
8 #include "sourcefile.h"
9
10 using namespace std;
11 using namespace Msp;
12
13 CompileCommandsGenerator::CompileCommandsGenerator(Builder &b):
14         Tool(b, "CCJG")
15 { }
16
17 Target *CompileCommandsGenerator::create_target(const list<Target *> &, const string &)
18 {
19         throw logic_error("Not implemented");
20 }
21
22 Task *CompileCommandsGenerator::run(const Target &target) const
23 {
24         const CompileCommandsJson &cmds = dynamic_cast<const CompileCommandsJson &>(target);
25         Worker *worker = new Worker(cmds);
26         return new InternalTask(worker);
27 }
28
29
30 CompileCommandsGenerator::Worker::Worker(const CompileCommandsJson &t):
31         target(t)
32 { }
33
34 void CompileCommandsGenerator::Worker::main()
35 {
36         Builder &builder = target.get_package()->get_builder();
37         const SourcePackage &spkg = *target.get_package();
38         string work_dir = c_escape(spkg.get_source_directory().str());
39
40         IO::BufferedFile out(target.get_path().str(), IO::M_WRITE);
41         IO::print(out, "[");
42
43         bool first = true;
44         const BuildGraph::TargetMap &targets = builder.get_build_graph().get_targets();
45         for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i)
46                 if(i->second->is_buildable() && i->second->get_package()==&spkg)
47                         if(ObjectFile *obj = dynamic_cast<ObjectFile *>(i->second))
48                         {
49                                 FS::Path src_path = obj->get_source().get_path();
50                                 Task *task = i->second->build();
51                                 if(!first)
52                                         out.put(',');
53                                 IO::print(out, "\n\t{\n");
54                                 IO::print(out, "\t\t\"file\": \"%s\"\n", src_path);
55                                 IO::print(out, "\t\t\"command\": \"%s\"\n", c_escape(task->get_command()));
56                                 IO::print(out, "\t\t\"directory\": \"%s\"\n", work_dir);
57                                 IO::print(out, "\t}");
58                                 delete task;
59                                 first = false;
60                         }
61
62         IO::print(out, "\n]\n");
63
64         status = Task::SUCCESS;
65 }