Browse Source

interface changes

rebrand
Martin Dørum 3 years ago
parent
commit
aaaa88a20a
4 changed files with 127 additions and 61 deletions
  1. 2
    3
      src/DepNode.cc
  2. 114
    58
      src/main.cc
  3. 10
    0
      src/sys.cc
  4. 1
    0
      src/sys.h

+ 2
- 3
src/DepNode.cc View File

@@ -85,11 +85,10 @@ void DepNode::joinBuild() {
}

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

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

+ 114
- 58
src/main.cc View File

@@ -5,6 +5,9 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <utility>
#include <stdexcept>

#include "BBParser.h"
#include "parallel.h"
@@ -15,32 +18,132 @@
#include "build.h"
#include "compdb.h"

static void run(std::vector<std::string> args, std::vector<std::pair<std::string, std::string>> kwargs) {
std::string op;
std::string path;

if (args.size() == 0) {
op = "build";
path = "./bb-out";
} else if (args[0][0] == '.' || args[0][0] == '/') {
op = "build";
path = args[0];
} else if (args.size() == 1) {
op = args[0];
path = "./bb-out";
} else if (args.size() == 2) {
op = args[0];
path = args[1];
} else {
// TODO: Print usage instead?
throw std::runtime_error("Incorrect number of arguments");
}

sys::mkdirp(path);

auto buildVariables = [&]() -> BBVariables {
BBVariables variables;
if (sys::fileExists(path + "/.config.bb")) {
std::ifstream f = sys::ifstream(path + "/.config.bb");
BBParser parser(f, BBParser::FLAG_NONE);
parser.parse(variables);
}

for (auto &pair: kwargs) {
std::stringstream ss(pair.second);
BBParser parser(ss, BBParser::FLAG_NONE);
auto &list = variables[pair.first];
list.clear();
parser.parseList(variables, list);
}

if (kwargs.size() > 0) {
std::ofstream f = sys::ofstream(path + "/.config.bb");
BBWriter w(f);
w.write(variables);
}

return variables;
};

auto buildTree = [&](BBVariables vars) -> std::unique_ptr<DepNode> {
return buildDepTree(path, std::move(vars));
};

auto buildCompileCommands = [&](DepNode &root) {
std::ofstream f = sys::ofstream(path + "/compile_commands.json");
compdb::Writer w(f);
root.writeCompDB(path, w);
sys::symlink(path + "/compile_commands.json", "compile_commands.json");
};

if (op == "build") {
auto root = buildTree(buildVariables());
buildCompileCommands(*root);

if (root->hasChanged(path)) {
root->startBuild(path);
root->joinBuild();
} else {
logger::log("Nothing to do.");
}

} else if (op == "config") {
BBVariables variables = buildVariables();

printf("%s:\n", (path + "/.config.bb").c_str());
if (variables.size() == 0) {
printf("No config options set.\n");
}
for (auto &pair: variables) {
printf("%s:", pair.first.c_str());
for (auto &val: pair.second) {
printf(" %s", val.c_str());
}
printf("\n");
}

} else if (op == "compile-commands") {
buildCompileCommands(*buildTree(buildVariables()));

} else if (op == "clean") {
// TODO: Remove what's needed, instead of removing everything and
// re-creating .config.bb
BBVariables variables = buildVariables();
sys::rmrf(path);
sys::rmrf("compile_commands.json");
sys::mkdirp(path);
std::ofstream f = sys::ofstream(path + "/.config.bb");
BBWriter w(f);
w.write(variables);

} else {
throw std::runtime_error("Unknown operation '" + op + "'");
}
}

int main(int argc, char **argv) {
std::string outDir = "bbbuild";
int jobs = parallel::coreCount() * 1.2 + 2;
std::string workDir = "";
std::string target = "";

const char *shortopts = "hvo:j:C:cp";
const char *shortopts = "hvj:C:";
const struct option opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ "output", required_argument, NULL, 'o' },
{ "jobs", required_argument, NULL, 'j' },
{ "directory", required_argument, NULL, 'C' },
{ "target", required_argument, NULL, 't' },
{},
};

const char usage[] =
"Usage: bbbuild [options...] [sources]\n"
"Usage: bbbuild [options...] [build | config | compile-commands | clean] [path]\n"
"\n"
" -h, --help "
"Show this help text.\n"
" -v, --verbose "
"Show every command as it's executing.\n"
" -o, --output <dir> "
"Set output directory. Default: bbbuild\n"
" -j, --jobs <count> "
"Set the number of jobs run simultaneously. "
"Default: the number of cores in the machine.\n"
@@ -65,10 +168,6 @@ int main(int argc, char **argv) {
global::verbose += 1;
break;

case 'o':
outDir = optarg;
break;

case 'j':
jobs = atoi(optarg);
if (jobs <= 0) {
@@ -96,62 +195,19 @@ int main(int argc, char **argv) {
sys::chdir(workDir);
}

// Read in variables from conf if it exists
BBVariables variables;
if (sys::fileExists(outDir + "/.config.bb")) {
std::ifstream f = sys::ifstream(outDir + "/.config.bb");
BBParser parser(f, BBParser::FLAG_NONE);
parser.parse(variables);
}

// Read non-option arguments (variable definitions and args)
bool varsChanged = false;
// Find args and keyword args
std::vector<std::string> args;
std::vector<std::pair<std::string, std::string>> kwargs;
while (optind < argc) {
char *arg = argv[optind++];
char *eq = strchr(arg, '=');
if (eq == nullptr) {
args.push_back(arg);
} else {
varsChanged = true;
std::stringstream val(eq + 1);
BBParser parser(val, BBParser::FLAG_NONE);
std::string key(arg, eq - arg);
std::vector<std::string> &list = variables[key];
list.clear();
parser.parseList(variables, list);
kwargs.push_back(std::make_pair(
std::string(arg, eq - arg), std::string(eq + 1)));
}
}

// If our variables changed, write out the new ones
if (varsChanged) {
std::ofstream f = sys::ofstream(outDir + "/.config.bb");
BBWriter w(f);
w.write(variables);
}

// Build dependency graph
std::unique_ptr<DepNode> root = buildDepTree(outDir, variables);
if (root == nullptr) {
logger::log("No source files.");
return 0;
}

sys::mkdirp(outDir);

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

// Build the project
if (root->hasChanged(outDir)) {
root->startBuild(outDir);
root->joinBuild();
} else {
logger::log("Nothing to do.");
}
run(std::move(args), std::move(kwargs));
}

+ 10
- 0
src/sys.cc View File

@@ -54,6 +54,16 @@ void mkdirp(const std::string &path) {
execute(argv, nullptr, global::verbose >= 2);
}

void rmrf(const std::string &path) {
// TODO: Implement this in C++ instead
std::vector<std::string> argv;
argv.push_back("rm");
argv.push_back("-rf");
argv.push_back("--");
argv.push_back(path);
execute(argv, nullptr, global::verbose >= 2);
}

void execute(const std::vector<std::string> &args, std::string *output, bool print) {
if (print) {
std::string str;

+ 1
- 0
src/sys.h View File

@@ -20,6 +20,7 @@ struct FileInfo {
FileInfo fileInfo(const std::string &path);
bool fileExists(const std::string &path);
void mkdirp(const std::string &path);
void rmrf(const std::string &path);
void execute(const std::vector<std::string> &args, std::string *output, bool print);
void readDir(const std::string &path, std::vector<std::string> &files);
void chdir(const std::string &path);

Loading…
Cancel
Save