This commit is contained in:
parent
94db4f2780
commit
0819baf6d3
8 changed files with 170 additions and 117 deletions
|
|
@ -28,6 +28,96 @@ import :Command;
|
|||
namespace fs = std::filesystem;
|
||||
|
||||
namespace Crafter {
|
||||
Project::Project(fs::path&& path) : path(std::move(path)) {
|
||||
if (!fs::exists(this->path)) {
|
||||
throw std::runtime_error(std::format("Project file: {} not found.", this->path.generic_string()));
|
||||
}
|
||||
|
||||
std::ifstream f(this->path);
|
||||
nlohmann::json data = nlohmann::json::parse(f);
|
||||
name = data["name"].get<std::string>();
|
||||
|
||||
this->path.remove_filename();
|
||||
|
||||
nlohmann::json configs = data["configurations"];
|
||||
nlohmann::json testJson = data["tests"];
|
||||
|
||||
if(data.contains("bin_dir")) {
|
||||
binDir = data["bin_dir"].get<std::string>();
|
||||
} else {
|
||||
binDir = "bin";
|
||||
}
|
||||
if(data.contains("build_dir")) {
|
||||
buildDir = data["build_dir"].get<std::string>();
|
||||
} else {
|
||||
buildDir = "build";
|
||||
}
|
||||
|
||||
if (!fs::exists(binDir)) {
|
||||
fs::create_directories(binDir);
|
||||
}
|
||||
|
||||
if (!fs::exists(buildDir)) {
|
||||
fs::create_directories(buildDir);
|
||||
}
|
||||
|
||||
for (nlohmann::json::iterator it = configs.begin(); it != configs.end(); ++it) {
|
||||
configurations.emplace_back(configs, (*it), this->path, *this);
|
||||
}
|
||||
|
||||
for (nlohmann::json::iterator it = testJson.begin(); it != testJson.end(); ++it) {
|
||||
tests.emplace_back(configs, (*it), this->path, *this);
|
||||
}
|
||||
|
||||
}
|
||||
Project::Project(fs::path&& path, const std::string_view config) : path(std::move(path)) {
|
||||
if (!fs::exists(this->path)) {
|
||||
throw std::runtime_error(std::format("Project file: {} not found.", path.generic_string()));
|
||||
}
|
||||
|
||||
std::ifstream f(this->path);
|
||||
nlohmann::json data = nlohmann::json::parse(f);
|
||||
name = data["name"].get<std::string>();
|
||||
|
||||
this->path.remove_filename();
|
||||
|
||||
nlohmann::json configs = data["configurations"];
|
||||
|
||||
if(data.contains("bin_dir")) {
|
||||
binDir = data["bin_dir"].get<std::string>();
|
||||
} else {
|
||||
binDir = "bin";
|
||||
}
|
||||
if(data.contains("build_dir")) {
|
||||
buildDir = data["build_dir"].get<std::string>();
|
||||
} else {
|
||||
buildDir = "build";
|
||||
}
|
||||
|
||||
if (!fs::exists(binDir)) {
|
||||
fs::create_directories(binDir);
|
||||
}
|
||||
|
||||
if (!fs::exists(buildDir)) {
|
||||
fs::create_directories(buildDir);
|
||||
}
|
||||
|
||||
|
||||
for (nlohmann::json::iterator it = configs.begin(); it != configs.end(); ++it) {
|
||||
if(it->contains("name")) {
|
||||
if((*it)["name"].get<std::string>() == config) {
|
||||
configurations.emplace_back(configs, (*it), this->path, *this);
|
||||
goto errorSkip;
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("Invalid config json, name field is missing");
|
||||
}
|
||||
}
|
||||
|
||||
throw std::runtime_error(std::format("Config {} not found, requested as dependency", config));
|
||||
|
||||
errorSkip:;
|
||||
}
|
||||
Project::Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations) : name(std::move(name)), path(std::move(path)), configurations(std::move(configurations)) {}
|
||||
Project::Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations, fs::path&& binDir, fs::path&& buildDir) : name(std::move(name)), path(std::move(path)), configurations(std::move(configurations)), binDir(std::move(binDir)), buildDir(std::move(buildDir)) {}
|
||||
|
||||
|
|
@ -51,6 +141,22 @@ namespace Crafter {
|
|||
BuildResult Project::Build(Configuration& config) const {
|
||||
return Build(config, binDir/config.name, binDir/config.name, buildDir/config.name, name);
|
||||
}
|
||||
|
||||
void AddLibsRecursive(std::string& libsString, std::unordered_set<std::string> depLibSet, Configuration& depConfig) {
|
||||
for(const std::string& lib2 : depConfig.libs) {
|
||||
if (depLibSet.insert(lib2).second) {
|
||||
libsString+=std::format(" -l{}", lib2);
|
||||
}
|
||||
}
|
||||
for(const std::tuple<std::shared_ptr<Project>, Configuration&>& dep2 : depConfig.dependencies) {
|
||||
std::string outputLib = std::get<0>(dep2)->name+std::get<1>(dep2).name;
|
||||
if (depLibSet.insert(outputLib).second) {
|
||||
libsString+=std::format(" -l{}", outputLib);
|
||||
}
|
||||
AddLibsRecursive(libsString, depLibSet, std::get<1>(dep2));
|
||||
}
|
||||
}
|
||||
|
||||
BuildResult Project::Build(Configuration& config, const fs::path& binDir, const fs::path& outputDir, const fs::path& buildDir, std::string outputName) const {
|
||||
BuildResult buildResult;
|
||||
if (!fs::exists(binDir)) {
|
||||
|
|
@ -193,55 +299,20 @@ namespace Crafter {
|
|||
|
||||
for(std::uint_fast32_t i = 0; i < depThreads.size(); i++) {
|
||||
depThreads[i] = std::thread([i, &config, &libMutex, &depLibSet, &buildDir, &pcmDir, &libsString, &binDir, this, &buildResult, &resultsDep](){
|
||||
if(config.dependencies[i].path.ends_with(".git")) {
|
||||
fs::path name = fs::path(config.dependencies[i].path).filename();
|
||||
name.replace_extension();
|
||||
if(!fs::exists(buildDir/name)) {
|
||||
if(!config.dependencies[i].branch.empty()) {
|
||||
system(std::format("cd {} && git clone {} && cd {} && git switch {}", buildDir.string(), config.dependencies[i].path, (buildDir/name).string(), config.dependencies[i].branch).c_str());
|
||||
} else if(!config.dependencies[i].commit.empty()){
|
||||
system(std::format("cd {} && git clone {} && cd {} && git checkout {}", buildDir.string(), config.dependencies[i].path, (buildDir/name).string(), config.dependencies[i].commit).c_str());
|
||||
} else {
|
||||
system(std::format("cd {} && git clone {}", buildDir.string(), config.dependencies[i].path).c_str());
|
||||
}
|
||||
} else if(config.dependencies[i].commit.empty()) {
|
||||
system(std::format("cd {} && git pull", (buildDir/name).string()).c_str());
|
||||
}
|
||||
config.dependencies[i].path = buildDir/name/"project.json";
|
||||
std::string outputLib = std::get<0>(config.dependencies[i])->name+std::get<1>(config.dependencies[i]).name;
|
||||
BuildResult depResult = std::get<0>(config.dependencies[i])->Build(std::get<1>(config.dependencies[i]), pcmDir, binDir, buildDir/std::get<0>(config.dependencies[i])->name/std::get<0>(config.dependencies[i])->buildDir, outputLib);
|
||||
libMutex.lock();
|
||||
if(depResult.repack) {
|
||||
buildResult.repack = true;
|
||||
}
|
||||
if(fs::path(config.dependencies[i].path).is_relative()) {
|
||||
config.dependencies[i].path = this->path/config.dependencies[i].path;
|
||||
}
|
||||
Project project = Project::LoadFromJSON(config.dependencies[i].path);
|
||||
for(Configuration& depConfig : project.configurations) {
|
||||
if(depConfig.name == config.dependencies[i].configuration){
|
||||
fs::path depBuildDir = fs::path(config.dependencies[i].path).parent_path()/project.buildDir/depConfig.name;
|
||||
BuildResult depResult = project.Build(depConfig, pcmDir, binDir, depBuildDir, project.name);
|
||||
libMutex.lock();
|
||||
if(depResult.repack) {
|
||||
buildResult.repack = true;
|
||||
}
|
||||
resultsDep[i] = depResult.errors;
|
||||
resultsDep[i] = depResult.errors;
|
||||
|
||||
if (depLibSet.insert(project.name).second) {
|
||||
libsString+=std::format(" -l{}", project.name);
|
||||
}
|
||||
for(const std::string& lib2 : depConfig.libs) {
|
||||
if (depLibSet.insert(lib2).second) {
|
||||
libsString+=std::format(" -l{}", lib2);
|
||||
}
|
||||
}
|
||||
for(const Dependency& dep2 : depConfig.dependencies) {
|
||||
if (depLibSet.insert(project.name).second) {
|
||||
libsString+=std::format(" -l{}", project.name);
|
||||
}
|
||||
}
|
||||
|
||||
libMutex.unlock();
|
||||
return;
|
||||
}
|
||||
if (depLibSet.insert(outputLib).second) {
|
||||
libsString+=std::format(" -l{}", outputLib);
|
||||
}
|
||||
throw std::runtime_error(std::format("Configuration: {} not found.", config.dependencies[i].configuration));
|
||||
|
||||
AddLibsRecursive(libsString, depLibSet, std::get<1>(config.dependencies[i]));
|
||||
libMutex.unlock();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -259,6 +330,15 @@ namespace Crafter {
|
|||
}
|
||||
|
||||
std::string files;
|
||||
|
||||
|
||||
for(const fs::path& cFile: config.c_files) {
|
||||
files+=std::format("{}_source.o ",(buildDir/cFile.filename()).string());
|
||||
if(!fs::exists((buildDir/cFile.filename()).string()+"_source.o") || fs::last_write_time(cFile.string()+".c") > fs::last_write_time((buildDir/cFile.filename()).string()+"_source.o")) {
|
||||
threads.emplace_back(&RunClang, std::format("clang {}.c -c -o {}_source.o", cFile.string(), (buildDir/cFile.filename()).string()));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> resultInterfaces(config.interfaces.size());
|
||||
|
||||
for(uint_fast32_t i = 0; i < config.interfaces.size(); i++) {
|
||||
|
|
@ -332,45 +412,6 @@ namespace Crafter {
|
|||
return buildResult;
|
||||
}
|
||||
|
||||
Project Project::LoadFromJSON(const fs::path& path) {
|
||||
if (!fs::exists(path)) {
|
||||
throw std::runtime_error(std::format("Project file: {} not found.", path.generic_string()));
|
||||
}
|
||||
|
||||
std::ifstream f(path);
|
||||
nlohmann::json data = nlohmann::json::parse(f);
|
||||
std::string name = data["name"].get<std::string>();
|
||||
|
||||
fs::path workingDir = path;
|
||||
workingDir.remove_filename();
|
||||
|
||||
std::vector<Configuration> configurations;
|
||||
nlohmann::json configs = data["configurations"];
|
||||
std::vector<Test> tests;
|
||||
nlohmann::json testJson = data["tests"];
|
||||
|
||||
for (nlohmann::json::iterator it = configs.begin(); it != configs.end(); ++it) {
|
||||
configurations.emplace_back(configs, (*it), workingDir);
|
||||
}
|
||||
|
||||
for (nlohmann::json::iterator it = testJson.begin(); it != testJson.end(); ++it) {
|
||||
tests.emplace_back(configs, (*it), workingDir);
|
||||
}
|
||||
|
||||
Project project(std::move(name), std::move(workingDir), std::move(configurations));
|
||||
if(data.contains("bin_dir")) {
|
||||
project.binDir = data["bin_dir"].get<std::string>();
|
||||
} else {
|
||||
project.binDir = "bin";
|
||||
}
|
||||
if(data.contains("build_dir")) {
|
||||
project.buildDir = data["build_dir"].get<std::string>();
|
||||
} else {
|
||||
project.buildDir = "build";
|
||||
}
|
||||
project.tests = std::move(tests);
|
||||
return project;
|
||||
}
|
||||
|
||||
std::vector<TestResult> Project::RunTests() {
|
||||
std::vector<TestResult> results;
|
||||
|
|
@ -396,6 +437,7 @@ namespace Crafter {
|
|||
BuildResult buildResult = Build(test.config, binDir, binDir, buildDir, test.config.name);
|
||||
|
||||
if(!buildResult.errors.empty()) {
|
||||
|
||||
return {test.config.name, buildResult.errors};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue