summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-07-17 07:32:30 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-07-17 07:36:57 +0100
commit20252df698106283d15ddf7d53f4e0dd9462666d (patch)
treebf77733ab5fddd3f09962cde9a22e9f1d485b6c9 /dev
parentcaecbd4e6eb2877b7e9bdd4fb2e4f3e370b336c9 (diff)
refactor! Lots of breaking changes to the codebase.
feat: Rename ‘btb‘ to ‘nebuild‘ to match nekernel.org's naming scheme. Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev')
-rw-r--r--dev/BuildKit/IManifestBuilder.h32
-rw-r--r--dev/BuildKit/Includes.h17
-rw-r--r--dev/BuildKit/JSONManifestBuilder.h30
-rw-r--r--dev/BuildKit/Macros.h34
-rw-r--r--dev/cli/CommandLine.cc77
-rw-r--r--dev/examples/example_01_hello_world/hello_world.cc7
-rw-r--r--dev/examples/example_01_hello_world/posix.json10
-rw-r--r--dev/examples/example_01_hello_world/win64.json10
-rw-r--r--dev/examples/example_02_libbtb/README.md7
-rw-r--r--dev/examples/example_02_libbtb/libbtb.cc15
-rw-r--r--dev/examples/example_02_libbtb/posix.json20
-rw-r--r--dev/examples/example_02_libbtb/win64.json19
-rw-r--r--dev/src/IManifestBuilder.cc6
-rw-r--r--dev/src/JSONManifestBuilder.cc153
14 files changed, 437 insertions, 0 deletions
diff --git a/dev/BuildKit/IManifestBuilder.h b/dev/BuildKit/IManifestBuilder.h
new file mode 100644
index 0000000..1c160c4
--- /dev/null
+++ b/dev/BuildKit/IManifestBuilder.h
@@ -0,0 +1,32 @@
+// ============================================================= //
+// nebuild
+// Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+// ============================================================= //
+
+#pragma once
+
+#include <BuildKit/Includes.h>
+#include <BuildKit/Macros.h>
+
+#define BTB_MANIFEST_BUILDER : public BTB::IManifestBuilder
+
+namespace BTB {
+/// @brief Builder interface class.
+/// @note This class is meant to be used as an interface.
+class IManifestBuilder {
+ public:
+ IManifestBuilder() = default;
+ virtual ~IManifestBuilder() = default;
+
+ IManifestBuilder& operator=(const IManifestBuilder&) = default;
+ IManifestBuilder(const IManifestBuilder&) = default;
+
+ /// @brief Builds a target using the implemented laguage.
+ /// @param arg_sz filename size
+ /// @param arg_val filename path.
+ /// @retval true succeeded.
+ /// @retval false failed.
+ virtual bool buildTarget(int arg_sz, const char* arg_val, const bool dry_run = false) = 0;
+ virtual const char* buildSystem() = 0;
+};
+} // namespace BTB \ No newline at end of file
diff --git a/dev/BuildKit/Includes.h b/dev/BuildKit/Includes.h
new file mode 100644
index 0000000..e321483
--- /dev/null
+++ b/dev/BuildKit/Includes.h
@@ -0,0 +1,17 @@
+// ============================================================= //
+// nebuild
+// Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+// ============================================================= //
+
+#ifndef BTB_INCLUDES_H
+#define BTB_INCLUDES_H
+
+#include <cstddef>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <thread>
+
+#endif // BTB_INCLUDES_H
diff --git a/dev/BuildKit/JSONManifestBuilder.h b/dev/BuildKit/JSONManifestBuilder.h
new file mode 100644
index 0000000..a4fe66b
--- /dev/null
+++ b/dev/BuildKit/JSONManifestBuilder.h
@@ -0,0 +1,30 @@
+// ============================================================= //
+// nebuild
+// Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+// ============================================================= //
+
+#pragma once
+
+#include <BuildKit/IManifestBuilder.h>
+#include <json.h>
+
+namespace BTB {
+/// @brief JSON builder
+class JSONManifestBuilder final BTB_MANIFEST_BUILDER {
+ public:
+ JSONManifestBuilder() = default;
+ ~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 build succeeded.
+ /// @retval false failed to build.
+ bool buildTarget(int arg_sz, const char* arg_val, const bool dry_run = false) override;
+ const char* buildSystem() override;
+};
+} // namespace BTB \ No newline at end of file
diff --git a/dev/BuildKit/Macros.h b/dev/BuildKit/Macros.h
new file mode 100644
index 0000000..1b1613d
--- /dev/null
+++ b/dev/BuildKit/Macros.h
@@ -0,0 +1,34 @@
+// ============================================================= //
+// nebuild
+// Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+// ============================================================= //
+
+#pragma once
+
+extern "C" {
+#include <assert.h>
+}
+
+#include <rang.h>
+
+#define LIKELY(ARG) ((ARG) ? assert(false) : ((void) 0))
+#define UNLIKELY(ARG) LIKELY(!(ARG))
+
+#define LIBBTB_VERSION "v0.0.1-libBTB"
+
+#define LIBBTB_VERSION_BCD 0x0001
+
+#define LIBBTB_VERSION_MAJOR 1
+#define LIBBTB_VERSION_MINOR 1
+#define LIBBTB_VERSION_PATCH 0
+
+#define LIBBTB_UNUSED(X) ((void) X)
+
+namespace BTB::Logger {
+/// @brief replacement for std::cout for BTB logging.
+inline std::ostream& info() noexcept {
+ auto& out = std::cout;
+ out << rang::fg::red << "nebuild: " << rang::style::reset;
+ return out;
+}
+} // namespace BTB::Logger
diff --git a/dev/cli/CommandLine.cc b/dev/cli/CommandLine.cc
new file mode 100644
index 0000000..e199e61
--- /dev/null
+++ b/dev/cli/CommandLine.cc
@@ -0,0 +1,77 @@
+
+// ============================================================= //
+// nebuild
+// Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+// ============================================================= //
+
+#include <BuildKit/Includes.h>
+#include <BuildKit/JSONManifestBuilder.h>
+
+static bool kFailed = false;
+static bool kDryRun = false;
+
+int main(int argc, char** argv) {
+ if (argc <= 1) return EXIT_FAILURE;
+
+ for (size_t index = 1; index < argc; ++index) {
+ std::string index_path = argv[index];
+
+ if (index_path == "-v" || index_path == "--version") {
+ BTB::Logger::info() << "Brought to you by Amlal El Mahrouss for the NeKernel project.\n";
+ BTB::Logger::info() << "© 2024-2025 Amlal El Mahrouss, all rights reserved.\n";
+
+ BTB::Logger::info()
+ << "Bugs, issues? Check out: https://github.com/nekernel-org/nebuild/issues\n";
+
+ return EXIT_SUCCESS;
+ } else if (index_path == "--dry-run") {
+ kDryRun = true;
+ continue;
+ } else if (index_path == "-h" || index_path == "--help") {
+ BTB::Logger::info() << "Usage: nebuild <file>\n";
+
+ return EXIT_SUCCESS;
+ }
+
+ if (index_path.starts_with("-")) {
+ BTB::Logger::info() << "error: unknown option '" << index_path << "'\n";
+
+ return EXIT_FAILURE;
+ }
+
+ std::thread job_build_thread(
+ [](std::string index_path) -> void {
+ BTB::IManifestBuilder* builder = nullptr;
+
+ const auto kJsonExtension = ".json";
+
+ if (index_path.ends_with(kJsonExtension)) {
+ builder = new BTB::JSONManifestBuilder();
+
+ if (!builder) {
+ kFailed = true;
+ return;
+ }
+ } else {
+ BTB::Logger::info() << "error: file '" << index_path << "' is not a JSON file!"
+ << std::endl;
+ kFailed = true;
+ return;
+ }
+
+ BTB::Logger::info() << "building manifest: " << index_path << std::endl;
+
+ if (builder && !builder->buildTarget(index_path.size(), index_path.c_str(), kDryRun)) {
+ kFailed = true;
+ }
+
+ delete builder;
+ builder = nullptr;
+ },
+ index_path);
+
+ job_build_thread.join();
+ }
+
+ return kFailed ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/dev/examples/example_01_hello_world/hello_world.cc b/dev/examples/example_01_hello_world/hello_world.cc
new file mode 100644
index 0000000..ae47ce8
--- /dev/null
+++ b/dev/examples/example_01_hello_world/hello_world.cc
@@ -0,0 +1,7 @@
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv) {
+ std::cout << "hello, world!\n";
+ return 0;
+}
diff --git a/dev/examples/example_01_hello_world/posix.json b/dev/examples/example_01_hello_world/posix.json
new file mode 100644
index 0000000..c3c8151
--- /dev/null
+++ b/dev/examples/example_01_hello_world/posix.json
@@ -0,0 +1,10 @@
+{
+ "compiler_path": "g++",
+ "compiler_std": "c++20",
+ "headers_path": ["lib"],
+ "sources_path": ["hello_world.cc"],
+ "output_name": "hello_world.elf",
+ "compiler_flags": ["-fPIC"],
+ "cpp_macros": ["FOO_MACRO"],
+ "run_after_build": true
+}
diff --git a/dev/examples/example_01_hello_world/win64.json b/dev/examples/example_01_hello_world/win64.json
new file mode 100644
index 0000000..4af5bdd
--- /dev/null
+++ b/dev/examples/example_01_hello_world/win64.json
@@ -0,0 +1,10 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": ["lib"],
+ "sources_path": ["hello_world.cc"],
+ "output_name": "hello_world.elf",
+ "compiler_flags": ["-fPIC"],
+ "cpp_macros": ["FOO_MACRO"],
+ "run_after_build": true
+}
diff --git a/dev/examples/example_02_libbtb/README.md b/dev/examples/example_02_libbtb/README.md
new file mode 100644
index 0000000..26ccb72
--- /dev/null
+++ b/dev/examples/example_02_libbtb/README.md
@@ -0,0 +1,7 @@
+# Notice for Deployment.
+
+In order to use libBTB, it shall live on the same directory,
+<br/>
+or within a directory recognized in the `$LD_LIBRARY_PATH` or `$DYLD_LIBRARY_PATH` variable.
+
+## Thanks in advance. \ No newline at end of file
diff --git a/dev/examples/example_02_libbtb/libbtb.cc b/dev/examples/example_02_libbtb/libbtb.cc
new file mode 100644
index 0000000..0b4d7c4
--- /dev/null
+++ b/dev/examples/example_02_libbtb/libbtb.cc
@@ -0,0 +1,15 @@
+#include <BuildKit/JSONManifestBuilder.h>
+#include <cstdlib>
+
+#ifndef _WIN32
+static auto kPath = "./posix.json";
+#else
+static auto kPath = ".\win64.json";
+#endif
+
+int main(int argc, char** argv) {
+ auto builder = new BTB::JSONManifestBuilder();
+ if (!builder) return EXIT_FAILURE;
+
+ return builder->buildTarget(strlen(kPath), kPath);
+}
diff --git a/dev/examples/example_02_libbtb/posix.json b/dev/examples/example_02_libbtb/posix.json
new file mode 100644
index 0000000..871712e
--- /dev/null
+++ b/dev/examples/example_02_libbtb/posix.json
@@ -0,0 +1,20 @@
+{
+ "compiler_path": "g++",
+ "compiler_std": "c++20",
+ "headers_path": [
+ "../../",
+ "../../vendor"
+ ],
+ "sources_path": [
+ "libbtb.cc"
+ ],
+ "output_name": "libbtb.elf",
+ "compiler_flags": [
+ "-L/usr/local/lib",
+ "-lBTB"
+ ],
+ "cpp_macros": [
+ "FOO_MACRO"
+ ],
+ "run_after_build": true
+} \ No newline at end of file
diff --git a/dev/examples/example_02_libbtb/win64.json b/dev/examples/example_02_libbtb/win64.json
new file mode 100644
index 0000000..658ee0f
--- /dev/null
+++ b/dev/examples/example_02_libbtb/win64.json
@@ -0,0 +1,19 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": [
+ "../../",
+ "../../vendor"
+ ],
+ "sources_path": [
+ "libbtb.cc"
+ ],
+ "output_name": "libbtb.exe",
+ "compiler_flags": [
+ "-lBTB"
+ ],
+ "cpp_macros": [
+ "FOO_MACRO"
+ ],
+ "run_after_build": true
+} \ No newline at end of file
diff --git a/dev/src/IManifestBuilder.cc b/dev/src/IManifestBuilder.cc
new file mode 100644
index 0000000..1397dd4
--- /dev/null
+++ b/dev/src/IManifestBuilder.cc
@@ -0,0 +1,6 @@
+// ============================================================= //
+// nebuild
+// Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+// ============================================================= //
+
+#include <BuildKit/IManifestBuilder.h>
diff --git a/dev/src/JSONManifestBuilder.cc b/dev/src/JSONManifestBuilder.cc
new file mode 100644
index 0000000..e93bcb7
--- /dev/null
+++ b/dev/src/JSONManifestBuilder.cc
@@ -0,0 +1,153 @@
+// ============================================================= //
+// nebuild
+// Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+// ============================================================= //
+
+#include <BuildKit/JSONManifestBuilder.h>
+
+using String = std::string;
+using JSON = nlohmann::json;
+
+namespace FS = std::filesystem;
+
+using namespace BTB;
+
+/// @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 building has succeeded.
+/// @retval false fail to build, see error message.
+bool JSONManifestBuilder::buildTarget(int arg_sz, const char* arg_val, const bool dry_run) {
+ String path;
+
+ if (!arg_val || arg_sz < 0) {
+ BTB::Logger::info() << "nebuild: error: file path is empty" << std::endl;
+ return false;
+ } else {
+ path += arg_val;
+
+ if (!FS::exists(path)) {
+ BTB::Logger::info() << "nebuild: error: file '" << path << "' does not exist" << std::endl;
+ return false;
+ }
+ }
+
+ try {
+ std::ifstream json(path);
+
+ if (!json.good()) {
+ BTB::Logger::info() << "nebuild: error: file '" << path << "' is not a valid JSON" << std::endl;
+ return false;
+ }
+
+ JSON json_obj = JSON::parse(json);
+
+ String compiler = json_obj["compiler_path"].get<String>();
+
+ JSON header_search_path = json_obj["headers_path"];
+ JSON sources_files = json_obj["sources_path"];
+
+ String command = compiler + " ";
+
+ for (auto& sources : sources_files) {
+ command += sources.get<String>() + " ";
+ }
+
+ for (auto& headers : header_search_path) {
+ command += "-I" + headers.get<String>() + " ";
+ }
+
+ JSON macros_list = json_obj["cpp_macros"];
+
+ for (auto& macro : macros_list) {
+ command += "-D" + macro.get<String>() + " ";
+ }
+
+ JSON compiler_flags = json_obj["compiler_flags"];
+
+ for (auto& flag : compiler_flags) {
+ command += flag.get<String>() + " ";
+ }
+
+ if (json_obj["compiler_std"].is_string())
+ command += "-std=" + json_obj["compiler_std"].get<String>() + " ";
+
+ command += "-o " + json_obj["output_name"].get<String>();
+
+ auto target = json_obj["output_name"].get<String>();
+
+ BTB::Logger::info() << "output path: " << target << "\n";
+ BTB::Logger::info() << "command: " << command << "\n";
+
+ try {
+ if (json_obj["dry_run"].get<bool>()) return true;
+ } catch (...) {
+ }
+
+ if (dry_run) {
+ return true;
+ }
+
+ auto ret_exec = std::system(command.c_str());
+
+ if (ret_exec > 0) {
+ BTB::Logger::info() << "error: exit with message: " << std::strerror(ret_exec) << "" << std::endl;
+ return false;
+ }
+
+ try {
+ if (json_obj["run_after_build"].get<bool>()) {
+ if (target.ends_with(".so")) {
+ BTB::Logger::info() << "error: can't open dynamic library, it mayn't have an entrypoint"
+ << std::endl;
+
+ return true;
+ } else if (target.ends_with(".dylib") || target.ends_with(".dll")) {
+ std::ifstream file = std::ifstream(target);
+ std::stringstream ss;
+
+ ss << file.rdbuf();
+
+ if (ss.str()[0] == 'O' && ss.str()[1] == 'p' && ss.str()[2] == 'e' && ss.str()[3] == 'n')
+ BTB::Logger::info()
+ << "error: can't open PEF dynamic library, it mayn't contain an entrypoint"
+ << std::endl;
+ else if (ss.str()[0] == 'n' && ss.str()[1] == 'e' && ss.str()[2] == 'p' &&
+ ss.str()[3] == 'O')
+ BTB::Logger::info()
+ << "error: can't open FEP dynamic library, it mayn't contain an entrypoint"
+ << std::endl;
+ else if (ss.str()[0] == 'M' && ss.str()[1] == 'Z')
+ BTB::Logger::info()
+ << "error: can't open MZ dynamic library, it mayn't contain an entrypoint"
+ << std::endl;
+ else if (ss.str()[0] == 0x7F && ss.str()[1] == 'E') {
+ BTB::Logger::info()
+ << "error: can't open ELF dynamic library, it mayn't contain an entrypoint"
+ << std::endl;
+ }
+
+ return true;
+ }
+
+#if defined(BTB_WINDOWS)
+ std::system((".\\" + target).c_str());
+#else
+ std::system(("./" + target).c_str());
+#endif
+ }
+ } catch (...) {
+ return true;
+ }
+ } catch (std::runtime_error& err) {
+ BTB::Logger::info() << "error: " << err.what() << std::endl;
+
+ return false;
+ }
+
+ return true;
+}
+
+const char* JSONManifestBuilder::buildSystem() {
+ return "json";
+}