This commit is contained in:
parent
94db4f2780
commit
0819baf6d3
8 changed files with 170 additions and 117 deletions
|
|
@ -22,6 +22,7 @@ module;
|
|||
module Crafter.Build:Configuration_impl;
|
||||
import :Configuration;
|
||||
import std;
|
||||
import :Project;
|
||||
//import :Dependency;
|
||||
import :Shader;
|
||||
import :Module;
|
||||
|
|
@ -32,11 +33,11 @@ namespace Crafter {
|
|||
Configuration::Configuration(std::string&& name) : name(std::move(name)) {
|
||||
|
||||
}
|
||||
Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir) {
|
||||
SetDataFromJson(configs, config, workingDir);
|
||||
Configuration::Configuration(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir, const Project& project) {
|
||||
SetDataFromJson(configs, config, workingDir, project);
|
||||
}
|
||||
|
||||
void Configuration::SetDataFromJson(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir) {
|
||||
void Configuration::SetDataFromJson(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir, const Project& project) {
|
||||
type = static_cast<ConfigurationType>(-1);
|
||||
debug = static_cast<bool>(2);
|
||||
if(config.contains("extends")) {
|
||||
|
|
@ -44,7 +45,7 @@ namespace Crafter {
|
|||
for(const std::string& extendName : extends) {
|
||||
for (auto it : configs) {
|
||||
if(it["name"].get<std::string>() == extendName) {
|
||||
SetDataFromJson(configs, it, workingDir);
|
||||
SetDataFromJson(configs, it, workingDir, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -213,6 +214,11 @@ namespace Crafter {
|
|||
shaders.emplace_back(workingDir / it["path"].get<std::string>(), it["entrypoint"].get<std::string>(), static_cast<EShLanguage>(it["type"].get<std::uint32_t>()));
|
||||
}
|
||||
}
|
||||
if(config.contains("c_files")) {
|
||||
for (auto it : config["c_files"]) {
|
||||
c_files.push_back(workingDir / it.get<std::string>());
|
||||
}
|
||||
}
|
||||
if(config.contains("defines")) {
|
||||
for (auto it : config["defines"]) {
|
||||
defines.emplace_back(it["name"].get<std::string>(), it["value"].get<std::string>());
|
||||
|
|
@ -226,15 +232,26 @@ namespace Crafter {
|
|||
}
|
||||
if(config.contains("dependencies")) {
|
||||
for (auto it : config["dependencies"]) {
|
||||
std::string commit;
|
||||
std::string branch;
|
||||
if(it.contains("commit")){
|
||||
commit = it["commit"].get<std::string>();
|
||||
fs::path path = it["path"].get<std::string>();
|
||||
std::string configName = it["configuration"].get<std::string>();
|
||||
if(path.string().ends_with(".git")) {
|
||||
fs::path name = path.filename();
|
||||
name.replace_extension();
|
||||
if(!fs::exists(project.buildDir/name)) {
|
||||
if(it.contains("branch")) {
|
||||
system(std::format("cd {} && git clone {} && cd {} && git switch {}",project.buildDir.string(), path.string(), (project.buildDir/name).string(), it["branch"].get<std::string>()).c_str());
|
||||
} else if(it.contains("commit")){
|
||||
system(std::format("cd {} && git clone {} && cd {} && git checkout {}", project.buildDir.string(), path.string(), (project.buildDir/name).string(), it["commit"].get<std::string>()).c_str());
|
||||
} else {
|
||||
system(std::format("cd {} && git clone {}", project.buildDir.string(), path.string()).c_str());
|
||||
}
|
||||
if(it.contains("branch")){
|
||||
branch = it["branch"].get<std::string>();
|
||||
} else if(!it.contains("commit")) {
|
||||
system(std::format("cd {} && git pull", (project.buildDir/name).string()).c_str());
|
||||
}
|
||||
dependencies.emplace_back(it["path"].get<std::string>(), it["configuration"].get<std::string>(), std::move(commit), std::move(branch));
|
||||
path = project.buildDir/name/"project.json";
|
||||
}
|
||||
std::unique_ptr<Project> depProject = std::make_unique<Project>(std::move(path), configName);
|
||||
dependencies.emplace_back(std::move(depProject), depProject->configurations[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,6 @@ namespace Crafter {
|
|||
}
|
||||
}
|
||||
}
|
||||
return RunClang(std::format("{} {}.cpp -c -o {}_impl.o", clang, path.string(), (buildDir/path.filename()).string()));
|
||||
result = RunClang(std::format("{} {}.cpp -c -o {}_impl.o", clang, path.string(), (buildDir/path.filename()).string()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (depLibSet.insert(outputLib).second) {
|
||||
libsString+=std::format(" -l{}", outputLib);
|
||||
}
|
||||
|
||||
AddLibsRecursive(libsString, depLibSet, std::get<1>(config.dependencies[i]));
|
||||
libMutex.unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error(std::format("Configuration: {} not found.", config.dependencies[i].configuration));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -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};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Crafter {
|
|||
Test::Test(Configuration&& config) : config(std::move(config)) {
|
||||
config.type = CRAFTER_CONFIGURATION_TYPE_SHARED_LIBRARY;
|
||||
}
|
||||
Test::Test(const nlohmann::json& configs, const nlohmann::json& config, const fs::path& workingDir): config(configs, config, workingDir) {
|
||||
Test::Test(const nlohmann::json& configs, const nlohmann::json& config, const fs::path& workingDir, const Project& project): config(configs, config, workingDir, project) {
|
||||
this->config.type = CRAFTER_CONFIGURATION_TYPE_SHARED_LIBRARY;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,19 +66,18 @@ int main(int argc, char* argv[]) {
|
|||
projectPath = filepath;
|
||||
}
|
||||
|
||||
Project project = Project::LoadFromJSON(projectPath);
|
||||
Project project(std::move(projectPath));
|
||||
|
||||
if(command == "build") {
|
||||
std::tuple<Configuration&, BuildResult> config = project.Build(argument);
|
||||
std::cout << "amogus" << std::endl;
|
||||
if(std::get<1>(config).errors.empty()) {
|
||||
if(run){
|
||||
std::string binDir = std::format("{}/{}", project.binDir.string(), std::get<0>(config).name);
|
||||
if(std::get<0>(config).debug) {
|
||||
system(std::format("cd {} && ./{}", (fs::path(projectPath).parent_path()/binDir).string(), project.name).c_str());
|
||||
system(std::format("cd {} && ./{}", (project.path.parent_path()/binDir).string(), project.name).c_str());
|
||||
//system(std::format("cd {} && lldb -o run {}", (fs::path(projectPath).parent_path()/binDir).string(), project.name).c_str());
|
||||
} else {
|
||||
system(std::format("cd {} && ./{}", (fs::path(projectPath).parent_path()/binDir).string(), project.name).c_str());
|
||||
system(std::format("cd {} && ./{}", (project.path.parent_path()/binDir).string(), project.name).c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -33,28 +33,21 @@ namespace Crafter {
|
|||
Define(std::string&& name, std::string&& value): name(std::move(name)), value(std::move(value)) { }
|
||||
};
|
||||
|
||||
export class Dependency {
|
||||
public:
|
||||
std::string path;
|
||||
std::string configuration;
|
||||
std::string commit;
|
||||
std::string branch;
|
||||
Dependency(std::string&& path, std::string&& configuration, std::string&& commit, std::string&& branch): path(std::move(path)), configuration(std::move(configuration)), commit(std::move(commit)), branch(std::move(branch)) { }
|
||||
};;
|
||||
|
||||
export enum ConfigurationType {
|
||||
CRAFTER_CONFIGURATION_TYPE_EXECUTABLE,
|
||||
CRAFTER_CONFIGURATION_TYPE_LIBRARY,
|
||||
CRAFTER_CONFIGURATION_TYPE_SHARED_LIBRARY,
|
||||
};
|
||||
|
||||
export class Project;
|
||||
export class Configuration {
|
||||
public:
|
||||
std::string name;
|
||||
std::string standard;
|
||||
std::vector<std::unique_ptr<Module>> interfaces;
|
||||
std::vector<Implementation> implementations;
|
||||
std::vector<Dependency> dependencies;
|
||||
std::vector<fs::path> c_files;
|
||||
std::vector<std::tuple<std::shared_ptr<Project>, Configuration&>> dependencies;
|
||||
std::vector<Shader> shaders;
|
||||
std::vector<fs::path> additionalFiles;
|
||||
std::vector<Define> defines;
|
||||
|
|
@ -64,7 +57,7 @@ namespace Crafter {
|
|||
bool debug;
|
||||
std::vector<std::string> libs;
|
||||
Configuration(std::string&& name);
|
||||
Configuration(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir);
|
||||
void SetDataFromJson(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir);
|
||||
Configuration(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir, const Project& project);
|
||||
void SetDataFromJson(const nlohmann::json& configs, const nlohmann::json& config, fs::path workingDir, const Project& project);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,10 @@ namespace Crafter {
|
|||
fs::path path;
|
||||
std::vector<Configuration> configurations;
|
||||
std::vector<Test> tests;
|
||||
Project(fs::path&& path);
|
||||
Project(fs::path&& path, const std::string_view config);
|
||||
Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations);
|
||||
Project(std::string&& name, fs::path&& path, std::vector<Configuration>&& configurations, fs::path&& buildDir, fs::path&& binDir);
|
||||
static Project LoadFromJSON(const fs::path& path);
|
||||
std::tuple<Configuration&, BuildResult> Build(std::string_view configuration);
|
||||
std::tuple<Configuration&, BuildResult> Build(std::string_view configuration, const fs::path& binDir, const fs::path& outputDir, const fs::path& buildDir, std::string outputName);
|
||||
BuildResult Build(Configuration& configuration) const;
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@ namespace Crafter {
|
|||
std::string message;
|
||||
};
|
||||
|
||||
export class Project;
|
||||
export class Test {
|
||||
public:
|
||||
Configuration config;
|
||||
Test(Configuration&& name);
|
||||
Test(const nlohmann::json& configs, const nlohmann::json& config, const fs::path& workingDir);
|
||||
Test(const nlohmann::json& configs, const nlohmann::json& config, const fs::path& workingDir, const Project& project);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue