summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2021-06-19 18:00:48 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2021-06-19 18:19:44 +0200
commit69528ba012ac2238f63464fb84e7623f3088603a (patch)
treec587fb15494d448a572e28ad6156aa9bb196ac17
parentf1fda74cb76600b746cc3239f3ebf2f69ce2bf53 (diff)
Add compilation database generation.
-rw-r--r--TODO3
-rw-r--r--libcppbuild.cc37
-rw-r--r--task.h2
-rw-r--r--task_cc.cc103
-rw-r--r--task_cc.h3
5 files changed, 106 insertions, 42 deletions
diff --git a/TODO b/TODO
index 34fe79a..2715747 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,6 @@
Glob convenience methods
std::string glob = getFilesInDir(...);
-Generate compilation database
-https://clang.llvm.org/docs/JSONCompilationDatabase.html
-
Add support for pre/post build hooks with conditions
Add shell script targets to be able to generate soucre files that can
diff --git a/libcppbuild.cc b/libcppbuild.cc
index 9fcc4d4..8d5231f 100644
--- a/libcppbuild.cc
+++ b/libcppbuild.cc
@@ -11,6 +11,7 @@
#include <list>
#include <array>
#include <deque>
+#include <fstream>
#include <getoptpp/getoptpp.hpp>
@@ -179,6 +180,9 @@ int main(int argc, char* argv[])
std::max(1u, std::thread::hardware_concurrency() * 2 - 1);
settings.verbose = 0;
+ bool write_compilation_database{false};
+ std::string compilation_database;
+
dg::Options opt;
opt.add("jobs", required_argument, 'j',
@@ -210,6 +214,14 @@ int main(int argc, char* argv[])
return 0;
});
+ opt.add("database", required_argument, 'd',
+ "Write compilation database json file.",
+ [&]() {
+ write_compilation_database = true;
+ compilation_database = optarg;
+ return 0;
+ });
+
opt.add("help", no_argument, 'h',
"Print this help text.",
[&]() {
@@ -246,6 +258,31 @@ int main(int argc, char* argv[])
}
}
+ if(write_compilation_database)
+ {
+ std::ofstream istr(compilation_database);
+ istr << "[";
+ bool first{true};
+ for(auto task : tasks)
+ {
+ auto s = task->toJSON();
+ if(!s.empty())
+ {
+ if(!first)
+ {
+ istr << ",\n";
+ }
+ else
+ {
+ istr << "\n";
+ }
+ first = false;
+ istr << s;
+ }
+ }
+ istr << "\n]\n";
+ }
+
for(auto task : tasks)
{
if(task->registerDepTasks(tasks))
diff --git a/task.h b/task.h
index f7a4758..9c2d622 100644
--- a/task.h
+++ b/task.h
@@ -31,6 +31,8 @@ public:
virtual std::vector<std::string> depends() const = 0;
virtual std::string target() const = 0;
+ virtual std::string toJSON() const { return {}; };
+
protected:
std::atomic<State> task_state{State::Unknown};
virtual int runInner() { return 0; };
diff --git a/task_cc.cc b/task_cc.cc
index b5cc768..6c7e3b7 100644
--- a/task_cc.cc
+++ b/task_cc.cc
@@ -175,44 +175,7 @@ int TaskCC::runInner()
return 1;
}
- std::string comp = compiler();
- auto compiler_flags = flags();
-
- std::vector<std::string> args;
- args.push_back("-MMD");
-
- if(std::filesystem::path(config.target).extension() == ".so")
- {
- // Add -fPIC arg to all contained object files
- args.push_back("-fPIC");
- }
-
- args.push_back("-c");
- args.push_back(std::string(sourceFile));
- args.push_back("-o");
- args.push_back(std::string(targetFile));
-
- for(const auto& flag : compiler_flags)
- {
- // Is arg an added include path?
- if(flag.substr(0, 2) == "-I")
- {
- std::string include_path = flag.substr(2);
- include_path.erase(0, include_path.find_first_not_of(' '));
- std::filesystem::path path(include_path);
-
- // Is it relative?
- if(path.is_relative())
- {
- path = (sourceDir / path).lexically_normal();
- std::string new_include_path = "-I" + path.string();
- args.push_back(new_include_path);
- continue;
- }
- }
-
- args.push_back(flag);
- }
+ auto args = getCompilerArgs();
{ // Write flags to file.
std::ofstream flagsStream(flagsFile);
@@ -225,7 +188,8 @@ int TaskCC::runInner()
sourceFile.lexically_normal().string() << " => " <<
targetFile.lexically_normal().string() << "\n";
}
- return execute(comp, args, settings.verbose > 0);
+
+ return execute(compiler(), args, settings.verbose > 0);
}
int TaskCC::clean()
@@ -261,6 +225,24 @@ std::string TaskCC::target() const
return targetFile;
}
+std::string TaskCC::toJSON() const
+{
+ std::string json;
+ json += "\t{\n";
+ json += "\t\t\"directory\": \"" + sourceDir.string() + "\",\n";
+ json += "\t\t\"file\": \"" + sourceFile.lexically_normal().string() + "\",\n";
+ json += "\t\t\"output\": \"" + targetFile.string() + "\",\n";
+ json += "\t\t\"arguments\": [ \"" + compiler() + "\"";
+ auto args = getCompilerArgs();
+ for(const auto& arg : args)
+ {
+ json += ", \"" + arg + "\"";
+ }
+ json += " ]\n";
+ json += "\t}";
+ return json;
+}
+
std::vector<std::string> TaskCC::flags() const
{
if(std::string(sourceFile.extension()) == ".c")
@@ -292,3 +274,46 @@ std::string TaskCC::compiler() const
}
return "/usr/bin/g++";
}
+
+std::vector<std::string> TaskCC::getCompilerArgs() const
+{
+ auto compiler_flags = flags();
+
+ std::vector<std::string> args;
+ args.push_back("-MMD");
+
+ if(std::filesystem::path(config.target).extension() == ".so")
+ {
+ // Add -fPIC arg to all contained object files
+ args.push_back("-fPIC");
+ }
+
+ args.push_back("-c");
+ args.push_back(std::string(sourceFile));
+ args.push_back("-o");
+ args.push_back(std::string(targetFile));
+
+ for(const auto& flag : compiler_flags)
+ {
+ // Is arg an added include path?
+ if(flag.substr(0, 2) == "-I")
+ {
+ std::string include_path = flag.substr(2);
+ include_path.erase(0, include_path.find_first_not_of(' '));
+ std::filesystem::path path(include_path);
+
+ // Is it relative?
+ if(path.is_relative())
+ {
+ path = (sourceDir / path).lexically_normal();
+ std::string new_include_path = "-I" + path.string();
+ args.push_back(new_include_path);
+ continue;
+ }
+ }
+
+ args.push_back(flag);
+ }
+
+ return args;
+}
diff --git a/task_cc.h b/task_cc.h
index 538188f..48910c3 100644
--- a/task_cc.h
+++ b/task_cc.h
@@ -28,10 +28,13 @@ public:
std::string target() const override;
+ std::string toJSON() const override;
+
private:
std::vector<std::string> flags() const;
std::string flagsString() const;
std::string compiler() const;
+ std::vector<std::string> getCompilerArgs() const;
std::filesystem::path sourceFile;
std::filesystem::path targetFile;