From dfcf57aae1cd8eca79319e2a89b501c150f88cf1 Mon Sep 17 00:00:00 2001 From: Interfiber Date: Sun, 29 Sep 2024 15:24:13 -0400 Subject: [PATCH] task support --- CMakeLists.txt | 2 +- HConfig | 9 ++++++++- build.ninja | 20 ++++++++++++++++++-- include/grbc/generator.h | 6 ++++++ include/grbc/ninja.h | 5 +++++ include/grbc/spec.h | 21 ++++++++++++++++++++- include/grbc/state.h | 3 ++- spec/datatypes.md | 14 ++++++++++++++ spec/functions.md | 5 ++++- src/main.cc | 9 +++++++++ src/ninja.cc | 40 +++++++++++++++++++++++++++++++++++----- src/task.cc | 12 ++++++++++++ 12 files changed, 134 insertions(+), 12 deletions(-) create mode 100644 src/task.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 48dbda7..3e91ebc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,5 +7,5 @@ add_subdirectory("vendor/sol2") include_directories("include") include_directories("vendor/sol2/include") -add_executable(grbc src/main.cc src/utils.cc src/file.cc src/target_exe.cc src/platform.cc src/ninja.cc src/generator.cc src/target_lib.cc src/package.cc src/ext.cc src/ext_pkg_config.cc) +add_executable(grbc src/main.cc src/utils.cc src/file.cc src/target_exe.cc src/platform.cc src/ninja.cc src/generator.cc src/target_lib.cc src/package.cc src/ext.cc src/ext_pkg_config.cc src/task.cc src/ext_profiles.cc) target_link_libraries(grbc sol2 lua) \ No newline at end of file diff --git a/HConfig b/HConfig index 6f06b5c..8b10ad9 100644 --- a/HConfig +++ b/HConfig @@ -46,7 +46,8 @@ local grbc_lib = grbc_library(LibraryConfig.new({ grbc_file("src/generator.cc"), grbc_file("src/target_lib.cc"), grbc_file("src/package.cc"), - grbc_file("src/ext.cc") + grbc_file("src/ext.cc"), + grbc_file("src/task.cc") }, lib_type = LibraryType.Static, @@ -88,5 +89,11 @@ local grbc_exe = grbc_executable(ExecutableConfig.new({ include_dirs = {} })) +grbc_task(TaskConfig.new({ + name = "Clean build", + task_id = "clean", + shell_script = "ninja -t clean" +})) + -- Output the final build script grbc_build("ninja") diff --git a/build.ninja b/build.ninja index 8df481d..dd58c6b 100644 --- a/build.ninja +++ b/build.ninja @@ -1,4 +1,5 @@ -### GRBC BUILT-IN NINJA GENERATOR ### +### GENERATED BY THE GRBC BUILT-IN NINJA GENERATOR ### +### GENERATED ON: 1727637831 ### ## Default variables ## @@ -99,9 +100,14 @@ build $builddir/src/package.o: cxx src/package.cc build $builddir/src/ext.o: cxx src/ext.cc p_cflags = -Iinclude -Ivendor/sol2/include +## Compile: src/task.cc ## + +build $builddir/src/task.o: cxx src/task.cc + p_cflags = -Iinclude -Ivendor/sol2/include + ## Link: libgrbc.a ## -build $builddir/libgrbc.a: archive $builddir/src/file.o $builddir/src/ninja.o $builddir/src/platform.o $builddir/src/target_exe.o $builddir/src/utils.o $builddir/src/generator.o $builddir/src/target_lib.o $builddir/src/package.o $builddir/src/ext.o +build $builddir/libgrbc.a: archive $builddir/src/file.o $builddir/src/ninja.o $builddir/src/platform.o $builddir/src/target_exe.o $builddir/src/utils.o $builddir/src/generator.o $builddir/src/target_lib.o $builddir/src/package.o $builddir/src/ext.o $builddir/src/task.o ## Compile: src/main.cc ## @@ -114,3 +120,13 @@ build $builddir/grbc: link_cxx $builddir/src/main.o | $builddir/libgrbc.a $buil p_linker_flags = -llua -lm -ldl build/libgrbc.a build/libgrbc_extensions.a -O3 -Lbuild -Wl,-rpath,build:. p_cflags = +## clean ## +rule clean_task + command = ninja -t clean + description = Running task: Clean build (clean) + +build clean: clean_task + +build all: phony $builddir/libgrbc_extensions.a $builddir/libgrbc.a $builddir/grbc + +default all diff --git a/include/grbc/generator.h b/include/grbc/generator.h index 9f0385e..c978001 100644 --- a/include/grbc/generator.h +++ b/include/grbc/generator.h @@ -38,6 +38,12 @@ struct GeneratorTarget { std::vector link_target_commands; }; +struct GeneratorTask { + std::string description, id; + + std::string shell_script; +}; + typedef GeneratorResult (*Generator_Run)(); struct Generator { diff --git a/include/grbc/ninja.h b/include/grbc/ninja.h index ed03cec..1485c4e 100644 --- a/include/grbc/ninja.h +++ b/include/grbc/ninja.h @@ -49,3 +49,8 @@ ninja_build_rule_link_exe_target(const GeneratorLinkTargetCommand &link_cmd); */ std::string ninja_build_rule_link_lib_target(const GeneratorLinkTargetCommand &link_cmd); + +/** + * Generate a line which describes the given task + */ +std::string ninja_build_rule_task(const GeneratorTask &task); \ No newline at end of file diff --git a/include/grbc/spec.h b/include/grbc/spec.h index 2c49d0c..83fc198 100644 --- a/include/grbc/spec.h +++ b/include/grbc/spec.h @@ -128,6 +128,23 @@ struct ExecutableConfig { std::vector include_dirs{}; }; +struct TaskConfig { + TaskConfig(const sol::table &table) { + name = table.get("name"); + task_id = table.get("task_id"); + shell_script = table.get("shell_script"); + } + + /// Name of the task + std::string name; + + /// ID of the task + std::string task_id; + + /// Shell script content for this task + std::string shell_script; +}; + struct LibraryConfig { LibraryConfig(const sol::table &table) { name = table.get("name"); @@ -253,4 +270,6 @@ bool grbc_has_ext(const std::string &extension_id); std::string grbc_platform_file(PlatformType platform_type, const std::string &file_name); -bool grbc_is_ext_loaded(const std::string &extension_name); \ No newline at end of file +bool grbc_is_ext_loaded(const std::string &extension_name); + +void grbc_task(const TaskConfig &config); \ No newline at end of file diff --git a/include/grbc/state.h b/include/grbc/state.h index 52fd4b0..fdf06d6 100644 --- a/include/grbc/state.h +++ b/include/grbc/state.h @@ -11,6 +11,7 @@ struct GState { Platform current_platform{}; sol::state lua; + std::vector tasks; std::vector targets; std::vector generators; @@ -19,7 +20,7 @@ struct GState { std::vector extensions; std::string global_compiler_flags = ""; - std::string global_linker_flags = ""; + std::string global_linker_flags = " "; std::string ninja_output; diff --git a/spec/datatypes.md b/spec/datatypes.md index 0c1fd2e..12c9779 100644 --- a/spec/datatypes.md +++ b/spec/datatypes.md @@ -162,4 +162,18 @@ enum LanguageType { LanguageType_CPP, LanguageType_C }; +``` + +## TaskConfig +```c++ +struct TaskConfig { + /// Name of the task, can have spaces unlike task_id + string task_name; + + /// ID used when invoking the task, ex: ```ninja task:helloworld``` + string task_id; + + /// Shell script to be executed when this task is called + string shell_script; +}; ``` \ No newline at end of file diff --git a/spec/functions.md b/spec/functions.md index a61496c..49e6450 100644 --- a/spec/functions.md +++ b/spec/functions.md @@ -80,4 +80,7 @@ Generate a compiler flag to define a variable Get the given extension for a library file on the current platform ## [X] grbc_bake_package_config(config: PackageConfig) -> Package -Convert a PackageConfig into a Package \ No newline at end of file +Convert a PackageConfig into a Package + +## [X] grbc_task(config: TaskConfig) -> Void +Create a task and add it to the build script \ No newline at end of file diff --git a/src/main.cc b/src/main.cc index 592572a..8690e95 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,8 @@ #include "grbc/ext_pkg_config.h" #include "grbc/ext_profiles.h" #include "grbc/state.h" +#include +#include #define SOL_ALL_SAFETIES_ON 1 #include "grbc/helpers.h" @@ -80,6 +82,12 @@ int main() { &Package::compiler_flags, "linker_flags", &Package::linker_flags); + // TaskConfig + lua.new_usertype( + "TaskConfig", sol::constructors(), "name", + &TaskConfig::name, "task_id", &TaskConfig::task_id, "shell_script", + &TaskConfig::shell_script); + lua.set("grbc_want_version", grbc_want_version); lua.set("grbc_exception", grbc_exception); lua.set("grbc_get_config", grbc_get_config); @@ -107,6 +115,7 @@ int main() { lua.set("grbc_has_ext", grbc_has_ext); lua.set("grbc_platform_file", grbc_platform_file); lua.set("grbc_is_ext_loaded", grbc_is_ext_loaded); + lua.set("grbc_task", grbc_task); // Load generators diff --git a/src/ninja.cc b/src/ninja.cc index 2740699..8ecbdde 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -74,7 +74,8 @@ ninja_build_rule_compile_file(const GeneratorCompileCommand &compile_cmd) { result += "build $builddir/" + compile_cmd.object_file + ": " + compiler_rule + " " + compile_cmd.source_file + "\n"; - result += " p_cflags = " + compile_cmd.compiler_flags + GState::get().global_compiler_flags + "\n\n"; + result += " p_cflags = " + compile_cmd.compiler_flags + + GState::get().global_compiler_flags + "\n\n"; return result; } @@ -104,7 +105,8 @@ ninja_build_rule_link_lib_target(const GeneratorLinkTargetCommand &link_cmd) { result += "build $builddir/" + link_cmd.output_name + ": link_cxx " + file_list + "\n"; - result += " p_linker_flags = " + link_cmd.linker_flags + " -shared" + GState::get().global_linker_flags + "\n"; + result += " p_linker_flags = " + link_cmd.linker_flags + " -shared" + + GState::get().global_linker_flags + "\n"; result += " p_cflags = " + GState::get().global_compiler_flags + "\n\n"; } else { result += "build $builddir/" + link_cmd.output_name + ": archive " + @@ -129,7 +131,8 @@ ninja_build_rule_link_exe_target(const GeneratorLinkTargetCommand &link_cmd) { if (!link_cmd.libraries.empty()) { lib_list = "| "; for (auto &lib : link_cmd.libraries) { - if (lib.empty()) continue; + if (lib.empty()) + continue; lib_list += "$builddir/" + lib + " "; } @@ -141,12 +144,26 @@ ninja_build_rule_link_exe_target(const GeneratorLinkTargetCommand &link_cmd) { result += "build $builddir/" + link_cmd.output_name + ": link_cxx " + file_list + " " + lib_list + "\n"; - result += " p_linker_flags = " + link_cmd.linker_flags + GState::get().global_linker_flags + "\n"; + result += " p_linker_flags = " + link_cmd.linker_flags + + GState::get().global_linker_flags + "\n"; result += " p_cflags = " + GState::get().global_compiler_flags + "\n\n"; return result; } +std::string ninja_build_rule_task(const GeneratorTask &task) { + std::string result; + + result += "## " + task.id + " ##\n"; + result += "rule " + task.id + "_task\n"; + result += " command = " + task.shell_script + "\n"; + result += " description = " + task.description += "\n\n"; + + result += "build " + task.id + ": " + task.id + "_task\n\n"; + + return result; +} + // Ninja generator entry GeneratorResult ninja_generator() { @@ -156,7 +173,9 @@ GeneratorResult ninja_generator() { result.file_name = "build.ninja"; - result.content += "### GRBC BUILT-IN NINJA GENERATOR ###\n\n"; + result.content += "### GENERATED BY THE GRBC BUILT-IN NINJA GENERATOR ###\n"; + result.content += "### GENERATED ON: " + std::to_string(std::time(nullptr)) + " ###\n\n"; + result.content += ninja_build_default_variables(); result.content += ninja_build_rule_compile_cc(); result.content += ninja_build_rule_compile_cxx(); @@ -164,6 +183,8 @@ GeneratorResult ninja_generator() { result.content += ninja_build_rule_link_cxx(); result.content += ninja_build_rule_archive_library(); + std::string targets; + for (auto &target : GState::get().targets) { for (auto &compile_cmd : target.compile_commands) { result.content += ninja_build_rule_compile_file(compile_cmd); @@ -175,8 +196,17 @@ GeneratorResult ninja_generator() { } else { result.content += ninja_build_rule_link_lib_target(link_cmd); } + + targets += "$builddir/" + link_cmd.output_name + " "; } } + for (auto &task : GState::get().tasks) { + result.content += ninja_build_rule_task(task); + } + + result.content += "build all: phony " + targets + "\n\n"; + result.content += "default all\n"; + return result; } \ No newline at end of file diff --git a/src/task.cc b/src/task.cc new file mode 100644 index 0000000..f7baf49 --- /dev/null +++ b/src/task.cc @@ -0,0 +1,12 @@ +#include "grbc/generator.h" +#include "grbc/spec.h" +#include "grbc/state.h" + +void grbc_task(const TaskConfig &config) { + GeneratorTask task{}; + task.description = "Running task: " + config.name + " (" + config.task_id + ")"; + task.id = config.task_id; + task.shell_script = config.shell_script; + + GState::get().tasks.push_back(task); +} \ No newline at end of file