diff options
| author | Amlal EL Mahrouss <amlalelmahrouss@icloud.com> | 2024-10-09 07:48:50 +0200 |
|---|---|---|
| committer | Amlal EL Mahrouss <amlalelmahrouss@icloud.com> | 2024-10-09 07:48:50 +0200 |
| commit | 904a70bf75ba9f5320cac611a2fab3f1fbd02425 (patch) | |
| tree | 3641832c9594993a51aab995258a4acf039c51ac | |
| parent | 35bf67c51b620b96827b75b0548f56d08415bb90 (diff) | |
IMP: Implement TOML C++ build system it's not perfect, but it's here.
Signed-off-by: Amlal EL Mahrouss <amlalelmahrouss@icloud.com>
| -rw-r--r-- | cli/AppMain.cxx | 2 | ||||
| -rw-r--r-- | inc/TOMLManifestBuilder.hxx | 2 | ||||
| -rw-r--r-- | src/JSONManifestBuilder.cxx | 69 | ||||
| -rw-r--r-- | src/TOMLManifestBuilder.cxx | 128 | ||||
| -rw-r--r-- | tests/example.toml | 12 |
5 files changed, 158 insertions, 55 deletions
diff --git a/cli/AppMain.cxx b/cli/AppMain.cxx index 0546aab..6719c19 100644 --- a/cli/AppMain.cxx +++ b/cli/AppMain.cxx @@ -55,7 +55,7 @@ int main(int argc, char** argv) return; } - std::cout << "btb: Building: " << index_path << std::endl; + std::cout << "btb: building: " << index_path << std::endl; if (builder && !builder->Build(index_path.size(), index_path.c_str())) { diff --git a/inc/TOMLManifestBuilder.hxx b/inc/TOMLManifestBuilder.hxx index 11406ce..8d9dfa2 100644 --- a/inc/TOMLManifestBuilder.hxx +++ b/inc/TOMLManifestBuilder.hxx @@ -1,5 +1,5 @@ // ============================================================= // -// btb +// btb // Copyright ZKA Technologies. // ============================================================= // diff --git a/src/JSONManifestBuilder.cxx b/src/JSONManifestBuilder.cxx index b9e186d..439155b 100644 --- a/src/JSONManifestBuilder.cxx +++ b/src/JSONManifestBuilder.cxx @@ -12,11 +12,11 @@ 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. +/// @brief Builds a JSON target from a JSON file. +/// @param arg_sz filename size (must be 1 or greater). +/// @param arg_val filename path (must be a valid JSON file). +/// @retval true succeeded building. +/// @retval false failed to build. bool JSONManifestBuilder::Build(int arg_sz, const char* arg_val) { std::string path; @@ -28,63 +28,72 @@ bool JSONManifestBuilder::Build(int arg_sz, const char* arg_val) else { path = arg_val; + + if (!std::filesystem::exists(path)) + { + std::cout << "btb: error: file '" << path << "' does not exist." << std::endl; + return false; + } } try { - std::ifstream json_obj(path); + std::ifstream json(path); - if (!json_obj.good()) + if (!json.good()) { return false; } - JSON buildme = JSON::parse(json_obj); + JSON json_obj = JSON::parse(json); - std::string compiler = buildme["compiler_path"].get<std::string>(); + std::string compiler = json_obj["compiler_path"].get<std::string>(); - JSON headerSearchPath = buildme["headers_path"]; - JSON sourceFiles = buildme["sources_path"]; + JSON header_search_path = json_obj["headers_path"]; + JSON sources_files = json_obj["sources_path"]; - std::string cmdLine = compiler + " "; + std::string command = compiler + " "; - for (auto& sources : sourceFiles) + for (auto& sources : sources_files) { - cmdLine += sources.get<std::string>() + " "; + command += sources.get<std::string>() + " "; } - for (auto& headers : headerSearchPath) + for (auto& headers : header_search_path) { - cmdLine += "-I" + headers.get<std::string>() + " "; + command += "-I" + headers.get<std::string>() + " "; } - JSON macrosList = buildme["cpp_macros"]; + JSON macros_list = json_obj["cpp_macros"]; - for (auto& macro : macrosList) + for (auto& macro : macros_list) { - cmdLine += "-D" + macro.get<std::string>() + " "; + command += "-D" + macro.get<std::string>() + " "; } - JSON compilerFlags = buildme["compiler_flags"]; + JSON compiler_flags = json_obj["compiler_flags"]; - for (auto& flag : compilerFlags) + for (auto& flag : compiler_flags) { - cmdLine += flag.get<std::string>() + " "; + command += flag.get<std::string>() + " "; } - if (buildme["compiler_std"].is_string()) - cmdLine += "-std=" + buildme["compiler_std"].get<std::string>() + " "; + if (json_obj["compiler_std"].is_string()) + command += "-std=" + json_obj["compiler_std"].get<std::string>() + " "; - cmdLine += "-o " + buildme["output_name"].get<std::string>(); + command += "-o " + json_obj["output_name"].get<std::string>(); - std::system(cmdLine.c_str()); + auto target = json_obj["output_name"].get<std::string>(); + + std::cout << "btb: output path: " << target << "\n"; + std::cout << "btb: command: " << command << "\n"; + + std::system(command.c_str()); try { - if (buildme["run_after_build"].get<bool>()) + if (json_obj["run_after_build"].get<bool>()) { - auto target = buildme["output_name"].get<std::string>(); - if (target.ends_with(".so") || target.ends_with(".dll")) { @@ -124,7 +133,7 @@ bool JSONManifestBuilder::Build(int arg_sz, const char* arg_val) } catch (...) { - // ignore error... + return true; } } catch (std::runtime_error& err) diff --git a/src/TOMLManifestBuilder.cxx b/src/TOMLManifestBuilder.cxx index 198c43b..8fd866d 100644 --- a/src/TOMLManifestBuilder.cxx +++ b/src/TOMLManifestBuilder.cxx @@ -5,29 +5,121 @@ #include <TOMLManifestBuilder.hxx> #include <toml.hxx> +#include <filesystem> #include <iostream> /// @brief Builds a TOML target. /// @param arg_sz filename size /// @param arg_val filename path. -/// @retval true succeeded. -/// @retval false failed. +/// @retval true succeeded to build. +/// @retval false failed to build. bool TOMLManifestBuilder::Build(int arg_sz, const char* arg_val) { - toml::table tbl; - - try - { - tbl = toml::parse_file(arg_val); - std::cout << tbl << "\n"; - - return true; - } - catch (const toml::parse_error& err) - { - std::cerr << "btb: error:" << err << "\n"; - return false; - } - - return false; + toml::table tbl; + + try + { + tbl = toml::parse_file(arg_val); + + if (tbl["CPlusPlus"].is_table()) + { + auto cxx = tbl["CPlusPlus"]; + std::string output_name = cxx["cxx_output_name"].value_or("assembly_out.exe"); + std::filesystem::path output_path = std::filesystem::current_path() / std::filesystem::path(output_name); + + std::vector<std::string> source_files_array; + + if (cxx["cxx_source_files"].is_array()) + { + auto header_files = cxx["cxx_source_files"].as_array(); + + for (size_t i = 0; i < header_files->size(); ++i) + { + source_files_array.push_back(header_files[i].as_string()->value_or(std::filesystem::current_path().string() + "*.cxx")); + } + } + + std::vector<std::string> include_directories_array; + + if (cxx["cxx_include_directories"].is_array()) + { + auto header_files = cxx["cxx_include_directories"].as_array(); + + for (size_t i = 0; i < header_files->size(); ++i) + { + include_directories_array.push_back(header_files[i].as_string()->value_or(std::filesystem::current_path().string())); + } + } + + std::vector<std::string> compiler_flags_array; + + if (cxx["cxx_compiler_flags"].is_array()) + { + auto header_files = cxx["cxx_compiler_flags"].as_array(); + + for (size_t i = 0; i < header_files->size(); ++i) + { + compiler_flags_array.push_back(header_files[i].as_string()->value_or(std::filesystem::current_path().string())); + } + } + + std::vector<std::string> linker_flags_array; + + if (cxx["cxx_linker_flags"].is_array()) + { + auto header_files = cxx["cxx_linker_flags"].as_array(); + + for (size_t i = 0; i < header_files->size(); ++i) + { + linker_flags_array.push_back(header_files[i].as_string()->value_or(std::filesystem::current_path().string())); + } + } + + // TODO: build the target + +#ifdef _WIN32 + std::string command = cxx["cxx_compiler"].value_or("g++.exe"); +#else + std::string command = cxx["cxx_compiler"].value_or("g++"); +#endif + + for (const auto& source_file : source_files_array) + { + command += " " + source_file; + } + + for (const auto& include_directory : include_directories_array) + { + command += " -I" + include_directory; + } + + for (const auto& compiler_flag : compiler_flags_array) + { + command += " " + compiler_flag; + } + + command += "-Wl,"; + + for (const auto& linker_flag : linker_flags_array) + { + command += "," + linker_flag; + } + + command += " -o " + output_path.string(); + + std::cout << "btb: command: " << command << "\n"; + std::cout << "btb: output path: " << output_path << "\n"; + + std::system(command.c_str()); + } + + return true; + } + catch (const toml::parse_error& err) + { + std::cerr << "btb: error:" << err << "\n"; + return false; + } + + return false; } diff --git a/tests/example.toml b/tests/example.toml index 64e38d2..1efa156 100644 --- a/tests/example.toml +++ b/tests/example.toml @@ -1,5 +1,7 @@ -[Linker] -output_name = "example.elf" -[Sources] -source_file = ["*.cxx"] - +[CPlusPlus] +cxx_compiler = "g++" +cxx_output_name = "example.elf" +cxx_source_files = ["*.cxx"] +cxx_include_directories = ["inc", "vendor"] +cxx_compiler_flags = ["-std=c++20"] +cxx_linker_flags = ["-lstdc++"] |
