|
|
@@ -1,13 +1,12 @@ |
|
|
|
//#bb ldlibs := -lpthread |
|
|
|
|
|
|
|
#include <unistd.h> |
|
|
|
#include <getopt.h> |
|
|
|
#include <dirent.h> |
|
|
|
#include <stdexcept> |
|
|
|
#include <string.h> |
|
|
|
#include <errno.h> |
|
|
|
#include <fstream> |
|
|
|
#include <iostream> |
|
|
|
#include <sstream> |
|
|
|
#include <unordered_set> |
|
|
|
#include <mutex> |
|
|
|
|
|
|
@@ -18,10 +17,10 @@ |
|
|
|
#include "globals.h" |
|
|
|
#include "logger.h" |
|
|
|
|
|
|
|
static void readDir(std::string dir, std::vector<SourceFile> &sources, |
|
|
|
static void findSourcesInDir(std::string dir, std::vector<SourceFile> &sources, |
|
|
|
BBBParser::Variables vars); |
|
|
|
|
|
|
|
static void readPath(std::string dir, std::string name, |
|
|
|
static void findSources(std::string dir, std::string name, |
|
|
|
std::vector<SourceFile> &sources, BBBParser::Variables vars) { |
|
|
|
std::string path = dir + "/" + name; |
|
|
|
sys::FileInfo finfo = sys::fileInfo(path); |
|
|
@@ -30,7 +29,7 @@ static void readPath(std::string dir, std::string name, |
|
|
|
// We don't want to send 'files' |
|
|
|
BBBParser::Variables subvars = vars; |
|
|
|
subvars.erase("files"); |
|
|
|
readDir(path, sources, std::move(subvars)); |
|
|
|
findSourcesInDir(path, sources, std::move(subvars)); |
|
|
|
} else { |
|
|
|
SourceFile::FileType type = SourceFile::fileTypeFrom(name); |
|
|
|
if (type != SourceFile::FileType::UNKNOWN) { |
|
|
@@ -39,7 +38,7 @@ static void readPath(std::string dir, std::string name, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void readDir(std::string dir, std::vector<SourceFile> &sources, |
|
|
|
static void findSourcesInDir(std::string dir, std::vector<SourceFile> &sources, |
|
|
|
BBBParser::Variables vars) { |
|
|
|
std::ifstream buildFile(dir + "/build.bbb"); |
|
|
|
std::vector<std::string> files; |
|
|
@@ -59,27 +58,14 @@ static void readDir(std::string dir, std::vector<SourceFile> &sources, |
|
|
|
|
|
|
|
// If build.bbb didn't specify 'files', we have to readdir |
|
|
|
if (!hasFiles) { |
|
|
|
DIR *d = opendir(dir.c_str()); |
|
|
|
if (d == NULL) { |
|
|
|
throw std::runtime_error("opendir '" + dir + "': " + strerror(errno)); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
struct dirent *ent; |
|
|
|
while ((ent = readdir(d)) != NULL) { |
|
|
|
if (ent->d_name[0] == '.') |
|
|
|
continue; |
|
|
|
files.emplace_back(ent->d_name); |
|
|
|
} |
|
|
|
|
|
|
|
closedir(d); |
|
|
|
sys::readDir(dir, files); |
|
|
|
} |
|
|
|
|
|
|
|
// Go through files |
|
|
|
for (auto &ent: files) { |
|
|
|
std::string path = dir + "/" + ent; |
|
|
|
BBBParser::Variables subvars = vars; |
|
|
|
readPath(dir, ent, sources, vars); |
|
|
|
findSources(dir, ent, sources, vars); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -178,7 +164,6 @@ static bool compileAndLink( |
|
|
|
int main(int argc, char **argv) { |
|
|
|
logger::LogContext logCtx = logger::init(); |
|
|
|
|
|
|
|
std::vector<std::string> srcDirs; |
|
|
|
std::string outDir = "bbbuild"; |
|
|
|
int jobs = parallel::coreCount(); |
|
|
|
std::string workDir = ""; |
|
|
@@ -254,10 +239,6 @@ int main(int argc, char **argv) { |
|
|
|
workDir = optarg; |
|
|
|
break; |
|
|
|
|
|
|
|
case 't': |
|
|
|
target = optarg; |
|
|
|
break; |
|
|
|
|
|
|
|
case 'p': |
|
|
|
action = Action::PRINT_STATE; |
|
|
|
break; |
|
|
@@ -271,31 +252,49 @@ int main(int argc, char **argv) { |
|
|
|
// Change directory? |
|
|
|
if (workDir.size() > 0) { |
|
|
|
fprintf(stderr, "Entering directory '%s'\n", workDir.c_str()); |
|
|
|
sys::chdir(workDir); |
|
|
|
} |
|
|
|
|
|
|
|
if (chdir(workDir.c_str()) < 0) { |
|
|
|
perror(workDir.c_str()); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
// Read config from file |
|
|
|
BBBParser::Variables variables; |
|
|
|
if (sys::fileExists("build.bbb")) { |
|
|
|
std::ifstream stream("build.bbb"); |
|
|
|
BBBParser parser(stream, BBBParser::FLAG_NONE); |
|
|
|
parser.parse(variables); |
|
|
|
} |
|
|
|
|
|
|
|
// Read variables from argv |
|
|
|
while (optind < argc) { |
|
|
|
std::istringstream stream(argv[optind++]); |
|
|
|
BBBParser parser(stream, BBBParser::FLAG_ONE_LINE); |
|
|
|
parser.parse(variables); |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: Read this from build.bbb |
|
|
|
// Find target |
|
|
|
if (target.size() == 0) { |
|
|
|
target = "target"; |
|
|
|
auto it = variables.find("target"); |
|
|
|
if (it == variables.end() || it->second.size() == 0) { |
|
|
|
target = "target"; |
|
|
|
} else { |
|
|
|
target = it->second[0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Parse non-opt argv as source dirs |
|
|
|
if (optind < argc) { |
|
|
|
while (optind < argc) { |
|
|
|
srcDirs.push_back(argv[optind++]); |
|
|
|
// Find source dirs |
|
|
|
std::vector<std::string> sourceDirs; |
|
|
|
{ |
|
|
|
auto it = variables.find("files"); |
|
|
|
if (it == variables.end()) { |
|
|
|
sys::readDir(".", sourceDirs); |
|
|
|
} else { |
|
|
|
sourceDirs = it->second; |
|
|
|
} |
|
|
|
} else { |
|
|
|
srcDirs.push_back("."); |
|
|
|
} |
|
|
|
|
|
|
|
// Read configs from source dirs |
|
|
|
std::vector<SourceFile> sources; |
|
|
|
for (std::string &dir: srcDirs) { |
|
|
|
readDir(dir, sources, {}); |
|
|
|
for (std::string &dir: sourceDirs) { |
|
|
|
findSources(".", dir, sources, variables); |
|
|
|
} |
|
|
|
|
|
|
|
switch (action) { |