From 33b3c10e4df0c3da08cedb39a433233f0d455244 Mon Sep 17 00:00:00 2001 From: Nikola Petrov Date: Fri, 19 Jul 2024 01:51:47 +0200 Subject: [PATCH] use my_build --- .gitignore | 6 +- build.cpp | 69 +++++++++++ build.hpp | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 33 ----- 4 files changed, 421 insertions(+), 34 deletions(-) create mode 100644 build.cpp create mode 100644 build.hpp delete mode 100644 makefile diff --git a/.gitignore b/.gitignore index b971c4c..ebbd38b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ *.bin .vscode -main \ No newline at end of file +main +obj +*.lib +*.exe +*.pdb \ No newline at end of file diff --git a/build.cpp b/build.cpp new file mode 100644 index 0000000..7457d62 --- /dev/null +++ b/build.cpp @@ -0,0 +1,69 @@ +#define NO_Werror +#include "build.hpp" + +bool build = false; +bool clear = false; +bool run = false; +bool opt = false; + +int main(int argc, char const *argv[]) +{ + if (rebuild_my_self(__FILE__, argc, argv)) + return 1; + + for (int i = 1; i < argc; ++i) + { + if (!std::strcmp(argv[i], "opt")) + { + opt_flags = "-O3"; + opt = true; + } + if (!std::strcmp(argv[i], "build")) + build = true; + + if (!std::strcmp(argv[i], "run")) + run = true; + + if (!std::strcmp(argv[i], "cla")) + { + clear_all_build(); + clear = true; + } + } + + if (clear && !build) + { + return 0; + } + + std::filesystem::create_directory(OBJ_DIR); + + if (!opt) + { + + int res = compile_src_dir(); + + switch (res) + { + case 1: + compile_obj_dir(); + break; + case -1: + return 0; + } + + if (!std::filesystem::exists(BUILD_FILE)) + compile_obj_dir(); + } + else + { + build_as_one(); + } + + if (run) + { + command = {"./" + BUILD_FILE.string(), "Pot", "20", "1080"}; + nob_cmd_run_sync(command); + } + return 0; +} diff --git a/build.hpp b/build.hpp new file mode 100644 index 0000000..ae9576b --- /dev/null +++ b/build.hpp @@ -0,0 +1,347 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// #define EXT_INC +// #define EXT_OBJ +// #define NO_Werror + +std::filesystem::path OBJ_DIR = "obj"; +std::filesystem::path INC_DIR = "include"; +std::filesystem::path SRC_DIR = "source"; +std::filesystem::path BUILD_FILE = "main"; + +std::string cpp_compiler = "g++"; +std::string c_compiler = "gcc"; +std::string opt_flags = "-ggdb"; +std::vector command; + +enum class Color +{ + black, + red, + green, + yellow, + blue, + purple, + cyan, + white, + reset, +}; + +void pick_color(Color color) +{ + switch (color) + { + case Color::black: + printf("\033[0;30m"); + break; + case Color::red: + printf("\033[0;31m"); + break; + case Color::green: + printf("\033[0;32m"); + break; + case Color::yellow: + printf("\033[0;33m"); + break; + case Color::blue: + printf("\033[0;34m"); + break; + case Color::purple: + printf("\033[0;35m"); + break; + case Color::cyan: + printf("\033[0;36m"); + break; + case Color::white: + printf("\033[0;37m"); + break; + case Color::reset: + printf("\033[0m"); + break; + default: + break; + } +} + +void print_command(std::vector &arguments) +{ + pick_color(Color::cyan); + for (auto &&i : arguments) + { + printf("%s ", i.c_str()); + } + pick_color(Color::white); + printf("\n"); +} + +bool nob_cmd_run_sync(std::vector &arguments) +{ + print_command(arguments); + std::string command = ""; + + for (auto &&i : arguments) + { + command += " " + i; + } + + return std::system(command.c_str()) == 0; +} + +bool check_if_rebuild(const std::filesystem::path &org_path, const std::filesystem::path &new_path) +{ + if (!std::filesystem::exists(org_path)) + return false; + + if (!std::filesystem::exists(new_path)) + return true; + + auto file_time_one = std::filesystem::last_write_time(org_path); + auto file_time_two = std::filesystem::last_write_time(new_path); + return file_time_one > file_time_two; +} + +bool rebuild_my_self(std::filesystem::path src_path, int argc, const char **exec_path) +{ + std::string p = exec_path[0]; + std::filesystem::path exec = p; + + if (!check_if_rebuild(src_path, exec) && !check_if_rebuild(__FILE__, exec)) + return false; + +#ifndef _WIN32 + std::vector input; + + for (int i = 0; i < argc; ++i) + input.push_back(exec_path[i]); + + std::vector comand = {cpp_compiler, src_path.string(), "-o", exec_path[0], "-g"}; + if (!nob_cmd_run_sync(comand)) + return false; + + if (!nob_cmd_run_sync(input)) + return false; + + printf("rebuild\n"); +#else + pick_color(Color::red); + printf("rebuild me\n"); + pick_color(Color::white); +#endif + return true; +} + +struct nob_directory +{ + std::vector files; + std::vector dirs; +}; + +nob_directory get_all_files_in_dir(std::filesystem::path directory_path) +{ + namespace fs = std::filesystem; + + nob_directory dir; + if (!fs::is_directory(directory_path)) + return dir; + + std::list dirs; + dirs.push_back(directory_path); + dir.dirs.push_back(directory_path); + + while (!dirs.empty()) + { + for (const auto &entry : fs::directory_iterator(dirs.front())) + { + // Check if the entry is a regular file + if (fs::is_regular_file(entry)) + { + dir.files.push_back(entry.path()); + } + // Check if the entry is a directory + else if (fs::is_directory(entry)) + { + dirs.push_back(entry.path()); + dir.dirs.push_back(entry.path()); + } + } + dirs.pop_front(); + } + + return dir; +} + +std::vector get_includes(const std::filesystem::path &path) +{ + std::vector ret; + + std::ifstream ifs(path); + std::string line; + + while (std::getline(ifs, line)) + { + if (line.empty()) + continue; + + if (line[0] != '#') + break; + + if (line[line.size() - 1] == '\"') + { + ret.push_back(line.substr(10, line.length() - 10 - 1)); + } + } + + return ret; +} + +void clear_all_build() +{ + std::filesystem::remove(OBJ_DIR); + std::filesystem::remove(BUILD_FILE); +} + +#ifdef EXT_INC +int compile_src_dir(std::vector ext_inc) +#else +int compile_src_dir() +#endif +{ + nob_directory src_dir = get_all_files_in_dir(SRC_DIR); + nob_directory obj_dir; + + for (auto &&i : src_dir.dirs) + { + std::filesystem::create_directory(OBJ_DIR / i); + } + + std::unordered_set modified_heders; + nob_directory inc_dir = get_all_files_in_dir(INC_DIR); + + for (size_t i = 0; i < inc_dir.files.size(); i++) + { + if (check_if_rebuild(inc_dir.files[i], BUILD_FILE)) + { + std::string heder = inc_dir.files[i].string().substr(4); + modified_heders.insert(heder); + } + } + + command.clear(); + command.push_back(cpp_compiler); + command.push_back("-c"); + int src_loc = command.size(); + command.push_back(""); + command.push_back("-o"); + int obj_loc = command.size(); + command.push_back(""); + command.push_back(opt_flags); + +#ifdef EXT_INC + command.insert(command.end(), ext_inc.begin(), ext_inc.end()); +#endif + + command.push_back("-I" + INC_DIR.string()); + command.push_back("-std=c++23"); + command.push_back("-Wall"); +#ifndef NO_Werror + command.push_back("-Werror"); +#endif + + int build = 0; + for (auto &&i : src_dir.files) + { + std::filesystem::path tmp = i; + std::filesystem::path out = OBJ_DIR / tmp.replace_extension(".o"); + bool reb = false; + if (check_if_rebuild(i, out)) + reb = true; + + if (!reb) + { + std::vector incudes = get_includes(i); + for (auto &&j : incudes) + { + if (modified_heders.find(j) != modified_heders.end()) + { + reb = true; + break; + } + } + } + + if (reb) + { + command[src_loc] = i.string(); + command[obj_loc] = out.string(); + if (!nob_cmd_run_sync(command)) + return -1; + + build = 1; + } + } + return build; +} + +void compile_obj_dir() +{ + nob_directory obj_dir = get_all_files_in_dir(OBJ_DIR); + + command.clear(); + command.push_back(cpp_compiler); + + for (auto &&i : obj_dir.files) + { + command.push_back(i.string()); + } + + command.push_back("-o"); + command.push_back(BUILD_FILE.string()); + + nob_cmd_run_sync(command); +} + +#if defined(EXT_OBJ) && defined(EXT_INC) +void build_as_one(std::vector ext_obj, std::vector ext_inc) +#elif defined(EXT_OBJ) +void build_as_one(std::vector ext_obj) +#elif defined(EXT_INC) +void build_as_one(std::vector ext_inc) +#else +void build_as_one() +#endif +{ + nob_directory src_dir = get_all_files_in_dir(SRC_DIR); + + command.clear(); + command.push_back(cpp_compiler); + command.push_back("-o"); + command.push_back(BUILD_FILE.string()); + command.push_back(opt_flags); + +#ifdef EXT_INC + command.insert(command.end(), ext_inc.begin(), ext_inc.end()); +#endif + + command.push_back("-I" + INC_DIR.string()); + command.push_back("-std=c++23"); + command.push_back("-Wall"); +#ifndef NO_Werror + command.push_back("-Werror"); +#endif + for (auto &&i : src_dir.files) + { + command.push_back(i.string()); + } + +#ifdef EXT_OBJ + command.insert(command.end(), ext_obj.begin(), ext_obj.end()); +#endif + nob_cmd_run_sync(command); +} \ No newline at end of file diff --git a/makefile b/makefile deleted file mode 100644 index 413acc5..0000000 --- a/makefile +++ /dev/null @@ -1,33 +0,0 @@ -CC=g++ - -CFLAGS= -std=c++23 - -INCLUDE_DIR= include - -SRC_DIR= source - -# Get all cpp files from src directory -SRCS := $(wildcard $(SRC_DIR)/*.cpp) - -# Get all header files from include directory -HDRS := $(wildcard $(INCLUDE_DIR)/*.h) - -all: main run - -main: main.cpp $(SRCS) $(HDRS) - $(CC) $(CFLAGS) -O3 -I$(INCLUDE_DIR) $(SRCS) main.cpp -o main -Wall - -debug: main.cpp $(SRCS) $(HDRS) - $(CC) $(CFLAGS) -I$(INCLUDE_DIR) $(SRCS) -g main.cpp -o main -Wall - -install: main - sudo mv main /usr/bin/pasman - -run: main - ./main - -zip: - zip -r main.zip main.cpp $(INCLUDE_DIR) $(SRC_DIR) makefile - -clean: - rm main