Browse Source

compile commands again

feature/dependency-graph
Martin Dørum 3 years ago
parent
commit
89b6935c76
8 changed files with 125 additions and 5 deletions
  1. 2
    2
      Makefile
  2. 4
    0
      src/CompileStep.cc
  3. 1
    0
      src/CompileStep.h
  4. 20
    2
      src/DepNode.cc
  5. 5
    0
      src/DepNode.h
  6. 57
    0
      src/compdb.cc
  7. 23
    0
      src/compdb.h
  8. 13
    1
      src/main.cc

+ 2
- 2
Makefile View File

@@ -1,9 +1,9 @@
SRCS = \
src/BBParser.cc src/build.cc src/CompileStep.cc src/DepNode.cc \
src/BBParser.cc src/build.cc src/compdb.cc src/CompileStep.cc src/DepNode.cc \
src/globals.cc src/LinkStep.cc src/logger.cc src/parallel.cc src/sys.cc \
src/toolchain.cc src/main.cc
HDRS = \
src/BBParser.h src/build.h src/CompileStep.h src/DepNode.h \
src/BBParser.h src/build.h src/compdb.h src/CompileStep.h src/DepNode.h \
src/globals.h src/LinkStep.h src/logger.h src/parallel.h src/sys.h \
src/toolchain.h
BUILD = build

+ 4
- 0
src/CompileStep.cc View File

@@ -98,6 +98,10 @@ void CompileStep::doBuild(const std::string &outDir) {
sys::execute(command, nullptr, global::verbose >= 1);
}

void CompileStep::doWriteCompDB(const std::string &outDir, compdb::Writer &w) {
w.write(sys::cwd(), path_, compileCommand(outDir));
}

std::vector<std::string> CompileStep::getPublicLDFlags(const std::string &outDir) {
BBVariables &vars = variables();
auto it = vars.find("ldflags");

+ 1
- 0
src/CompileStep.h View File

@@ -15,6 +15,7 @@ private:

bool checkHasChanged(const std::string &outDir) override;
void doBuild(const std::string &outDir) override;
void doWriteCompDB(const std::string &outDir, compdb::Writer &w) override;
std::vector<std::string> getPublicLDFlags(const std::string &outDir) override;
std::vector<std::string> getPublicLDLibs(const std::string &outDir) override;
std::vector<std::string> getPublicObjects(const std::string &outDir) override;

+ 20
- 2
src/DepNode.cc View File

@@ -62,7 +62,7 @@ bool DepNode::haveDepsChanged(const std::string &outDir) {
}

bool DepNode::hasChanged(const std::string &outDir) {
std::lock_guard<std::mutex> lock(mut_);
std::unique_lock<std::mutex> glock(mut_);

if (was_rebuilt_) {
return true;
@@ -74,8 +74,12 @@ bool DepNode::hasChanged(const std::string &outDir) {
return false;
} else {
bool changed = checkHasChanged(outDir);

if (!changed) {
// Check children without blocking this node
glock.unlock();
changed = haveDepsChanged(outDir);
glock.lock();
}

if (changed) {
@@ -90,13 +94,15 @@ bool DepNode::hasChanged(const std::string &outDir) {

void DepNode::build(const std::string &outDir) {
bool changed = hasChanged(outDir);
std::lock_guard<std::mutex> lock(mut_);\
std::unique_lock<std::mutex> glock(mut_);\

if (!was_rebuilt_ && changed) {
int workers = 0;
std::mutex mut;
std::condition_variable cond;

// Build children without blocking this node
glock.unlock();
std::unique_lock<std::mutex> lock(mut, std::defer_lock);
for (auto &dep: deps_) {
if (dep->hasChanged(outDir)) {
@@ -116,11 +122,23 @@ void DepNode::build(const std::string &outDir) {

lock.lock();
cond.wait(lock, [&] { return workers == 0; });
glock.lock();
doBuild(outDir);
was_rebuilt_ = true;
}
}

void DepNode::writeCompDB(const std::string &outDir, compdb::Writer &w) {
std::unique_lock<std::mutex> glock(mut_);\
doWriteCompDB(outDir, w);

// Write children without blocking this node
glock.unlock();
for (auto &dep: deps_) {
dep->writeCompDB(outDir, w);
}
}

std::vector<std::string> DepNode::publicLDFlags(const std::string &outDir) {
std::unordered_set<std::string> set;
std::vector<std::string> flags;

+ 5
- 0
src/DepNode.h View File

@@ -4,12 +4,16 @@
#include <memory>
#include <mutex>
#include <string>
#include <ostream>

#include "compdb.h"

class DepNode {
public:
void addChild(std::shared_ptr<DepNode> node);
bool hasChanged(const std::string &outDir);
void build(const std::string &outDir);
void writeCompDB(const std::string &outDir, compdb::Writer &w);
virtual std::vector<std::string> publicLDFlags(const std::string &outDir);
virtual std::vector<std::string> publicLDLibs(const std::string &outDir);
virtual std::vector<std::string> publicObjects(const std::string &outDir);
@@ -21,6 +25,7 @@ protected:

virtual bool checkHasChanged(const std::string &outDir) = 0;
virtual void doBuild(const std::string &outDir) = 0;
virtual void doWriteCompDB(const std::string &outDir, compdb::Writer &w) {}
virtual std::vector<std::string> getPublicLDFlags(const std::string &outDir) { return {}; }
virtual std::vector<std::string> getPublicLDLibs(const std::string &outDir) { return {}; }
virtual std::vector<std::string> getPublicObjects(const std::string &outDir) { return {}; }

+ 57
- 0
src/compdb.cc View File

@@ -0,0 +1,57 @@
#include "compdb.h"

namespace compdb {

std::string escape(const std::string &str) {
std::string out;

// TODO: Handle unicode according to JSON spec
for (char ch: str) {
if (ch == '\\' || ch == '\"') {
out += '\\';
out += ch;
} else if (ch == '\r') {
out += '\\';
out += 'r';
} else if (ch == '\n') {
out += '\\';
out += 'n';
} else {
out += ch;
}
}

return out;
}

void Writer::write(
const std::string &dir, const std::string &file,
const std::vector<std::string> &cmd) {
if (first_) {
stream_ << "[\n\t{\n";
first_ = false;
} else {
stream_ << ", {\n";
}

stream_
<< "\t\t\"directory\": \"" << escape(dir) << "\"\n"
<< "\t\t\"file\": \"" << escape(file) << "\"\n"
<< "\t\t\"command\": \"" << escape(cmd[0]);

for (size_t i = 1; i < cmd.size(); ++i) {
stream_ << ' ' << escape('"' + escape(cmd[i]) + '"');
}

stream_ << "\"\n\t}";
}

Writer::~Writer() {
if (first_) {
stream_ << "[]\n";
} else {
stream_ << "\n]\n";
}
}

}

+ 23
- 0
src/compdb.h View File

@@ -0,0 +1,23 @@
#pragma once

#include <string>
#include <vector>
#include <ostream>

namespace compdb {

class Writer {
public:
Writer(std::ostream &stream): stream_(stream) {}
~Writer();

void write(
const std::string &dir, const std::string &file,
const std::vector<std::string> &cmd);

private:
std::ostream &stream_;
bool first_ = true;
};

}

+ 13
- 1
src/main.cc View File

@@ -2,6 +2,7 @@

#include <getopt.h>
#include <iostream>
#include <fstream>

#include "BBParser.h"
#include "parallel.h"
@@ -10,6 +11,7 @@
#include "logger.h"
#include "sys.h"
#include "build.h"
#include "compdb.h"

int main(int argc, char **argv) {
std::string outDir = "bbbuild";
@@ -105,7 +107,17 @@ int main(int argc, char **argv) {
std::unique_ptr<DepNode> root = buildDepTree(outDir, vars);
if (root == nullptr) {
logger::log("No source files.");
} else if (root->hasChanged(outDir)) {
return 0;
}

{
std::ofstream f(outDir + "/compile_commands.json");
compdb::Writer writer(f);
root->writeCompDB(outDir, writer);
sys::symlink(outDir + "/compile_commands.json", "compile_commands.json");
}

if (root->hasChanged(outDir)) {
root->build(outDir);
} else {
logger::log("Nothing to do.");

Loading…
Cancel
Save