From e59596db6f3e92098fdc0c3715f0a41cd10a0333 Mon Sep 17 00:00:00 2001 From: Amlal Date: Fri, 20 Sep 2024 15:50:58 +0200 Subject: Add new contract for buildable manifests. Signed-off-by: Amlal --- cli/AppMain.cxx | 69 +++++++++++++++++++++ cli/BuilderJSON.cxx | 62 ------------------- inc/IManifestBuilder.hxx | 19 ++++++ inc/JSONManifestBuilder.hxx | 22 +++++++ inc/manifest_builder.hxx | 22 ------- makefile | 2 +- src/IManifestBuilder.cxx | 1 + src/JSONManifestBuilder.cxx | 145 ++++++++++++++++++++++++++++++++++++++++++++ src/ManifestBuilder.cxx | 145 -------------------------------------------- 9 files changed, 257 insertions(+), 230 deletions(-) create mode 100644 cli/AppMain.cxx delete mode 100644 cli/BuilderJSON.cxx create mode 100644 inc/IManifestBuilder.hxx create mode 100644 inc/JSONManifestBuilder.hxx delete mode 100644 inc/manifest_builder.hxx create mode 100644 src/IManifestBuilder.cxx create mode 100644 src/JSONManifestBuilder.cxx delete mode 100644 src/ManifestBuilder.cxx diff --git a/cli/AppMain.cxx b/cli/AppMain.cxx new file mode 100644 index 0000000..e52daa3 --- /dev/null +++ b/cli/AppMain.cxx @@ -0,0 +1,69 @@ +#include "IManifestBuilder.hxx" +#include +#include +#include +#include +#include +#include + +int cJobIndex = 0; +bool cFailed = false; + +static IManifestBuilder* cBuilder = new JSONManifestBuilder(); + +int main(int argc, char** argv) +{ + cJobIndex = argc - 1; + + for (size_t index = 1; index < argc; ++index) + { + std::string index_json = argv[index]; + + if (index_json == "/Ver" || + index_json == "/Version") + { + std::cout << "Usage: btb \n"; + std::cout << "Filename is: " << argv[0] << "\n"; + + std::cout << "Check for issues at: www.el-mahrouss-logic.com/btb/issues\n"; + + std::cout << "Brought to you by Amlal El Mahrouss.\n"; + std::cout << "© ZKA Technologies, all rights reserved.\n"; + + return 0; + } + else if (index_json == "/?" || + index_json == "/Help") + { + std::cout << "btb: Build a JSON file: btb .json\n"; + std::cout << "btb: Build a TOML file: btb .toml\n"; + + return 0; + } + + std::thread job([](std::string index_json) -> void { + std::cout << "btb: Building " << index_json << std::endl; + + if (!cBuilder->Build(index_json.size(), index_json.c_str())) + { + std::string format = "btb "; + format += index_json; + + cFailed = true; + } + + --cJobIndex; + }, + index_json); + + job.detach(); + } + + // wait for completion of all jobs. + while (cJobIndex) + ; + + delete cBuilder; + + return cFailed ? 1 : 0; +} diff --git a/cli/BuilderJSON.cxx b/cli/BuilderJSON.cxx deleted file mode 100644 index cffbe45..0000000 --- a/cli/BuilderJSON.cxx +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int cJobIndex = 0; -bool cFailed = false; - -int main(int argc, char** argv) -{ - cJobIndex = argc - 1; - - for (size_t index = 1; index < argc; ++index) - { - std::string index_json = argv[index]; - - if (index_json == "/Ver" || - index_json == "/Version" || - index_json == "/?" || - index_json == "/Help") - { - std::cout << "btb: 🚀 Basic Tool for Building (JSON support).\n"; - std::cout << "btb: Brought to you by Amlal El Mahrouss.\n"; - std::cout << "btb: © ZKA Technologies, all rights reserved.\n"; - - if (index_json == "/?" || - index_json == "/Help") - std::cout << "btb: 🆘 run file: btb .json\n"; - - return 0; - } - - std::thread job([](std::string index_json) -> void { - std::cout << "btb: " << index_json << std::endl; - - ManifestBuilder builder; - - if (!builder.buildJson(index_json.size(), index_json.c_str())) - { - std::string format = "btb "; - format += index_json; - - perror(format.c_str()); - - cFailed = true; - } - - --cJobIndex; - }, - index_json); - - job.detach(); - } - - // wait for completion of all jobs. - while (cJobIndex) - ; - - return cFailed ? 1 : 0; -} diff --git a/inc/IManifestBuilder.hxx b/inc/IManifestBuilder.hxx new file mode 100644 index 0000000..404f8b2 --- /dev/null +++ b/inc/IManifestBuilder.hxx @@ -0,0 +1,19 @@ +#pragma once + +/// @brief Builder interface +class IManifestBuilder +{ +public: + explicit IManifestBuilder() = default; + virtual ~IManifestBuilder() = default; + + IManifestBuilder& operator=(const IManifestBuilder&) = default; + IManifestBuilder(const IManifestBuilder&) = default; + + /// @brief Builds a target. + /// @param arg_sz filename size + /// @param arg_val filename path. + /// @retval true succeeded. + /// @retval false failed. + virtual bool Build(int arg_sz, const char* arg_val) = 0; +}; diff --git a/inc/JSONManifestBuilder.hxx b/inc/JSONManifestBuilder.hxx new file mode 100644 index 0000000..5e29a96 --- /dev/null +++ b/inc/JSONManifestBuilder.hxx @@ -0,0 +1,22 @@ +#pragma once + +#include + +/// @brief JSON builder +class JSONManifestBuilder final : public IManifestBuilder +{ +public: + explicit JSONManifestBuilder() = default; + virtual ~JSONManifestBuilder() override = default; + + JSONManifestBuilder& operator=(const JSONManifestBuilder&) = default; + JSONManifestBuilder(const JSONManifestBuilder&) = default; + +public: + /// @brief Builds a JSON target. + /// @param arg_sz filename size + /// @param arg_val filename path. + /// @retval true succeeded. + /// @retval false failed. + virtual bool Build(int arg_sz, const char* arg_val) override; +}; diff --git a/inc/manifest_builder.hxx b/inc/manifest_builder.hxx deleted file mode 100644 index 5d882ff..0000000 --- a/inc/manifest_builder.hxx +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -class ManifestBuilder; - -/// @brief JSON builder -class ManifestBuilder final -{ -public: - explicit ManifestBuilder() = default; - ~ManifestBuilder() = default; - - ManifestBuilder& operator=(const ManifestBuilder&) = default; - ManifestBuilder(const ManifestBuilder&) = default; - -public: - /// @brief Builds a JSON target. - /// @param arg_sz filename size - /// @param arg_val filename path. - /// @retval true succeeded. - /// @retval false failed. - bool buildJson(int arg_sz, const char* arg_val); -}; diff --git a/makefile b/makefile index bf257aa..43b8cbb 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,7 @@ build-btb-core: .PHONY: build-btb build-btb: - sudo g++ -I./inc $(wildcard cli/*.cxx) -std=c++20 -L/usr/local -lbtb -o btb + sudo g++ -I./inc $(wildcard cli/*.cxx) $(wildcard src/*.cxx) -std=c++20 -L/usr/local -lbtb -o btb sudo cp btb /usr/local/bin .PHONY: help diff --git a/src/IManifestBuilder.cxx b/src/IManifestBuilder.cxx new file mode 100644 index 0000000..c1dbe51 --- /dev/null +++ b/src/IManifestBuilder.cxx @@ -0,0 +1 @@ +#include diff --git a/src/JSONManifestBuilder.cxx b/src/JSONManifestBuilder.cxx new file mode 100644 index 0000000..d456bb7 --- /dev/null +++ b/src/JSONManifestBuilder.cxx @@ -0,0 +1,145 @@ +// +// main.cpp +// btb +// +// Created by Amlal on 6/20/24. +// + +#include + +#include + +#include +#include + +#include +#include +#include + +using json = nlohmann::json; + +/// @brief Builds a JSON target. +/// @param arg_sz filename size +/// @param arg_val filename path. +/// @retval true succeeded. +/// @retval false failed. +bool JSONManifestBuilder::Build(int arg_sz, const char* arg_val) +{ + std::string path; + + if (arg_sz < 0) + { + return false; + } + else + { + path = arg_val; + } + + try + { + std::ifstream json_obj(path); + + if (!json_obj.good()) + { + return false; + } + + json buildme = json::parse(json_obj); + + std::string compiler = buildme["compiler_path"].get(); + + json headerSearchPath = buildme["headers_path"]; + json sourceFiles = buildme["sources_path"]; + + std::string cmdLine = compiler + " "; + + for (auto& sources : sourceFiles) + { + cmdLine += sources.get() + " "; + } + + for (auto& headers : headerSearchPath) + { + cmdLine += "-I" + headers.get() + " "; + } + + json macrosList = buildme["cpp_macros"]; + + for (auto& macro : macrosList) + { + cmdLine += "-D" + macro.get() + " "; + } + + json compilerFlags = buildme["compiler_flags"]; + + for (auto& flag : compilerFlags) + { + cmdLine += flag.get() + " "; + } + + if (buildme["compiler_std"].is_string()) + cmdLine += "-std=" + buildme["compiler_std"].get() + " "; + + cmdLine += "-o " + buildme["output_name"].get(); + + std::system(cmdLine.c_str()); + + try + { + if (buildme["run_after_build"].get()) + { + auto target = buildme["output_name"].get(); + + if (target.ends_with(".so") || + target.ends_with(".dll")) + { + std::cout << "btb: error: can't open DLL/SO, it mayn't contain an entrypoint." << std::endl; + return true; + } + else if (target.ends_with(".dll")) + { + auto file = std::ifstream(target); + std::stringstream ss; + ss << file.rdbuf(); + + if (ss.str()[0] == 'J' && + ss.str()[1] == 'o' && + ss.str()[2] == 'y' && + ss.str()[3] == '!') + std::cout << "btb: error: can't open Joy! DLL, it maynt't contain an entrypoint." << std::endl; + else if (ss.str()[0] == '!' && + ss.str()[1] == 'y' && + ss.str()[2] == 'o' && + ss.str()[3] == 'J') + std::cout << "btb: error: can't open !yoJ DLL, it maynt't contain an entrypoint." << std::endl; + else if (ss.str()[0] == 'M' && + ss.str()[1] == 'Z') + std::cout << "btb: error: can't open MZ DLL, it maynt't contain an entrypoint." << std::endl; + else if (ss.str()[0] == 0x7F && + ss.str()[1] == 'E') + { + std::cout << "btb: error: can't open ELF DLL, it maynt't contain an entrypoint." << std::endl; + } + + return true; + } + + std::system(("./" + target).c_str()); + } + } + catch (...) + { + // ignore error... + } + } + catch (std::runtime_error& err) + { + std::cout << "btb: error: " << err.what() << std::endl; + perror("btb"); + + return false; + } + + return true; +} diff --git a/src/ManifestBuilder.cxx b/src/ManifestBuilder.cxx deleted file mode 100644 index 70f3475..0000000 --- a/src/ManifestBuilder.cxx +++ /dev/null @@ -1,145 +0,0 @@ -// -// main.cpp -// btb -// -// Created by Amlal on 6/20/24. -// - -#include - -#include - -#include -#include - -#include -#include -#include - -using json = nlohmann::json; - -/// @brief Builds a JSON target. -/// @param arg_sz filename size -/// @param arg_val filename path. -/// @retval true succeeded. -/// @retval false failed. -bool ManifestBuilder::buildJson(int arg_sz, const char* arg_val) -{ - std::string path; - - if (arg_sz < 0) - { - return false; - } - else - { - path = arg_val; - } - - try - { - std::ifstream json_obj(path); - - if (!json_obj.good()) - { - return false; - } - - json buildme = json::parse(json_obj); - - std::string compiler = buildme["compiler_path"].get(); - - json headerSearchPath = buildme["headers_path"]; - json sourceFiles = buildme["sources_path"]; - - std::string cmdLine = compiler + " "; - - for (auto& sources : sourceFiles) - { - cmdLine += sources.get() + " "; - } - - for (auto& headers : headerSearchPath) - { - cmdLine += "-I" + headers.get() + " "; - } - - json macrosList = buildme["cpp_macros"]; - - for (auto& macro : macrosList) - { - cmdLine += "-D" + macro.get() + " "; - } - - json compilerFlags = buildme["compiler_flags"]; - - for (auto& flag : compilerFlags) - { - cmdLine += flag.get() + " "; - } - - if (buildme["compiler_std"].is_string()) - cmdLine += "-std=" + buildme["compiler_std"].get() + " "; - - cmdLine += "-o " + buildme["output_name"].get(); - - std::system(cmdLine.c_str()); - - try - { - if (buildme["run_after_build"].get()) - { - auto target = buildme["output_name"].get(); - - if (target.ends_with(".so") || - target.ends_with(".dll")) - { - std::cout << "btb: error: can't open DLL/SO, it mayn't contain an entrypoint." << std::endl; - return true; - } - else if (target.ends_with(".dll")) - { - auto file = std::ifstream(target); - std::stringstream ss; - ss << file.rdbuf(); - - if (ss.str()[0] == 'J' && - ss.str()[1] == 'o' && - ss.str()[2] == 'y' && - ss.str()[3] == '!') - std::cout << "btb: error: can't open Joy! DLL, it maynt't contain an entrypoint." << std::endl; - else if (ss.str()[0] == '!' && - ss.str()[1] == 'y' && - ss.str()[2] == 'o' && - ss.str()[3] == 'J') - std::cout << "btb: error: can't open !yoJ DLL, it maynt't contain an entrypoint." << std::endl; - else if (ss.str()[0] == 'M' && - ss.str()[1] == 'Z') - std::cout << "btb: error: can't open MZ DLL, it maynt't contain an entrypoint." << std::endl; - else if (ss.str()[0] == 0x7F && - ss.str()[1] == 'E') - { - std::cout << "btb: error: can't open ELF DLL, it maynt't contain an entrypoint." << std::endl; - } - - return true; - } - - std::system(("./" + target).c_str()); - } - } - catch (...) - { - // ignore error... - } - } - catch (std::runtime_error& err) - { - std::cout << "btb: error: " << err.what() << std::endl; - perror("btb"); - - return false; - } - - return true; -} -- cgit v1.2.3