diff --git a/.bazelrc b/.bazelrc index e3df8c2..7e572cb 100644 --- a/.bazelrc +++ b/.bazelrc @@ -4,8 +4,6 @@ build --@boost.dll//:use_std_fs query --@boost.dll//:use_std_fs build --@boost.process//:use_std_fs query --@boost.process//:use_std_fs -build --//:use_sdk_version -query --//:use_sdk_version build:windows --workspace_status_command=bazel/tools/wsc.cmd build:linux --workspace_status_command=bazel/tools/wsc.sh diff --git a/MODULE.bazel b/MODULE.bazel index 974cd3f..5884edb 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -9,7 +9,7 @@ bazel_dep(name = "nlohmann_json", version = "3.11.3") bazel_dep(name = "platforms", version = "0.0.10") bazel_dep(name = "rules_pkg", version = "0.10.1") bazel_dep(name = "bazel_skylib", version = "1.6.1") -bazel_dep(name = "ecsact_runtime", version = "0.6.7") +bazel_dep(name = "ecsact_runtime", version = "0.6.8") bazel_dep(name = "ecsact_interpret", version = "0.6.4") bazel_dep(name = "ecsact_codegen", version = "0.4.1") bazel_dep(name = "boost.dll", version = "1.83.0.bzl.2") diff --git a/ecsact/cli/BUILD.bazel b/ecsact/cli/BUILD.bazel index b499941..2a14c6e 100644 --- a/ecsact/cli/BUILD.bazel +++ b/ecsact/cli/BUILD.bazel @@ -6,15 +6,15 @@ package(default_visibility = ["//:__subpackages__"]) cc_library( name = "report_message", - copts = copts, hdrs = ["report_message.hh"], + copts = copts, ) cc_library( name = "report", - copts = copts, - hdrs = ["report.hh"], srcs = ["report.cc"], + hdrs = ["report.hh"], + copts = copts, deps = [ ":report_message", ], @@ -27,17 +27,17 @@ cc_stamp_header( cc_binary( name = "ecsact", - visibility = ["//visibility:public"], srcs = [ - "ecsact_cli.cc", "bazel_stamp_header.hh", + "ecsact_cli.cc", ], + copts = copts, defines = select({ "//:use_sdk_version_enabled": ["ECSACT_CLI_USE_SDK_VERSION"], "//:use_sdk_version_disabled": [], }), - copts = copts, stamp = 1, + visibility = ["//visibility:public"], deps = [ # "//ecsact/cli/commands:benchmark", "//ecsact/cli/commands:codegen", diff --git a/ecsact/cli/commands/BUILD.bazel b/ecsact/cli/commands/BUILD.bazel index df88e66..639e547 100644 --- a/ecsact/cli/commands/BUILD.bazel +++ b/ecsact/cli/commands/BUILD.bazel @@ -34,15 +34,14 @@ cc_library( hdrs = ["common.hh"], copts = copts, deps = [ - "@docopt.cpp//:docopt", "//ecsact/cli:report", "//ecsact/cli:report_message", "//ecsact/cli/detail:json_report", "//ecsact/cli/detail:text_report", + "@docopt.cpp//:docopt", ], ) - cc_library( name = "codegen", srcs = ["codegen.cc"], @@ -51,15 +50,15 @@ cc_library( deps = [ ":command", ":common", - "//ecsact/cli/commands/codegen:codegen", - "@magic_enum", - "@docopt.cpp//:docopt", + "//ecsact/cli/commands/codegen", "@boost.dll", - "@ecsact_interpret", + "@docopt.cpp//:docopt", "@ecsact_codegen//:plugin", "@ecsact_codegen//:plugin_validate", + "@ecsact_interpret", "@ecsact_runtime//:dylib", "@ecsact_runtime//:meta", + "@magic_enum", ], ) @@ -86,13 +85,14 @@ cc_library( ":common", "//ecsact/cli:report", "//ecsact/cli:report_message", - "//ecsact/cli/commands/build/recipe:taste", - "//ecsact/cli/commands/build/recipe:cook", - "//ecsact/cli/commands/build:cc_compiler", "//ecsact/cli/commands/build:build_recipe", + "//ecsact/cli/commands/build:cc_compiler", + "//ecsact/cli/commands/build/recipe:cook", + "//ecsact/cli/commands/build/recipe:taste", "//ecsact/cli/commands/recipe-bundle:build_recipe_bundle", - "@ecsact_interpret", "@docopt.cpp//:docopt", + "@ecsact_codegen//:plugin_validate", + "@ecsact_interpret", "@magic_enum", ], ) @@ -110,8 +110,9 @@ cc_library( "//ecsact/cli/commands/build:build_recipe", "//ecsact/cli/commands/recipe-bundle:build_recipe_bundle", "//ecsact/cli/detail:argv0", - "@ecsact_interpret", "@docopt.cpp//:docopt", + "@ecsact_codegen//:plugin_validate", + "@ecsact_interpret", "@magic_enum", ], ) diff --git a/ecsact/cli/commands/build.cc b/ecsact/cli/commands/build.cc index 98294d4..f9a9a56 100644 --- a/ecsact/cli/commands/build.cc +++ b/ecsact/cli/commands/build.cc @@ -21,10 +21,13 @@ #include "ecsact/cli/commands/build/recipe/cook.hh" #include "ecsact/cli/commands/build/recipe/taste.hh" #include "ecsact/cli/commands/recipe-bundle/build_recipe_bundle.hh" +#include "ecsact/codegen/plugin_validate.hh" +#include "codegen/codegen_util.hh" namespace fs = std::filesystem; using namespace std::string_view_literals; +using namespace std::string_literals; constexpr auto USAGE = R"docopt(Ecsact Build Command @@ -107,28 +110,15 @@ auto ecsact::cli::detail::build_command( // auto recipe_composite = std::optional{}; auto recipe_paths = args.at("--recipe").asStringList(); + for(auto& recipe_path_str : recipe_paths) { auto builtin_path = resolve_builtin_recipe(recipe_path_str, argv); - fs::path recipe_path; if(builtin_path) { - recipe_path = *builtin_path; - } else { - recipe_path = fs::path{recipe_path_str}; + recipe_path_str = builtin_path->string(); } - if(std::ranges::find(allowed_recipe_extensions, recipe_path.extension()) == - allowed_recipe_extensions.end()) { - ecsact::cli::report_error( - "Invalid recipe file extension {}", - recipe_path.extension().string() - ); - return 1; - } - - if(!recipe_path.has_extension()) { - recipe_path.replace_extension("ecsact-recipe-bundle"); - } + auto recipe_path = fs::path(recipe_path_str); if(recipe_path.extension() == ".ecsact-recipe-bundle") { auto bundle_result = ecsact::build_recipe_bundle::from_file(recipe_path); @@ -152,14 +142,36 @@ auto ecsact::cli::detail::build_command( // return 1; } - recipe_path = extract_result.recipe_path(); - recipe_path_str = recipe_path.generic_string(); + recipe_path_str = extract_result.recipe_path().generic_string(); ecsact::cli::report_info( "Extracted build recipe bundle to {}", recipe_path.parent_path().generic_string() ); } + } + + auto additional_plugin_dirs = std::vector{}; + for(fs::path recipe_path : recipe_paths) { + if(recipe_path.has_parent_path()) { + additional_plugin_dirs.emplace_back(recipe_path.parent_path()); + } + } + + for(const auto& recipe_path_str : recipe_paths) { + auto recipe_path = fs::path(recipe_path_str); + if(std::ranges::find(allowed_recipe_extensions, recipe_path.extension()) == + allowed_recipe_extensions.end()) { + ecsact::cli::report_error( + "Invalid recipe file extension {}", + recipe_path.extension().string() + ); + return 1; + } + + if(!recipe_path.has_extension()) { + recipe_path.replace_extension("ecsact-recipe-bundle"); + } auto recipe_result = build_recipe::from_yaml_file(recipe_path); @@ -173,6 +185,49 @@ auto ecsact::cli::detail::build_command( // } auto recipe = std::move(std::get(recipe_result)); + + for(auto& source : recipe.sources()) { + auto result = std::get_if(&source); + if(result) { + if(result->plugins.empty()) { + ecsact::cli::report_error( + "Recipe source build has no plugins {}", + recipe_path_str + ); + return 1; + } + + for(auto plugin : result->plugins) { + auto checked_plugin_paths = std::vector{}; + auto plugin_path = resolve_plugin_path( + {.plugin_arg = plugin, + .default_plugins_dir = get_default_plugins_dir(), + .additional_plugin_dirs = additional_plugin_dirs}, + checked_plugin_paths + ); + if(plugin_path) { + auto validate_result = + ecsact::codegen::plugin_validate(*plugin_path); + if(!validate_result.ok()) { + auto err_msg = "Plugin validation failed for '" + plugin + "'\n"; + for(auto err : validate_result.errors) { + err_msg += " - "s + to_string(err) + "\n"; + } + ecsact::cli::report_error("{}", err_msg); + return 1; + } + } else { + auto err_msg = "Unable to find codegen plugin '" + plugin + + "'. Paths checked:\n"; + for(auto& checked_path : checked_plugin_paths) { + err_msg += " - " + fs::relative(checked_path).string() + "\n"; + } + ecsact::cli::report_error("{}", err_msg); + } + } + } + } + if(!recipe_composite) { recipe_composite.emplace(std::move(recipe)); } else { @@ -290,13 +345,6 @@ auto ecsact::cli::detail::build_command( // compiler->compiler_version ); - auto additional_plugin_dirs = std::vector{}; - for(fs::path recipe_path : recipe_paths) { - if(recipe_path.has_parent_path()) { - additional_plugin_dirs.emplace_back(recipe_path.parent_path()); - } - } - auto cook_options = cook_recipe_options{ .files = file_paths, .work_dir = work_dir, diff --git a/ecsact/cli/commands/build/build_recipe.cc b/ecsact/cli/commands/build/build_recipe.cc index a803783..280bcfd 100644 --- a/ecsact/cli/commands/build/build_recipe.cc +++ b/ecsact/cli/commands/build/build_recipe.cc @@ -182,6 +182,8 @@ static auto parse_sources( // for(auto src : sources) { if(src.IsMap()) { + ecsact::cli::report_error("UHHH IT'S A MAP??"); + auto codegen = src["codegen"]; auto fetch = src["fetch"]; auto path = src["path"]; @@ -192,12 +194,20 @@ static auto parse_sources( // } if(codegen) { + ecsact::cli::report_error("CODEGEN??"); + auto entry = source_codegen{}; if(src["outdir"]) { entry.outdir = src["outdir"].as(); } if(codegen.IsSequence()) { + ecsact::cli::report_error("CODEGEN??!!"); + entry.plugins = codegen.as>(); + for(auto plugin : entry.plugins) { + ecsact::cli::report_error("CODEGEN PLUGINS: {}", plugin); + } + } else { entry.plugins.push_back(codegen.as()); } diff --git a/ecsact/cli/commands/build/recipe/BUILD.bazel b/ecsact/cli/commands/build/recipe/BUILD.bazel index d6a491b..0117946 100644 --- a/ecsact/cli/commands/build/recipe/BUILD.bazel +++ b/ecsact/cli/commands/build/recipe/BUILD.bazel @@ -5,22 +5,22 @@ package(default_visibility = ["//:__subpackages__"]) cc_library( name = "taste", - copts = copts, srcs = ["taste.cc"], hdrs = ["taste.hh"], + copts = copts, deps = [ "//ecsact/cli:report", "//ecsact/cli/commands/build:build_recipe", - "@ecsact_runtime//:dylib", "@boost.dll", + "@ecsact_runtime//:dylib", ], ) cc_library( name = "integrity", - copts = copts, srcs = ["integrity.cc"], hdrs = ["integrity.hh"], + copts = copts, deps = [ "@boringssl//:crypto", ], @@ -28,9 +28,30 @@ cc_library( cc_library( name = "cook", - copts = copts, srcs = ["cook.cc"], hdrs = ["cook.hh"], + copts = copts, + data = select({ + "//:use_sdk_version_enabled": [ + ], + "//:use_sdk_version_disabled": [ + "@ecsact_runtime//:ecsact/lib.hh", + "@ecsact_runtime//:ecsact/runtime.h", + "@ecsact_runtime//:ecsact/runtime/async.h", + "@ecsact_runtime//:ecsact/runtime/async.hh", + "@ecsact_runtime//:ecsact/runtime/common.h", + "@ecsact_runtime//:ecsact/runtime/core.h", + "@ecsact_runtime//:ecsact/runtime/core.hh", + "@ecsact_runtime//:ecsact/runtime/definitions.h", + "@ecsact_runtime//:ecsact/runtime/dylib.h", + "@ecsact_runtime//:ecsact/runtime/dynamic.h", + "@ecsact_runtime//:ecsact/runtime/meta.h", + "@ecsact_runtime//:ecsact/runtime/meta.hh", + "@ecsact_runtime//:ecsact/runtime/serialize.h", + "@ecsact_runtime//:ecsact/runtime/serialize.hh", + "@ecsact_runtime//:ecsact/runtime/static.h", + ], + }), defines = select({ "//:use_sdk_version_enabled": ["ECSACT_CLI_USE_SDK_VERSION"], "//:use_sdk_version_disabled": [], @@ -44,19 +65,19 @@ cc_library( deps = [ ":integrity", "//ecsact/cli:report", - "//ecsact/cli/detail:argv0", - "//ecsact/cli/detail:download", - "//ecsact/cli/detail:glob", - "//ecsact/cli/detail:archive", "//ecsact/cli/commands/build:build_recipe", "//ecsact/cli/commands/build:cc_compiler_config", "//ecsact/cli/commands/build:cc_defines_gen", "//ecsact/cli/commands/build:get_modules", - "//ecsact/cli/commands/codegen:codegen", + "//ecsact/cli/commands/codegen", "//ecsact/cli/commands/codegen:codegen_util", + "//ecsact/cli/detail:archive", + "//ecsact/cli/detail:argv0", + "//ecsact/cli/detail:download", + "//ecsact/cli/detail:glob", "//ecsact/cli/detail:proc_exec", - "@curl", "@boost.url", + "@curl", "@magic_enum", ] + select({ "//:use_sdk_version_enabled": [], @@ -64,25 +85,4 @@ cc_library( "@bazel_tools//tools/cpp/runfiles", ], }), - data = select({ - "//:use_sdk_version_enabled": [ - ], - "//:use_sdk_version_disabled": [ - "@ecsact_runtime//:ecsact/lib.hh", - "@ecsact_runtime//:ecsact/runtime.h", - "@ecsact_runtime//:ecsact/runtime/async.h", - "@ecsact_runtime//:ecsact/runtime/async.hh", - "@ecsact_runtime//:ecsact/runtime/common.h", - "@ecsact_runtime//:ecsact/runtime/core.h", - "@ecsact_runtime//:ecsact/runtime/core.hh", - "@ecsact_runtime//:ecsact/runtime/definitions.h", - "@ecsact_runtime//:ecsact/runtime/dylib.h", - "@ecsact_runtime//:ecsact/runtime/dynamic.h", - "@ecsact_runtime//:ecsact/runtime/meta.h", - "@ecsact_runtime//:ecsact/runtime/meta.hh", - "@ecsact_runtime//:ecsact/runtime/serialize.h", - "@ecsact_runtime//:ecsact/runtime/serialize.hh", - "@ecsact_runtime//:ecsact/runtime/static.h", - ], - }), ) diff --git a/ecsact/cli/commands/build/recipe/cook.cc b/ecsact/cli/commands/build/recipe/cook.cc index e56bf0a..3ed0255 100644 --- a/ecsact/cli/commands/build/recipe/cook.cc +++ b/ecsact/cli/commands/build/recipe/cook.cc @@ -584,16 +584,7 @@ auto cl_compile(compile_options options) -> int { cl_args.push_back("/diagnostics:column"); cl_args.push_back("/DECSACT_BUILD"); - // TODO(zaucy): Add debug mode - // if(options.debug) { - // compile_proc_args.push_back("/DEBUG:FULL"); - // compile_proc_args.push_back("/MDd"); - // compile_proc_args.push_back("/Z7"); - // compile_proc_args.push_back("/EHsc"); - // compile_proc_args.push_back("/bigobj"); - // } - - // cl_args.push_back("/we4530"); // treat exceptions as errors + cl_args.push_back("/we4530"); // treat exceptions as errors cl_args.push_back("/wd4530"); // ignore use of exceptions warning cl_args.push_back("/MD"); cl_args.push_back("/DNDEBUG"); @@ -605,6 +596,18 @@ auto cl_compile(compile_options options) -> int { std::format("{}\\", fs::path{options.work_dir}.lexically_normal().string()) ); + if(!options.debug) { + cl_args.push_back("/MD"); + cl_args.push_back("/DNDEBUG"); + } else { + cl_args.push_back("/FC"); // full source paths + cl_args.push_back("/MD"); + cl_args.push_back("/Z7"); + cl_args.push_back("/EHsc"); + cl_args.push_back("/bigobj"); + cl_args.push_back("/Od"); + } + auto generated_defines = ecsact::cli::cc_defines_gen(options.imports, options.exports); diff --git a/ecsact/cli/commands/recipe-bundle.cc b/ecsact/cli/commands/recipe-bundle.cc index 23073fc..ed1cd87 100644 --- a/ecsact/cli/commands/recipe-bundle.cc +++ b/ecsact/cli/commands/recipe-bundle.cc @@ -8,6 +8,7 @@ #include #include #include +#include "codegen/codegen_util.hh" #include "docopt.h" #include "magic_enum.hpp" #include "ecsact/cli/report.hh" @@ -17,10 +18,12 @@ #include "ecsact/cli/commands/common.hh" #include "ecsact/cli/commands/build/build_recipe.hh" #include "ecsact/cli/commands/recipe-bundle/build_recipe_bundle.hh" +#include "ecsact/codegen/plugin_validate.hh" namespace fs = std::filesystem; using namespace std::string_view_literals; +using namespace std::string_literals; constexpr auto USAGE = R"docopt(Ecsact Recipe Bundle Command @@ -82,7 +85,15 @@ auto ecsact::cli::detail::recipe_bundle_command( // auto recipe_composite = std::optional{}; auto recipe_paths = args.at("").asStringList(); - for(auto recipe_path : args.at("").asStringList()) { + + auto additional_plugin_dirs = std::vector{}; + for(fs::path recipe_path : recipe_paths) { + if(recipe_path.has_parent_path()) { + additional_plugin_dirs.emplace_back(recipe_path.parent_path()); + } + } + + for(auto recipe_path : recipe_paths) { auto recipe_result = build_recipe::from_yaml_file(recipe_path); if(std::holds_alternative(recipe_result)) { @@ -95,53 +106,91 @@ auto ecsact::cli::detail::recipe_bundle_command( // } auto recipe = std::move(std::get(recipe_result)); - if(!recipe_composite) { - recipe_composite.emplace(std::move(recipe)); - } else { - auto merge_result = build_recipe::merge(*recipe_composite, recipe); - if(std::holds_alternative(merge_result)) { - auto merge_error = std::get(merge_result); - ecsact::cli::report_error( - "Recipe Merge Error {}", - magic_enum::enum_name(merge_error) + + for(auto& source : recipe.sources()) { + auto result = std::get_if(&source); + if(result) { + if(result->plugins.empty()) { + ecsact::cli::report_error( + "Recipe source in recipe bundle has no plugins {}", + recipe_path + ); + return 1; + } + + for(auto plugin : result->plugins) { + auto checked_plugin_paths = std::vector{}; + auto plugin_path = resolve_plugin_path( + {.plugin_arg = plugin, + .default_plugins_dir = get_default_plugins_dir(), + .additional_plugin_dirs = additional_plugin_dirs}, + checked_plugin_paths + ); + if(plugin_path) { + auto validate_result = + ecsact::codegen::plugin_validate(*plugin_path); + + if(!validate_result.ok()) { + auto err_msg = "Plugin validation failed for '" + plugin + "'\n"; + for(auto err : validate_result.errors) { + err_msg += " - "s + to_string(err) + "\n"; + } + ecsact::cli::report_error("{}", err_msg); + return 1; + } + } else { + auto err_msg = "Unable to find codegen plugin '" + plugin + + "'. Paths checked:\n"; + for(auto& checked_path : checked_plugin_paths) { + err_msg += " - " + fs::relative(checked_path).string() + "\n"; + } + ecsact::cli::report_error("{}", err_msg); + } + } + } + + if(!recipe_composite) { + recipe_composite.emplace(std::move(recipe)); + } else { + auto merge_result = build_recipe::merge(*recipe_composite, recipe); + if(std::holds_alternative(merge_result)) { + auto merge_error = std::get(merge_result); + ecsact::cli::report_error( + "Recipe Merge Error {}", + magic_enum::enum_name(merge_error) + ); + return 1; + } + + recipe_composite.emplace(std::get(std::move(merge_result)) ); - return 1; } + } - recipe_composite.emplace(std::get(std::move(merge_result))); + if(!recipe_composite) { + ecsact::cli::report_error("No recipes"); + return 1; } - } - if(!recipe_composite) { - ecsact::cli::report_error("No recipes"); - return 1; - } + auto bundle = ecsact::build_recipe_bundle::create(*recipe_composite); - auto additional_plugin_dirs = std::vector{}; - for(fs::path recipe_path : recipe_paths) { - if(recipe_path.has_parent_path()) { - additional_plugin_dirs.emplace_back(recipe_path.parent_path()); + if(!bundle) { + ecsact::cli::report_error( + "Failed to create recipe bundle {}", + bundle.error().what() + ); + return 1; } - } - auto bundle = ecsact::build_recipe_bundle::create(*recipe_composite); + if(!write_file(output_path, bundle->bytes())) { + return 1; + } - if(!bundle) { - ecsact::cli::report_error( - "Failed to create recipe bundle {}", - bundle.error().what() + ecsact::cli::report_info( + "Created bundle {}", + fs::absolute(output_path).string() ); - return 1; - } - if(!write_file(output_path, bundle->bytes())) { - return 1; + return 0; } - - ecsact::cli::report_info( - "Created bundle {}", - fs::absolute(output_path).string() - ); - - return 0; } diff --git a/test_script.nu b/test_script.nu new file mode 100644 index 0000000..4eef237 --- /dev/null +++ b/test_script.nu @@ -0,0 +1,4 @@ + +(bazel run //ecsact/cli:ecsact -- build "C:/Users/Austin/Documents/programming/ecsact/ecsact_cli/test/build_recipe/test.ecsact" +--output=test +--recipe="C:/Program Files/WindowsApps/EcsactSdk_0.7.3.0_neutral__ngfmvx8bw6yvm/share/ecsact/recipes/ecsact_rt_entt.ecsact-recipe-bundle")